@reticlehq/server 3.2.0 → 3.4.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/LICENSE-ENTERPRISE +1 -1
- package/README.md +3 -3
- package/SKILL.md +23 -22
- package/dist/chromium-launch-options.d.ts +4 -3
- package/dist/chromium-launch-options.js +6 -2
- package/dist/command/cli/adhoc-suite.d.ts +41 -0
- package/dist/command/cli/adhoc-suite.js +159 -0
- package/dist/command/cli/adhoc-verdict.d.ts +58 -2
- package/dist/command/cli/adhoc-verdict.js +108 -13
- package/dist/command/cli/answers/gate-hook-message.d.ts +6 -0
- package/dist/command/cli/answers/gate-hook-message.js +6 -0
- package/dist/command/cli/auth/cloud-keystore.d.ts +0 -2
- package/dist/command/cli/auth/cloud-keystore.js +0 -3
- package/dist/command/cli/auth/cloud-session.d.ts +4 -0
- package/dist/command/cli/auth/cloud-session.js +2 -0
- package/dist/command/cli/cli-doctor.js +30 -8
- package/dist/command/cli/cli-flow-commands.d.ts +3 -6
- package/dist/command/cli/cli-flow-commands.js +67 -4
- package/dist/command/cli/cli-parse-grammar.d.ts +7 -0
- package/dist/command/cli/cli-parse-grammar.js +7 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -5
- package/dist/command/cli/cli-parse-verify.js +86 -13
- package/dist/command/cli/cli-parse.d.ts +14 -1
- package/dist/command/cli/cli-parse.js +54 -8
- package/dist/command/cli/cli-update-commands.js +8 -1
- package/dist/command/cli/cli-verify.d.ts +80 -0
- package/dist/command/cli/cli-verify.js +181 -26
- package/dist/command/cli/cloud-cli.js +5 -2
- package/dist/command/cli/cloud-kit.d.ts +0 -2
- package/dist/command/cli/cloud-kit.js +3 -5
- package/dist/command/cli/cloud-login.js +21 -3
- package/dist/command/cli/demo/demo-page.js +6 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +5 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +5 -0
- package/dist/command/cli/doctor/doctor-sessions-line.d.ts +2 -1
- package/dist/command/cli/launch/cli-launch.d.ts +9 -29
- package/dist/command/cli/launch/cli-launch.js +27 -49
- package/dist/command/cli/launch/sdk-version-match.d.ts +84 -0
- package/dist/command/cli/launch/sdk-version-match.js +206 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +2 -16
- package/dist/command/cli/ports/resolve/cli-port.d.ts +38 -0
- package/dist/command/cli/ports/resolve/cli-port.js +169 -15
- package/dist/command/cli/report-command.d.ts +16 -0
- package/dist/command/cli/report-command.js +97 -0
- package/dist/command/cli/setup-mcp-cli.js +13 -13
- package/dist/command/cli/tutorial.d.ts +2 -2
- package/dist/command/cli/tutorial.js +21 -7
- package/dist/command/cli.js +67 -10
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +44 -2
- package/dist/command/daemon/binding/daemon-status-probe.js +79 -6
- package/dist/command/daemon/binding/port-presence.d.ts +1 -1
- package/dist/command/daemon/daemon-resolve.d.ts +9 -0
- package/dist/command/daemon/daemon-resolve.js +1 -1
- package/dist/command/daemon/idle-shutdown.d.ts +2 -1
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +7 -1
- package/dist/command/daemon/lifetime/daemon-usefulness.js +30 -7
- package/dist/command/dev/stale-issue-guard.d.ts +3 -4
- package/dist/command/dev/stale-issue-guard.js +8 -8
- package/dist/command/setup/bringup/connect-lease.d.ts +17 -0
- package/dist/command/setup/bringup/connect-lease.js +38 -0
- package/dist/command/setup/bringup/dev-server-files.d.ts +68 -0
- package/dist/command/setup/bringup/dev-server-files.js +131 -0
- package/dist/command/setup/bringup/dev-server-log-cap.d.ts +35 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +121 -0
- package/dist/command/setup/bringup/ensure-daemon.d.ts +65 -4
- package/dist/command/setup/bringup/ensure-daemon.js +135 -16
- package/dist/command/setup/bringup/static-page-server.d.ts +35 -0
- package/dist/command/setup/bringup/static-page-server.js +151 -0
- package/dist/command/setup/desktop-shape.d.ts +4 -0
- package/dist/command/setup/desktop-shape.js +18 -2
- package/dist/command/setup/init/init-host.js +8 -0
- package/dist/command/setup/init/init-port.d.ts +15 -0
- package/dist/command/setup/init/init-port.js +44 -0
- package/dist/command/setup/init/init-runtime.d.ts +1 -1
- package/dist/command/setup/init/init-runtime.js +39 -2
- package/dist/command/setup/node-effects.d.ts +27 -14
- package/dist/command/setup/node-effects.js +80 -44
- package/dist/command/setup/probe/loopback-probe-urls.d.ts +7 -0
- package/dist/command/setup/probe/loopback-probe-urls.js +40 -0
- package/dist/command/setup/probe/page-probe.d.ts +13 -2
- package/dist/command/setup/probe/page-probe.js +18 -3
- package/dist/command/setup/run-setup.d.ts +26 -1
- package/dist/command/setup/run-setup.js +96 -13
- package/dist/command/setup/session-pick.d.ts +13 -0
- package/dist/command/setup/session-pick.js +20 -0
- package/dist/command/setup/setup-command.d.ts +2 -14
- package/dist/command/setup/setup-command.js +105 -31
- package/dist/command/setup/setup-mcp.js +3 -3
- package/dist/command/setup/terminal/wait-progress.d.ts +8 -0
- package/dist/command/setup/terminal/wait-progress.js +17 -0
- package/dist/features/crawl/crawl-empty.js +1 -1
- package/dist/features/crawl/crawl-tools.d.ts +6 -0
- package/dist/features/crawl/crawl-tools.js +57 -0
- package/dist/features/crawl/crawl.d.ts +2 -0
- package/dist/features/crawl/crawl.js +171 -156
- package/dist/features/exhaust/app-coverage.d.ts +33 -0
- package/dist/features/exhaust/app-coverage.js +31 -0
- package/dist/features/exhaust/code-coverage.d.ts +47 -0
- package/dist/features/exhaust/code-coverage.js +77 -0
- package/dist/features/exhaust/exhaust-run.d.ts +33 -0
- package/dist/features/exhaust/exhaust-run.js +82 -0
- package/dist/features/exhaust/explorer.d.ts +103 -0
- package/dist/features/exhaust/explorer.js +195 -0
- package/dist/features/exhaust/failure-branches.d.ts +33 -0
- package/dist/features/exhaust/failure-branches.js +92 -0
- package/dist/features/exhaust/ledger.d.ts +202 -0
- package/dist/features/exhaust/ledger.js +252 -0
- package/dist/features/exhaust/session-fold.d.ts +31 -0
- package/dist/features/exhaust/session-fold.js +79 -0
- package/dist/features/exhaust/session-port.d.ts +36 -0
- package/dist/features/exhaust/session-port.js +102 -0
- package/dist/features/harness/drive-report.d.ts +0 -9
- package/dist/features/harness/drive-report.js +18 -0
- package/dist/features/harness/driver.js +4 -7
- package/dist/features/harness/fill-values.d.ts +6 -0
- package/dist/features/harness/fill-values.js +3 -0
- package/dist/features/harness/jev-driver.js +36 -22
- package/dist/features/harness/openai-driver.js +4 -7
- package/dist/features/harness/platform-config.d.ts +10 -0
- package/dist/features/harness/platform-config.js +13 -6
- package/dist/index.d.ts +10 -1
- package/dist/index.js +78 -104
- package/dist/judgement/capsule/capsule-store.d.ts +31 -2
- package/dist/judgement/capsule/capsule-store.js +58 -6
- package/dist/judgement/capsule/capsule.js +5 -0
- package/dist/judgement/capsule/causal-summary.d.ts +13 -1
- package/dist/judgement/capsule/causal-summary.js +7 -0
- package/dist/judgement/domain/domain-model.js +40 -9
- package/dist/judgement/oracles/self-instrument.js +4 -2
- package/dist/judgement/outcome/assertion-integrity.d.ts +3 -3
- package/dist/judgement/runs/artifact/gap-report.d.ts +17 -0
- package/dist/judgement/runs/artifact/gap-report.js +46 -0
- package/dist/judgement/runs/artifact/gap-summary.d.ts +58 -0
- package/dist/judgement/runs/artifact/gap-summary.js +85 -0
- package/dist/judgement/runs/artifact/render-report.js +4 -1
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +2 -2
- package/dist/judgement/runs/artifact/replay-mapping.js +44 -9
- package/dist/judgement/runs/artifact/to-artifact.d.ts +7 -2
- package/dist/judgement/runs/artifact/to-artifact.js +1 -1
- package/dist/judgement/runs/context-tools.js +21 -3
- package/dist/judgement/runs/drive-run.js +7 -2
- package/dist/judgement/runs/verification-sync.d.ts +3 -1
- package/dist/judgement/runs/verification-sync.js +1 -1
- package/dist/language/flows/annotate-notes/annotate.d.ts +0 -15
- package/dist/language/flows/annotate-notes/annotate.js +66 -18
- package/dist/language/flows/change/affected.d.ts +9 -0
- package/dist/language/flows/change/affected.js +35 -0
- package/dist/language/flows/change/gate.d.ts +20 -0
- package/dist/language/flows/change/gate.js +12 -1
- package/dist/language/flows/flow-anchor.d.ts +12 -0
- package/dist/language/flows/flow-anchor.js +20 -0
- package/dist/language/flows/flow-author.d.ts +7 -0
- package/dist/language/flows/flow-author.js +19 -0
- package/dist/language/flows/flow-expect-grammar.d.ts +2 -2
- package/dist/language/flows/flow-expect-grammar.js +92 -11
- package/dist/language/flows/flow-intent.js +1 -1
- package/dist/language/flows/flow-journey.d.ts +54 -0
- package/dist/language/flows/flow-journey.js +119 -0
- package/dist/language/flows/flow-learning.d.ts +3 -0
- package/dist/language/flows/flow-learning.js +39 -8
- package/dist/language/flows/flow-replay-run.d.ts +33 -12
- package/dist/language/flows/flow-replay-run.js +131 -52
- package/dist/language/flows/flow-replay-types.d.ts +9 -0
- package/dist/language/flows/flow-replay.d.ts +27 -12
- package/dist/language/flows/flow-replay.js +127 -111
- package/dist/language/flows/flow-result.d.ts +2 -0
- package/dist/language/flows/flow-result.js +25 -0
- package/dist/language/flows/flow-step-runners.d.ts +26 -10
- package/dist/language/flows/flow-step-runners.js +20 -4
- package/dist/language/flows/flow-success.d.ts +21 -6
- package/dist/language/flows/flow-success.js +50 -138
- package/dist/language/flows/flow-tools.js +17 -5
- package/dist/language/flows/flows.d.ts +18 -5
- package/dist/language/flows/flows.js +101 -16
- package/dist/language/flows/heal.d.ts +9 -1
- package/dist/language/flows/heal.js +24 -2
- package/dist/language/flows/learned-sources.d.ts +21 -0
- package/dist/language/flows/learned-sources.js +84 -0
- package/dist/language/flows/recording/recording-backtrack.d.ts +0 -7
- package/dist/language/flows/recording/recording-backtrack.js +1 -1
- package/dist/language/flows/recording/replay-halt.d.ts +2 -1
- package/dist/language/flows/recording/replay-halt.js +3 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +31 -2
- package/dist/language/flows/recording/tape/recordings.js +55 -1
- package/dist/language/flows/replay.d.ts +19 -0
- package/dist/language/flows/replay.js +53 -13
- package/dist/language/flows/stores/annotation-store.d.ts +5 -5
- package/dist/language/flows/stores/assertion-tiers-store.js +2 -3
- package/dist/language/flows/stores/flake-store.js +2 -3
- package/dist/language/flows/suite/coverage.d.ts +1 -1
- package/dist/language/flows/suite/parallel-suite.d.ts +2 -1
- package/dist/language/flows/verify-change-tools.js +19 -2
- package/dist/launch-chromium.d.ts +80 -0
- package/dist/launch-chromium.js +218 -0
- package/dist/memory/cloud/cloud-config.d.ts +11 -2
- package/dist/memory/cloud/cloud-config.js +47 -7
- package/dist/memory/cloud/cloud-sync.d.ts +4 -3
- package/dist/memory/cloud/cloud-sync.js +7 -10
- package/dist/memory/cloud/harness-config.d.ts +2 -0
- package/dist/memory/cloud/harness-offer.js +5 -6
- package/dist/memory/cloud/harness-switch.js +5 -6
- package/dist/memory/cloud/sync-cycle.d.ts +78 -1
- package/dist/memory/cloud/sync-cycle.js +321 -53
- package/dist/memory/cloud/sync-daemon.d.ts +13 -0
- package/dist/memory/cloud/sync-daemon.js +45 -20
- package/dist/memory/cloud/sync-disk.js +27 -8
- package/dist/memory/impact/impact-store.js +6 -0
- package/dist/memory/intent/inline-intent.js +8 -3
- package/dist/memory/intent/intent-shard-store.d.ts +33 -47
- package/dist/memory/intent/intent-shard-store.js +252 -140
- package/dist/memory/intent/intent-shard.d.ts +0 -23
- package/dist/memory/intent/intent-shard.js +1 -11
- package/dist/memory/intent/intent-store.d.ts +13 -8
- package/dist/memory/intent/intent-store.js +46 -90
- package/dist/memory/intent/intent-tools.js +34 -23
- package/dist/memory/journal/ambient-store.js +2 -3
- package/dist/memory/journal/deviation-report.js +4 -1
- package/dist/memory/journal/deviation-service.js +10 -2
- package/dist/memory/journal/drive-flow.d.ts +19 -14
- package/dist/memory/journal/drive-flow.js +65 -48
- package/dist/memory/journal/envelope-store.js +2 -3
- package/dist/memory/journal/journal-recorder.d.ts +21 -0
- package/dist/memory/journal/on-disk/retain-policy.d.ts +34 -0
- package/dist/memory/journal/on-disk/retain-policy.js +44 -0
- package/dist/memory/journal/on-disk/retention.d.ts +14 -10
- package/dist/memory/journal/on-disk/retention.js +13 -12
- package/dist/memory/journal/on-disk/startup-maintenance.d.ts +42 -0
- package/dist/memory/journal/on-disk/startup-maintenance.js +14 -0
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +0 -11
- package/dist/memory/journal/on-disk/workspace-gitignore.js +6 -45
- package/dist/memory/journal/on-disk/workspace-tiers.d.ts +52 -0
- package/dist/memory/journal/on-disk/workspace-tiers.js +90 -0
- package/dist/memory/journal/route-template.d.ts +22 -0
- package/dist/memory/journal/route-template.js +44 -0
- package/dist/memory/journal/session-end.d.ts +13 -2
- package/dist/memory/journal/session-end.js +88 -18
- package/dist/memory/journal/session-journal.d.ts +8 -1
- package/dist/memory/journal/session-journal.js +10 -0
- package/dist/memory/project/baselines.d.ts +1 -1
- package/dist/memory/project/dir/reticle-dir.d.ts +3 -1
- package/dist/memory/project/dir/reticle-dir.js +1 -0
- package/dist/memory/project/fs/fs-port.js +44 -5
- package/dist/memory/project/fs/write-atomic.d.ts +26 -0
- package/dist/memory/project/fs/write-atomic.js +48 -0
- package/dist/memory/project/project-tools.js +3 -1
- package/dist/memory/recall/prior/connection-memory.d.ts +6 -0
- package/dist/memory/recall/prior/connection-memory.js +8 -0
- package/dist/memory/recall/registered-projects.d.ts +2 -1
- package/dist/portal/bridge/auth-failure-reason.d.ts +1 -1
- package/dist/portal/bridge/auth-failure-reason.js +9 -4
- package/dist/portal/bridge/bridge.d.ts +8 -0
- package/dist/portal/bridge/bridge.js +43 -2
- package/dist/portal/input/js-coverage.d.ts +25 -0
- package/dist/portal/input/js-coverage.js +30 -0
- package/dist/portal/input/real-input.d.ts +11 -0
- package/dist/portal/input/real-input.js +31 -5
- package/dist/portal/pool/browser-pool.d.ts +10 -0
- package/dist/portal/pool/browser-pool.js +10 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +21 -13
- package/dist/portal/pool/pool-contract.d.ts +2 -0
- package/dist/portal/pool/storage-seed.d.ts +2 -1
- package/dist/portal/pool/zero-install.d.ts +27 -0
- package/dist/portal/pool/zero-install.js +54 -0
- package/dist/portal/realm/web-realm.js +6 -0
- package/dist/portal/session/dev-server/dev-command.d.ts +2 -2
- package/dist/portal/session/dev-server/dev-command.js +30 -12
- package/dist/portal/session/dev-server/dev-server-probe.d.ts +2 -1
- package/dist/portal/session/dev-server/dev-server-probe.js +17 -1
- package/dist/portal/session/dev-server/route-status-probe.d.ts +24 -0
- package/dist/portal/session/dev-server/route-status-probe.js +57 -0
- package/dist/portal/session/dev-server/served-document.d.ts +21 -0
- package/dist/portal/session/dev-server/served-document.js +57 -0
- package/dist/portal/session/facts/background-traffic.d.ts +9 -0
- package/dist/portal/session/facts/background-traffic.js +25 -0
- package/dist/portal/session/facts/observed-state.d.ts +11 -0
- package/dist/portal/session/facts/observed-state.js +34 -0
- package/dist/portal/session/live-control-tools.js +48 -3
- package/dist/portal/session/no-session-diagnosis.d.ts +29 -0
- package/dist/portal/session/no-session-diagnosis.js +62 -5
- package/dist/portal/session/no-session-next-action.d.ts +13 -0
- package/dist/portal/session/no-session-next-action.js +48 -9
- package/dist/portal/session/no-session-watch.d.ts +18 -0
- package/dist/portal/session/no-session-watch.js +88 -2
- package/dist/portal/session/presence/attachment-history.d.ts +13 -2
- package/dist/portal/session/session-health.d.ts +61 -0
- package/dist/portal/session/session-health.js +43 -3
- package/dist/portal/session/session-info.d.ts +6 -0
- package/dist/portal/session/session-manager.d.ts +29 -6
- package/dist/portal/session/session-manager.js +42 -5
- package/dist/portal/session/session-reaper.d.ts +28 -0
- package/dist/portal/session/session-reaper.js +49 -1
- package/dist/portal/session/session-successor.d.ts +11 -0
- package/dist/portal/session/session-successor.js +14 -1
- package/dist/portal/session/session-verdict-facts.d.ts +28 -0
- package/dist/portal/session/session-verdict-facts.js +15 -0
- package/dist/portal/session/session.d.ts +10 -0
- package/dist/portal/session/session.js +34 -26
- package/dist/surface/http-server.d.ts +2 -1
- package/dist/surface/http-server.js +4 -2
- package/dist/surface/mcp/mcp-proxy.d.ts +2 -2
- package/dist/surface/mcp/mcp-proxy.js +5 -5
- package/dist/surface/mcp/mcp.js +4 -2
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +13 -1
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +27 -2
- package/dist/surface/mcp/proxy-idle-exit.d.ts +2 -1
- package/dist/surface/mcp/server-instructions.js +21 -8
- package/dist/surface/tools/act/after-match.d.ts +17 -0
- package/dist/surface/tools/act/after-match.js +30 -0
- package/dist/surface/tools/act/already-true.d.ts +40 -0
- package/dist/surface/tools/act/already-true.js +36 -0
- package/dist/surface/tools/act/durable.d.ts +69 -0
- package/dist/surface/tools/act/durable.js +139 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +19 -6
- package/dist/surface/tools/act/navigation/navigate-arrival.js +60 -10
- package/dist/surface/tools/act/navigation/navigate-result.d.ts +1 -12
- package/dist/surface/tools/act/navigation/navigate-result.js +21 -3
- package/dist/surface/tools/act/proved-controls.d.ts +9 -0
- package/dist/surface/tools/act/proved-controls.js +11 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +5 -0
- package/dist/surface/tools/act/sequence-grade.js +32 -1
- package/dist/surface/tools/act/settle-in-flight.d.ts +6 -2
- package/dist/surface/tools/act/settle-in-flight.js +29 -6
- package/dist/surface/tools/act-capsule.d.ts +7 -0
- package/dist/surface/tools/act-capsule.js +68 -8
- package/dist/surface/tools/act-sequence-tool.js +25 -8
- package/dist/surface/tools/act-tools.js +51 -74
- package/dist/surface/tools/args/numeric-bounds.d.ts +15 -2
- package/dist/surface/tools/args/numeric-bounds.js +30 -3
- package/dist/surface/tools/assert/assert-grade.js +26 -3
- package/dist/surface/tools/assert/assert-verdict.js +32 -6
- package/dist/surface/tools/browser-tools.js +17 -4
- package/dist/surface/tools/coverage-tools.js +27 -1
- package/dist/surface/tools/dynamic-tools.js +6 -0
- package/dist/surface/tools/error-recovery.js +4 -4
- package/dist/surface/tools/feedback-invite.js +6 -4
- package/dist/surface/tools/feedback-tools.d.ts +2 -1
- package/dist/surface/tools/feedback-tools.js +1 -1
- package/dist/surface/tools/harness-explore.d.ts +3 -2
- package/dist/surface/tools/harness-explore.js +7 -6
- package/dist/surface/tools/invoke-tool.js +17 -4
- package/dist/surface/tools/lease-hint.d.ts +8 -0
- package/dist/surface/tools/lease-hint.js +10 -0
- package/dist/surface/tools/lease-tools.d.ts +16 -28
- package/dist/surface/tools/lease-tools.js +68 -11
- package/dist/surface/tools/lineage-tools.js +1 -1
- package/dist/surface/tools/live-call-text.js +4 -1
- package/dist/surface/tools/observe-tools.js +23 -7
- package/dist/surface/tools/real-input-attempt.d.ts +0 -5
- package/dist/surface/tools/real-input-attempt.js +1 -1
- package/dist/surface/tools/tool-kit.d.ts +5 -0
- package/dist/surface/tools/tool-kit.js +6 -1
- package/dist/surface/tools/tool-surface.js +17 -5
- package/dist/surface/tools/tools.js +68 -29
- package/dist/telemetry/argument-shape.d.ts +0 -2
- package/dist/telemetry/argument-shape.js +0 -4
- package/dist/telemetry/error-class.d.ts +2 -3
- package/dist/telemetry/error-class.js +2 -3
- package/dist/telemetry/feedback-local.d.ts +1 -0
- package/dist/telemetry/feedback-local.js +1 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/harness-drive.d.ts +0 -2
- package/dist/telemetry/harness-drive.js +0 -4
- package/dist/telemetry/hud-metrics.d.ts +32 -0
- package/dist/telemetry/hud-metrics.js +95 -0
- package/dist/telemetry/session-metrics.d.ts +5 -0
- package/dist/telemetry/session-metrics.js +15 -1
- package/dist/wire-journal.d.ts +34 -0
- package/dist/wire-journal.js +104 -0
- package/dist/workspace-packages.d.ts +0 -2
- package/dist/workspace-packages.js +1 -9
- package/docs/README.md +5 -2
- package/docs/actions.mdx +3 -3
- package/docs/agent-cheatsheet.md +4 -4
- package/docs/architecture.md +6 -6
- package/docs/best-practices.mdx +1 -1
- package/docs/capabilities.mdx +32 -1
- package/docs/cli/cloud.mdx +21 -9
- package/docs/cli/doctor.mdx +4 -0
- package/docs/cli/feedback.mdx +2 -2
- package/docs/cli/gate.mdx +9 -4
- package/docs/cli/init.mdx +1 -0
- package/docs/cli/report.mdx +44 -0
- package/docs/cli/update.mdx +10 -0
- package/docs/cli.mdx +9 -0
- package/docs/desktop.mdx +14 -10
- package/docs/environment.mdx +87 -0
- package/docs/faq.mdx +18 -16
- package/docs/first-drive.md +5 -13
- package/docs/flows.md +32 -2
- package/docs/frameworks.mdx +140 -9
- package/docs/getting-started.md +3 -3
- package/docs/http-transport.md +6 -3
- package/docs/human-control.md +2 -2
- package/docs/index.mdx +16 -6
- package/docs/install-agentic.mdx +37 -1
- package/docs/install-manual.mdx +1 -1
- package/docs/integration-patterns.md +3 -3
- package/docs/multi-agent-testing.md +1 -1
- package/docs/packages/babel-plugin.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/react.mdx +2 -2
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages/vite-plugin.mdx +2 -2
- package/docs/packages.mdx +9 -9
- package/docs/predicates.mdx +176 -7
- package/docs/quickstart.mdx +2 -2
- package/docs/recipes.mdx +2 -2
- package/docs/state-management.mdx +2 -2
- package/docs/system-map.md +1 -1
- package/docs/telemetry.md +1 -1
- package/docs/token-efficiency.md +3 -3
- package/docs/tools/act-and-wait.mdx +1 -0
- package/docs/tools/act-sequence.mdx +1 -1
- package/docs/tools/console.mdx +1 -1
- package/docs/tools/inspect.mdx +1 -1
- package/docs/tools/network.mdx +1 -1
- package/docs/tools/query.mdx +11 -11
- package/docs/tools/sessions.mdx +1 -1
- package/docs/tools/snapshot.mdx +1 -1
- package/docs/tools/state.mdx +1 -1
- package/docs/tools/wait-for.mdx +1 -1
- package/docs/usage.md +8 -7
- package/docs/use-cases.mdx +157 -0
- package/docs/vs-screenshots.mdx +3 -3
- package/docs/what-is-recorded.md +62 -0
- package/docs/what-is-reticle.mdx +17 -20
- package/docs/why-reticle.mdx +14 -21
- package/package.json +11 -10
- package/dist/judgement/capsule/minimize.d.ts +0 -12
- package/dist/judgement/capsule/minimize.js +0 -22
- package/dist/judgement/outcome/predicate-to-expect.d.ts +0 -44
- package/dist/judgement/outcome/predicate-to-expect.js +0 -148
- package/dist/judgement/phenomena/phenomena.d.ts +0 -26
- package/dist/judgement/phenomena/phenomena.js +0 -101
- package/dist/language/flows/flow-report.d.ts +0 -22
- package/dist/language/flows/flow-report.js +0 -106
package/docs/frameworks.mdx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 'Frameworks: proven, wired, and the difference'
|
|
3
3
|
sidebarTitle: Frameworks
|
|
4
|
-
description: Which frameworks Reticle supports, which are wired but unverified, and the exact wiring for each one. React, Next.js, Remix, Astro, SvelteKit, TanStack Start, Nuxt, Vue and plain HTML.
|
|
4
|
+
description: Which frameworks Reticle supports, which are wired but unverified, and the exact wiring for each one. React, Next.js, Remix, Astro, SvelteKit, TanStack Start, Nuxt, Vue, Angular and plain HTML.
|
|
5
5
|
icon: layer-group
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
**React + Vite, Next.js, Remix and Astro are fully supported, each with an example app driven to a verdict in CI. Astro, SvelteKit, Nuxt, React Router framework mode, Create React App and
|
|
8
|
+
**React + Vite, Next.js, Remix and Astro are fully supported, each with an example app driven to a verdict in CI. Astro, SvelteKit, Nuxt, React Router framework mode, Create React App, Vue and Angular have their INSTALL gated: the install gate scaffolds each from scratch on every change and requires a real session, but no gate drives them to a verdict. TanStack Start, Preact and plain HTML are wired by `init` and documented but not gated at all, so treat them as plausible rather than proven.** The exact wiring for each is below.
|
|
9
9
|
|
|
10
10
|
Reticle is a verification layer that embeds a dev-only SDK in your running web app so an AI coding agent can prove a change works. Its core is framework-neutral: DOM, network, console, routing, animations and source mapping work anywhere JavaScript runs.
|
|
11
11
|
|
|
@@ -32,9 +32,11 @@ Two columns say different things and it is worth keeping them apart. **CI gate**
|
|
|
32
32
|
| **Nuxt** | yes | no | install only | unproven | Install gated, drive unverified |
|
|
33
33
|
| **React Router (framework mode)** | yes | no | install only | yes | Install gated, drive unverified |
|
|
34
34
|
| **Create React App** | yes | no | install only | unproven | Install gated, drive unverified |
|
|
35
|
+
| **Angular 17+** | yes | no | install only | no | Install gated, drive unverified |
|
|
35
36
|
| **Plain HTML** | yes | no | no | no | Wired, unverified |
|
|
36
37
|
| **Vue (non-Nuxt)** | as Vite | no | install only | no | Install gated, drive unverified |
|
|
37
|
-
| **Preact** | as Vite | no | no | unproven | Sensor, React adapter via `preact/compat` |
|
|
38
|
+
| **Preact** | as Vite | no | no | transform-tested; drive unproven | Sensor, React adapter via `preact/compat` |
|
|
39
|
+
| **Server-rendered (Django, Flask, FastAPI, Streamlit, Rails)** | yes | no | no | no | Wired, unverified |
|
|
38
40
|
|
|
39
41
|
<Warning>
|
|
40
42
|
"Wired, unverified" means exactly that. The recipe exists and was written from a real integration,
|
|
@@ -85,7 +87,41 @@ module.exports = withReticle({/* your config */});
|
|
|
85
87
|
|
|
86
88
|
## Remix and Astro
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
Remix v2 on Vite is its own framework to `init`, not plain Vite. Remix SSRs its own HTML, so the plugin's `index.html` injection never reaches the page and the connect comes from `app/entry.client.tsx` instead, the same way as React Router framework mode. `init` adds the dev-only connect line to that entry, or writes the file when the app has none: `app/entry.client.tsx` only exists after `remix reveal`, so the written file is Remix's own default entry (`RemixBrowser`, `hydrateRoot`) with the one line added. The Vite plugin, `reticle()` in the `vite.config` that carries `vitePlugin`, stamps `file:line` and serves the connect module the entry imports. The classic Remix compiler (no `vite.config`) gets a manual step rather than a green plan, because there is no plugin to serve that module.
|
|
91
|
+
|
|
92
|
+
Astro uses the Vite plugin (wire it with `inject: false` if you want source pointers on JSX islands) and uses a different channel for the pairing token. `vite.define` does not reach Astro's client pipeline on 7.2+, so the identifier stays literal and the bridge refuses the dial. `init` reads the token in frontmatter and puts it on a `<meta name="reticle-pairing-token">`. Reading it per request also means a token written after the dev server started is picked up on the next load, with no restart.
|
|
93
|
+
|
|
94
|
+
Use a processed page `<script>` with a static SDK import. Vite owns that module graph from the first transform:
|
|
95
|
+
|
|
96
|
+
```astro
|
|
97
|
+
---
|
|
98
|
+
import { readFileSync } from 'node:fs';
|
|
99
|
+
import { homedir } from 'node:os';
|
|
100
|
+
import { join } from 'node:path';
|
|
101
|
+
const pairingToken = (() => {
|
|
102
|
+
if (!import.meta.env.DEV) return '';
|
|
103
|
+
const dir = process.env['RETICLE_PAIRING_TOKEN_DIR'] || join(homedir(), '.reticle');
|
|
104
|
+
try { return readFileSync(join(dir, 'pairing-token'), 'utf8').trim(); } catch { return ''; }
|
|
105
|
+
})();
|
|
106
|
+
const pairingRoot = import.meta.env.DEV ? process.cwd() : '';
|
|
107
|
+
---
|
|
108
|
+
<meta name="reticle-pairing-token" content={pairingToken} />
|
|
109
|
+
<meta name="reticle-pairing-root" content={pairingRoot} />
|
|
110
|
+
<script>
|
|
111
|
+
import { reticle, install } from '@reticlehq/react';
|
|
112
|
+
if (import.meta.env.DEV) {
|
|
113
|
+
const token = document.querySelector('meta[name="reticle-pairing-token"]')?.getAttribute('content') ?? '';
|
|
114
|
+
const root = document.querySelector('meta[name="reticle-pairing-root"]')?.getAttribute('content') ?? '';
|
|
115
|
+
install();
|
|
116
|
+
reticle.connect({
|
|
117
|
+
...(0 < token.length ? { token } : {}),
|
|
118
|
+
...(0 < root.length ? { root } : {}),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
</script>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The `<script>` tag must not sit inside a conditional. Astro hoists them statically, so `{isDev && (<script />)}` is never hoisted. `init` writes the same `<meta>` tags and a local `src/components/ReticleDev.ts` that the script statically imports. It also raises `vite.build.target` to `es2022` (Astro's default down-levels the SDK), declares the SDK in `optimizeDeps.include`, and keeps `.reticle/` out of the watcher. Static `.astro` markup still gets DOM, network and routing without the React integration.
|
|
89
125
|
|
|
90
126
|
## SvelteKit
|
|
91
127
|
|
|
@@ -120,7 +156,7 @@ useEffect(() => {
|
|
|
120
156
|
}, []);
|
|
121
157
|
```
|
|
122
158
|
|
|
123
|
-
`init`
|
|
159
|
+
`init` writes this for you: a `src/reticle-connect.tsx` client effect that connects, declares `__RETICLE_TOKEN__` so `tsc` passes, and loads `src/reticle-dev.ts`, plus `<ReticleConnect />` rendered before `<Scripts />` in `src/routes/__root.tsx`. When the root route is not a shape it can patch, it prints a recipe naming the real parts (`shellComponent`, `<Scripts />`) instead. There is no example app and no CI gate, so treat a connected session as the proof, not the plan.
|
|
124
160
|
|
|
125
161
|
## Nuxt
|
|
126
162
|
|
|
@@ -182,6 +218,10 @@ Detected as its own UI library, because a Preact app using `preact/compat` alias
|
|
|
182
218
|
|
|
183
219
|
The sensor works. If you use `preact/compat`, the React adapter can attach through the alias, but that path is not gated.
|
|
184
220
|
|
|
221
|
+
**The source-pointer transform works on Preact code, and that is measured rather than assumed.** The stamper is JSX-syntactic: it tags a host element by its tag name and reads nothing about React, so a Preact `.jsx` or `.tsx` file is stamped exactly as a React one is. `class` instead of `className`, a `@jsxImportSource preact` pragma and a `@preact/signals` value in the tree all leave it unmoved. There are tests for each of those in `adapters/build/babel-plugin`. They prove the Babel transform, not the `@preact/preset-vite` pipeline end to end: nobody has yet driven a Preact app and seen a verdict name a `file:line`, so the drive stays unproven until someone does.
|
|
222
|
+
|
|
223
|
+
What is still missing on Preact is the enrichment above the DOM: `reticle_inspect` returns no `component`/`componentStack`, `@preact/signals` has no `reticle_state` adapter, and the render meter counts React commits only. Tracked in [#129](https://github.com/reticlehq/reticle/issues/129).
|
|
224
|
+
|
|
185
225
|
## Create React App and plain bundlers
|
|
186
226
|
|
|
187
227
|
No config file to patch, so `connect()` goes in your entry module.
|
|
@@ -196,14 +236,105 @@ The same shape works for webpack, Parcel, and the Vue and Svelte CLIs.
|
|
|
196
236
|
|
|
197
237
|
## Plain HTML
|
|
198
238
|
|
|
239
|
+
A directory with an `index.html` and no `package.json` is wired by `init` itself: it writes the connect snippet into `index.html`, before `</body>`, writes `.reticle.json`, and hands over to setup. The block is marked, so a re-run finds it and never writes a second one, and a re-run with a new `--port` rewrites the port inside it. It loads the SDK from a CDN and runs only when the page is opened on `localhost`, `127.0.0.1` or `[::1]`: a static file has no development build to strip it, so the host is the only line between the snippet and a published page. The page carries no pairing token: `init` writes it into `reticle.local.js` beside the page, which the snippet imports, and adds that file to `.gitignore`. Keep it out of anything you publish, and let each teammate run `reticle init` for their own. Several pages and no `index.html` is a choice `init` does not make for you: it prints the snippet, filled in with your project id and token, for you to paste:
|
|
240
|
+
|
|
199
241
|
```html
|
|
200
242
|
<script type="module">
|
|
201
|
-
import { reticle } from '/
|
|
202
|
-
reticle.connect();
|
|
243
|
+
import { reticle } from 'https://cdn.jsdelivr.net/npm/@reticlehq/browser@<version>/+esm';
|
|
244
|
+
reticle.connect({ projectId: '<your-project-id>', token: '<pairing token>' });
|
|
203
245
|
</script>
|
|
204
246
|
```
|
|
205
247
|
|
|
206
|
-
|
|
248
|
+
A bare `/node_modules/...` import does not work here: the SDK's own `dist` imports bare specifiers, which a browser cannot resolve without a bundler. A page with a `package.json` and a bundler takes the entry-module path above instead.
|
|
249
|
+
|
|
250
|
+
## Angular
|
|
251
|
+
|
|
252
|
+
Angular 17 and later, on the Vite-based `@angular/build` dev server. `init` installs only `@reticlehq/browser`, the framework-neutral sensor, and makes three edits:
|
|
253
|
+
|
|
254
|
+
- **The browser entry** (`src/main.ts`, or whatever `angular.json` names) gets a connect guarded on Angular's `ngDevMode` global (`typeof ngDevMode === 'undefined' || ngDevMode`), through a dynamic `import('@reticlehq/browser')` appended after the bootstrap. A production `ng build` defines `ngDevMode` as `false`, so the build drops the block and the chunk with it. The output carries no Reticle code at all, and the app never waits on Reticle. `isDevMode()` is not used because the build cannot fold a function call; an entry wired that way by an older `init` is rewritten in place on the next run.
|
|
255
|
+
- **`reticle.proxy.mjs`**, beside `angular.json`, answers one same-origin route, `/__reticle/pairing-token`, with this machine's pairing token, read from `~/.reticle/pairing-token` at request time. It refuses a request that did not arrive over loopback or came from another origin.
|
|
256
|
+
- **`angular.json`** gets the serve target's `proxyConfig` pointed at that file. `ng serve` loads it; `ng build` never reads a proxy config, so a production bundle has no route to the token and the token is never written into the project.
|
|
257
|
+
|
|
258
|
+
The token takes that route because the Angular CLI has no config file that runs code: a literal in `angular.json` commits a per-machine secret, and a gitignored module imported from `main.ts` is bundled into `ng build` whether or not anything can reach it. An existing `proxyConfig` is yours and is never replaced: the step goes manual and names the entry to add to it. A workspace with several served applications is also manual, because which one is the app is not `init`'s to guess.
|
|
259
|
+
|
|
260
|
+
You get DOM, network, console, routing and state tools. You do not get component identity (that is the React adapter) or a `source` field (the stamper covers JSX and Svelte). The install gate scaffolds an Angular app (no SSR) on every change and requires a session; SSR was proven by hand, and nothing drives an Angular app to a verdict.
|
|
261
|
+
|
|
262
|
+
## Server-rendered apps (Django, Flask, FastAPI, Rails)
|
|
263
|
+
|
|
264
|
+
There is no JS build to import the SDK from, and no single template to paste a script tag into: an app has many templates and may not have a base one. The SDK loads from a URL instead, so a page with no build step is not a blocker.
|
|
265
|
+
|
|
266
|
+
`reticle init` detects these and prints the right thing for the stack it found, writing `.reticle.json` as it goes. What follows is the same wiring, written down so you can read it before running anything, or wire it by hand.
|
|
267
|
+
|
|
268
|
+
### Django
|
|
269
|
+
|
|
270
|
+
Middleware is the Django-shaped answer: one place, runs for every page, no template to find.
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
# reticle_dev.py: add to MIDDLEWARE while DEBUG is on:
|
|
274
|
+
# MIDDLEWARE = [..., "reticle_dev.ReticleDevMiddleware"]
|
|
275
|
+
from django.conf import settings
|
|
276
|
+
|
|
277
|
+
_SNIPPET = """<script type="module">
|
|
278
|
+
import { reticle } from 'https://cdn.jsdelivr.net/npm/@reticlehq/browser@<version>/+esm';
|
|
279
|
+
reticle.connect({ projectId: '<your-project-id>', token: '<pairing token>' });
|
|
280
|
+
</script>"""
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class ReticleDevMiddleware:
|
|
284
|
+
"""Inject the Reticle SDK into HTML responses during development only."""
|
|
285
|
+
|
|
286
|
+
def __init__(self, get_response):
|
|
287
|
+
self.get_response = get_response
|
|
288
|
+
|
|
289
|
+
def __call__(self, request):
|
|
290
|
+
response = self.get_response(request)
|
|
291
|
+
if not settings.DEBUG:
|
|
292
|
+
return response
|
|
293
|
+
if "text/html" not in response.get("Content-Type", ""):
|
|
294
|
+
return response
|
|
295
|
+
# Streaming responses have no .content to rewrite; leave them alone.
|
|
296
|
+
if getattr(response, "streaming", False):
|
|
297
|
+
return response
|
|
298
|
+
body = response.content.decode(response.charset)
|
|
299
|
+
if "</body>" not in body:
|
|
300
|
+
return response
|
|
301
|
+
response.content = body.replace("</body>", _SNIPPET + "</body>", 1).encode(
|
|
302
|
+
response.charset
|
|
303
|
+
)
|
|
304
|
+
if response.has_header("Content-Length"):
|
|
305
|
+
response["Content-Length"] = str(len(response.content))
|
|
306
|
+
return response
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
`reticle init` emits this with your real version, project id and pairing token filled in. Copy it from there rather than from this page: the placeholders above are the three things that have to be right.
|
|
310
|
+
|
|
311
|
+
Four details in that middleware are load-bearing, and each is there because the obvious version is wrong:
|
|
312
|
+
|
|
313
|
+
- **`settings.DEBUG`** is the guard. Reticle is dev-only, and this is the lock that cannot be forgotten at deploy time.
|
|
314
|
+
- **the `text/html` check** keeps it from corrupting a JSON API response or a file download.
|
|
315
|
+
- **the `streaming` check** exists because a `StreamingHttpResponse` has no `.content` to rewrite, and touching it raises.
|
|
316
|
+
- **`</body>`, not `<head>`** so the SDK sees a parsed document.
|
|
317
|
+
|
|
318
|
+
Re-setting `Content-Length` matters for the same reason: the body grew, and a stale length truncates the page in the browser rather than failing loudly.
|
|
319
|
+
|
|
320
|
+
### Flask and FastAPI with Jinja
|
|
321
|
+
|
|
322
|
+
Same shape, one hook instead of a middleware class: an `@app.after_request` in Flask, or a middleware in FastAPI, with the same four guards: a debug flag, `text/html` only, not streaming, and injected before `</body>`.
|
|
323
|
+
|
|
324
|
+
### Streamlit
|
|
325
|
+
|
|
326
|
+
Different again: Streamlit owns the top-level document, so there is no served template, and scripts passed to `st.markdown` do not run. Use `st.html` on Streamlit 1.63 or newer. `reticle init` prints the helper, which also guards against connecting twice across reruns.
|
|
327
|
+
|
|
328
|
+
### What you get, and what you do not
|
|
329
|
+
|
|
330
|
+
Everything that comes from reading the live page works: queries, snapshots, actions, network and console channels, verdicts.
|
|
331
|
+
|
|
332
|
+
What is missing is the **source pointer**. `file:line` on a verdict comes from the build plugin stamping `data-reticle-source`, and there is no build step here to stamp it. You get every other signal and no `source` field, the same way a Vue single-file component does.
|
|
333
|
+
|
|
334
|
+
<Warning>
|
|
335
|
+
Wired, unverified. No app in CI drives one of these to a verdict, so nothing will tell us if it
|
|
336
|
+
breaks. If a page does not register a session, that is worth reporting.
|
|
337
|
+
</Warning>
|
|
207
338
|
|
|
208
339
|
## Desktop is a different shape
|
|
209
340
|
|
|
@@ -215,7 +346,7 @@ Electron and Tauri invert the direction: your app dials the daemon, and there is
|
|
|
215
346
|
|
|
216
347
|
## Not supported
|
|
217
348
|
|
|
218
|
-
|
|
349
|
+
Solid appears in dependency detection but has no wiring, no adapter and no gate. The sensor may work if you call `connect()` yourself. Nothing proves it, so we are not going to list them as supported.
|
|
219
350
|
|
|
220
351
|
## Frequently asked questions
|
|
221
352
|
|
package/docs/getting-started.md
CHANGED
|
@@ -78,7 +78,7 @@ The bridge + MCP server is a single process that serves all your projects, so it
|
|
|
78
78
|
|
|
79
79
|
Re-running is safe: already-registered and already-patched steps are skipped, and on a wired project it goes straight to proving the app still works. Preview without writing via `npx @reticlehq/server init --dry-run`.
|
|
80
80
|
|
|
81
|
-
`init` does not stop at writing files. It starts your dev server
|
|
81
|
+
`init` does not stop at writing files. It starts your dev server, opens the app, and waits for a session to connect from inside it. That connection is the whole proof that onboarding worked. If a dev server was already running without Reticle, restart it once: it read the build config before `init` edited it. It exits non-zero if nothing connected and prints what is left to do. It does NOT drive. Then prove a flow. That is the FIRST RUN, and it is a separate call: `reticle_verify { action: "explore", persona: "<who does what>" }`. It drives with a model inside the daemon and records what it drove, so later checks replay it with no model in the loop.
|
|
82
82
|
|
|
83
83
|
These carry what the command cannot work out for itself:
|
|
84
84
|
|
|
@@ -90,7 +90,7 @@ These carry what the command cannot work out for itself:
|
|
|
90
90
|
|
|
91
91
|
The rest are dials: `--license <key>` (writes it to `.env` and keeps `.env` out of git), `--json` (one object for an agent to read), `--files-only` (write, register, pre-approve, and stop, which is what `init` did before it learned to boot the app, and what an existing install re-runs to pick up new wiring), `--relaunch` (prints the command that restarts the conversation you are in, with the tools loaded: the restart step most installs stall on, and it composes with `--files-only`), `--no-open`, `--dry-run`, `--port N`, `--no-mcp`, `--no-install`.
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
If you ran `--files-only` with a dev server already running, restart it, then skip to [Step 4](#step-4-run-it-and-verify-the-connection). The manual steps below explain what `init` sets up, if you prefer to wire it yourself.
|
|
94
94
|
|
|
95
95
|
---
|
|
96
96
|
|
|
@@ -464,7 +464,7 @@ Everything below comes from the `@reticlehq/react` kit plus your framework's bui
|
|
|
464
464
|
|
|
465
465
|
**You do not get** component identity. `@reticlehq/react` walks the fiber tree to answer "which component rendered this element"; there is no Svelte equivalent, so snapshots carry the file and line but no component name. Stamping targets Svelte 5's compiler AST and also accepts Svelte 4's; `.svelte.ts` runes modules are code rather than markup and are not stamped.
|
|
466
466
|
|
|
467
|
-
**It is
|
|
467
|
+
**It is install-gated, drive-unverified.** The install gate scaffolds a SvelteKit app from scratch, runs `init`, boots it and waits for a session, so the setup is proven. There is no SvelteKit example app that CI drives to a verdict, so the drive is not. [Frameworks](/frameworks) has the full status table.
|
|
468
468
|
|
|
469
469
|
**Vue is install-gated, drive-unverified.** `init` detects a Vue app (as a Vite app with Vue as the UI library) and the install gate scaffolds one from scratch, runs `init`, boots it and waits for a session, so the setup is proven. What is not proven is the drive: there is no Vue example app in CI. `piniaStore` reads a Pinia store, and everything the framework-neutral core provides works. What you do not get is a `source` field, because source stamping covers JSX and Svelte components and a `.vue` single-file component is neither. See [Frameworks](/frameworks) for the full status table.
|
|
470
470
|
|
package/docs/http-transport.md
CHANGED
|
@@ -8,7 +8,7 @@ Most clients reach Reticle over stdio: they spawn `reticle mcp`, and the tools a
|
|
|
8
8
|
|
|
9
9
|
The daemon also speaks MCP over HTTP, on the same port as everything else. Nothing has to reload for a client to reach it, so this is the transport for scripted runs, CI, a language with no MCP client library, and any editor that will not pick up tools mid-session.
|
|
10
10
|
|
|
11
|
-
It is the same tool surface. Not a subset, not a simplified one. `
|
|
11
|
+
It is the same tool surface. Not a subset, not a simplified one. `reticle_look { action: "page" }`, `reticle_act_and_wait`, `reticle_assert` and the rest behave exactly as they do over stdio, because they are the same server behind a different transport.
|
|
12
12
|
|
|
13
13
|
## The two endpoints
|
|
14
14
|
|
|
@@ -136,7 +136,10 @@ async function start() {
|
|
|
136
136
|
const listed = await send('tools/list', {});
|
|
137
137
|
console.log(listed.result.tools.map((t) => t.name).join(', '));
|
|
138
138
|
|
|
139
|
-
const snapshot = await send('tools/call', {
|
|
139
|
+
const snapshot = await send('tools/call', {
|
|
140
|
+
name: 'reticle_look',
|
|
141
|
+
arguments: { action: 'page' },
|
|
142
|
+
});
|
|
140
143
|
console.log(snapshot.result.content[0].text);
|
|
141
144
|
}
|
|
142
145
|
```
|
|
@@ -159,6 +162,6 @@ The `202` comes back here; the tool list appears in the first shell.
|
|
|
159
162
|
|
|
160
163
|
## What this does not change
|
|
161
164
|
|
|
162
|
-
The transport carries the tools. It does not replace the rest of the setup. The app still has to be instrumented and connected, and `
|
|
165
|
+
The transport carries the tools. It does not replace the rest of the setup. The app still has to be instrumented and connected, and `reticle_session { action: "list" }` is still what tells you whether a session is there to drive. A verdict reached over HTTP is a verdict reached the usual way: only `verified: "yes"` is a pass.
|
|
163
166
|
|
|
164
167
|
The endpoints, the handshake, the three status codes and the `202`-then-SSE shape are pinned by `server/src/mcp-http-transport.test.ts`, which drives them over raw HTTP with no client library, so the contract this page describes fails the build if it changes.
|
package/docs/human-control.md
CHANGED
|
@@ -17,7 +17,7 @@ The panel header shows a running **✓N ✗M** tally: the verdict score, live. I
|
|
|
17
17
|
MCP is **pull-based**: the agent only receives data when it calls a tool. Reticle can't freeze the model mid-thought, but it **intercepts the agent's next tool call**, which is exactly when the agent would touch the page. That makes steering reliable:
|
|
18
18
|
|
|
19
19
|
- **Nudge** (a message, no pause). Your text is queued and rides back on the agent's **next** tool result as `guidance` (delivered once). The agent reads it and adjusts.
|
|
20
|
-
- **Pause.** The agent's next `reticle_act`
|
|
20
|
+
- **Pause.** The agent's next `reticle_act` (single or `steps`) / `reticle_act_and_wait` **refuses to execute** and returns `{ paused: true, guidance: ["<your message>"], hint: "…" }`. The page is untouched until resume. _Read-only tools (snapshot/query/observe) still work_, so the agent can look while paused.
|
|
21
21
|
- **End.** The session is over; the panel shows "Session ended" and clears.
|
|
22
22
|
|
|
23
23
|
## From the panel (the human)
|
|
@@ -35,7 +35,7 @@ The floating panel (bottom-center, `present: true`) gives you:
|
|
|
35
35
|
You don't have to describe a bug in prose. **Point at it.** The flag captures the element's re-resolvable anchor _and_ the source `file:line` (when the framework stamped one), so the agent fixes the exact element and code, not a guess. The loop:
|
|
36
36
|
|
|
37
37
|
1. **You** flag the element and type the problem → Reticle emits a `HUMAN_MARK`.
|
|
38
|
-
2. **The agent** drains it with `reticle_session {action:"review"}`, getting note + element label + `source: { file, line }` + a ready-to-act `fix` hint. `
|
|
38
|
+
2. **The agent** drains it with `reticle_session {action:"review"}`, getting note + element label + `source: { file, line }` + a ready-to-act `fix` hint. `reticle_session { action: "list" }` also reports `pendingMarks` so the agent notices flags.
|
|
39
39
|
3. **The agent** opens the file, fixes it, and calls `reticle_session {action:"review"}({ resolve: "m1" })`.
|
|
40
40
|
4. **You** see **"✓ fixed: \<your note\>"** land in the panel. Flag → fix → confirmation.
|
|
41
41
|
|
package/docs/index.mdx
CHANGED
|
@@ -73,13 +73,16 @@ Afterwards, use it whenever you change any user-facing behaviour.
|
|
|
73
73
|
The four files it writes, the marks it prints, and how to read its report.
|
|
74
74
|
</Card>
|
|
75
75
|
|
|
76
|
-
<CardGroup cols={
|
|
76
|
+
<CardGroup cols={3}>
|
|
77
77
|
<Card title="Quickstart" icon="rocket" href="/quickstart">
|
|
78
78
|
Install, connect your agent, and get a real verdict. Five minutes.
|
|
79
79
|
</Card>
|
|
80
80
|
<Card title="Why Reticle" icon="lightbulb" href="/why-reticle">
|
|
81
81
|
The false-green problem, and the evidence that this fixes it.
|
|
82
82
|
</Card>
|
|
83
|
+
<Card title="Use cases" icon="list-check" href="/use-cases">
|
|
84
|
+
Agent-built changes, security behaviour, accessibility, performance, SEO basics and personas.
|
|
85
|
+
</Card>
|
|
83
86
|
</CardGroup>
|
|
84
87
|
|
|
85
88
|
<CardGroup cols={3}>
|
|
@@ -127,18 +130,25 @@ Reticle clicks, watches, and reports what actually happened. A verdict of `unkno
|
|
|
127
130
|
single step.
|
|
128
131
|
</Card>
|
|
129
132
|
<Card title="Yours, locally" icon="lock">
|
|
130
|
-
Dev-only
|
|
133
|
+
Dev-only and localhost-only. Your app's data stays on your machine; anonymous usage counts are
|
|
134
|
+
sent unless you [turn them off](/telemetry).
|
|
131
135
|
</Card>
|
|
132
136
|
</CardGroup>
|
|
133
137
|
|
|
138
|
+
## What people use it for
|
|
139
|
+
|
|
140
|
+
Beyond proving an agent's change, people use Reticle to check security behaviour (access control by role, calls that must never fire, CSP violations), accessibility and UX (roles, names, focus, keyboard), performance (request counts, long tasks, layout shift), SEO basics (titles, headings, links, redirects), and to drive the app as different users. [Use cases](/use-cases) has what each one checks and a call to run.
|
|
141
|
+
|
|
142
|
+
It pairs well with a visual testing tool for pixel diffs, Playwright for sites you don't own, axe for full WCAG audits and a security scanner for vulnerability discovery.
|
|
143
|
+
|
|
134
144
|
## The evidence
|
|
135
145
|
|
|
136
|
-
|
|
146
|
+
Every number is measured by a committed harness, including the ties.
|
|
137
147
|
|
|
138
148
|

|
|
139
149
|
|
|
140
150
|
<Card title="Read the full benchmark" icon="chart-column" href="/benchmarks">
|
|
141
|
-
How every number was measured, what it means, and where
|
|
151
|
+
How every number was measured, what it means, and where the tools tie.
|
|
142
152
|
</Card>
|
|
143
153
|
|
|
144
154
|
## Built for agents, readable by humans
|
|
@@ -151,7 +161,7 @@ Reticle is used by a coding agent far more often than by a person, so these docs
|
|
|
151
161
|
|
|
152
162
|
## Build with us
|
|
153
163
|
|
|
154
|
-
|
|
164
|
+
The roadmap moves on what people actually hit, so tell us.
|
|
155
165
|
|
|
156
166
|
<CardGroup cols={2}>
|
|
157
167
|
<Card title="Join the Discord" icon="discord" href="https://discord.gg/BwAbzv9ZRz">
|
|
@@ -163,4 +173,4 @@ Reticle is early, and the sharp edges get filed down fastest when someone tells
|
|
|
163
173
|
</Card>
|
|
164
174
|
</CardGroup>
|
|
165
175
|
|
|
166
|
-
Found a bug, or something you wished existed? `
|
|
176
|
+
Found a bug, or something you wished existed? `reticle_session { action: "feedback" }` sends it in one call from your agent, and `npx @reticlehq/server feedback "…"` from a terminal. If Reticle could not tell you what happened, that is our defect and we want to know.
|
package/docs/install-agentic.mdx
CHANGED
|
@@ -131,7 +131,7 @@ That `ℹ` line is the one people skim past, so here it is in full:
|
|
|
131
131
|
```
|
|
132
132
|
[ℹ] AGENT: finish the capabilities file → src/reticle-dev.ts
|
|
133
133
|
src/reticle-dev.ts was written but registers nothing, so `hasCapabilities` stays false
|
|
134
|
-
and
|
|
134
|
+
and reticle_look { action: "state" } has nothing to read.
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
`init` wrote the file, but a brand-new Vite template has no testids and no state library, so there was nothing to register. Reticle tells you this instead of counting it as a win. See [Instrument your app](/instrumentation) for what to put in it.
|
|
@@ -150,6 +150,42 @@ Four files in your project, none of them mysterious.
|
|
|
150
150
|
```
|
|
151
151
|
The `projectId` is how Reticle scopes sessions to this project, so two apps running at once
|
|
152
152
|
don't get confused for each other.
|
|
153
|
+
|
|
154
|
+
**Keeping `.reticle/` small.** Reticle bounds the directory for you, by count and by total size.
|
|
155
|
+
Add a `retain` block to change what it keeps:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"retain": { "sessions": 20, "visual": 10, "feedback": 20, "budgetMb": 512 }
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Those are the defaults, and every field is optional. `sessions` is how many session journals
|
|
164
|
+
survive, `visual` how many overlay diffs (pixel baselines are never deleted, because the next
|
|
165
|
+
comparison needs them), `feedback` how many local copies of reports already sent, and `budgetMb`
|
|
166
|
+
the total the whole evidence tier may occupy. `0` means keep none, and `"sessions": 0` also stops
|
|
167
|
+
journals being written in the first place.
|
|
168
|
+
|
|
169
|
+
Saved flows, capsules, baselines, the contract and the intent ledger are not touched by any of
|
|
170
|
+
this. They are the part meant to be committed, and a bound that deleted them would be deleting
|
|
171
|
+
the regression checks your team shares.
|
|
172
|
+
|
|
173
|
+
**Your app's own background calls.** An analytics or heartbeat endpoint on your app's own host
|
|
174
|
+
looks exactly like the app's work, so Reticle never guesses. If one of them keeps a verdict
|
|
175
|
+
waiting, or fails and gets blamed on an unrelated action, name it:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"background": ["/api/analytics/events", "/api/heartbeat"]
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Each entry is matched the way `urlContains` is. A listed request stops holding the wait open and
|
|
184
|
+
stops contradicting a claim; when a contradiction is still reported, it lists what was set aside.
|
|
185
|
+
It is never hidden from an assertion that names it: `net { urlContains: "/api/heartbeat" }` still
|
|
186
|
+
sees it. Keep entries specific: `/api` would set aside your whole backend.
|
|
187
|
+
Third-party calls (another site's beacon or SDK) need no entry; they are already set aside.
|
|
188
|
+
|
|
153
189
|
</Accordion>
|
|
154
190
|
|
|
155
191
|
<Accordion title="vite.config.ts (the plugin)">
|
package/docs/install-manual.mdx
CHANGED
|
@@ -22,7 +22,7 @@ The basics in [Getting Started](getting-started.md) work with **zero app changes
|
|
|
22
22
|
|
|
23
23
|
Adoption is **free → cheap → targeted**. You don't instrument everything; you reuse what you have, then add the handful of facts the DOM can't express.
|
|
24
24
|
|
|
25
|
-
**1. Reuse your existing `data-testid` (free).** If you already test with Playwright or Cypress, your testids work in Reticle unchanged; `
|
|
25
|
+
**1. Reuse your existing `data-testid` (free).** If you already test with Playwright or Cypress, your testids work in Reticle unchanged; `reticle_look({ action: "find", by: 'testid', value: 'checkout' })` matches them exactly. No new markup, no new code.
|
|
26
26
|
|
|
27
27
|
**2. Advertise the surface from your existing constants (cheap).** You already keep a `TestIds` constant object for your E2E suite. Pass it straight in. Now `reticle_capabilities()` tells a fresh agent your whole surface without reading source.
|
|
28
28
|
|
|
@@ -107,7 +107,7 @@ If `mutate` throws, the mutation never happened, so **the signal is not emitted
|
|
|
107
107
|
|
|
108
108
|
> **The documented exception:** genuinely view-level signals (render or async completions like `diff:shown` or `caption:generated`, which aren't store state) legitimately stay in your components. Only commit-point signals belong in the store layer.
|
|
109
109
|
|
|
110
|
-
Pair this with store registration so the agent can _read_ state instead of you emitting a signal per fact: `registerStore('workspace', useWorkspace)`, then `
|
|
110
|
+
Pair this with store registration so the agent can _read_ state instead of you emitting a signal per fact: `registerStore('workspace', useWorkspace)`, then `reticle_look({ action: "state", store: 'workspace' })`.
|
|
111
111
|
|
|
112
112
|
## 4. Self-registering domains (`registerReticleDomain`)
|
|
113
113
|
|
|
@@ -164,7 +164,7 @@ Or turn it on with the shipped preset: `plugin.configs.recommended`, which sets
|
|
|
164
164
|
|
|
165
165
|
Reticle observes and drives a tab through the in-page SDK plus (optionally) CDP. It **cannot bring to front or recover a browser tab the OS won't let it script**: a backgrounded tab, say, or a non-default browser (Dia, etc.) reporting `hidden:true` / `throttled:true`.
|
|
166
166
|
|
|
167
|
-
When that happens, `
|
|
167
|
+
When that happens, `reticle_session { action: "list" }` and every act/assert result carry a `session.recommendation` saying so. The escape hatch is **`reticle drive <url>`** (add `--headed` to watch). Reticle launches and owns a guaranteed-scriptable browser. See [usage §18](usage.md#18-real-input-mode-native-hover--drag) for the full note.
|
|
168
168
|
|
|
169
169
|
## Checklist
|
|
170
170
|
|
|
@@ -45,7 +45,7 @@ This is the design target, and it needs no special setup:
|
|
|
45
45
|
- Flows can't bleed into each other: contexts are isolated and every session is scoped by `projectId`.
|
|
46
46
|
- A single crashed page is reclaimed on its own, and if an agent crashes or hangs its lease stops being touched and the **lease reaper** reclaims the context after a TTL, freeing the slot. One dead agent never starves the others.
|
|
47
47
|
|
|
48
|
-
`
|
|
48
|
+
`reticle_session { action: "list" }` lists everything with `projectId` (group by app) and `leased` (pool context vs a human tab), so an orchestrator can see the whole fleet at a glance.
|
|
49
49
|
|
|
50
50
|
## Knobs
|
|
51
51
|
|
|
@@ -76,4 +76,4 @@ module.exports = {
|
|
|
76
76
|
|
|
77
77
|
## Why an attribute rather than a runtime lookup
|
|
78
78
|
|
|
79
|
-
The stamp survives minification of everything else, costs nothing at runtime, and is readable from the DOM node itself. That is what lets [`
|
|
79
|
+
The stamp survives minification of everything else, costs nothing at runtime, and is readable from the DOM node itself. That is what lets [`reticle_look { action: "element" }`](/tools/inspect) answer with a file and a line rather than a component name and a shrug.
|
|
@@ -12,7 +12,7 @@ icon: window
|
|
|
12
12
|
|
|
13
13
|
This is what makes Reticle different from a browser-automation tool. Because it runs _inside_ the app rather than driving it from outside, it can see a state mutation and a fired signal, not just a rendered pixel. It never imports a Node API; that boundary is enforced by the dependency graph.
|
|
14
14
|
|
|
15
|
-
[`
|
|
15
|
+
[`reticle_look { action: "find" }`](/tools/query) speaks role, label and testid instead of CSS selectors through its own local accessibility engine: one engine computes both what elements are called and what they match by, so a reported identity always round-trips.
|
|
16
16
|
|
|
17
17
|
## When you need it directly
|
|
18
18
|
|
|
@@ -90,7 +90,7 @@ Also exported: `getCapabilities()`, `hasCapabilities()`, `setCapabilitiesListene
|
|
|
90
90
|
|
|
91
91
|
## State adapters
|
|
92
92
|
|
|
93
|
-
Register a store and its contents become readable through [`
|
|
93
|
+
Register a store and its contents become readable through [`reticle_look { action: "state" }`](/tools/state).
|
|
94
94
|
|
|
95
95
|
`registerStore`, `unregisterStore`, `storeNames`, `readStores`, `readStoresWithTruncation`.
|
|
96
96
|
|
package/docs/packages/react.mdx
CHANGED
|
@@ -76,7 +76,7 @@ import { useReticleStore } from '@reticlehq/react/store';
|
|
|
76
76
|
|
|
77
77
|
function Cart() {
|
|
78
78
|
const [items, setItems] = useState([]);
|
|
79
|
-
useReticleStore('cart', items); // now readable via
|
|
79
|
+
useReticleStore('cart', items); // now readable via reticle_look { action: "state" }
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
@@ -87,5 +87,5 @@ function Cart() {
|
|
|
87
87
|
React 19 dropped `_debugSource`, so `identify` can name the component but not the file unless something stamps the source at build time. That is [`@reticlehq/babel-plugin`](/packages/babel-plugin), pulled in for you by [`@reticlehq/vite-plugin`](/packages/vite-plugin) or [`@reticlehq/next`](/packages/next).
|
|
88
88
|
|
|
89
89
|
<Card title="Reading component state" icon="layer-group" href="/state-management">
|
|
90
|
-
What `
|
|
90
|
+
What `reticle_look { action: "state" }` can see, and how to widen it.
|
|
91
91
|
</Card>
|
package/docs/packages/tauri.mdx
CHANGED
|
@@ -21,7 +21,7 @@ Tauri IPC observation needs nothing on the Rust side. An `invoke('load_todos')`
|
|
|
21
21
|
|
|
22
22
|
```toml
|
|
23
23
|
[dependencies]
|
|
24
|
-
reticle-tauri = "3.
|
|
24
|
+
reticle-tauri = "3.4"
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Its own dependencies are `tauri = "2"` plus the per-platform capture backends: `objc2` and friends on macOS, `webview2-com` and `windows` on Windows, `webkit2gtk` and `cairo-rs` on Linux and the BSDs.
|
|
@@ -61,7 +61,7 @@ Plus a dynamic import of your dev module if one exists. It looks for `src/reticl
|
|
|
61
61
|
| `token` | `string` | `readPairingToken()`, from `~/.reticle/pairing-token` |
|
|
62
62
|
| `sourceMapping` | `boolean` | `true`. Set `false` to skip the Babel pass |
|
|
63
63
|
| `inject` | `boolean` | `true`. Set `false` to call `connect()` yourself |
|
|
64
|
-
| `desktop` | `boolean` | `false`. When `true` the
|
|
64
|
+
| `desktop` | `boolean` | `false`. When `true` the connect passes `allowInProduction: true`, which an Electron or Tauri renderer needs, and a `vite build` in a non-production mode (`--mode development`) is instrumented too. A production-mode build is stubbed like a web build |
|
|
65
65
|
| `captureNetworkBodies` | `boolean` | `false`. Also enabled by `VITE_RETICLE_CAPTURE_BODIES=1` |
|
|
66
66
|
| `onWarn` | `(message: string) => void` | `console.warn` |
|
|
67
67
|
|
|
@@ -87,7 +87,7 @@ Types: `ReticleVitePluginOptions`, `ReticleVitePlugin`, `ViteDevServerLike`.
|
|
|
87
87
|
reticle({ desktop: true });
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
A packaged Electron or Tauri renderer is
|
|
90
|
+
A packaged Electron or Tauri renderer is loaded from a custom protocol with no dev server and reports `NODE_ENV=production`, so the default guards would refuse. This flag injects the connect into the entry module and opts it into production. It does NOT instrument a release: a production-mode `vite build` (the default) ships no Reticle code, exactly like a web build. To drive a packaged renderer with no dev server, build it with `vite build --mode development`.
|
|
91
91
|
|
|
92
92
|
<Card title="Desktop wiring in full" icon="display" href="/desktop">
|
|
93
93
|
Including the Tauri CSP whose failure is completely silent.
|
package/docs/packages.mdx
CHANGED
|
@@ -38,12 +38,12 @@ You never install `@reticlehq/server`. Your agent runs it with `npx`.
|
|
|
38
38
|
|
|
39
39
|
The package split is not cosmetic. Each boundary enforces something:
|
|
40
40
|
|
|
41
|
-
| Package
|
|
42
|
-
|
|
|
43
|
-
| `core`
|
|
44
|
-
| `browser` | the browser | Never imports a Node API
|
|
45
|
-
| `server`
|
|
46
|
-
| `react`
|
|
41
|
+
| Package | Runs in | Hard rule |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| `core` | both | Depends only on `zod` and `open-verification`. Sits at the bottom of the graph |
|
|
44
|
+
| `browser` | the browser | Never imports a Node API |
|
|
45
|
+
| `server` | Node | Never imports a DOM API |
|
|
46
|
+
| `react` | the browser | Optional. Core must work without it |
|
|
47
47
|
|
|
48
48
|
Those rules are why the browser SDK cannot accidentally pull in a filesystem call, and why the server cannot accidentally depend on `window`. They are enforced by the dependency graph, not by discipline.
|
|
49
49
|
|
|
@@ -72,7 +72,7 @@ Those rules are why the browser SDK cannot accidentally pull in a filesystem cal
|
|
|
72
72
|
|
|
73
73
|
**Why it exists:** this is the part that makes Reticle different from a browser-automation tool. Because it runs _inside_ the app rather than driving it from outside, it can see a state mutation and a fired signal, not just a rendered pixel.
|
|
74
74
|
|
|
75
|
-
**Depends on:** `@reticlehq/core`. [`
|
|
75
|
+
**Depends on:** `@reticlehq/core`. [`reticle_look { action: "find" }`](/tools/query) speaks role, label and testid rather than CSS selectors through its own local accessibility engine, so what a snapshot reports is exactly what a query matches.
|
|
76
76
|
|
|
77
77
|
**Install it directly when** you are not on React, or you want `connect()` under your own control:
|
|
78
78
|
|
|
@@ -147,7 +147,7 @@ export default defineConfig({ plugins: [reticle(), react()] });
|
|
|
147
147
|
|
|
148
148
|
**Stamps `data-reticle-source="file:line:col"` onto JSX host elements.**
|
|
149
149
|
|
|
150
|
-
**Why it exists:** React 19 dropped `_debugSource`, which is what source mapping used to rely on. This plugin puts the information back, at build time, in dev only. Without it, `
|
|
150
|
+
**Why it exists:** React 19 dropped `_debugSource`, which is what source mapping used to rely on. This plugin puts the information back, at build time, in dev only. Without it, `reticle_look { action: "element" }` can still tell you the component name but not the file.
|
|
151
151
|
|
|
152
152
|
**Depends on:** nothing. **Peer:** `@babel/core`.
|
|
153
153
|
|
|
@@ -239,7 +239,7 @@ A lint rule makes the signal layer self-enforcing, which is the only way a conve
|
|
|
239
239
|
|
|
240
240
|
```toml
|
|
241
241
|
[dependencies]
|
|
242
|
-
reticle-tauri = "3.
|
|
242
|
+
reticle-tauri = "3.4"
|
|
243
243
|
```
|
|
244
244
|
|
|
245
245
|
<Warning>
|