@reticlehq/server 2.11.0 → 2.12.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 +26 -2
- package/dist/bridge/bridge.d.ts +0 -13
- package/dist/bridge/bridge.js +1 -1
- package/dist/bridge/bridge.test-harness.d.ts +2 -0
- package/dist/bridge/bridge.test-harness.js +8 -1
- package/dist/capsule/capsule-store.d.ts +2 -1
- package/dist/capsule/capsule-store.js +1 -1
- package/dist/capsule/causal-summary.d.ts +2 -2
- package/dist/chromium-launch-options.d.ts +28 -0
- package/dist/chromium-launch-options.js +29 -0
- package/dist/cli/cli-doctor.js +8 -0
- package/dist/cli/cli-flow-commands.d.ts +3 -1
- package/dist/cli/cli-flow-commands.js +34 -4
- package/dist/cli/cli-kill.d.ts +2 -1
- package/dist/cli/cli-parse.d.ts +3 -1
- package/dist/cli/cli-parse.js +29 -7
- package/dist/cli/cli-update-commands.js +20 -1
- package/dist/cli/cli-verify.d.ts +1 -1
- package/dist/cli/cli-verify.js +2 -2
- package/dist/cli/cloud-cli.js +12 -6
- package/dist/cli/config-discovery.d.ts +2 -1
- package/dist/cli/doctor-rows.d.ts +3 -1
- package/dist/cli/doctor-rows.js +3 -1
- package/dist/cli/gate-exit.d.ts +21 -0
- package/dist/cli/gate-exit.js +21 -0
- package/dist/cli/gate-hook-message.d.ts +33 -0
- package/dist/cli/gate-hook-message.js +46 -0
- package/dist/cli/mcp-command.d.ts +25 -0
- package/dist/cli/mcp-command.js +143 -0
- package/dist/cli/sibling-ports.d.ts +37 -0
- package/dist/cli/sibling-ports.js +56 -0
- package/dist/cli.js +37 -110
- package/dist/cloud/cloud-config.d.ts +2 -1
- package/dist/cloud/cloud-sync.d.ts +11 -0
- package/dist/cloud/cloud-sync.js +32 -0
- package/dist/crawl/crawl.d.ts +9 -13
- package/dist/crawl/crawl.js +20 -3
- package/dist/daemon/daemon-resolve.d.ts +79 -0
- package/dist/daemon/daemon-resolve.js +118 -0
- package/dist/daemon/free-port.d.ts +29 -0
- package/dist/daemon/free-port.js +55 -0
- package/dist/daemon/heartbeat.d.ts +0 -4
- package/dist/daemon/heartbeat.js +2 -2
- package/dist/dev/stale-issue-guard.d.ts +0 -2
- package/dist/dev/stale-issue-guard.js +1 -1
- package/dist/events/contradictions.d.ts +41 -0
- package/dist/events/contradictions.js +125 -12
- package/dist/events/declared.d.ts +14 -0
- package/dist/events/declared.js +33 -0
- package/dist/events/echo-mismatch.js +14 -0
- package/dist/events/observed-in-window.d.ts +12 -0
- package/dist/events/observed-in-window.js +17 -0
- package/dist/events/predicate-asks.d.ts +13 -0
- package/dist/events/predicate-asks.js +22 -0
- package/dist/events/predicate-eval.js +64 -22
- package/dist/events/predicate-parse.d.ts +0 -6
- package/dist/events/predicate-parse.js +43 -3
- package/dist/events/predicate-schema.d.ts +44 -0
- package/dist/events/predicate-schema.js +126 -23
- package/dist/events/predicate.d.ts +15 -0
- package/dist/events/predicate.js +41 -2
- package/dist/flows/coverage.d.ts +0 -8
- package/dist/flows/coverage.js +1 -1
- package/dist/flows/decision.d.ts +5 -1
- package/dist/flows/decision.js +33 -7
- package/dist/flows/flake.d.ts +0 -2
- package/dist/flows/flake.js +1 -1
- package/dist/flows/flow-intent.d.ts +52 -0
- package/dist/flows/flow-intent.js +123 -0
- package/dist/flows/flow-replay-run.js +27 -4
- package/dist/flows/flow-success.js +15 -3
- package/dist/flows/flow-tools.js +32 -4
- package/dist/flows/flows.d.ts +6 -1
- package/dist/flows/flows.js +34 -22
- package/dist/flows/predicate-to-expect.js +6 -3
- package/dist/flows/server-verify.js +16 -2
- package/dist/flows/verify-change-tools.js +4 -1
- package/dist/honesty/blind-spots.d.ts +0 -17
- package/dist/honesty/blind-spots.js +1 -1
- package/dist/honesty/feature-capture.d.ts +150 -0
- package/dist/honesty/feature-capture.js +233 -0
- package/dist/honesty/instrumentation-gaps.d.ts +30 -6
- package/dist/honesty/instrumentation-gaps.js +61 -5
- package/dist/honesty/tool-hit-rate.d.ts +86 -0
- package/dist/honesty/tool-hit-rate.js +90 -0
- package/dist/honesty/undeclared-change.d.ts +51 -0
- package/dist/honesty/undeclared-change.js +56 -0
- package/dist/honesty/verified.d.ts +15 -0
- package/dist/honesty/verified.js +68 -4
- package/dist/http-server.d.ts +0 -1
- package/dist/http-server.js +1 -1
- package/dist/hunt/hunt-report.d.ts +0 -2
- package/dist/hunt/hunt-report.js +1 -1
- package/dist/impact/impact-store.d.ts +0 -5
- package/dist/impact/impact-store.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/init/agent-rules.d.ts +17 -0
- package/dist/init/agent-rules.js +31 -1
- package/dist/init/capabilities.d.ts +0 -2
- package/dist/init/capabilities.js +1 -1
- package/dist/init/closing-hint.d.ts +36 -0
- package/dist/init/closing-hint.js +120 -0
- package/dist/init/confirm.d.ts +0 -25
- package/dist/init/confirm.js +3 -3
- package/dist/init/cra.d.ts +14 -1
- package/dist/init/cra.js +43 -12
- package/dist/init/dev-script.d.ts +48 -0
- package/dist/init/dev-script.js +63 -0
- package/dist/init/mcp.d.ts +16 -5
- package/dist/init/mcp.js +26 -10
- package/dist/init/plan-framework.d.ts +0 -5
- package/dist/init/plan-framework.js +83 -9
- package/dist/init/plan.d.ts +10 -30
- package/dist/init/plan.js +30 -15
- package/dist/init/refresh-rules.d.ts +39 -0
- package/dist/init/refresh-rules.js +51 -0
- package/dist/init/run.d.ts +0 -26
- package/dist/init/run.js +14 -87
- package/dist/init/snippets.js +53 -10
- package/dist/input/real-input.d.ts +2 -0
- package/dist/input/real-input.js +3 -2
- package/dist/input/scroll-find.d.ts +7 -4
- package/dist/input/scroll-find.js +63 -25
- package/dist/intent/inline-intent.d.ts +46 -0
- package/dist/intent/inline-intent.js +103 -0
- package/dist/intent/intent-store.d.ts +37 -0
- package/dist/intent/intent-store.js +112 -0
- package/dist/intent/intent-tools.d.ts +2 -0
- package/dist/intent/intent-tools.js +80 -0
- package/dist/intent/open-intents.d.ts +21 -0
- package/dist/intent/open-intents.js +25 -0
- package/dist/journal/envelope.d.ts +26 -26
- package/dist/journal/journal-recorder.d.ts +23 -0
- package/dist/journal/journal-recorder.js +35 -0
- package/dist/mcp/attach-memory.d.ts +67 -0
- package/dist/mcp/attach-memory.js +142 -0
- package/dist/mcp/mcp-proxy.d.ts +0 -7
- package/dist/mcp/mcp-proxy.js +14 -2
- package/dist/mcp/mcp.d.ts +2 -0
- package/dist/mcp/mcp.js +45 -23
- package/dist/mcp/server-instructions.js +45 -3
- package/dist/mcp/tool-catalog-cache.d.ts +8 -0
- package/dist/mcp/tool-catalog-cache.js +10 -0
- package/dist/oracles/flow-instrument-gaps.d.ts +4 -4
- package/dist/oracles/flow-instrument-gaps.js +4 -5
- package/dist/oracles/self-instrument.d.ts +9 -9
- package/dist/oracles/self-instrument.js +19 -13
- package/dist/pool/browser-pool.d.ts +12 -1
- package/dist/pool/browser-pool.js +31 -1
- package/dist/pool/playwright-launcher.js +3 -1
- package/dist/project/fs-port.d.ts +3 -0
- package/dist/project/fs-port.js +3 -2
- package/dist/project/memory-fs.js +6 -1
- package/dist/project/project-tools.js +3 -32
- package/dist/project/reticle-dir.d.ts +2 -0
- package/dist/project/reticle-dir.js +1 -0
- package/dist/runs/context-tools.d.ts +2 -0
- package/dist/runs/context-tools.js +89 -0
- package/dist/runs/run-context.d.ts +40 -0
- package/dist/runs/run-context.js +158 -0
- package/dist/runs/run-diff.d.ts +2 -1
- package/dist/runs/verification-sync.js +2 -2
- package/dist/session/dev-server-probe.d.ts +0 -8
- package/dist/session/dev-server-probe.js +1 -1
- package/dist/session/last-act.d.ts +7 -1
- package/dist/session/last-act.js +2 -2
- package/dist/session/live-control-tools.js +1 -42
- package/dist/session/no-session-diagnosis.d.ts +10 -0
- package/dist/session/no-session-diagnosis.js +24 -7
- package/dist/session/no-session-next-action.d.ts +5 -0
- package/dist/session/no-session-next-action.js +35 -3
- package/dist/session/no-session-watch.d.ts +8 -0
- package/dist/session/no-session-watch.js +82 -64
- package/dist/session/output-budget.js +4 -1
- package/dist/session/session-health.d.ts +9 -0
- package/dist/session/session-health.js +23 -0
- package/dist/session/session-manager.js +50 -1
- package/dist/session/session-successor.d.ts +37 -0
- package/dist/session/session-successor.js +78 -0
- package/dist/session/session.d.ts +31 -1
- package/dist/session/session.js +75 -2
- package/dist/telemetry/automation-hint.d.ts +2 -1
- package/dist/telemetry/feedback-outbox.d.ts +2 -1
- package/dist/telemetry/project-profile.d.ts +0 -8
- package/dist/telemetry/project-profile.js +1 -1
- package/dist/telemetry/run-telemetry.d.ts +0 -2
- package/dist/telemetry/run-telemetry.js +1 -1
- package/dist/telemetry/verification-of.js +2 -2
- package/dist/tools/act-tools.js +126 -21
- package/dist/tools/assert-source.d.ts +22 -0
- package/dist/tools/assert-source.js +53 -0
- package/dist/tools/assert-verdict.d.ts +20 -3
- package/dist/tools/assert-verdict.js +36 -4
- package/dist/tools/browser-tools.js +0 -20
- package/dist/tools/complete-snapshot.d.ts +48 -0
- package/dist/tools/complete-snapshot.js +75 -0
- package/dist/tools/coverage-tools.d.ts +10 -1
- package/dist/tools/coverage-tools.js +123 -69
- package/dist/tools/dynamic-tools.js +29 -8
- package/dist/tools/error-recovery.d.ts +24 -14
- package/dist/tools/error-recovery.js +70 -9
- package/dist/tools/feedback-tools.d.ts +1 -1
- package/dist/tools/feedback-tools.js +2 -2
- package/dist/tools/invoke-tool.js +62 -2
- package/dist/tools/lease-hint.d.ts +10 -0
- package/dist/tools/lease-hint.js +53 -4
- package/dist/tools/lease-tools.d.ts +5 -1
- package/dist/tools/lease-tools.js +22 -8
- package/dist/tools/navigate-arrival.d.ts +0 -2
- package/dist/tools/navigate-arrival.js +1 -1
- package/dist/tools/observe-tools.js +63 -26
- package/dist/tools/read-tools.js +5 -3
- package/dist/tools/real-input-attempt.d.ts +22 -0
- package/dist/tools/real-input-attempt.js +153 -1
- package/dist/tools/reconcile-tools.js +18 -4
- package/dist/tools/resolve-target.d.ts +0 -7
- package/dist/tools/sdk-marker-probe.d.ts +29 -0
- package/dist/tools/sdk-marker-probe.js +57 -0
- package/dist/tools/snapshot-delta.d.ts +1 -1
- package/dist/tools/tool-kit.d.ts +12 -0
- package/dist/tools/tool-kit.js +16 -0
- package/dist/tools/tool-names.d.ts +3 -0
- package/dist/tools/tool-names.js +3 -0
- package/dist/tools/tool-surface.d.ts +85 -6
- package/dist/tools/tool-surface.js +122 -2
- package/dist/tools/tools.js +22 -4
- package/dist/tools/unadvertised-help.js +4 -4
- package/dist/tools/verify-next-baton.d.ts +53 -0
- package/dist/tools/verify-next-baton.js +52 -0
- package/dist/update/update-nudge.d.ts +7 -10
- package/dist/update/update-nudge.js +12 -3
- package/dist/update/updater.d.ts +1 -1
- package/docs/README.md +2 -1
- package/docs/cli/cloud.mdx +1 -1
- package/docs/cli/doctor.mdx +1 -0
- package/docs/cli/verify.mdx +4 -5
- package/docs/desktop.mdx +1 -1
- package/docs/docs.json +2 -2
- package/docs/gates.md +1 -1
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/server.mdx +1 -1
- package/docs/packages.mdx +8 -6
- package/docs/platform-integration.md +17 -0
- package/docs/predicates.mdx +8 -0
- package/docs/reticle-manual.md +106 -0
- package/docs/tools-tools-and-run.mdx +2 -4
- package/docs/troubleshooting.mdx +9 -0
- package/docs/usage.md +3 -2
- package/package.json +2 -2
- package/dist/session/session-readiness.d.ts +0 -34
- package/dist/session/session-readiness.js +0 -36
|
@@ -93,6 +93,23 @@ Live, clickable demo of each: `apps/vibe-builder-demo/` (set `BUG_MODE=…`). Pr
|
|
|
93
93
|
|
|
94
94
|
---
|
|
95
95
|
|
|
96
|
+
## The minimal attach contract (for a harness or MCP host)
|
|
97
|
+
|
|
98
|
+
Reticle is a stdio MCP server. A host that wires it correctly does four things, and each one is a step Reticle can see:
|
|
99
|
+
|
|
100
|
+
1. **Spawn it.** `npx @reticlehq/server mcp`, over stdio, one process per host. That process is the proxy: it starts the local daemon on demand, reconnects on its own when the stream drops, and answers from cache while a daemon comes back.
|
|
101
|
+
2. **Complete `initialize`.** Reticle answers the handshake itself when the daemon is slow, so a host that waits for a reply gets one either way.
|
|
102
|
+
3. **Send `tools/list`, and send it again on `notifications/tools/list_changed`.** This is the step hosts skip. Registering a server is not the same as enumerating it: a host can register Reticle and never ask for the tool list until the client is restarted, and the model then has no Reticle tools at all while the install looks healthy from every other angle. Reticle declares `tools.listChanged` so a host that honours the notification recovers without a restart.
|
|
103
|
+
4. **Call the tools.** `tools/call`, with the tool name and its arguments.
|
|
104
|
+
|
|
105
|
+
`reticle status` reports how far a host has got. `mcpClient: "never-attached"` means no client has started the server on this port. `mcpClient: "never-enumerated"` means one started it and never asked for the tool list, which is the state a client restart fixes. `mcpClient: "enumerated"` means the client side is done, and anything still missing is the app rather than the host. The record is per port rather than per client, and it begins the first time a client starts a Reticle version that keeps it, so `status` says both of those out loud instead of naming a client it cannot see.
|
|
106
|
+
|
|
107
|
+
### Hosts that cap the number of tools
|
|
108
|
+
|
|
109
|
+
Some editors cap the total tool count across every MCP server, which is why Reticle advertises a small surface instead of everything it can do. Nothing is out of reach: `reticle_tools { names: [...] }` lists the tools and returns the full argument grammar for the ones you name, and `reticle_run { tool, args }` invokes any of them, advertised or not. A host that is short on tool slots pays for the advertised handful and still reaches the whole surface through that pair. See [`reticle_tools` and `reticle_run`](/tools-tools-and-run).
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
96
113
|
## Exact steps per platform
|
|
97
114
|
|
|
98
115
|
The shape is identical (in-app SDK in the template → verify in the sandbox → act on the verdict); the specifics differ by where each platform runs the preview.
|
package/docs/predicates.mdx
CHANGED
|
@@ -115,6 +115,14 @@ A passing route verdict quotes the transition itself:
|
|
|
115
115
|
|
|
116
116
|
The app emitted a named signal via `reticle.signal()`. `dataMatches` is shallow JSON matching, and `*` means "present, any value".
|
|
117
117
|
|
|
118
|
+
`count` works here exactly as it does on `net`:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{ "kind": "signal", "name": "order:placed", "count": 1 }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Exactly once.** A handler wired twice fires the signal twice and leaves the store in the right shape either way, so every state-only check stays green. `count: 0` is a claim of its own (the signal never fired) and is not the same as leaving `count` out, which asserts presence.
|
|
125
|
+
|
|
118
126
|
Nothing outranks this. A `200` proves the server was reachable; a rendered row proves React ran. A signal is the application itself saying the thing succeeded. See [instrumentation](/instrumentation) for how to emit them.
|
|
119
127
|
|
|
120
128
|
### state
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Reticle: what each tool actually does'
|
|
3
|
+
description: Generated from real calls against a running app. Every row is a probe that ran and the answer it got.
|
|
4
|
+
icon: table-list
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Generated by `bench/harness/behaviour-matrix.mjs`. Do not edit by hand.**
|
|
8
|
+
|
|
9
|
+
Every row below is a call that was made against a running app and the answer that came back. Nothing here is described from the source or from intent. If a claim has no probe behind it, it is not in this file. That is the whole point: the hand-written guides drifted, and the drift was invisible because nobody ran them.
|
|
10
|
+
|
|
11
|
+
`refused (names the fix)` means the error told you what to call instead, so you can correct without reading anything else. `refused (no fix named)` means it did not.
|
|
12
|
+
|
|
13
|
+
## reticle_snapshot
|
|
14
|
+
|
|
15
|
+
| you call it with | you get back | bytes |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| an argument the tool does not declare: `{"thisArgDoesNotExist":1}` | refused (names the fix) | 273 |
|
|
18
|
+
| the documented call: `{"mode":"interactive"}` | ran | 434 |
|
|
19
|
+
| a value outside the allowed set: `{"mode":"not-a-mode"}` | refused (names the fix) | 236 |
|
|
20
|
+
|
|
21
|
+
## reticle_query
|
|
22
|
+
|
|
23
|
+
| you call it with | you get back | bytes |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| an argument the tool does not declare: `{"thisArgDoesNotExist":1}` | refused (names the fix) | 368 |
|
|
26
|
+
| the documented call: `{"by":"role","value":"button"}` | ran | 200 |
|
|
27
|
+
| a value outside the allowed set: `{"by":"telepathy","value":"x"}` | refused (names the fix) | 290 |
|
|
28
|
+
|
|
29
|
+
## reticle_network
|
|
30
|
+
|
|
31
|
+
| you call it with | you get back | bytes |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| an argument the tool does not declare: `{"thisArgDoesNotExist":1}` | refused (names the fix) | 354 |
|
|
34
|
+
| the documented call: `{"limit":5}` | ran | 1175 |
|
|
35
|
+
| a number outside its range: `{"limit":-1}` | refused (names the fix) | 222 |
|
|
36
|
+
|
|
37
|
+
## reticle_console
|
|
38
|
+
|
|
39
|
+
| you call it with | you get back | bytes |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| an argument the tool does not declare: `{"thisArgDoesNotExist":1}` | refused (names the fix) | 293 |
|
|
42
|
+
|
|
43
|
+
## reticle_state
|
|
44
|
+
|
|
45
|
+
| you call it with | you get back | bytes |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| an argument the tool does not declare: `{"thisArgDoesNotExist":1}` | refused (names the fix) | 268 |
|
|
48
|
+
| a number outside its range: `{"depth":-5}` | refused (names the fix) | 173 |
|
|
49
|
+
| the documented call: `{"depth":2}` | ran | 210 |
|
|
50
|
+
|
|
51
|
+
- a negative depth was silently ignored before v2.12.0
|
|
52
|
+
|
|
53
|
+
## reticle_observe
|
|
54
|
+
|
|
55
|
+
| you call it with | you get back | bytes |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| an argument the tool does not declare: `{"thisArgDoesNotExist":1}` | refused (names the fix) | 305 |
|
|
58
|
+
|
|
59
|
+
## reticle_act_and_wait
|
|
60
|
+
|
|
61
|
+
| you call it with | you get back | bytes |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| no expectation declared: `{"ref":"e1005","action":"click"}` | verified:no-fault | 1343 |
|
|
64
|
+
| the documented call: `{"ref":"e1105","action":"click","until":{"kind":"text","value":"Invalid email or password"},"timeout_ms":6000}` | verified:yes | 1297 |
|
|
65
|
+
| no expectation declared: `{"ref":"e1205","action":"click","until":{"kind":"settled"}}` | verified:no-fault | 1343 |
|
|
66
|
+
| a value outside the allowed set: `{"ref":"e903","action":"click","until":[{"kind":"text","value":"x"}]}` | refused (names the fix) | 399 |
|
|
67
|
+
| a ref that no longer resolves: `{"ref":"e999999","action":"click"}` | refused (names the fix) | 519 |
|
|
68
|
+
|
|
69
|
+
- no `until`: this returned verified:"yes" before v2.12.0
|
|
70
|
+
|
|
71
|
+
- a consequence the click CAUSES: the shape that earns verified:"yes"
|
|
72
|
+
|
|
73
|
+
- an explicit `{kind:"settled"}` is the idle wait, not a declaration, so it grades no-fault too
|
|
74
|
+
|
|
75
|
+
- a bare array is not a predicate
|
|
76
|
+
|
|
77
|
+
## reticle_act
|
|
78
|
+
|
|
79
|
+
| you call it with | you get back | bytes |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| a required argument omitted: `{"ref":"e901"}` | refused (names the fix) | 192 |
|
|
82
|
+
| a value outside the allowed set: `{"ref":"e901","action":"teleport"}` | refused (names the fix) | 415 |
|
|
83
|
+
| an argument the tool does not declare: `{"ref":"e901","action":"fill","value":"x"}` | refused (names the fix) | 314 |
|
|
84
|
+
| the documented call: `{"ref":"e901","action":"fill","args":{"value":"probe"}}` | refused (names the fix) | 516 |
|
|
85
|
+
|
|
86
|
+
- action arguments nest under `args`
|
|
87
|
+
|
|
88
|
+
## reticle_assert
|
|
89
|
+
|
|
90
|
+
| you call it with | you get back | bytes |
|
|
91
|
+
| --- | --- | --- |
|
|
92
|
+
| a required argument omitted: `{}` | refused (names the fix) | 592 |
|
|
93
|
+
| the documented call: `{"predicate":{"kind":"text","value":"Sign in"},"timeout_ms":3000}` | verified:yes | 794 |
|
|
94
|
+
|
|
95
|
+
## reticle_tools
|
|
96
|
+
|
|
97
|
+
| you call it with | you get back | bytes |
|
|
98
|
+
| ------------------------- | ----------------------- | ----- |
|
|
99
|
+
| the documented call: `{}` | refused (names the fix) | 246 |
|
|
100
|
+
|
|
101
|
+
## reticle_run
|
|
102
|
+
|
|
103
|
+
| you call it with | you get back | bytes |
|
|
104
|
+
| --- | --- | --- |
|
|
105
|
+
| a value outside the allowed set: `{"tool":"reticle_nope","args":{}}` | refused (names the fix) | 894 |
|
|
106
|
+
| the documented call: `{"tool":"reticle_context","args":{}}` | ran | 54 |
|
|
@@ -6,9 +6,7 @@ icon: boxes-stacked
|
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
`reticle_tools` discovers. `reticle_run` invokes. Together they cost two tool definitions instead of twenty-nine.
|
|
9
|
+
`reticle_tools` discovers. `reticle_run` invokes. Together they cost two tool definitions instead of the rest of the catalog.
|
|
12
10
|
|
|
13
11
|
## Discovering what exists
|
|
14
12
|
|
|
@@ -41,7 +39,7 @@ The response also tells you which surface is active:
|
|
|
41
39
|
"profile": {
|
|
42
40
|
"active": "all",
|
|
43
41
|
"source": "RETICLE_ADVERTISE_ALL_TOOLS set in the DAEMON's environment at startup",
|
|
44
|
-
"note": "The
|
|
42
|
+
"note": "The surface is read once at daemon startup: set RETICLE_ADVERTISE_ALL_TOOLS=1 and restart the daemon, or it has no effect. No surface advertises every tool: the advertised count is capped because editors budget tools across all connected MCP servers. Every tool listed here is callable through reticle_run { tool, args } whether or not it is advertised."
|
|
45
43
|
},
|
|
46
44
|
"next": "Load params with reticle_tools { names:[…] }, then call reticle_run { tool, args }."
|
|
47
45
|
}
|
package/docs/troubleshooting.mdx
CHANGED
|
@@ -83,6 +83,15 @@ the URL explicitly (Vite: VITE_RETICLE_WS_URL, or reticle.connect({ url })). An
|
|
|
83
83
|
open a ws:// socket at all. Still retrying…
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
+
**You should not have to read this page to find that out.** If the agent opened the app with `reticle_lease`, which is the path `init` steers it to, the daemon reads that address off the page's own console, compares it with the port it is bound to, and puts the mismatch in the tool result:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
The page dialled ws://localhost:4460/reticle (port 4460) and this daemon is on
|
|
90
|
+
4400, so the dial never reached it. Nothing about the app's wiring is in question.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Neither side can work that out alone: the page cannot see the daemon, and the daemon never saw a dial that went somewhere else. The rest of this section covers what the lease cannot: a tab you opened yourself, or an app the pool cannot reach.
|
|
94
|
+
|
|
86
95
|
That message names the exact address it tried. Compare its port with `bridge port` from `doctor` and set whichever is wrong:
|
|
87
96
|
|
|
88
97
|
```bash
|
package/docs/usage.md
CHANGED
|
@@ -183,7 +183,7 @@ The timeline + summary of what happened.
|
|
|
183
183
|
|
|
184
184
|
Act, then wait for a predicate: the whole act→observe→assert loop in one hop.
|
|
185
185
|
|
|
186
|
-
- **args:** `ref`, `action`, `args?`, `until: <predicate>`, `timeout_ms?` (default 4000; 0 = evaluate once), `refuseWhenThrottled?`, `sessionId?`.
|
|
186
|
+
- **args:** `ref`, `action`, `args?`, `until: <predicate>`, `timeout_ms?` (default 4000; 0 = evaluate once), `refuseWhenThrottled?`, `intent?`, `sessionId?`.
|
|
187
187
|
- **returns:** `{ effect, verdict, trace, session, warning? }`. `effect` is the action result (`{ ok, ref, action }`), `verdict` is `{ pass, evidence?, failureReason? }`, `trace` is the reaction report of everything the app did after the action, and `session` is the tab-health block `{ lastSeenMs, throttled, focused }` (with a `warning` when throttled). A failing `verdict` still returns `effect` + `trace` so you can see what _did_ happen. The predicate is automatically floored at this act's cursor, so it only matches events the action actually caused.
|
|
188
188
|
|
|
189
189
|
### `reticle_wait_for`
|
|
@@ -197,9 +197,10 @@ Block until a predicate holds (or time out). Looks both backward (recent buffer)
|
|
|
197
197
|
|
|
198
198
|
Verify a predicate; optionally wait for it.
|
|
199
199
|
|
|
200
|
-
- **args:** `predicate`, `timeout_ms?` (0 = evaluate once), `since?`, `sessionId?`.
|
|
200
|
+
- **args:** `predicate`, `timeout_ms?` (0 = evaluate once), `since?`, `intent?`, `sessionId?`.
|
|
201
201
|
- Same `since` default as `reticle_wait_for`: scoped to your last act so a stale buffered event can't fake a pass; override with an explicit `since`.
|
|
202
202
|
- **returns:** `{ verified, because, pass, evidence, contradictions?, coverage?, failureReason?, session, warning? }`. On failure includes a **near-miss** (e.g. "found the dialog but not visible", or "no button named 'Submit'; saw: Cancel"). The `session` block `{ lastSeenMs, throttled, focused }` reports tab health on every assert; when throttled a `warning` is attached so you never assert against a tab that is silently no-oping.
|
|
203
|
+
- **`intent` declares what the change was FOR, inline.** Pass a sentence in your own words and it lands in `.reticle/intent.json`, the same git-checked ledger `reticle_intent` writes, before the verdict is drawn; a green verdict then marks it proved and names itself as the proof. Pass the **id** of an intent you already declared instead, to point several verdicts at one statement rather than restating it. `reticle_act_and_wait` takes the same argument. Omit it and nothing is written.
|
|
203
204
|
- **Read `verified`, not `pass`.** `pass` says the predicate held; `verified` says whether that means anything. It is `"no"` when a channel contradicts the assertion (a failed write under a green screen, a batch whose body reports per-item failures, a request still in flight), and `"unknown"` when the outcome could not be known yet: a `202 Accepted` that has not reconciled, or a write whose response body was never recorded. `because` names the deciding evidence in one sentence.
|
|
204
205
|
|
|
205
206
|
### `reticle_reconcile`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reticlehq/server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Reticle bridge + MCP server. Hosts the browser WS endpoint and exposes MCP tools to the coding agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
23
23
|
"ws": "^8.21.3",
|
|
24
24
|
"zod": "^3.24.1",
|
|
25
|
-
"@reticlehq/core": "2.
|
|
25
|
+
"@reticlehq/core": "2.12.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/pngjs": "^6.0.5",
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* First-run readiness: the agent often issues its first tool call in the window between `reticle init`
|
|
3
|
-
* and the app's SDK actually connecting its WebSocket — so a naive resolve throws "no session". This
|
|
4
|
-
* lets the agent (via reticle_wait_ready) BLOCK briefly until a session appears instead of failing the
|
|
5
|
-
* race, smoothing the most common first-5-minutes footgun.
|
|
6
|
-
*
|
|
7
|
-
* Pure control loop: the session count, clock, and sleep are all injected, so it is unit-tested with
|
|
8
|
-
* no real timers — and in production it polls a real `setTimeout` sleep.
|
|
9
|
-
*/
|
|
10
|
-
interface WaitForReadyOptions {
|
|
11
|
-
/** Live count of connected sessions (SessionManager.count). */
|
|
12
|
-
count: () => number;
|
|
13
|
-
/** Give up after this much elapsed time. */
|
|
14
|
-
timeoutMs: number;
|
|
15
|
-
/** Injected monotonic clock (ms). */
|
|
16
|
-
now: () => number;
|
|
17
|
-
/** Injected delay between polls. */
|
|
18
|
-
sleep: (ms: number) => Promise<void>;
|
|
19
|
-
/** Poll interval (ms). Default 25 — see DEFAULT_POLL_MS. */
|
|
20
|
-
pollMs?: number;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* One-line orientation for a FRESH agent — the Reticle loop, returned by reticle_wait_ready (the first call)
|
|
24
|
-
* so an agent learns how to drive Reticle without reading docs. Named so it is not a free string; kept
|
|
25
|
-
* terse on purpose (it rides the first response, where token budget is tightest).
|
|
26
|
-
*/
|
|
27
|
-
export declare const RETICLE_LOOP_GUIDE: string;
|
|
28
|
-
/**
|
|
29
|
-
* Resolve `true` as soon as at least one session is connected, or `false` if the timeout elapses
|
|
30
|
-
* first. Returns immediately when a session is already connected (the common, already-ready case —
|
|
31
|
-
* so this never adds latency on the happy path, including the benchmark which always has a session).
|
|
32
|
-
*/
|
|
33
|
-
export declare function waitForReady(opts: WaitForReadyOptions): Promise<boolean>;
|
|
34
|
-
export {};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Same reasoning as session-reconnect: the check is an in-memory lookup and the thing awaited is an
|
|
3
|
-
* event (a session registering), so a coarse grid only adds latency to the first call an agent
|
|
4
|
-
* makes. Four times the checks of something with no I/O costs nothing measurable.
|
|
5
|
-
*/
|
|
6
|
-
const DEFAULT_POLL_MS = 25;
|
|
7
|
-
/**
|
|
8
|
-
* One-line orientation for a FRESH agent — the Reticle loop, returned by reticle_wait_ready (the first call)
|
|
9
|
-
* so an agent learns how to drive Reticle without reading docs. Named so it is not a free string; kept
|
|
10
|
-
* terse on purpose (it rides the first response, where token budget is tightest).
|
|
11
|
-
*/
|
|
12
|
-
export const RETICLE_LOOP_GUIDE = 'Reticle loop — LOOK: reticle_snapshot / reticle_query / reticle_inspect · ACT: reticle_act (or reticle_act_and_wait) · ' +
|
|
13
|
-
'OBSERVE: reticle_observe / reticle_wait_for / reticle_network / reticle_console · ASSERT: reticle_assert over program ' +
|
|
14
|
-
'truth, not just the DOM · REGRESS: reticle_record{action:"start"} → reticle_replay, or reticle_verify{action:"flows"} for the whole ' +
|
|
15
|
-
'suite. The human can flag bugs from the panel — drain them with reticle_session{action:"review"} and resolve each once fixed. ' +
|
|
16
|
-
'MANDATORY: the moment you stop driving — finishing your reply or waiting on the human — call reticle_session {action:"yield"} ' +
|
|
17
|
-
'(mode:"waiting", or mode:"ask" with the question) so the panel shows your real state; reticle_session{action:"end"} ' +
|
|
18
|
-
'only when the whole task is done. Never leave the panel reading "live" when you have actually stopped.';
|
|
19
|
-
/**
|
|
20
|
-
* Resolve `true` as soon as at least one session is connected, or `false` if the timeout elapses
|
|
21
|
-
* first. Returns immediately when a session is already connected (the common, already-ready case —
|
|
22
|
-
* so this never adds latency on the happy path, including the benchmark which always has a session).
|
|
23
|
-
*/
|
|
24
|
-
export async function waitForReady(opts) {
|
|
25
|
-
if (opts.count() > 0)
|
|
26
|
-
return true;
|
|
27
|
-
const start = opts.now();
|
|
28
|
-
const poll = opts.pollMs ?? DEFAULT_POLL_MS;
|
|
29
|
-
for (;;) {
|
|
30
|
-
if (opts.now() - start >= opts.timeoutMs)
|
|
31
|
-
return opts.count() > 0;
|
|
32
|
-
await opts.sleep(poll);
|
|
33
|
-
if (opts.count() > 0)
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
}
|