@reticlehq/server 2.6.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 +251 -33
- package/dist/bridge/bridge.d.ts +6 -1
- package/dist/bridge/bridge.js +27 -4
- 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 +68 -0
- package/dist/cli/chromium-hint.js +145 -0
- package/dist/cli/cli-doctor.js +31 -36
- package/dist/cli/cli-kill.d.ts +58 -0
- package/dist/cli/cli-kill.js +162 -0
- package/dist/cli/cli-launch.d.ts +18 -0
- package/dist/cli/cli-launch.js +32 -1
- 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 +36 -1
- package/dist/cli/cli-verify.js +2 -2
- package/dist/cli/doctor-daemon-line.js +10 -1
- 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 +139 -23
- 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/daemon/daemon-resilience.js +2 -2
- package/dist/daemon/loopback-alias.d.ts +32 -0
- package/dist/daemon/loopback-alias.js +80 -0
- package/dist/events/contradictions.d.ts +14 -0
- package/dist/events/contradictions.js +26 -17
- package/dist/events/predicate-eval.d.ts +26 -3
- package/dist/events/predicate-eval.js +284 -95
- package/dist/events/predicate-parse.d.ts +1 -1
- package/dist/events/predicate-parse.js +18 -4
- package/dist/events/predicate.js +170 -18
- package/dist/events/ring-buffer.d.ts +8 -0
- package/dist/events/ring-buffer.js +34 -1
- 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/honesty.d.ts +11 -0
- package/dist/honesty/honesty.js +9 -1
- 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 +27 -4
- package/dist/http-server.js +11 -1
- package/dist/index.js +29 -2
- package/dist/init/agent-rules.d.ts +16 -0
- package/dist/init/agent-rules.js +96 -17
- 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/detect.d.ts +8 -0
- package/dist/init/detect.js +15 -0
- package/dist/init/non-js-project.d.ts +27 -0
- package/dist/init/non-js-project.js +84 -0
- package/dist/init/plan-framework.d.ts +9 -0
- package/dist/init/plan-framework.js +72 -16
- package/dist/init/plan.d.ts +40 -4
- package/dist/init/plan.js +183 -43
- package/dist/init/run.d.ts +24 -2
- package/dist/init/run.js +181 -46
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/slash-command.js +46 -6
- package/dist/init/snippets.d.ts +64 -5
- package/dist/init/snippets.js +220 -31
- 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 +215 -23
- package/dist/mcp/mcp.js +58 -7
- package/dist/mcp/proxy-lifecycle.d.ts +20 -1
- package/dist/mcp/proxy-lifecycle.js +22 -1
- package/dist/pool/browser-pool.d.ts +22 -2
- package/dist/pool/browser-pool.js +44 -4
- package/dist/pool/playwright-launcher.js +10 -2
- 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/live-control-tools.js +39 -2
- package/dist/session/live-control.d.ts +7 -9
- package/dist/session/live-control.js +34 -1
- package/dist/session/no-session-diagnosis.d.ts +23 -4
- package/dist/session/no-session-diagnosis.js +128 -44
- 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/review-store.d.ts +19 -0
- package/dist/session/review-store.js +34 -5
- package/dist/session/session-lease.js +1 -1
- package/dist/session/session-manager.d.ts +9 -0
- package/dist/session/session-manager.js +11 -0
- package/dist/session/session.d.ts +8 -0
- package/dist/session/session.js +12 -0
- package/dist/status-payload.d.ts +13 -1
- package/dist/status-payload.js +6 -1
- package/dist/telemetry/app-instrumented.d.ts +37 -0
- package/dist/telemetry/app-instrumented.js +54 -0
- package/dist/telemetry/automation-hint.d.ts +17 -0
- package/dist/telemetry/automation-hint.js +71 -0
- package/dist/telemetry/bug-found.d.ts +0 -20
- package/dist/telemetry/bug-found.js +38 -21
- package/dist/telemetry/cli-telemetry.js +7 -1
- package/dist/telemetry/daemon-telemetry.d.ts +4 -4
- package/dist/telemetry/daemon-telemetry.js +8 -4
- 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.d.ts +3 -3
- package/dist/telemetry/session-metrics.js +9 -4
- package/dist/telemetry/telemetry.d.ts +7 -1
- package/dist/telemetry/telemetry.js +17 -2
- package/dist/telemetry/tool-refused.d.ts +19 -0
- package/dist/telemetry/tool-refused.js +55 -0
- package/dist/telemetry/verification-of.js +72 -8
- package/dist/temp-dir.d.ts +27 -0
- package/dist/temp-dir.js +46 -0
- package/dist/tools/act-tools.js +77 -11
- package/dist/tools/assert-grade.d.ts +1 -1
- package/dist/tools/assert-grade.js +27 -5
- package/dist/tools/assert-verdict.js +25 -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 +70 -5
- package/dist/tools/feedback-invite.js +1 -1
- package/dist/tools/invoke-tool.js +149 -32
- 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-kit.d.ts +52 -5
- package/dist/tools/tool-kit.js +55 -24
- package/dist/tools/tool-surface.js +28 -9
- package/dist/tools/tools.js +38 -4
- package/dist/visual/capture-cleanup.d.ts +16 -0
- package/dist/visual/capture-cleanup.js +39 -0
- package/dist/visual/visual-tools.d.ts +18 -0
- package/dist/visual/visual-tools.js +24 -5
- package/docs/README.md +56 -11
- package/docs/actions.mdx +87 -0
- package/docs/agent-cheatsheet.md +102 -26
- 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 +23 -19
- 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 +101 -46
- package/docs/telemetry-events.mdx +430 -0
- package/docs/telemetry.md +63 -50
- 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,387 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Beyond the verify loop
|
|
3
|
+
description: Coverage, storage, fake clocks, autonomous crawling, visual diffing and network mocking. What Reticle does once look-act-observe-assert is not enough.
|
|
4
|
+
icon: sparkles
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Most of the time you want the verify loop. Look, act, observe, assert.
|
|
8
|
+
|
|
9
|
+
These are the tools for the times you want something else, and they are the ones people are most surprised exist. All of them live in the cold tail, reachable through [`reticle_run`](/tools-tools-and-run).
|
|
10
|
+
|
|
11
|
+
## Available anywhere
|
|
12
|
+
|
|
13
|
+
These work through the always-on SDK, in any connected session.
|
|
14
|
+
|
|
15
|
+
### Coverage: what you have not driven yet
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{ "tool": "reticle_coverage" }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"total": 3,
|
|
24
|
+
"exercised": 0,
|
|
25
|
+
"untouched": [
|
|
26
|
+
{ "ref": "e3", "label": "textbox \"Email\"" },
|
|
27
|
+
{ "ref": "e4", "label": "textbox \"Password\"" },
|
|
28
|
+
{ "ref": "e5", "label": "button \"Sign in\"" }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Not code coverage. Control coverage: which interactive elements this session has actually touched.
|
|
34
|
+
|
|
35
|
+
Useful at the end of a drive, when the agent is about to report success. "I verified the page" reads differently next to `exercised: 0`.
|
|
36
|
+
|
|
37
|
+
### Storage: the persistence layer
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{ "tool": "reticle_storage" }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"local": {},
|
|
46
|
+
"session": { "__reticle_ref_base": "100", "__reticle_session": "lease-0cee1313…" },
|
|
47
|
+
"cookies": {}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
localStorage, sessionStorage and readable cookies.
|
|
52
|
+
|
|
53
|
+
This is where the "logged in but nothing persisted" bug lives. A login can fire its success signal, mutate state, and write nothing. Reload, and you are back at the login screen.
|
|
54
|
+
|
|
55
|
+
<Tip>
|
|
56
|
+
`storageKeysChanged` already appears in every `act_and_wait` summary, so you often do not need
|
|
57
|
+
this tool. Read it there first.
|
|
58
|
+
</Tip>
|
|
59
|
+
|
|
60
|
+
### Clock: freeze time, skip the wait
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "tool": "reticle_clock", "args": { "freeze": true } }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "frozen": true }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{ "tool": "reticle_clock", "args": { "advanceMs": 5000 } }
|
|
72
|
+
{ "tool": "reticle_clock", "args": { "reset": true } }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Toasts that auto-dismiss, debounced search, polling, session timeouts, retry backoff. All of these are normally verified by sleeping, which is slow and flaky in equal measure.
|
|
76
|
+
|
|
77
|
+
Freeze the clock, advance it by exactly the interval, assert the consequence. No sleeping, no guessing, and the same result on a fast laptop and a loaded CI runner.
|
|
78
|
+
|
|
79
|
+
### Crawl: click everything, report anomalies
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{ "tool": "reticle_crawl", "args": { "maxSteps": 6 } }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"interactiveFound": 3,
|
|
88
|
+
"stepsRun": 3,
|
|
89
|
+
"anomalies": [],
|
|
90
|
+
"counts": { "consoleErrors": 0, "failedRequests": 0, "deadControls": 0, "contradictions": 0 },
|
|
91
|
+
"visited": ["- textbox \"Email\"", "- textbox \"Password\"", "- button \"Sign in\""],
|
|
92
|
+
"truncated": false
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Autonomously clicks every reachable control and reports what went wrong. No script, no plan. The counts are the useful part: `deadControls` and `contradictions` are the two that indicate a real problem rather than a busy page.
|
|
97
|
+
|
|
98
|
+
This is the tool for an app you did not write and do not understand yet.
|
|
99
|
+
|
|
100
|
+
<Warning>
|
|
101
|
+
It clicks **everything**, so point it at a dev environment. `maxSteps` bounds it, defaulting to
|
|
102
|
+
25.
|
|
103
|
+
</Warning>
|
|
104
|
+
|
|
105
|
+
### Reconcile: what the API said versus what rendered
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{ "tool": "reticle_reconcile" }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Compares the data an endpoint returned against what the page actually displays.
|
|
112
|
+
|
|
113
|
+
The bug it catches is specific and common: the API returned ten rows, the table shows nine, and nothing errored. Neither the network log nor the DOM is wrong on its own. Only the comparison is.
|
|
114
|
+
|
|
115
|
+
### Domain: which of your flows actually prove anything
|
|
116
|
+
|
|
117
|
+
The most useful tool nobody knows about.
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{ "tool": "reticle_domain" }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"flowCount": 47,
|
|
126
|
+
"coverage": { "asserted": 14, "presenceOnly": 2, "assertionFree": 31 },
|
|
127
|
+
"gaps": {
|
|
128
|
+
"declaredUntestedSignals": [
|
|
129
|
+
"deploy:created",
|
|
130
|
+
"deploy:shipped",
|
|
131
|
+
"modal:opened",
|
|
132
|
+
"toast:shown",
|
|
133
|
+
"…"
|
|
134
|
+
],
|
|
135
|
+
"declaredUntestedTestids": ["deploy-submit", "drawer", "palette", "…"]
|
|
136
|
+
},
|
|
137
|
+
"summary": "47 flows: 14 asserted, 2 presence-only, 31 assertion-free. 13 declared signal(s) no flow asserts. 33 flow(s) assert no consequence."
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Read that summary again. Thirty-one of forty-seven flows **assert no consequence**, which means they replay green whatever the app does. That is a suite that looks like coverage and is not.
|
|
142
|
+
|
|
143
|
+
Each flow comes back graded, with the consequence that must hold and a risk level:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"name": "deploy-journey",
|
|
148
|
+
"grade": "asserted",
|
|
149
|
+
"mustHold": "nav:changed",
|
|
150
|
+
"risk": { "level": "high", "reason": "last run drifted", "lastStatus": "drift" }
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"name": "console-compose",
|
|
157
|
+
"grade": "assertion-free",
|
|
158
|
+
"warning": "This flow performs actions but asserts no observable consequence, so it will pass even if the feature is broken. Add a consequence assertion with reticle_annotate (assert-signal / assert-net) or a success-state."
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`declaredUntestedSignals` is the other half: signals your app emits that no flow ever checks. It is a to-do list for your test suite, generated from what the app says about itself.
|
|
163
|
+
|
|
164
|
+
<Tip>
|
|
165
|
+
Run this before writing a new flow. It tells you what is already covered, what is covered badly,
|
|
166
|
+
and which declared signal has never been asserted. All three are better starting points than
|
|
167
|
+
guessing.
|
|
168
|
+
</Tip>
|
|
169
|
+
|
|
170
|
+
### Baselines: semantic snapshots, not pixels
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{ "tool": "reticle_baseline", "args": { "action": "save", "name": "checkout-empty" } }
|
|
174
|
+
{ "tool": "reticle_baseline", "args": { "action": "diff", "name": "checkout-empty" } }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Records the meaningful state of a page and compares later. Structure and content rather than pixels, so a font change does not fail your check and a missing row does.
|
|
178
|
+
|
|
179
|
+
## Needs a driven browser
|
|
180
|
+
|
|
181
|
+
Four tools apply their effects through the Chrome DevTools Protocol. The always-on SDK cannot do that, so they need a browser Reticle is driving.
|
|
182
|
+
|
|
183
|
+
<Warning>
|
|
184
|
+
**A pooled lease is not enough.** Verified: acquiring one with `reticle_lease` and calling these
|
|
185
|
+
still returns `{ "ok": false, "reason": "no-cdp-provider" }` and `"no-visual-provider"`.
|
|
186
|
+
|
|
187
|
+
Point `RETICLE_CDP_URL` at a Chrome started with `--remote-debugging-port`. That is currently the reliable route.
|
|
188
|
+
|
|
189
|
+
</Warning>
|
|
190
|
+
|
|
191
|
+
### Screenshots and visual diffing
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{ "tool": "reticle_screenshot", "args": { "name": "login-baseline" } }
|
|
195
|
+
{ "tool": "reticle_visual_diff", "args": { "baseline": "login-baseline" } }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
<Warning>
|
|
199
|
+
Note the asymmetry. `reticle_screenshot` names the baseline with **`name`**; `reticle_visual_diff`
|
|
200
|
+
refers to it with **`baseline`**. Passing `name` to the diff is rejected, and it is an easy
|
|
201
|
+
mistake to make twice.
|
|
202
|
+
</Warning>
|
|
203
|
+
|
|
204
|
+
`fullPage` captures the whole scroll height. `ref` or `clip` scopes to one element or region. `threshold` sets the pixel-difference tolerance, defaulting to `0.01`, and `masks` excludes regions that are expected to change.
|
|
205
|
+
|
|
206
|
+
Reticle reads program truth, not pixels, so this is the deliberate exception: a font that failed to load or a compositing glitch is only visible in the actual frame.
|
|
207
|
+
|
|
208
|
+
### Viewport pinning
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{ "tool": "reticle_viewport", "args": { "width": 1280, "height": 800 } }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Fixes the viewport so a visual baseline is reproducible across machines. Without it, a diff taken on a laptop and re-run in CI compares two different layouts and fails for a reason nobody wants to debug.
|
|
215
|
+
|
|
216
|
+
### Network mocking
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"tool": "reticle_network_mock",
|
|
221
|
+
"args": { "mocks": [{ "urlContains": "/api/deploys", "status": 500 }] }
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Return a 500, force offline, or delay a response. First matching rule wins. `clear: true` turns it off.
|
|
226
|
+
|
|
227
|
+
Most error states have never actually run. This is how you find out whether yours works, without touching the backend or waiting for a real outage to tell you.
|
|
228
|
+
|
|
229
|
+
## Flows: record once, replay forever
|
|
230
|
+
|
|
231
|
+
The loop closer, and the reason Reticle is not only an interactive tool.
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{ "tool": "reticle_record", "args": { "action": "start", "recordingName": "ship-a-deploy" } }
|
|
235
|
+
{ "tool": "reticle_record", "args": { "action": "stop", "recordingName": "ship-a-deploy" } }
|
|
236
|
+
{ "tool": "reticle_flow_save", "args": { "flowName": "ship-a-deploy" } }
|
|
237
|
+
{ "tool": "reticle_flow_verify" }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
<Warning>
|
|
241
|
+
The argument names are not interchangeable. `reticle_record` takes **`recordingName`**,
|
|
242
|
+
`reticle_flow_save` takes **`flowName`**, and neither accepts `name`. Reticle rejects the call
|
|
243
|
+
rather than guessing, which is the right call and still costs you a turn.
|
|
244
|
+
</Warning>
|
|
245
|
+
|
|
246
|
+
Stopping a recording returns a **large** payload. A one-click recording came back at roughly 63,000 characters, and 69,000 of the 70,000 were the raw `events` array. There is currently no way to cap it: `max_events` and `filters` are rejected, even though the response's own `cost.recommendation` suggests them.
|
|
247
|
+
|
|
248
|
+
The parts you actually want are tiny. Read these and ignore the rest:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"program": { "name": "ship-a-deploy", "steps": [{ "tool": "reticle_act", "stable": true, "args": { … } }] },
|
|
253
|
+
"proposedConsequences": [
|
|
254
|
+
{ "predicate": { "kind": "signal", "name": "auth:granted" }, "tier": 0, "label": "signal \"auth:granted\" fires" },
|
|
255
|
+
{ "predicate": { "kind": "state", "store": "app", "path": "auth" }, "tier": 1, "label": "state \"app\" changes" },
|
|
256
|
+
{ "predicate": { "kind": "net", "method": "POST", "urlContains": "/api/login", "status": 200 }, "tier": 1, "label": "POST /api/login responds" }
|
|
257
|
+
],
|
|
258
|
+
"summary": { "total": 440, "network": 1, "consoleErrors": 0, "signals": 1 }
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`proposedConsequences` is the useful part and the reason to record at all. Reticle watched the interaction and worked out what would have proved it, ranked by strength. Tier 0 is the app's own signal. You do not have to invent the assertion; you pick one.
|
|
263
|
+
|
|
264
|
+
### Saving and replaying
|
|
265
|
+
|
|
266
|
+
```json
|
|
267
|
+
{ "tool": "reticle_flow_save", "args": { "flowName": "ship-a-deploy" } }
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"name": "ship-a-deploy",
|
|
273
|
+
"stepCount": 1,
|
|
274
|
+
"assertions": {
|
|
275
|
+
"grade": "assertion-free",
|
|
276
|
+
"warning": "This flow performs actions but asserts no observable consequence, so it will pass even if the feature is broken."
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Reticle grades the flow as you save it, and tells you when you have just created a test that cannot fail. Take the warning seriously: an assertion-free flow replays green whatever the app does.
|
|
282
|
+
|
|
283
|
+
A replay against a drifted app names what moved and where:
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"status": "drift",
|
|
288
|
+
"decision": {
|
|
289
|
+
"whatChanged": "testid \"login-submit\" not found",
|
|
290
|
+
"whereInSource": "src/components/Login.tsx:81",
|
|
291
|
+
"suggestedFix": "rebind the anchor to \"sign-out\" (closest survivor)"
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
`reticle_flow_heal` proposes the rebind. It refuses when it is not confident:
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"status": "unhealable",
|
|
301
|
+
"applied": false,
|
|
302
|
+
"message": "drift found, but no nearest match cleared the confidence floor (HEAL_CONFIDENCE_MIN=0.5); file left untouched; add a data-testid or fix the flow by hand"
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Flows live in `.reticle/` as human-readable files, so they are reviewed in pull requests and diffed like code. They anchor on meaning, a testid plus a signal, rather than volatile refs or coordinates.
|
|
307
|
+
|
|
308
|
+
<Card title="Flows in full" icon="repeat" href="/flows">
|
|
309
|
+
Recording, replay, self-healing, and what lives in `.reticle/`.
|
|
310
|
+
</Card>
|
|
311
|
+
|
|
312
|
+
## Handing results to something else
|
|
313
|
+
|
|
314
|
+
### The CI artifact
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{ "tool": "reticle_run_export" }
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
```json
|
|
321
|
+
{
|
|
322
|
+
"schemaVersion": 1,
|
|
323
|
+
"runId": "11fd8ee9-2820-4bfa-bfe3-e4eeb111af26",
|
|
324
|
+
"durationMs": 41968,
|
|
325
|
+
"project": { "name": "reticle", "framework": "other" },
|
|
326
|
+
"agent": { "id": "reticle-mcp", "kind": "coding-agent" },
|
|
327
|
+
"flows": [
|
|
328
|
+
{ "name": "suite-404", "status": "pass", "steps": 3, "oracle": "fault:injected" },
|
|
329
|
+
{
|
|
330
|
+
"name": "deploy-journey",
|
|
331
|
+
"status": "fail",
|
|
332
|
+
"steps": 1,
|
|
333
|
+
"failureReason": "testid \"login-submit\" not found"
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
"verdict": { "status": "partial", "confidence": "high", "blockingRisks": 0 }
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
A versioned, machine-readable record of a verification run. This is what you hand to CI, a dashboard, or a platform embedding Reticle in its pipeline.
|
|
341
|
+
|
|
342
|
+
`oracle` on a passing flow names the consequence that made it a pass, so a green row says what it proved rather than only that it was green.
|
|
343
|
+
|
|
344
|
+
### The capability contract
|
|
345
|
+
|
|
346
|
+
```json
|
|
347
|
+
{ "tool": "reticle_contract_save" }
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{ "saved": true, "path": ".reticle/contract.json", "testidCount": 49, "signalCount": 16 }
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Persists the app's live capability registry to a git-checked file. A fresh agent can read it without booting the app, and a diff shows when someone removes a signal something depended on.
|
|
355
|
+
|
|
356
|
+
### Talking to the human
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{ "tool": "reticle_session", "args": { "action": "narrate", "text": "Checking the deploy flow." } }
|
|
360
|
+
{ "tool": "reticle_session", "args": { "action": "review" } }
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
`narrate` writes a line into the presenter panel, so the person watching knows what you are doing. `review` drains the bugs they pinned on elements from that panel:
|
|
364
|
+
|
|
365
|
+
```json
|
|
366
|
+
{ "marks": [], "pendingCount": 0 }
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
An empty list here is a real reading, not a missing one.
|
|
370
|
+
|
|
371
|
+
## Discovering the rest
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{ "tool": "reticle_tools" }
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Returns every tool with a one-line summary, and the profile currently in force. Load the full argument grammar for the ones you want before calling them:
|
|
378
|
+
|
|
379
|
+
```json
|
|
380
|
+
{ "names": ["reticle_network_mock", "reticle_clock"] }
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
<Tip>
|
|
384
|
+
Do this rather than guessing at arguments. Reticle refuses a call with unknown parameters rather
|
|
385
|
+
than running it, and says why: *"NOT applied, so any result would be an answer to a different
|
|
386
|
+
question."* Good behaviour, but a wasted turn you can skip.
|
|
387
|
+
</Tip>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle affected
|
|
3
|
+
description: List which saved flows must re-verify for a set of changed files.
|
|
4
|
+
icon: code-branch
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle affected` answers one question: given these changed files, which saved flows cover them? It is the foundation the [gate](/cli/gate) and [watch](/cli/watch) are built on, and it costs your agent nothing per turn because it runs in the environment.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @reticlehq/server affected [--since <ref>] [file...]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Arguments and flags
|
|
14
|
+
|
|
15
|
+
| Argument | Type | Default | What it does |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| `file...` | strings, positional | none | Explicit changed files |
|
|
18
|
+
| `--since <ref>` | string | `HEAD` when no files are given | Also include files git reports as changed since this ref |
|
|
19
|
+
|
|
20
|
+
With nothing after it, `reticle affected` means the working tree against `HEAD`. It used to be a usage error, while the rule `reticle init` writes into the agent's own instruction file told the agent to run it.
|
|
21
|
+
|
|
22
|
+
## What it prints
|
|
23
|
+
|
|
24
|
+
One `reticle_affected` line. Real capture from this repository, with the file and flow lists trimmed for length:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"t": "2026-08-14T19:38:46.407Z",
|
|
29
|
+
"event": "reticle_affected",
|
|
30
|
+
"changedFiles": ["docs/cli.mdx", "packages/server/src/tools/e2e-surface-drift.test.ts"],
|
|
31
|
+
"affected": ["deploy-journey", "verify-route", "console-compose"],
|
|
32
|
+
"unknownProvenance": ["deploy-journey", "verify-route", "console-compose"]
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Field | Meaning |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `changedFiles` | The resolved file set: your positional arguments plus whatever `--since` added |
|
|
39
|
+
| `affected` | Saved flows that cover at least one of those files |
|
|
40
|
+
| `unknownProvenance` | Flows with no recorded source mapping. They are listed as affected because the safe assumption is that they might be |
|
|
41
|
+
|
|
42
|
+
## Exit codes
|
|
43
|
+
|
|
44
|
+
Always `0`. A load error is logged as `reticle_affected_failed`, not thrown. Use [`reticle gate`](/cli/gate) when you want a non-zero exit.
|
|
45
|
+
|
|
46
|
+
## Worked example
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx @reticlehq/server affected --since origin/main
|
|
50
|
+
npx @reticlehq/server affected src/components/Login.tsx
|
|
51
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle capsules
|
|
3
|
+
description: List the saved fail-to-pass bug capsules recorded from failed assertions.
|
|
4
|
+
icon: capsules
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle capsules` lists what is in `.reticle/capsules`. A capsule is a minimal failing reproduction plus the consequence that should have held. Replay one with the `reticle_flow_replay` tool.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @reticlehq/server capsules
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
No flags.
|
|
14
|
+
|
|
15
|
+
## What it prints
|
|
16
|
+
|
|
17
|
+
One `reticle_capsules` line: a `count` and an array. Real capture from this repository, trimmed to three of the sixty-three entries:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"event": "reticle_capsules",
|
|
22
|
+
"count": 63,
|
|
23
|
+
"capsules": [
|
|
24
|
+
{
|
|
25
|
+
"id": "1786713193695-e23",
|
|
26
|
+
"origin": "failed-assert",
|
|
27
|
+
"expected": "declared consequence",
|
|
28
|
+
"observed": "no element matched {\"role\":\"dialog\"} in state 'visible'",
|
|
29
|
+
"steps": 1
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "1786696531874-e103",
|
|
33
|
+
"origin": "failed-assert",
|
|
34
|
+
"expected": "signal auth:granted",
|
|
35
|
+
"observed": "signal \"auth:granted\" never fired",
|
|
36
|
+
"steps": 1
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "1785653101906-e3",
|
|
40
|
+
"origin": "failed-assert",
|
|
41
|
+
"expected": "declared consequence",
|
|
42
|
+
"observed": "not settled: 236 request(s) still in flight",
|
|
43
|
+
"steps": 1
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Field | Meaning |
|
|
50
|
+
| ---------- | ------------------------------------------------ |
|
|
51
|
+
| `id` | Capsule id, timestamp plus a cursor |
|
|
52
|
+
| `flow` | Present when the capsule came from a named flow |
|
|
53
|
+
| `origin` | How it was captured, for example `failed-assert` |
|
|
54
|
+
| `expected` | The consequence that was declared |
|
|
55
|
+
| `observed` | What actually happened |
|
|
56
|
+
| `steps` | How many steps the reproduction is |
|
|
57
|
+
|
|
58
|
+
## Exit codes
|
|
59
|
+
|
|
60
|
+
| Code | Meaning |
|
|
61
|
+
| ---- | ------------------------------------------------------------------------ |
|
|
62
|
+
| `0` | Listed, even when the count is zero |
|
|
63
|
+
| `1` | The capsule store could not be read. Logged as `reticle_capsules_failed` |
|
|
64
|
+
|
|
65
|
+
## Worked example
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx @reticlehq/server capsules | jq '.capsules[] | select(.origin == "failed-assert") | .observed'
|
|
69
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle cloud commands
|
|
3
|
+
description: Sign in, link a repository, and read runs and regressions from Reticle Cloud.
|
|
4
|
+
icon: cloud
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Ten subcommands bind this repository to Reticle Cloud so runs and flows land on a dashboard. They dispatch before the local parser, so `reticle login` is one tool, not a second binary.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @reticlehq/server <login|logout|whoami|link|project|config|push|runs|regression|share>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
These are thin clients over the `/v1` API. The moat is the server, not the verbs.
|
|
14
|
+
|
|
15
|
+
## Where credentials live
|
|
16
|
+
|
|
17
|
+
| Path | Contents | Secret |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `~/.reticle/session.json` | `{ url, token, orgName }` from `reticle login` | Yes |
|
|
20
|
+
| `~/.reticle/credentials.json` | Project-scoped API keys from `reticle link`, keyed by `projectId` | Yes |
|
|
21
|
+
| `<repo>/.reticle/cloud.json` | `{ projectId, projectName, url, sync, verify }`. The non-secret binding | No, commit it |
|
|
22
|
+
|
|
23
|
+
Auth for any command is `RETICLE_CLOUD_KEY` from the environment (the agent path) if set, otherwise the login token. `RETICLE_CLOUD_URL` overrides the endpoint; the default is `http://localhost:8890`.
|
|
24
|
+
|
|
25
|
+
## The commands
|
|
26
|
+
|
|
27
|
+
### `reticle login`
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx @reticlehq/server login # browser device flow (the default)
|
|
31
|
+
npx @reticlehq/server login --email you@acme.com # headless: requests a code
|
|
32
|
+
npx @reticlehq/server login --email you@acme.com --code 123456 # headless: exchanges it
|
|
33
|
+
npx @reticlehq/server login --email you@acme.com --org "Acme" # --org is consulted only for a brand new account
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
With no `--email`, it runs a browser device flow like `gh auth login`: fetch a device and user code, open the browser to approve, poll until confirmed. With `--email` it keeps the two-step code path for CI and servers, because it proves you own the inbox before handing out a session. A local cloud whose dev mailer cannot deliver echoes the code back and completes in one command.
|
|
37
|
+
|
|
38
|
+
### `reticle logout`
|
|
39
|
+
|
|
40
|
+
Empties `session.json`. Per-project keys in `credentials.json` stay. Prints `{ "loggedOut": true }`.
|
|
41
|
+
|
|
42
|
+
### `reticle whoami`
|
|
43
|
+
|
|
44
|
+
The one call to make when you do not know your state. Real capture:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"loggedInAs": "acme",
|
|
49
|
+
"repo": {
|
|
50
|
+
"attached": false,
|
|
51
|
+
"projectId": null,
|
|
52
|
+
"url": null,
|
|
53
|
+
"sync": { "runs": true, "memory": true, "flows": true },
|
|
54
|
+
"verify": "local"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
An unattached repo also gets a next-step nudge on stderr, telling you to run `reticle link`.
|
|
60
|
+
|
|
61
|
+
### `reticle link`
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx @reticlehq/server link [--project <name|id>]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Binds this repository to a cloud project. With a login token it **mints** a project-scoped key, so there is nothing to paste. With `RETICLE_CLOUD_KEY` already set, it resolves that key's project instead. `--project` accepts a slug id or a display name; omitted, it uses the `default` project. Writes `cloud.json` and the key.
|
|
68
|
+
|
|
69
|
+
### `reticle project`
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx @reticlehq/server project ls
|
|
73
|
+
npx @reticlehq/server project create "My App"
|
|
74
|
+
npx @reticlehq/server project rename <projectId> "New name"
|
|
75
|
+
npx @reticlehq/server project rm <projectId>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`rename` and `rm` work but are not in the usage block. Missing or malformed arguments exit `2`.
|
|
79
|
+
|
|
80
|
+
### `reticle config`
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npx @reticlehq/server config [--runs on|off] [--memory on|off] [--flows on|off] [--verify local|server]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Edits `.reticle/cloud.json` in place. Any value other than `on` or `off` (or `local` or `server` for `--verify`) exits `2`. Requires the repo to be linked.
|
|
87
|
+
|
|
88
|
+
### `reticle push`
|
|
89
|
+
|
|
90
|
+
Sends local run artifacts from `.reticle` to the linked project, honoring the sync policy. With `sync.runs` off it does nothing and says so. Prints `{ pushed, failed, total, project }`.
|
|
91
|
+
|
|
92
|
+
### `reticle runs`
|
|
93
|
+
|
|
94
|
+
The linked project's recent run artifacts. The key scopes the query server-side.
|
|
95
|
+
|
|
96
|
+
### `reticle regression`
|
|
97
|
+
|
|
98
|
+
The CI gate: which flows broke relative to before. **Exits `3`** when any flow regressed, which is the whole point of it being a separate command.
|
|
99
|
+
|
|
100
|
+
### `reticle share`
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npx @reticlehq/server share <runId>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Mints a public proof link for one run. A missing `runId` exits `2`.
|
|
107
|
+
|
|
108
|
+
## Exit codes
|
|
109
|
+
|
|
110
|
+
| Code | Meaning |
|
|
111
|
+
| ---- | ----------------------------------------------------------------------------------- |
|
|
112
|
+
| `0` | Success |
|
|
113
|
+
| `1` | The API call failed, or the repository is not attached where attachment is required |
|
|
114
|
+
| `2` | Usage error, or not signed in and no `RETICLE_CLOUD_KEY` |
|
|
115
|
+
| `3` | `regression` only: at least one flow broke |
|
|
116
|
+
|
|
117
|
+
Output is pretty-printed JSON on stdout. Errors and next-step nudges go to stderr, so an agent parsing stdout is unaffected.
|
|
118
|
+
|
|
119
|
+
## Worked example
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx @reticlehq/server login
|
|
123
|
+
npx @reticlehq/server project create "Checkout"
|
|
124
|
+
npx @reticlehq/server link --project "Checkout"
|
|
125
|
+
npx @reticlehq/server verify http://localhost:4173 # runs auto-push once linked
|
|
126
|
+
npx @reticlehq/server regression # exit 3 fails the pipeline
|
|
127
|
+
```
|