@reticlehq/server 3.5.0 → 3.7.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 +1 -1
- package/SKILL.md +123 -116
- package/dist/chromium-launch-options.d.ts +3 -1
- package/dist/chromium-launch-options.js +2 -1
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +19 -2
- package/dist/command/cli/adhoc-verdict.js +76 -9
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/answers/open-note.d.ts +2 -0
- package/dist/command/cli/answers/open-note.js +22 -0
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +31 -112
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +35 -5
- package/dist/command/cli/cli-verify.js +114 -35
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +192 -341
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +22 -0
- package/dist/command/cli/cloud-login.js +96 -8
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/drive/drive-attach.d.ts +27 -2
- package/dist/command/cli/drive/drive-attach.js +71 -4
- package/dist/command/cli/drive/drive-command.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +13 -7
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.d.ts +10 -0
- package/dist/command/cli/ports/port-holder.js +25 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +35 -12
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -181
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +20 -0
- package/dist/command/cli.js +130 -104
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +23 -1
- package/dist/command/daemon/daemon-resolve.js +79 -9
- package/dist/command/setup/agent-writer.d.ts +1 -1
- package/dist/command/setup/agent-writer.js +3 -2
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
- package/dist/command/setup/bringup/connect-lease.js +1 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
- package/dist/command/setup/bringup/dev-server-wait.js +19 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +14 -1
- package/dist/command/setup/init/init-port.js +32 -2
- package/dist/command/setup/init/init-runtime.d.ts +22 -2
- package/dist/command/setup/init/init-runtime.js +114 -38
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +38 -9
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +2 -1
- package/dist/command/setup/run-setup.d.ts +34 -9
- package/dist/command/setup/run-setup.js +65 -51
- package/dist/command/setup/setup-command.d.ts +25 -1
- package/dist/command/setup/setup-command.js +59 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +49 -4
- package/dist/features/crawl/crawl-tools.js +4 -0
- package/dist/features/crawl/crawl.d.ts +6 -0
- package/dist/features/crawl/crawl.js +23 -2
- package/dist/features/exhaust/ledger.d.ts +21 -14
- package/dist/features/exhaust/ledger.js +35 -9
- package/dist/features/harness/app-findings.d.ts +2 -0
- package/dist/features/harness/app-findings.js +52 -0
- package/dist/features/harness/drive-report.d.ts +61 -1
- package/dist/features/harness/drive-report.js +394 -26
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +10 -14
- package/dist/features/harness/drivers.js +10 -14
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/fill-values.d.ts +3 -73
- package/dist/features/harness/fill-values.js +3 -169
- package/dist/features/harness/goals.d.ts +82 -0
- package/dist/features/harness/goals.js +330 -0
- package/dist/features/harness/harness.d.ts +51 -1
- package/dist/features/harness/harness.js +207 -6
- package/dist/features/harness/platform/drive-target.d.ts +30 -0
- package/dist/features/harness/platform/drive-target.js +81 -0
- package/dist/features/harness/platform/local-apps.d.ts +127 -0
- package/dist/features/harness/platform/local-apps.js +280 -0
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +186 -0
- package/dist/features/harness/platform/remote-drive.js +378 -0
- package/dist/features/harness/platform/script.d.ts +94 -0
- package/dist/features/harness/platform/script.js +260 -0
- package/dist/features/harness/platform/server-driver.d.ts +54 -0
- package/dist/features/harness/platform/server-driver.js +182 -0
- package/dist/features/harness/platform-config.d.ts +41 -1
- package/dist/features/harness/platform-config.js +106 -9
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/app-controls.d.ts +5 -0
- package/dist/features/harness/script/app-controls.js +40 -0
- package/dist/features/harness/script/lane-ids.d.ts +14 -0
- package/dist/features/harness/script/lane-ids.js +16 -0
- package/dist/features/harness/script/script-run.d.ts +70 -0
- package/dist/features/harness/script/script-run.js +606 -0
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.d.ts +10 -1
- package/dist/features/visual/visual-tools.js +62 -17
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +23 -0
- package/dist/hooks/driven-by.js +56 -0
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/hooks/hook-commands.js +15 -4
- package/dist/hooks/tool-log.d.ts +9 -0
- package/dist/hooks/tool-log.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +80 -243
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
- package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
- package/dist/judgement/runs/artifact/run-store.js +195 -3
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +71 -1
- package/dist/judgement/runs/drive-run.js +317 -5
- package/dist/judgement/runs/repair-prompt.js +1 -1
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +13 -3
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +5 -2
- package/dist/judgement/runs/verification-sync.js +40 -18
- package/dist/language/flows/change/gate.d.ts +10 -0
- package/dist/language/flows/change/gate.js +22 -0
- package/dist/language/flows/decision.js +36 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +61 -10
- package/dist/language/flows/flow-anchor.js +98 -6
- package/dist/language/flows/flow-cross-step.d.ts +15 -0
- package/dist/language/flows/flow-cross-step.js +21 -0
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +45 -14
- package/dist/language/flows/flow-mutate-tools.js +5 -3
- package/dist/language/flows/flow-replay-run.d.ts +23 -9
- package/dist/language/flows/flow-replay-run.js +115 -110
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +40 -1
- package/dist/language/flows/flow-replay.js +110 -22
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-scope.js +5 -1
- package/dist/language/flows/flow-step-runners.d.ts +22 -2
- package/dist/language/flows/flow-step-runners.js +247 -47
- package/dist/language/flows/flow-store-for-session.d.ts +2 -2
- package/dist/language/flows/flow-store-for-session.js +7 -3
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +112 -89
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +74 -12
- package/dist/language/flows/heal-run.js +6 -4
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/flake.d.ts +2 -2
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
- package/dist/language/flows/recording/tape/recordings.js +95 -13
- package/dist/language/flows/replay-from-hud.d.ts +20 -0
- package/dist/language/flows/replay-from-hud.js +51 -0
- package/dist/language/flows/replay.d.ts +9 -5
- package/dist/language/flows/replay.js +56 -15
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/suite/suite-flakes.js +2 -0
- package/dist/language/flows/suite-selection.d.ts +2 -15
- package/dist/language/flows/suite-selection.js +4 -3
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +202 -191
- package/dist/launch-chromium.d.ts +27 -5
- package/dist/launch-chromium.js +38 -8
- package/dist/memory/cloud/cloud-config.d.ts +22 -1
- package/dist/memory/cloud/cloud-config.js +34 -5
- package/dist/memory/cloud/cloud-sync.d.ts +17 -14
- package/dist/memory/cloud/cloud-sync.js +15 -4
- package/dist/memory/cloud/harness-config.d.ts +75 -1
- package/dist/memory/cloud/harness-config.js +115 -24
- package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
- package/dist/memory/cloud/hud-notices-source.js +128 -0
- package/dist/memory/cloud/memory-scope.d.ts +161 -0
- package/dist/memory/cloud/memory-scope.js +227 -0
- package/dist/memory/cloud/sync-cycle.d.ts +44 -7
- package/dist/memory/cloud/sync-cycle.js +129 -15
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +121 -9
- package/dist/memory/cloud/sync-disk.d.ts +1 -1
- package/dist/memory/cloud/sync-disk.js +31 -10
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +34 -0
- package/dist/memory/impact/account-watch.js +59 -0
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +12 -2
- package/dist/memory/impact/impact-store.d.ts +17 -4
- package/dist/memory/impact/impact-store.js +169 -63
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +14 -2
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +122 -4
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/envelope.d.ts +8 -8
- package/dist/memory/journal/journal-recorder.js +52 -3
- package/dist/memory/journal/on-disk/retention.d.ts +8 -0
- package/dist/memory/journal/on-disk/retention.js +32 -2
- package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
- package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +42 -9
- package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
- package/dist/memory/project/artifact-root-resolver.js +125 -16
- package/dist/memory/project/artifact-root.d.ts +46 -8
- package/dist/memory/project/artifact-root.js +89 -10
- package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
- package/dist/memory/project/dir/reticle-dir.js +26 -3
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/project-tools.js +22 -3
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +26 -1
- package/dist/memory/project/session-root.js +49 -5
- package/dist/memory/project/sync-status.d.ts +85 -0
- package/dist/memory/project/sync-status.js +224 -0
- package/dist/memory/recall/memory-tools.js +47 -2
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.d.ts +19 -0
- package/dist/memory/recall/project-memory.js +80 -13
- package/dist/portal/bridge/bridge.d.ts +9 -3
- package/dist/portal/bridge/bridge.js +82 -22
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/pairing-token.d.ts +9 -0
- package/dist/portal/bridge/pairing-token.js +17 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +83 -10
- package/dist/portal/input/real-input.js +218 -30
- package/dist/portal/input/viewport-tools.js +3 -3
- package/dist/portal/pool/browser-pool.d.ts +70 -9
- package/dist/portal/pool/browser-pool.js +190 -37
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +35 -0
- package/dist/portal/pool/playwright-launcher.js +64 -3
- package/dist/portal/pool/pool-contract.d.ts +28 -5
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.d.ts +8 -0
- package/dist/portal/session/command-payload.js +24 -0
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
- package/dist/portal/session/dev-server/dev-command.js +87 -12
- package/dist/portal/session/facts/departure-note.d.ts +22 -0
- package/dist/portal/session/facts/departure-note.js +47 -0
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/facts/session-replaced.d.ts +5 -0
- package/dist/portal/session/facts/session-replaced.js +5 -0
- package/dist/portal/session/first-run-wiring.d.ts +42 -0
- package/dist/portal/session/first-run-wiring.js +132 -0
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/human/notes-ledger.d.ts +20 -0
- package/dist/portal/session/human/notes-ledger.js +55 -0
- package/dist/portal/session/human/review-store.d.ts +12 -0
- package/dist/portal/session/human/review-store.js +18 -10
- package/dist/portal/session/live-control-tools.d.ts +0 -13
- package/dist/portal/session/live-control-tools.js +107 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
- package/dist/portal/session/no-session-diagnosis.js +46 -9
- package/dist/portal/session/no-session-next-action.d.ts +31 -0
- package/dist/portal/session/no-session-next-action.js +159 -60
- package/dist/portal/session/no-session-watch.d.ts +14 -1
- package/dist/portal/session/no-session-watch.js +227 -17
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/presence/session-mirror.js +3 -0
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/serving-directory.d.ts +27 -0
- package/dist/portal/session/serving-directory.js +45 -0
- package/dist/portal/session/session-health.d.ts +18 -0
- package/dist/portal/session/session-health.js +9 -1
- package/dist/portal/session/session-info.d.ts +8 -1
- package/dist/portal/session/session-info.js +8 -1
- package/dist/portal/session/session-manager.d.ts +39 -0
- package/dist/portal/session/session-manager.js +98 -11
- package/dist/portal/session/session-reaper.js +4 -1
- package/dist/portal/session/session-successor.d.ts +13 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session-tools.js +26 -3
- package/dist/portal/session/session.d.ts +22 -30
- package/dist/portal/session/session.js +81 -79
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +12 -0
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +23 -1
- package/dist/status-payload.js +36 -1
- package/dist/surface/http-server.js +18 -2
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
- package/dist/surface/mcp/mcp-proxy.js +65 -13
- package/dist/surface/mcp/mcp.d.ts +34 -6
- package/dist/surface/mcp/mcp.js +61 -17
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.d.ts +4 -2
- package/dist/surface/mcp/server-instructions.js +32 -14
- package/dist/surface/mcp/shared-params.js +2 -2
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act/settle-in-flight.js +25 -3
- package/dist/surface/tools/act-sequence-tool.js +138 -29
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +71 -41
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +42 -17
- package/dist/surface/tools/browser-tools.js +51 -2
- package/dist/surface/tools/chat-drives.d.ts +101 -0
- package/dist/surface/tools/chat-drives.js +409 -0
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +51 -0
- package/dist/surface/tools/empty-session-list.js +120 -0
- package/dist/surface/tools/error-recovery.d.ts +14 -0
- package/dist/surface/tools/error-recovery.js +105 -8
- package/dist/surface/tools/explore-tools.d.ts +31 -1
- package/dist/surface/tools/explore-tools.js +438 -66
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +18 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +118 -57
- package/dist/surface/tools/harness-explore.js +344 -292
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +17 -0
- package/dist/surface/tools/harness-plan.js +38 -0
- package/dist/surface/tools/harness-script.d.ts +30 -0
- package/dist/surface/tools/harness-script.js +560 -0
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +22 -1
- package/dist/surface/tools/harness-toolset.js +101 -7
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +263 -85
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +49 -0
- package/dist/surface/tools/lease-seed.js +167 -0
- package/dist/surface/tools/lease-tools.d.ts +13 -24
- package/dist/surface/tools/lease-tools.js +146 -197
- package/dist/surface/tools/live-call-text.js +4 -4
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +29 -0
- package/dist/surface/tools/next-step.js +214 -0
- package/dist/surface/tools/observe-tools.js +45 -9
- package/dist/surface/tools/platform-moment.d.ts +72 -0
- package/dist/surface/tools/platform-moment.js +296 -0
- package/dist/surface/tools/query-hint-schema.d.ts +7 -0
- package/dist/surface/tools/query-hint-schema.js +10 -0
- package/dist/surface/tools/read-tools.js +71 -14
- package/dist/surface/tools/real-input-attempt.js +96 -13
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +83 -3
- package/dist/surface/tools/tool-kit.js +77 -7
- package/dist/surface/tools/tools.js +43 -59
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +29 -6
- package/dist/telemetry/hud-metrics.js +116 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +38 -2
- package/dist/telemetry/telemetry.js +144 -34
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +13 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +20 -6
- package/docs/README.md +3 -3
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +25 -28
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +33 -28
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +14 -3
- package/docs/cli/drive.mdx +20 -14
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +43 -28
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +18 -5
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +5 -4
- package/docs/cli.mdx +111 -42
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +9 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +7 -8
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +65 -61
- package/docs/human-control.md +16 -16
- package/docs/index.mdx +15 -42
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +23 -13
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +9 -9
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +32 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +69 -30
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +23 -25
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +22 -13
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +55 -46
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +17 -5
- package/docs/what-is-reticle.mdx +5 -3
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -241
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/features/harness/driver.d.ts +0 -50
- package/dist/features/harness/driver.js +0 -236
- package/dist/features/harness/jev-driver.d.ts +0 -188
- package/dist/features/harness/jev-driver.js +0 -678
- package/dist/features/harness/openai-driver.d.ts +0 -58
- package/dist/features/harness/openai-driver.js +0 -206
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
- package/dist/memory/project/dir/fill-value-store.js +0 -88
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
- package/docs/local-registry.md +0 -143
package/docs/agent-cheatsheet.md
CHANGED
|
@@ -4,7 +4,7 @@ description: 'One screen to get fluent: the look → act → observe → assert
|
|
|
4
4
|
icon: bolt
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
The loop is **look → act → observe → assert
|
|
7
|
+
The loop is **look → act → observe → assert**. Verdicts come from `reticle_act_and_wait`, `reticle_assert`, `reticle_act { steps }` when a step declares `expect`, and `reticle_verify` (`change`/`flows`). Everything else moves or reads the app and proves nothing. Only `verified: "yes"` is a pass: `unknown` means Reticle could not tell, and `no-fault` means nothing was declared to prove. Reach for `reticle_act_and_wait({ ref, action, until })` first: it names the expected consequence before the action, which is the difference between a check and a rationalisation.
|
|
8
8
|
|
|
9
9
|
One screen to get fluent. Reticle is the **proof layer for AI agents**: no screenshots, no vision model, evidence not prose. Everything below returns structured data. Full guide: [usage.md](usage.md).
|
|
10
10
|
|
|
@@ -14,18 +14,18 @@ One screen to get fluent. Reticle is the **proof layer for AI agents**: no scree
|
|
|
14
14
|
| --- | --- | --- |
|
|
15
15
|
| **look** | `reticle_look { action: "page" }` / `reticle_look { action: "find" }` | See the page (semantic tree) / find one specific element. |
|
|
16
16
|
| **act** | **`reticle_act_and_wait`** / `reticle_act { steps: [...] }` / `reticle_act` | **Act + name the consequence, one hop. Reach for this first.** / batch a whole journey in one hop / move the app and prove nothing. |
|
|
17
|
-
| **observe** | `reticle_observe` / `reticle_assert { action: "wait" }` | Everything the app did after `since` / block until true. |
|
|
17
|
+
| **observe** | `reticle_observe` / `reticle_assert { action: "wait" }` | Everything the app did after `since` / block until true. The wait carries `verified` and is graded the way `reticle_assert` grades it. |
|
|
18
18
|
| **assert** | `reticle_assert` | Evaluate a predicate → `{ pass, evidence, failureReason? }`. The end of every loop. |
|
|
19
19
|
|
|
20
|
-
> **Verdicts come from `reticle_act_and_wait`, `reticle_assert`,
|
|
20
|
+
> **Verdicts come from `reticle_act_and_wait`, `reticle_assert`, `reticle_act { steps }` when a step declares `expect`, and `reticle_verify` (`change`/`flows`). Everything else moves or reads the app and proves nothing. Only `verified: "yes"` is a pass: `unknown` means Reticle could not tell, and `no-fault` means nothing was declared to prove.** A drive ending without a verdict has no result however many tools it used. `reticle_act` is the tool agents reach for by habit and it catches nothing; `act_and_wait` is where defects actually surface. Report `unknown` as unknown.
|
|
21
21
|
|
|
22
|
-
`reticle_act` returns a `since` cursor; pass it to `reticle_observe({ since })` to scope the window. Elements are addressed by stable refs (`e7`) from `
|
|
22
|
+
`reticle_act` returns a `since` cursor; pass it to `reticle_observe({ since })` to scope the window. Elements are addressed by stable refs (`e7`) from `reticle_look { action: "page" }` or `{ action: "find" }`; they re-resolve across re-renders.
|
|
23
23
|
|
|
24
24
|
**`assert`/`wait_for` are auto-scoped to your last act.** By default they only count events buffered _since_ the most recent act, so a stale signal from a previous step can't fake a pass. Pass an explicit `since` to override. **Clicks run the code, not pixels:** `reticle_act` click fires the full pointer sequence on the element (no coordinate gesture for the HUD to intercept), reports `occluded:true` when something covers the target, and stays synthetic even with CDP configured (use `args:{ native:true }` for a trusted native click).
|
|
25
25
|
|
|
26
26
|
**Never sleep. Wait deterministically.** Fixed sleeps are the #1 cause of flaky agent tests. Instead:
|
|
27
27
|
|
|
28
|
-
- `reticle_act_and_wait({ ref, action })` with **no `until`** waits for the page to _settle_ (network + structural DOM idle; ambient count-up/spinner churn is ignored so an animated page still settles) before returning: the one-call replacement for "click then sleep 500ms".
|
|
28
|
+
- `reticle_act_and_wait({ ref, action })` with **no `until`** waits for the page to _settle_ (settle: nothing new happening for a short quiet window, measured as network + structural DOM idle; ambient count-up/spinner churn is ignored so an animated page still settles) before returning: the one-call replacement for "click then sleep 500ms".
|
|
29
29
|
- Need to wait without acting? `reticle_assert({ action: "wait", predicate: { kind: "settled", quietMs } })`.
|
|
30
30
|
- Waiting for a specific outcome? Pass that consequence as the predicate (`{ signal }` / `{ net }`), or `allOf` it with `{ kind: "settled" }` to wait for both the event _and_ the page going quiet.
|
|
31
31
|
|
|
@@ -37,21 +37,19 @@ One screen to get fluent. Reticle is the **proof layer for AI agents**: no scree
|
|
|
37
37
|
| `{ kind: "element", role: "button", text: "Save" }` | `{ kind: "element", query: { role, text } }` |
|
|
38
38
|
| `{ kind: "route", url: "/checkout" }` | `{ kind: "route", contains: "/checkout" }` |
|
|
39
39
|
|
|
40
|
-
**
|
|
40
|
+
**An element predicate CHECKS `value` and `text`.** They are not folded into the locator and ignored.
|
|
41
41
|
|
|
42
42
|
```jsonc
|
|
43
|
-
//
|
|
44
|
-
// whatever the input held, because `value` was read as a locator operand and,
|
|
45
|
-
// with no `by`, silently did nothing.
|
|
43
|
+
// A real assertion about the field's contents.
|
|
46
44
|
{ "kind": "element", "role": "textbox", "name": "GST amount", "value": "274.58" }
|
|
47
45
|
```
|
|
48
46
|
|
|
49
|
-
Two consequences worth knowing
|
|
47
|
+
Two consequences worth knowing:
|
|
50
48
|
|
|
51
|
-
- **You can
|
|
52
|
-
- **`{ role, text }`
|
|
49
|
+
- **You can assert what a field contains.** Do not read the value with `reticle_look { action: "find" }` and compare it in prose: that produces no verdict and does not count as verification.
|
|
50
|
+
- **`{ role, text }` checks the text,** so it does not match every button with that role.
|
|
53
51
|
|
|
54
|
-
Fields that nothing can check are refused rather than ignored: `by` without a `value`, and `label`, `placeholder`, `testid
|
|
52
|
+
Fields that nothing can check are refused rather than ignored: `by` without a `value`, and `label`, `placeholder`, `testid` or `component` when a higher-precedence field already selected the element. `alt` is the one that can still be checked beside another locator: on an image it is compared with the image's `alt` attribute (so `alt: ""` passes on a decorative image but not on one missing its alt), and on anything that is not an image it is refused, with a hint to use `name`. An element query is a first-match dispatch, not a conjunction.
|
|
55
53
|
|
|
56
54
|
**Combinators take `predicates`, not a bare array.** This is the shape most often got wrong, and it is the one that produces no verdict at all:
|
|
57
55
|
|
|
@@ -113,9 +111,9 @@ A claim is real only when the layers agree. Check more than the UI:
|
|
|
113
111
|
|
|
114
112
|
## Core tool set
|
|
115
113
|
|
|
116
|
-
The tools you are shown
|
|
114
|
+
The ten tools you are shown. `reticle_run` is one of them: it calls any registered tool by name, advertised or not.
|
|
117
115
|
|
|
118
|
-
`reticle_navigate` · `reticle_act` · `reticle_act_and_wait` · `reticle_assert` · `reticle_look` · `reticle_observe` · `reticle_session` · `reticle_verify` · `reticle_tools`
|
|
116
|
+
`reticle_navigate` · `reticle_act` · `reticle_act_and_wait` · `reticle_assert` · `reticle_look` · `reticle_observe` · `reticle_session` · `reticle_verify` · `reticle_tools` · `reticle_run`
|
|
119
117
|
|
|
120
118
|
Most of what used to be a tool of its own is now an action on one of them:
|
|
121
119
|
|
|
@@ -125,21 +123,21 @@ Call an old name and you are told the new one. `reticle_tools` prints the live s
|
|
|
125
123
|
|
|
126
124
|
- `reticle_verify`: **the only core tool that CONCLUDES.** `{ action:"crawl" }` drives every reachable control itself and reports the whole fault set in one call (destructive: it really clicks). `{ action:"flows" }` replays every saved flow with no model in the loop. Reach for it when you think you are done: every other tool here answers "here is more to look at".
|
|
127
125
|
|
|
128
|
-
Not on this surface at all, but one hop away: `reticle_run { tool, args }` calls any registered tool by name, advertised or not, and `reticle_tools { names: [...] }` loads its arguments. That reaches `reticle_capabilities` (the app's whole testable surface in one call), `reticle_domain` (learn the app + gaps), `reticle_baseline {action:"diff"}`, `reticle_project` (run history), `reticle_screenshot`, `reticle_visual_diff`, `reticle_storage`, `reticle_network_mock` and `reticle_clock`. A daemon started with `RETICLE_ADVERTISE_ALL_TOOLS=1` advertises
|
|
126
|
+
Not on this surface at all, but one hop away: `reticle_run { tool, args }` calls any registered tool by name, advertised or not, and `reticle_tools { names: [...] }` loads its arguments. That reaches `reticle_capabilities` (the app's whole testable surface in one call), `reticle_domain` (learn the app + gaps), `reticle_run { tool: "reticle_baseline", args: { action: "diff" } }`, `reticle_project` (run history), `reticle_screenshot`, `reticle_visual_diff`, `reticle_storage`, `reticle_network_mock` and `reticle_clock`. A daemon started with `RETICLE_ADVERTISE_ALL_TOOLS=1` advertises some of these directly (`reticle_capabilities`, `reticle_screenshot`, `reticle_visual_diff`, `reticle_storage`, `reticle_network_mock`, `reticle_clock`, plus `reticle_record`, `reticle_flow_save`, `reticle_flow_replay`, `reticle_intent` and `reticle_context`); the rest stay behind `reticle_run`. It also switches to the unmerged spelling: `reticle_snapshot`/`reticle_query`/`reticle_inspect`/`reticle_state` replace `reticle_look`, `reticle_network`/`reticle_console` replace `reticle_observe { action }`, `reticle_wait_for` replaces `reticle_assert { action: "wait" }`, `reticle_sessions`/`reticle_feedback` replace `reticle_session` list/feedback, and `reticle_act_sequence` replaces `reticle_act { steps }`. Examples on this page use the default spelling.
|
|
129
127
|
|
|
130
|
-
**What the wider surface adds, through `reticle_run`
|
|
128
|
+
**What the wider surface adds, through `reticle_run` (a few are also advertised directly with `RETICLE_ADVERTISE_ALL_TOOLS=1`):** record/replay a journey (`reticle_run { tool: "reticle_record", args: { action: "start" } }/stop`, `reticle_replay`), persist a self-healing golden flow (`reticle_flow_save*` / `reticle_flow_replay` / `reticle_verify { action: "heal" }`), compile annotations (`reticle_annotate`), explore autonomously (`reticle_explore` lists controls; `reticle_verify { action: "crawl" }` is now advertised directly, clicks them all and reports anomalies, and is **destructive**), reveal a virtualized off-screen row (`reticle_scroll_to`, for when `reticle_look { action: "find" }` finds nothing because a windowed list hasn't rendered it yet), visual-check (`reticle_screenshot` / `reticle_visual_diff`, pinned with `reticle_viewport` for reproducible baselines), test error/edge states by stubbing the network (`reticle_network_mock`: 500 / offline / delay, driven or leased), control time for toasts/debounces/auto-dismiss (`reticle_clock { freeze | advanceMs | reset }`), or work with a human (`reticle_session { action: "end" }` / `reticle_session { action: "resume" }` / `reticle_session { action: "messages" }`, and **`reticle_session { action: "review" }`** to drain + fix the bugs the human flagged from the panel).
|
|
131
129
|
|
|
132
130
|
## flows vs baselines vs project.json (the persistence layers)
|
|
133
131
|
|
|
134
132
|
| Artifact | Tool(s) | What it is |
|
|
135
133
|
| --- | --- | --- |
|
|
136
134
|
| **flows** | `reticle_flow_save*` / `reticle_flow_replay` / `reticle_verify { action: "heal" }` | Replayable **golden journeys**, anchored to testids/signals; drift is legible and self-heals. |
|
|
137
|
-
| **baselines** | `reticle_baseline {action:"save"}` / `reticle_baseline {action:"diff"}` | Structural **"before" snapshots**; `reticle_baseline {action:"diff"}` flags regressions against them. |
|
|
138
|
-
| **project.json** | `reticle_project` | Cross-run **run-history**: "did it behave like last run?" read via `reticle_project`. |
|
|
135
|
+
| **baselines** | `reticle_run { tool: "reticle_baseline", args: { action: "save" } }` / `reticle_run { tool: "reticle_baseline", args: { action: "diff" } }` | Structural **"before" snapshots**; `reticle_run { tool: "reticle_baseline", args: { action: "diff" } }` flags regressions against them. |
|
|
136
|
+
| **project.json** | `reticle_project` | Cross-run **run-history**: "did it behave like last run?" read via `reticle_project`. Its `cloud.sync` says where this project's runs stand with the platform (on it, waiting, refused, last push); `push: true` syncs before answering. |
|
|
139
137
|
|
|
140
138
|
> `reticle_project` / `project.json` are the **run-history layer**. flows answer "does the journey still work?"; baselines answer "did the structure change?"; project.json answers "is this run consistent with prior runs?".
|
|
141
139
|
|
|
142
|
-
**Visual layer (opt-in).** `reticle_screenshot` saves a PNG baseline to `.reticle/visual/<name>.png`; `reticle_visual_diff` perceptually compares the live page to it (`{ masks }` to ignore volatile regions, `{ maxRatio }` tolerance) → `{ matched, changedPixels, ratio, region, diffPath }`. It answers "does it **look** right", complementary to the behavioral layers, never a replacement. Both need a **driven browser** (`reticle drive <url>` / `RETICLE_CDP_URL`); without one they return `{ ok:false, reason:"no-visual-provider" }` (the always-on SDK ships no screenshotter).
|
|
140
|
+
**Visual layer (opt-in).** `reticle_screenshot` saves a PNG baseline to `.reticle/visual/<name>.png`; `reticle_visual_diff` perceptually compares the live page to it (`{ masks }` to ignore volatile regions, `{ maxRatio }` tolerance) → `{ matched, changedPixels, ratio, region, diffPath }`. It answers "does it **look** right", complementary to the behavioral layers, never a replacement. Both need a **driven browser** (`reticle drive <url>` / `RETICLE_CDP_URL`) or a leased tab (`reticle_lease`); without one they return `{ ok:false, reason:"no-visual-provider" }` (the always-on SDK ships no screenshotter).
|
|
143
141
|
|
|
144
142
|
## Fields worth reading that you may not know are there
|
|
145
143
|
|
|
@@ -147,22 +145,21 @@ Recent additions, each of which answers a question agents were previously asking
|
|
|
147
145
|
|
|
148
146
|
| Field | On | What it tells you |
|
|
149
147
|
| --- | --- | --- |
|
|
150
|
-
| `expiresInMs` | `reticle_lease { action: "acquire" }` | How long the lease lives if untouched, reset by every call that targets it. Plan a pass to finish inside it, or re-acquire deliberately, rather than losing a measurement to a silent expiry. |
|
|
148
|
+
| `expiresInMs` | `reticle_run { tool: "reticle_lease", args: { action: "acquire" } }` | How long the lease lives if untouched, reset by every call that targets it. Plan a pass to finish inside it, or re-acquire deliberately, rather than losing a measurement to a silent expiry. |
|
|
151
149
|
| `scroll` | `reticle_look { action: "element" }` | `scrollTop`, `scrollHeight`, `clientHeight`, `overflowY`. Whether the element scrolls, which you cannot infer from geometry alone. |
|
|
152
|
-
| `timeline_omitted` | `reticle_record { action: "stop" }` | The raw event timeline is not in the response. It says how many events there were and names the call that returns them, with the cursor filled in. |
|
|
150
|
+
| `timeline_omitted` | `reticle_run { tool: "reticle_record", args: { action: "stop" } }` | The raw event timeline is not in the response. It says how many events there were and names the call that returns them, with the cursor filled in. |
|
|
153
151
|
| `elided` | `reticle_act_and_wait` | Some diff arrays were capped. The count is real even when the list is trimmed, so a small array does not mean a quiet app. |
|
|
154
152
|
| `colorTokens`, `themeScope` | `reticle_look { action: "element" }` | Every design token matching a colour, not one arbitrary winner, and which theme the reading was taken under. The singular `colorToken` is `null` when several tokens share a colour, because naming one of them was the defect. |
|
|
155
153
|
| `why` | `reticle_session { action: "list" }`, when the list is empty | Why nothing is connected, and the next action. An empty list is never the end of the road. |
|
|
156
154
|
|
|
157
155
|
**When a verdict comes back `unsettled`,** it now names what it was waiting for and what the window actually held. Read those before retrying: an `unknown` that explains itself is a retry with a better `until`, and one that does not is a dead end.
|
|
158
156
|
|
|
159
|
-
**If the port is taken,** `reticle
|
|
157
|
+
**If the port is taken,** `reticle stop --force` frees it and leaves your own MCP proxy alone. Do not reach for `lsof -i :4400` and kill what it lists; that matches every process on the port, including the proxy you are talking through.
|
|
160
158
|
|
|
161
159
|
## Start here
|
|
162
160
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
2. `reticle_domain` learns the app BEFORE testing: the saved flows, what each asserts, and the **gaps** (declared signals/testids that no flow verifies, i.e. untested intent). Tells you what to test and where the real risk is without crawling the whole app. Falls back to `reticle_capabilities` for the raw testable surface (`testids`, `signals`, `stores`, `flows`).
|
|
161
|
+
1. **First move, always:** `reticle_session { action: "list" }` finds the connected tab. Just ran `reticle init` or restarted the dev server? You do not need to poll: live tools wait briefly for a tab that is about to connect. Omit `sessionId` if there's only one tab. **An empty list is not a dead end: read the `why` field.** It names which case this is (no app running, an app running that has never dialled this daemon, a project that never went through `init`, or a tab that closed) and the fix for each. Do not fall back to static reasoning until you have read it.
|
|
162
|
+
2. `reticle_run({ tool: "reticle_domain", args: {} })` learns the app BEFORE testing: the saved flows, what each asserts, and the **gaps** (declared signals/testids that no flow verifies, i.e. untested intent). Tells you what to test and where the real risk is without crawling the whole app. Falls back to `reticle_run({ tool: "reticle_capabilities", args: {} })` for the raw testable surface (`testids`, `signals`, `stores`, `flows`).
|
|
166
163
|
3. Run the loop: **look → act → observe → assert**, cross-checking the 4 layers on anything that matters.
|
|
167
164
|
|
|
168
165
|
## Token note
|
|
@@ -171,5 +168,5 @@ Recent additions, each of which answers a question agents were previously asking
|
|
|
171
168
|
- **Re-look with `reticle_look({ action: "page", diff:true })`** after an action; it returns only what changed (`mode:delta`/`unchanged`), ~99% fewer tokens than a full re-snapshot and no stale tree to mis-read. Every snapshot/query result carries `cost:{ bytes, tokens }`, so re-scope before reading if it's large.
|
|
172
169
|
- **Cap broad reads.** `reticle_look { action: "find" }` takes `limit` (caps descriptors; reports `total`/`truncated`) and `count_only` (just the match count). `reticle_observe { action: "network" }` / `reticle_observe { action: "console" }` take `limit` (most-recent-N, reports `droppedOldest`) and carry the same `cost` hint, so a busy page or wide window never floods your context unnoticed.
|
|
173
170
|
- **A saved flow tells you if it's a real test.** `reticle_flow_save` returns `assertions.grade` (`asserted` / `presence-only` / `assertion-free`); if it's not `asserted`, add a consequence (`reticle_annotate` assert-signal/assert-net or a success-state) so it can't pass while broken. On replay, an ambiguous heal (two testids tie) is surfaced, never auto-applied. And an `apply` heal re-replays the rebound flow and **refuses to write** if the success consequence no longer fires (`status:consequence_broken`): it heals the locator, never the intent.
|
|
174
|
-
- **Predicate schema is not bloated.** The recursive predicate DSL used by `reticle_assert` / `reticle_assert { action: "wait" }` / `reticle_act_and_wait` is
|
|
175
|
-
- **One tool surface, and a hatch behind it.** Reticle advertises navigate/act/act_and_wait/assert/look/observe/session/verify, plus `reticle_tools` and `reticle_run`. That is the whole detect loop, the file-pointer, the feedback channel, the handback, and the one tool that CONCLUDES, reached by an `action` argument rather than by a name each. `reticle_tools` discovers: no args lists every registered tool name and summary, `names:[…]` loads full params on demand. `reticle_run { tool, args }` then calls any of them, advertised or not, which is what keeps recording a flow, screenshots, visual diff, storage, network mocking and the clock reachable without spending a slot on each. A daemon started with `RETICLE_ADVERTISE_ALL_TOOLS=1` (read at startup, so restart it) advertises the
|
|
171
|
+
- **Predicate schema is not bloated.** The recursive predicate DSL used by `reticle_assert` / `reticle_assert { action: "wait" }` / `reticle_act_and_wait` is defined once (`PredicateSchema` in `@reticlehq/core`) and shared by all three tools. No action needed.
|
|
172
|
+
- **One tool surface, and a hatch behind it.** Reticle advertises navigate/act/act_and_wait/assert/look/observe/session/verify, plus `reticle_tools` and `reticle_run`. That is the whole detect loop, the file-pointer, the feedback channel, the handback, and the one tool that CONCLUDES, reached by an `action` argument rather than by a name each. `reticle_tools` discovers: no args lists every registered tool name and summary, `names:[…]` loads full params on demand. `reticle_run { tool, args }` then calls any of them, advertised or not, which is what keeps recording a flow, screenshots, visual diff, storage, network mocking and the clock reachable without spending a slot on each. A daemon started with `RETICLE_ADVERTISE_ALL_TOOLS=1` (read at startup, so restart it) advertises a wider set outright (the default tools plus the extra ones listed above), with output schemas, under the unmerged names listed above. It is not the whole registry: the count is capped because editors budget tools across every connected MCP server. `reticle_verify` is advertised: `{ action:"flows" }` replays every saved flow with no model in the loop, and `{ action:"crawl" }` drives every reachable control itself and reports the whole fault set in one call. **Sizes are deliberately not quoted here.** A count in prose goes stale, and has three times already. `reticle_tools` reports the live surface, and SKILL.md carries the one gated table.
|
package/docs/architecture.md
CHANGED
|
@@ -44,14 +44,14 @@ Reticle is a pnpm + Turborepo monorepo. The split is not cosmetic: each boundary
|
|
|
44
44
|
| `@reticlehq/babel-plugin`, `@reticlehq/next`, `@reticlehq/vite-plugin` | build time | Stamp `data-reticle-source` for source mapping (and, for Vite, inject `connect()`) | Plain tooling |
|
|
45
45
|
| `@reticlehq/electron` | Electron main process | Adapter for the desktop runtime: IPC observer, main-process capture | Desktop-only, outside the web gates |
|
|
46
46
|
| `adapters/realm/tauri` (`reticle-tauri`) | Tauri (Rust) | Capture backend for the Tauri desktop runtime | Rust, outside every JS gate; compiled by CI's `rust`/`rust-macos` jobs |
|
|
47
|
-
| `@reticlehq/test` | Node (dev dependency) | Spec runner + matchers
|
|
48
|
-
| `@reticlehq/eslint-plugin` | dev tooling |
|
|
47
|
+
| `@reticlehq/test` | Node (dev dependency) | Spec runner + matchers for running Reticle checks in your CI | Peer dependency on `vitest` |
|
|
48
|
+
| `@reticlehq/eslint-plugin` | dev tooling | Lint rule for your app: a state change must fire a signal | Dev-only, never shipped in a user's bundle |
|
|
49
49
|
|
|
50
50
|
> Note: pre-2.0, `@reticlehq/core` was a single umbrella package that re-exported all of the above under subpaths. In 2.0 the umbrella was retired and `@reticlehq/core` became the bottom-of-graph wire contract.
|
|
51
51
|
|
|
52
52
|
**Why core-as-contract matters:** because the browser and the server are two different runtimes (a DOM and a Node process) that must agree exactly on every message, the temptation is to inline a string like `"net.request"` in both. That's how drift and silent breakage start. Instead, every such string and shape lives once in `@reticlehq/core` as a named constant + a zod schema.
|
|
53
53
|
|
|
54
|
-
The browser and server both import it; neither can invent a message the other doesn't understand. The server zod-parses **every** inbound WebSocket message; malformed input
|
|
54
|
+
The browser and server both import it; neither can invent a message the other doesn't understand. The server zod-parses **every** inbound WebSocket message; malformed input never flows into logic. A malformed `HELLO` is refused, and a malformed frame on a live session is dropped and recorded as a gap in that window.
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
@@ -87,7 +87,7 @@ The same verification runs over and over, every commit, every CI run. Reticle re
|
|
|
87
87
|
|
|
88
88
|
### 4. Dev-only, localhost-only, your app data stays local
|
|
89
89
|
|
|
90
|
-
The SDK is tree-shaken out of production builds and connects only to a local bridge. The bridge binds to loopback by default; exposing it beyond localhost _requires_ a pairing token (the server refuses to
|
|
90
|
+
The SDK is tree-shaken out of production builds and connects only to a local bridge. The bridge binds to loopback by default; exposing it beyond localhost _requires_ a pairing token (and the server refuses to start on a non-loopback host unless `RETICLE_ALLOWED_ORIGINS` names the app's origins). Every environment variable that gates a security control is a single named constant, so a typo can't silently disable auth. Nothing from the app under test leaves your machine unless you link a project: no DOM, network, console, state, or source. What a linked project syncs is set by `reticle config`; see [what is recorded](what-is-recorded.md). The CLI reports anonymous, opt-out usage metrics only (a random id + event names like `cli_command_run`/`daemon_started`; no code, no PII; see [telemetry](telemetry.md)); opt out with `reticle telemetry disable`, `RETICLE_TELEMETRY=0`, or `DO_NOT_TRACK=1`. The one thing that carries free text is feedback you or your agent deliberately send (`reticle feedback` / `reticle_session { action: "feedback" }`). It is never collected passively, it is redacted before sending, and it is disabled separately with `RETICLE_FEEDBACK=0`.
|
|
91
91
|
|
|
92
92
|
---
|
|
93
93
|
|
|
@@ -119,7 +119,7 @@ This is plain, reviewable, version-controllable data, not a black box.
|
|
|
119
119
|
- The **server / CLI** is under the **Functional Source License (FSL-1.1, Apache-2.0 future)**: source-available, converts to Apache-2.0 over time.
|
|
120
120
|
- Enterprise-only features live behind a license gate and are clearly separated.
|
|
121
121
|
|
|
122
|
-
See [LICENSE](
|
|
122
|
+
See [LICENSE](https://github.com/reticlehq/reticle/blob/main/LICENSE) and each package's own `LICENSE` file. The licensing _mechanism_ is open and inspectable; activation is offline (no phone-home).
|
|
123
123
|
|
|
124
124
|
---
|
|
125
125
|
|
package/docs/autodrive.md
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Let Reticle drive
|
|
3
|
-
description: Hand the whole drive to
|
|
3
|
+
description: Hand the whole drive to the Reticle Harness on the platform, and get back the flows it recorded, so every run after the first one replays with no model in the loop.
|
|
4
4
|
icon: steering-wheel
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
Driving an app is the expensive part of verifying one. Every snapshot, every act result and every observation lands in your agent's context and is re-read on every turn after, and none of it is kept: the next run starts from nothing and pays again.
|
|
8
8
|
|
|
9
|
-
`reticle_verify { action: "explore" }`
|
|
9
|
+
`reticle_verify { action: "explore" }` hands the driving to the Reticle Harness. It decides on the Reticle platform, and the daemon on your machine executes each step through the same tool surface your agent uses, records what it drove as saved flows, and hands back a few lines. It needs a linked project (`reticle connect`).
|
|
10
10
|
|
|
11
11
|
```jsonc
|
|
12
12
|
reticle_verify {
|
|
13
13
|
action: "explore",
|
|
14
14
|
persona: "a returning customer checking out with a saved card"
|
|
15
15
|
}
|
|
16
|
-
// → { stopReason, steps, savedFlows: ["checkout"], summary, usage }
|
|
16
|
+
// → within `wait` seconds (default 50): { status, runId, stopReason, steps, savedFlows: ["checkout"], summary, usage, ... }
|
|
17
|
+
// still driving: { status: "running", runId }, poll again with that runId
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
From the command line, on a project with nothing recorded yet:
|
|
@@ -32,57 +33,61 @@ So the drive is a one-off: pay for it once, and the journeys it recorded become
|
|
|
32
33
|
|
|
33
34
|
A drive reads `.reticle` first: every saved flow with the consequence that must still hold, and every signal and testid your app declares that no flow has ever asserted. It builds a plan from that before it opens its eyes on a page.
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
With no persona, anything already recorded is **replayed**, deterministically, with no model call at all, and only the gaps are driven (see the plan below). With a persona, it drives that journey and replays nothing else: the saved flows have nothing to do with the journey you named. So a second run over the same app is mostly free, and the model budget is spent on the part nobody has proved yet rather than on rediscovering what is already on disk. A replay that goes red is reported as a regression; one that DRIFTS is reported separately, because the app moved under the recording and that needs re-anchoring rather than a code change.
|
|
36
37
|
|
|
37
38
|
Every journey a drive walks is saved, whatever happens to the drive, including one that broke, ran out of budget, or whose model simply stopped asking for tools.
|
|
38
39
|
|
|
39
|
-
##
|
|
40
|
+
## The platform plans the drive
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
The platform plans every drive (link the project once with `reticle connect`, or set `RETICLE_API_KEY` in CI). With a persona or without one, it proposes the people worth being, orders the saved flows, finds where they branch, and writes into each journey the product rules that apply to it, read from your project's own intents. The rules tell the Harness what the journey is for and where it ends (a journey that names Settings is not finished before Settings). They are not checked as assertions: a rule like "the row shows refunded" is guidance, and the checks are the consequences each step declares. Your machine sends what the project knows, with each saved step as a short hash and never the values it typed. It runs the plan it gets back and reports what happened. The plan is checked before it runs, and a plan that fails the checks is dropped. Every decision while it drives is the platform's too: your machine executes each step it is handed and reports what happened.
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
| --- | --- |
|
|
45
|
-
| `RETICLE_API_KEY` | `jev`, against the platform's own proxy, using the key `reticle link` already wrote. No model API key of your own, and the cheap path: it answers typed questions about the page rather than generating tool calls as text. |
|
|
46
|
-
| `ANTHROPIC_API_KEY` | `anthropic`, which generates its calls as text. |
|
|
47
|
-
| `OPENAI_API_KEY` | `openai`, the same, on OpenAI. |
|
|
48
|
-
| `JEV_API_KEY` | `jev`, against TypeSafe directly, for anyone who holds their own key. |
|
|
44
|
+
## With no persona, it writes a plan first
|
|
49
45
|
|
|
50
|
-
|
|
46
|
+
Called with no `persona`, explore writes the whole drive down before it starts, as a drive plan:
|
|
51
47
|
|
|
52
|
-
|
|
48
|
+
- **Journeys.** Each saved flow worth replaying, plus one open journey for each persona the platform proposes, for the request the user declared (`reticle_run { tool: "reticle_intent", args: { action: "declare" } }`), and for each intent nobody has proved. Replays need no model; only open journeys reach one.
|
|
49
|
+
- **Order.** A flow that `needs` another runs after it. An open journey runs after the flow everything else needs, usually sign-in.
|
|
50
|
+
- **Lanes.** Each journey nothing else needs gets a lane holding what it needs, in order. Lanes run side by side, each in its own leased browser context, up to four at a time (fewer when the browser pool has less room). A journey that needs one from another lane waits for it, and is blocked if that journey failed. A prerequisite that commits something (a payment, an email) runs in one lane only, and the others wait on it rather than commit it twice.
|
|
51
|
+
- **Branches.** Flows that start with the same steps become one journey. The shared steps are driven once and marked as a checkpoint, then each flow continues from that point. Every flow after the first replays back to the checkpoint first, so none of them starts from the page the previous one left.
|
|
53
52
|
|
|
54
|
-
|
|
53
|
+
The plan appears at the top of the HUD's Agent Log: one row per lane, a card per journey, the running journey opened to its steps, and each card marked as it passes, fails or is blocked. The tool's answer carries one line per journey.
|
|
54
|
+
|
|
55
|
+
Two arguments of the flow replay make the branches possible, and you can use them directly through `reticle_run { tool: "reticle_flow_replay", args: { flowName, to | at } }`. `to` stops before a step. `at` continues at a step on the page as it is, without driving the steps before it. A part-way replay checks the steps it drove and records nothing about the flow as a whole.
|
|
56
|
+
|
|
57
|
+
## What it needs
|
|
58
|
+
|
|
59
|
+
**A project on the Reticle platform.** Every plan includes the Harness. A new account gets 10 free credits (about two full drives of a small app), a card starts a 14-day trial with 500, and the paid plan includes 1,000 credits per seat each month. Run `reticle connect` once in your app's folder. The Harness runs on the platform: planning, personas, and every choice of what to press next. A model key of your own does not drive it, and a machine with no platform link gets the refusal and the way to fix it.
|
|
55
60
|
|
|
56
61
|
| Variable | What it does |
|
|
57
62
|
| --- | --- |
|
|
58
|
-
| `
|
|
59
|
-
| `RETICLE_HARNESS_MAX_STEPS` | Ceiling on
|
|
60
|
-
| `
|
|
61
|
-
|
|
62
|
-
## Two models, and what each one is for
|
|
63
|
+
| `RETICLE_API_KEY` | For CI, where nobody ran `reticle connect`. Locally the daemon uses the key `connect` stored in `~/.reticle/credentials.json`; either way it is what asks the platform to drive. |
|
|
64
|
+
| `RETICLE_HARNESS_MAX_STEPS` | Ceiling on steps in one drive. Bounds cost, not value. |
|
|
65
|
+
| `RETICLE_SECRET_<FIELD>` | The value for a secret field, such as `RETICLE_SECRET_AUTH_PASSWORD` for a field named `auth-password`. Only the field's NAME goes to the platform. The value is typed in on your machine and never sent. |
|
|
63
66
|
|
|
64
|
-
The
|
|
67
|
+
**What you see.** The HUD's Agent Log marks the moment the Harness takes over ("Reticle Harness is driving") and gives its steps their own colour, so you can tell its work from your agent's. Each Harness drive is recorded as its own run, named for its journey and credited to the Harness, beside your agent's run. Any "double-quoted text" in a persona must be on the page when the journey ends, and is checked.
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
## How it decides
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
The platform drives with Jev, a System One model that answers typed questions and cannot write. Every choice is a selection from candidates read off the page: which element, which tool, what consequence to claim. Three rules sit around those choices, because each one was a drive that stopped short or claimed nothing:
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
- A journey that names a page it has not reached ("then turn on automatic refunds in Settings") is not finished. The Harness goes there instead of stopping.
|
|
74
|
+
- A dialog whose destructive action already ran is closed rather than treated as the end of the journey.
|
|
75
|
+
- A control the destructive-action gate refused is a write, so the Harness always claims a request or a signal for it. A save the server rejects then fails visibly instead of passing as nothing to prove.
|
|
71
76
|
|
|
72
77
|
## Turning it off, and who pays for it
|
|
73
78
|
|
|
74
79
|
A project linked to a Reticle workspace reads two things from it before a drive starts, and honours both:
|
|
75
80
|
|
|
76
|
-
- **The switch.** Autonomous driving can be turned off per project
|
|
77
|
-
- **
|
|
81
|
+
- **The switch.** Autonomous driving can be turned off per project, from the HUD's Reticle Harness switch or the dashboard (Settings → Projects → Reticle Harness on <project>). A drive then refuses and says where to turn it back on. Switched off while a platform drive is running, the drive stops at its next turn with `stopReason: "stopped"`, keeps what it drove, and says so in the Agent Log. Everything else is unaffected, including the tools your own agent drives with.
|
|
82
|
+
- **Credits.** Harness drives and dashboard chat checks spend Harness credits. The platform sets the amount for your plan (see above). The HUD shows how many are left; once they are spent a drive is refused with that number and the way to get more.
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
If only the settings endpoint is unreachable, the on/off switch and the credit check do not block a drive: an unreachable settings endpoint is not a reason to lose a feature you were never told to stop using. The drive itself still needs the platform, so with no connection at all it is refused with the reason.
|
|
80
85
|
|
|
81
86
|
## What it will not do
|
|
82
87
|
|
|
83
88
|
**It does not decide whether your app is correct.** The model chooses what to _try_; the engine decides what _happened_, from what it recorded. A model that graded its own driving would be scoring its own homework, and its verdict would be unfalsifiable. So the summary it writes is an account of what it drove, and nothing downstream grades from it.
|
|
84
89
|
|
|
85
|
-
That split is also why the
|
|
90
|
+
That split is also why the platform's model is not the largest one available. The harness is exploring an interface and stating expectations, not reasoning about your business logic. If finding defects needed a frontier model _there_, the engine would not be doing its job.
|
|
86
91
|
|
|
87
92
|
**It really clicks.** A drive navigates, submits forms and mutates state, exactly like the crawl does. Point it at a preview or a dev environment, not production.
|
|
88
93
|
|
package/docs/benchmarks.md
CHANGED
|
@@ -8,7 +8,7 @@ Two different measurements, because there are two different questions.
|
|
|
8
8
|
|
|
9
9
|
Against a **Playwright script** over an 88-bug registry, each tool running its own native check deterministically with no model in the loop, Reticle caught **85 of 88** and Playwright **59 of 88**, both with zero false alarms on the clean build. The gap is not spread evenly: it is 26 bugs Playwright **structurally cannot** see, and on everything observable from outside the app the two tie exactly. See Part 5a.
|
|
10
10
|
|
|
11
|
-
Against **Playwright MCP and Chrome DevTools MCP**, the agent-driven tools where cost per look matters, Reticle caught 10 of 10 injected regressions to Playwright MCP's 9 and DevTools' 8, averaging 815 tokens per look against 1,292 and 758. See Part 5b.
|
|
11
|
+
Against **Playwright MCP and Chrome DevTools MCP**, the agent-driven tools where cost per look matters, Reticle caught 10 of 10 injected regressions to Playwright MCP's 9 and DevTools' 8, averaging 815 tokens per look against 1,292 and 758. That pass last ran on 2026-06-22, against versions of both tools that have since moved on. See Part 5b.
|
|
12
12
|
|
|
13
13
|
Where Reticle loses is stated plainly in Part 5, and it loses in more places than these two tables show.
|
|
14
14
|
|
|
@@ -28,7 +28,7 @@ There are roughly three ways teams do this:
|
|
|
28
28
|
|
|
29
29
|
1. **Manual testing.** A human clicks through the app. Accurate, but slow and easy to skip.
|
|
30
30
|
2. **Automated tests**: code that clicks through the app for you. Fast to re-run, but expensive to write and notoriously **flaky** (they break for reasons unrelated to real bugs).
|
|
31
|
-
3. **Nothing.** Ship and hope. More common than anyone admits
|
|
31
|
+
3. **Nothing.** Ship and hope. More common than anyone admits.
|
|
32
32
|
|
|
33
33
|
A **regression** is the specific bug this page cares about: something that _used to work_ and quietly _stopped working_ after a change. Regressions are insidious because the feature looked done, right up until a later edit broke it and nobody noticed.
|
|
34
34
|
|
|
@@ -151,7 +151,7 @@ Bug registry: `bench/pw-vs-reticle/bugs.mjs`. Runner: `bench/pw-vs-reticle/run.m
|
|
|
151
151
|
|
|
152
152
|
### 5b. The controlled toy app (the demo)
|
|
153
153
|
|
|
154
|
-
Measured on the observation-cost pass (numbers regenerate from `bench/raw/`):
|
|
154
|
+
Measured on the observation-cost pass (numbers regenerate from `bench/raw/`). The cross-tool passes last ran on 2026-06-22, against `@playwright/mcp@0.0.76` and `chrome-devtools-mcp@1.3.0`; re-run `pnpm bench:full` before quoting a competitive delta:
|
|
155
155
|
|
|
156
156
|
| Tool | Bugs caught (of 10) | Detection accuracy | Avg tokens per look | Verification Efficiency |
|
|
157
157
|
| --- | --- | --- | --- | --- |
|
|
@@ -201,7 +201,7 @@ Honesty is the point of this page, so here are the places Reticle does **not** w
|
|
|
201
201
|
|
|
202
202
|
The numbers above are for **one** verification. But a test suite's real job is the **same** check, over and over, every commit, every CI run. Here the picture changes shape:
|
|
203
203
|
|
|
204
|
-
- Reticle records a flow once, then **replays it with no AI model at all** (re-resolving each element and re-asserting the outcome) for **~239 tokens per run** (re-measured 2026-08-11
|
|
204
|
+
- Reticle records a flow once, then **replays it with no AI model at all** (re-resolving each element and re-asserting the outcome) for **~239 tokens per flow, per run** (re-measured 2026-08-11). Verifying a whole four-flow suite in one call reads **~480 tokens** for the suite (re-measured 2026-10-06; see `bench/SCORECARD.md`), about 60 tokens per added flow.
|
|
205
205
|
- Playwright MCP and DevTools MCP have no replay: re-checking means an agent **re-drives the whole flow with the model every time**, costing tens of thousands of tokens per run.
|
|
206
206
|
|
|
207
207
|
That's a **~127× cost difference per re-run**, and it grows with how often you run. This is where the "much cheaper than screenshots" claim becomes dramatic rather than incremental.
|
|
@@ -227,7 +227,7 @@ A fleet of agents (or a parallel suite) verifying the same app doesn't need a br
|
|
|
227
227
|
|
|
228
228
|
- **Every number comes from a committed harness**, not a slide. Re-run it: `pnpm bench`.
|
|
229
229
|
- **A no-bug control** runs in every pass, so a tool can't look good by flagging everything.
|
|
230
|
-
- **Tool versions are
|
|
230
|
+
- **Tool versions are recorded by hand in `bench/README.md`; re-derive before quoting.** The raw payloads are saved to `bench/raw/` so anyone can audit them.
|
|
231
231
|
- **The token counter is a tokenizer**, not a guess. Where we use a proxy tokenizer instead of a specific model's, we say so and lean on _relative_ differences, which are robust to the choice.
|
|
232
232
|
- **We publish where we lose** (above). A benchmark that only flatters its author isn't a benchmark.
|
|
233
233
|
|
package/docs/best-practices.mdx
CHANGED
|
@@ -5,7 +5,7 @@ description: The habits that make a verdict worth trusting, and the specific mis
|
|
|
5
5
|
icon: star
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
A green is worth trusting when you named the consequence **before** you acted, ended the run on `reticle_act_and_wait`
|
|
8
|
+
A green is worth trusting when you named the consequence **before** you acted, ended the run on a call that produces a verdict (`reticle_act_and_wait`, `reticle_assert`, a `reticle_act { steps }` whose last step declares `expect`, or `reticle_verify`), scoped the assertion with `since`, and read `verified` rather than `pass`. Everything below is one of those habits, or the specific mistake that breaks it.
|
|
9
9
|
|
|
10
10
|
Everything here comes from driving Reticle against real apps and getting it wrong first. None of it is theoretical, and several entries exist because they bit us while writing these docs.
|
|
11
11
|
|
|
@@ -27,7 +27,7 @@ An agent that acts first and then decides what counts as success will always fin
|
|
|
27
27
|
|
|
28
28
|
## A drive that ends on `reticle_act` proved nothing
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Verdicts come from `reticle_act_and_wait`, `reticle_assert`, `reticle_act { steps }` when a step declares `expect`, and `reticle_verify` (`change`/`flows`). Everything else moves or reads the app and proves nothing. Only `verified: "yes"` is a pass: `unknown` means Reticle could not tell, and `no-fault` means nothing was declared to prove.
|
|
31
31
|
|
|
32
32
|
This is not pedantry. Here is a real `act_sequence` response:
|
|
33
33
|
|
|
@@ -37,7 +37,7 @@ This is not pedantry. Here is a real `act_sequence` response:
|
|
|
37
37
|
|
|
38
38
|
`ok: true`, and the login **failed**. `ok` means the actions were dispatched, which they were. If your run ends there, you have a green tick attached to a broken flow.
|
|
39
39
|
|
|
40
|
-
**Batch the setup, prove the outcome.** Use `
|
|
40
|
+
**Batch the setup, prove the outcome.** Use `reticle_act { steps }` for the fills, then `act_and_wait` on the final click.
|
|
41
41
|
|
|
42
42
|
## Treat `unknown` as unknown
|
|
43
43
|
|
|
@@ -172,10 +172,10 @@ If you relax a predicate, you should be able to say why the _original_ expectati
|
|
|
172
172
|
|
|
173
173
|
| Instead of | Use | Why |
|
|
174
174
|
| --- | --- | --- |
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `observe` for one question | `network` or `console` | The summary block is usually enough |
|
|
175
|
+
| `look { action: "page" }` on every turn | `look { action: "page", mode: "status" }` | 25 tokens to answer "where am I?" |
|
|
176
|
+
| `look { action: "page" }` then reading it | `look { action: "find", by: "testid" }` | Retrieval, not orientation |
|
|
177
|
+
| `look { action: "find" }` to count rows | `look { action: "find", count_only: true }` | Around 30x smaller |
|
|
178
|
+
| `observe` for one question | `observe { action: "network" }` or `{ action: "console" }` | The summary block is usually enough |
|
|
179
179
|
| Re-snapshotting after each act | Reuse the `ref` | Refs stay valid until the element leaves the DOM |
|
|
180
180
|
|
|
181
181
|
Every response carries `cost: { bytes, tokens }`. If a loop is expensive, that field tells you which call to fix.
|
|
@@ -192,11 +192,29 @@ Sessions accumulate. Four stale ones pointing at dev servers you restarted an ho
|
|
|
192
192
|
{ "action": "yield", "mode": "waiting" }
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
`yield` when you are pausing, `end` when you are done.
|
|
195
|
+
`yield` when you are pausing, `end` when you are done. A yielded session revives on your next action; `end` is terminal, so use it only when the whole task is complete. The difference is also what the human watching the panel is told. The panel reads "live" until you say otherwise.
|
|
196
|
+
|
|
197
|
+
## End with the Reticle result
|
|
198
|
+
|
|
199
|
+
`reticle_verify` (`flows` and `change`) and `reticle_session { action: "end" }` return `reticleResult`: a short markdown block the server builds from the verdicts it holds. Paste it to the user verbatim as the last thing you say. It reads the same wherever it came from:
|
|
200
|
+
|
|
201
|
+
```md
|
|
202
|
+
**Reticle result: proved** · 3 of 3 checks held
|
|
203
|
+
|
|
204
|
+
- Checks: 3 yes · 0 no · 0 undecided
|
|
205
|
+
- Covered: checkout-pay, login
|
|
206
|
+
- Metrics: 3 checks · 2 flows replayed · 4.2s
|
|
207
|
+
- Evidence: .reticle/visual/runs/r1/0001-act.jpg, .reticle/visual/runs/r1/0002-act.jpg
|
|
208
|
+
- Run on the dashboard: https://app.reticle.sh/runs/r1
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- The verdict line has three words only: **proved**, **not proved**, **failed**. One undecided check makes the whole result not proved. Do not reword it into a pass.
|
|
212
|
+
- A metric Reticle did not measure is left out, never printed as zero. Model tokens saved by replay are not measured per run, so the block never claims them.
|
|
213
|
+
- The last line is about the platform, once per result. Linked, it links the run. Not linked, it says what the platform adds (run history, your team, Reticle Harness), the trial, and `npx @reticlehq/server connect`. Keep it; do not repeat it elsewhere.
|
|
196
214
|
|
|
197
215
|
## Confirm a navigation landed
|
|
198
216
|
|
|
199
|
-
`reticle_navigate`
|
|
217
|
+
`reticle_navigate`'s `ok` only means the navigation was dispatched: it destroys the document the SDK lives in. It then waits up to `timeout_ms` (default 5000) for the SDK to reconnect. `confirmed: true` with a `sessionId` means the page arrived; `confirmed: false` with `landedOn` means a redirect took it elsewhere; `confirmed: false` alone means it was not seen in time. Re-snapshot either way: refs do not survive a new document.
|
|
200
218
|
|
|
201
219
|
## Start with what the app says about itself
|
|
202
220
|
|
package/docs/capabilities.mdx
CHANGED
|
@@ -4,7 +4,7 @@ description: Coverage, storage, fake clocks, autonomous crawling, visual diffing
|
|
|
4
4
|
icon: sparkles
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
These are the Reticle tools that do something other than look, act, observe and assert: control coverage, client storage, a fake clock, autonomous crawling, semantic and visual baselines, network mocking, flow recording and replay, and the CI artifact. Reach for them when the verify loop is not the shape of the question. They are **not advertised on the default tool surface, but they are reachable from it**: `reticle_run({ tool, args })` dispatches to any registered tool by name, advertised or not, which is the spelling used on this page.
|
|
7
|
+
These are the Reticle tools that do something other than look, act, observe and assert: control coverage, client storage, a fake clock, autonomous crawling, semantic and visual baselines, network mocking, flow recording and replay, and the CI artifact. Reach for them when the verify loop is not the shape of the question. They are **not advertised on the default tool surface, but they are reachable from it**: `reticle_run({ tool, args })` dispatches to any registered tool by name, advertised or not, which is the spelling used on this page. Starting the daemon with `RETICLE_ADVERTISE_ALL_TOOLS=1` (read once at startup, so restart it) advertises some of them outright, with their output schemas: storage, clock, screenshot, visual diff, network mocking, recording, flow save and replay. The rest stay behind `reticle_run` on every surface.
|
|
8
8
|
|
|
9
9
|
Most of the time you want the verify loop. Look, act, observe, assert. These are the tools for the times you want something else, and they are the ones people are most surprised exist.
|
|
10
10
|
|
|
@@ -255,11 +255,10 @@ Records the meaningful state of a page and compares later. Structure and content
|
|
|
255
255
|
|
|
256
256
|
## Needs a driven browser
|
|
257
257
|
|
|
258
|
-
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.
|
|
258
|
+
Four tools apply their effects through the Chrome DevTools Protocol or a browser page Reticle owns. The always-on SDK cannot do that, so they need a browser Reticle is driving (`reticle drive <url>`, or `RETICLE_CDP_URL` pointed at a Chrome started with `--remote-debugging-port`) or a leased tab (`reticle_lease { action: "acquire" }`).
|
|
259
259
|
|
|
260
260
|
<Warning>
|
|
261
|
-
|
|
262
|
-
`reticle_screenshot` answers
|
|
261
|
+
On a tab the SDK alone is connected to, `reticle_screenshot` answers
|
|
263
262
|
|
|
264
263
|
```json
|
|
265
264
|
{
|
|
@@ -269,9 +268,7 @@ Four tools apply their effects through the Chrome DevTools Protocol. The always-
|
|
|
269
268
|
}
|
|
270
269
|
```
|
|
271
270
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
Run `reticle drive <url>`, or point `RETICLE_CDP_URL` at a Chrome started with `--remote-debugging-port`.
|
|
271
|
+
and `reticle_network_mock` answers `{ "applied": false, "count": 0, "ok": false, "reason": "no-cdp-provider" }`. The captures below were taken under a driven browser.
|
|
275
272
|
|
|
276
273
|
</Warning>
|
|
277
274
|
|
|
@@ -317,7 +314,7 @@ Run `reticle drive <url>`, or point `RETICLE_CDP_URL` at a Chrome started with `
|
|
|
317
314
|
mistake to make twice.
|
|
318
315
|
</Warning>
|
|
319
316
|
|
|
320
|
-
`fullPage` captures the whole scroll height. `ref` or `clip` scopes to one element or region. `threshold` sets the pixel-difference tolerance, defaulting to `0.
|
|
317
|
+
`fullPage` captures the whole scroll height. `ref` or `clip` scopes to one element or region. `threshold` sets the pixel-difference tolerance, defaulting to `0.1`, `maxRatio` caps the acceptable changed fraction, and `masks` excludes regions that are expected to change.
|
|
321
318
|
|
|
322
319
|
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.
|
|
323
320
|
|
|
@@ -361,11 +358,11 @@ The loop closer, and the reason Reticle is not only an interactive tool.
|
|
|
361
358
|
{ "tool": "reticle_verify", "args": { "action": "flows" } }
|
|
362
359
|
```
|
|
363
360
|
|
|
364
|
-
<
|
|
365
|
-
|
|
366
|
-
`
|
|
367
|
-
|
|
368
|
-
</
|
|
361
|
+
<Note>
|
|
362
|
+
`reticle_record` takes **`recordingName`** and `reticle_flow_save` takes **`flowName`**. Both also
|
|
363
|
+
accept `name` as an alias. `flowName` on `reticle_flow_save` is the recording to save; pass
|
|
364
|
+
`saveAs` to choose the flow's file name.
|
|
365
|
+
</Note>
|
|
369
366
|
|
|
370
367
|
Stopping a recording used to return a very large payload, almost all of it the raw `events` array. It no longer does. The timeline is omitted and replaced with a pointer, so a stop is under a kilobyte. This is a real capture of a one-click recording, complete rather than trimmed:
|
|
371
368
|
|
|
@@ -394,8 +391,9 @@ Each step's `args` is elided above because a recorded step is an anchor, not a c
|
|
|
394
391
|
Nine hundred and fifty-three bytes for 445 recorded events. `timeline_omitted` hands you the exact `reticle_observe` call to make if you want them, so nothing is lost, it is only not charged for by default.
|
|
395
392
|
|
|
396
393
|
<Note>
|
|
397
|
-
`reticle_record` takes `action`, `recordingName`
|
|
398
|
-
and `filters` are rejected, which no longer matters now that the
|
|
394
|
+
`reticle_record` takes `action`, `recordingName` (or its alias `name`) and `sessionId`, and
|
|
395
|
+
nothing else. `max_events` and `filters` are rejected, which no longer matters now that the
|
|
396
|
+
timeline is omitted anyway.
|
|
399
397
|
</Note>
|
|
400
398
|
|
|
401
399
|
`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.
|
|
@@ -427,7 +425,7 @@ Nine hundred and fifty-three bytes for 445 recorded events. `timeline_omitted` h
|
|
|
427
425
|
|
|
428
426
|
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.
|
|
429
427
|
|
|
430
|
-
A replay against a drifted app names what moved and where. This is `reticle_verify {action:"flows"}` reporting the same flow after the app changed underneath it:
|
|
428
|
+
A replay against a drifted app names what moved and where. This is `reticle_verify { action: "flows" }` reporting the same flow after the app changed underneath it:
|
|
431
429
|
|
|
432
430
|
```json
|
|
433
431
|
{
|
package/docs/cli/affected.mdx
CHANGED
|
@@ -4,7 +4,7 @@ description: List which saved flows must re-verify for a set of changed files.
|
|
|
4
4
|
icon: code-branch
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
`reticle affected` answers one question: given these changed files, which saved flows cover them? It is the foundation the [gate](/cli/gate)
|
|
7
|
+
`reticle affected` answers one question: given these changed files, which saved flows cover them? It is the foundation the [gate](/cli/gate) is built on, and it costs your agent nothing per turn because it runs in the environment.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npx @reticlehq/server affected [--since <ref>] [file...]
|