@reticlehq/server 2.13.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +8 -18
- package/bin/reticle.js +3 -0
- package/dist/bridge/auth-failure-reason.js +12 -1
- package/dist/bridge/bridge-security.d.ts +8 -0
- package/dist/bridge/bridge-security.js +6 -1
- package/dist/bridge/bridge.d.ts +3 -0
- package/dist/bridge/bridge.js +23 -1
- package/dist/bridge/bridge.test-harness.d.ts +10 -1
- package/dist/bridge/bridge.test-harness.js +7 -1
- package/dist/bridge/pairing-token.d.ts +17 -0
- package/dist/bridge/pairing-token.js +26 -0
- package/dist/bridge/token-auth.d.ts +7 -0
- package/dist/bridge/token-auth.js +7 -1
- package/dist/capsule/capsule-store.d.ts +4 -4
- package/dist/capsule/capsule.d.ts +1 -1
- package/dist/capsule/capsule.js +3 -3
- package/dist/capsule/causal-summary.d.ts +21 -1
- package/dist/capsule/causal-summary.js +8 -6
- package/dist/capsule/divergence.d.ts +1 -1
- package/dist/capsule/divergence.js +26 -10
- package/dist/chromium-launch-options.d.ts +2 -1
- package/dist/cli/adhoc-verdict.d.ts +58 -0
- package/dist/cli/adhoc-verdict.js +115 -0
- package/dist/cli/chromium-hint.d.ts +18 -4
- package/dist/cli/chromium-hint.js +54 -6
- package/dist/cli/cli-doctor.js +1 -2
- package/dist/cli/cli-flow-commands.d.ts +16 -2
- package/dist/cli/cli-flow-commands.js +28 -9
- package/dist/cli/cli-parse-feedback.js +1 -1
- package/dist/cli/cli-parse.d.ts +2 -1
- package/dist/cli/cli-parse.js +38 -0
- package/dist/cli/cli-port.d.ts +5 -13
- package/dist/cli/cli-port.js +5 -38
- package/dist/cli/cli-update-commands.js +4 -4
- package/dist/cli/cli-verify.d.ts +24 -7
- package/dist/cli/cli-verify.js +87 -13
- package/dist/cli/cloud-keystore.d.ts +2 -1
- package/dist/cli/cloud-login.d.ts +2 -1
- package/dist/cli/cloud-session.d.ts +2 -1
- package/dist/cli/cloud-session.js +1 -1
- package/dist/cli/daemon-start-options.d.ts +2 -1
- package/dist/cli/device-flow.d.ts +2 -2
- package/dist/cli/doctor-daemon-line.d.ts +2 -1
- package/dist/cli/doctor-project-line.d.ts +2 -1
- package/dist/cli/doctor-rows.d.ts +2 -1
- package/dist/cli/drive-attach.d.ts +4 -3
- package/dist/cli/gate-hook-message.d.ts +2 -1
- package/dist/cli/status-next-action.js +10 -11
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +21 -9
- package/dist/cloud/account-state.d.ts +20 -0
- package/dist/cloud/account-state.js +65 -0
- package/dist/cloud/cloud-sync.d.ts +46 -3
- package/dist/cloud/cloud-sync.js +116 -0
- package/dist/cloud/sync-cycle.d.ts +5 -4
- package/dist/cloud/sync-cycle.js +1 -1
- package/dist/cloud/sync-daemon.d.ts +3 -19
- package/dist/cloud/sync-daemon.js +2 -2
- package/dist/crawl/crawl-tools.js +1 -1
- package/dist/crawl/crawl.d.ts +5 -5
- package/dist/crawl/crawl.js +138 -4
- package/dist/daemon/daemon-resilience.d.ts +3 -2
- package/dist/daemon/daemon-resilience.js +43 -4
- package/dist/daemon/daemon-resolve.d.ts +0 -9
- package/dist/daemon/daemon-resolve.js +2 -2
- package/dist/daemon/dev-servers.d.ts +1 -1
- package/dist/daemon/dev-servers.js +1 -1
- package/dist/daemon/loopback-alias.d.ts +2 -1
- package/dist/daemon/startup-failure.d.ts +11 -0
- package/dist/daemon/startup-failure.js +46 -0
- package/dist/events/contradictions.d.ts +10 -16
- package/dist/events/contradictions.js +149 -17
- package/dist/events/declared.d.ts +13 -1
- package/dist/events/declared.js +59 -3
- package/dist/events/echo-mismatch.js +75 -6
- package/dist/events/lineage.d.ts +52 -0
- package/dist/events/lineage.js +122 -0
- package/dist/events/net-evidence.d.ts +21 -0
- package/dist/events/net-evidence.js +81 -0
- package/dist/events/predicate-console.d.ts +13 -0
- package/dist/events/predicate-console.js +138 -0
- package/dist/events/predicate-element.d.ts +13 -0
- package/dist/events/predicate-element.js +214 -0
- package/dist/events/predicate-eval.d.ts +15 -3
- package/dist/events/predicate-eval.js +128 -110
- package/dist/events/predicate-parse.js +34 -1
- package/dist/events/predicate-request-body.d.ts +50 -0
- package/dist/events/predicate-request-body.js +120 -0
- package/dist/events/predicate-route.d.ts +21 -1
- package/dist/events/predicate-route.js +149 -21
- package/dist/events/predicate-schema.d.ts +8 -1
- package/dist/events/predicate-schema.js +34 -0
- package/dist/events/predicate.d.ts +2 -0
- package/dist/events/predicate.js +52 -159
- package/dist/events/split-text-miss.d.ts +6 -4
- package/dist/events/split-text-miss.js +12 -5
- package/dist/flows/affected-tools.js +22 -9
- package/dist/flows/annotate.d.ts +2 -1
- package/dist/flows/annotate.js +19 -1
- package/dist/flows/coverage.d.ts +2 -2
- package/dist/flows/flake.d.ts +3 -3
- package/dist/flows/flow-expect-grammar.d.ts +33 -0
- package/dist/flows/flow-expect-grammar.js +155 -0
- package/dist/flows/flow-replay-run.d.ts +1 -1
- package/dist/flows/flow-replay-run.js +28 -15
- package/dist/flows/flow-replay.d.ts +10 -0
- package/dist/flows/flow-replay.js +57 -22
- package/dist/flows/flow-secret-field.d.ts +14 -0
- package/dist/flows/flow-secret-field.js +22 -0
- package/dist/flows/flow-step-runners.d.ts +1 -0
- package/dist/flows/flow-step-runners.js +91 -34
- package/dist/flows/flow-success.js +22 -0
- package/dist/flows/flow-tools.js +27 -8
- package/dist/flows/flow-upload-resolve.d.ts +23 -0
- package/dist/flows/flow-upload-resolve.js +46 -0
- package/dist/flows/flows.d.ts +15 -0
- package/dist/flows/flows.js +17 -14
- package/dist/flows/git-changed.d.ts +23 -4
- package/dist/flows/git-changed.js +32 -6
- package/dist/flows/heal-run.js +2 -2
- package/dist/flows/predicate-to-expect.d.ts +3 -2
- package/dist/flows/predicate-to-expect.js +11 -5
- package/dist/flows/recording-backtrack.d.ts +24 -0
- package/dist/flows/recording-backtrack.js +73 -0
- package/dist/flows/recordings.d.ts +6 -0
- package/dist/flows/replay-halt.d.ts +26 -0
- package/dist/flows/replay-halt.js +30 -0
- package/dist/flows/replay.d.ts +0 -8
- package/dist/flows/replay.js +15 -3
- package/dist/flows/suite-flakes.d.ts +2 -1
- package/dist/flows/verify-change-tools.js +16 -4
- package/dist/honesty/already-true.d.ts +14 -0
- package/dist/honesty/already-true.js +47 -4
- package/dist/honesty/blind-spots.d.ts +3 -1
- package/dist/honesty/blind-spots.js +24 -1
- package/dist/honesty/body-capture-remedy.d.ts +42 -0
- package/dist/honesty/body-capture-remedy.js +95 -0
- package/dist/honesty/feature-capture.d.ts +3 -2
- package/dist/honesty/feature-capture.js +1 -1
- package/dist/honesty/gap-ledger.d.ts +1 -1
- package/dist/honesty/gap-ledger.js +1 -1
- package/dist/honesty/instrumentation-gaps.d.ts +8 -1
- package/dist/honesty/instrumentation-gaps.js +12 -2
- package/dist/honesty/observability.d.ts +4 -3
- package/dist/honesty/tool-hit-rate.d.ts +3 -2
- package/dist/honesty/uncaptured-bodies.d.ts +3 -1
- package/dist/honesty/uncaptured-bodies.js +6 -2
- package/dist/honesty/unsettled.d.ts +9 -0
- package/dist/honesty/unsettled.js +45 -0
- package/dist/honesty/verified.d.ts +32 -1
- package/dist/honesty/verified.js +37 -10
- package/dist/impact/impact-store.d.ts +5 -14
- package/dist/impact/impact-store.js +49 -6
- package/dist/index.js +1 -1
- package/dist/input/network-detail.d.ts +26 -1
- package/dist/input/network-detail.js +44 -12
- package/dist/input/network-mock-tools.js +24 -17
- package/dist/input/real-input.js +1 -1
- package/dist/input/viewport-tools.js +25 -13
- package/dist/intent/inline-intent.d.ts +0 -10
- package/dist/intent/inline-intent.js +1 -1
- package/dist/intent/intent-shard-store.d.ts +3 -2
- package/dist/intent/intent-shard-store.js +1 -1
- package/dist/intent/intent-shard.d.ts +14 -14
- package/dist/intent/intent-shard.js +4 -4
- package/dist/intent/intent-store.d.ts +1 -1
- package/dist/intent/intent-store.js +1 -1
- package/dist/intent/intent-subject.d.ts +2 -1
- package/dist/intent/open-intents.d.ts +3 -2
- package/dist/license/license.d.ts +4 -4
- package/dist/license/license.js +1 -1
- package/dist/mcp/attach-memory.d.ts +2 -1
- package/dist/mcp/client-identity.d.ts +2 -1
- package/dist/mcp/mcp-outage.d.ts +1 -1
- package/dist/mcp/mcp-outage.js +1 -1
- package/dist/mcp/mcp-proxy.d.ts +3 -1
- package/dist/mcp/mcp-proxy.js +32 -7
- package/dist/mcp/mcp.js +3 -1
- package/dist/mcp/proxy-handshake.d.ts +2 -1
- package/dist/mcp/proxy-idle-exit.d.ts +45 -0
- package/dist/mcp/proxy-idle-exit.js +94 -0
- package/dist/mcp/server-instructions.d.ts +2 -1
- package/dist/memory/project-memory.d.ts +2 -3
- package/dist/memory/project-memory.js +1 -1
- package/dist/oracles/propose-consequences.js +5 -5
- package/dist/oracles/self-instrument.d.ts +2 -2
- package/dist/oracles/self-instrument.js +1 -1
- package/dist/platform.d.ts +3 -5
- package/dist/platform.js +3 -5
- package/dist/pool/browser-pool.d.ts +92 -0
- package/dist/pool/browser-pool.js +119 -5
- package/dist/pool/playwright-launcher.js +29 -2
- package/dist/pool/storage-seed.d.ts +23 -0
- package/dist/pool/storage-seed.js +198 -0
- package/dist/project/artifact-root.d.ts +2 -1
- package/dist/project/memory-fs.d.ts +2 -1
- package/dist/project/reticle-dir.js +1 -1
- package/dist/project/session-root.d.ts +8 -0
- package/dist/project/session-root.js +9 -2
- package/dist/runs/reticle-runner.d.ts +14 -1
- package/dist/runs/reticle-runner.js +39 -2
- package/dist/session/attachment-history.d.ts +2 -1
- package/dist/session/fake-session.d.ts +37 -0
- package/dist/session/fake-session.js +81 -0
- package/dist/session/lease-visibility.d.ts +2 -1
- package/dist/session/live-control-tools.js +6 -0
- package/dist/session/no-session-diagnosis.d.ts +17 -1
- package/dist/session/no-session-diagnosis.js +32 -6
- package/dist/session/no-session-next-action.d.ts +14 -0
- package/dist/session/no-session-next-action.js +18 -0
- package/dist/session/no-session-watch.js +46 -3
- package/dist/session/registered-projects.d.ts +54 -0
- package/dist/session/registered-projects.js +73 -0
- package/dist/session/review-store.d.ts +2 -1
- package/dist/session/session-health.d.ts +62 -1
- package/dist/session/session-health.js +82 -2
- package/dist/session/session-manager.d.ts +11 -1
- package/dist/session/session-manager.js +18 -3
- package/dist/session/session-replaced.d.ts +24 -0
- package/dist/session/session-replaced.js +29 -0
- package/dist/session/session-successor.js +20 -4
- package/dist/session/session.d.ts +13 -5
- package/dist/session/session.js +31 -23
- package/dist/setup/agent-configs.d.ts +3 -2
- package/dist/setup/agent-writer.d.ts +3 -2
- package/dist/setup/approval-migration.d.ts +2 -1
- package/dist/setup/approval-migration.js +1 -1
- package/dist/setup/auto-approve.d.ts +11 -19
- package/dist/setup/auto-approve.js +15 -12
- package/dist/{init → setup}/confirm.js +1 -1
- package/dist/setup/desktop-shape.d.ts +3 -2
- package/dist/setup/dev-server-wait.d.ts +8 -0
- package/dist/setup/dev-server-wait.js +3 -1
- package/dist/setup/drive-agent.d.ts +2 -3
- package/dist/setup/drive-agent.js +1 -1
- package/dist/setup/drive-plan.d.ts +3 -2
- package/dist/setup/ensure-daemon.d.ts +2 -1
- package/dist/setup/existing-app.d.ts +12 -0
- package/dist/setup/existing-app.js +13 -0
- package/dist/setup/init-host.d.ts +11 -0
- package/dist/setup/init-host.js +26 -0
- package/dist/setup/init-runtime.d.ts +4 -10
- package/dist/setup/init-runtime.js +23 -16
- package/dist/setup/license-key.d.ts +2 -1
- package/dist/setup/listeners.d.ts +2 -1
- package/dist/setup/loopback-probe-urls.d.ts +18 -0
- package/dist/setup/loopback-probe-urls.js +52 -0
- package/dist/setup/node-effects.d.ts +3 -0
- package/dist/setup/node-effects.js +26 -11
- package/dist/setup/page-probe.d.ts +5 -0
- package/dist/setup/relaunch.d.ts +2 -1
- package/dist/setup/run-setup.d.ts +5 -1
- package/dist/setup/run-setup.js +155 -48
- package/dist/setup/setup-command.d.ts +3 -2
- package/dist/setup/setup-command.js +8 -0
- package/dist/setup/setup-options.d.ts +5 -3
- package/dist/setup/setup-options.js +3 -2
- package/dist/setup/wait-progress.d.ts +28 -0
- package/dist/setup/wait-progress.js +43 -0
- package/dist/telemetry/app-instrumented.d.ts +2 -1
- package/dist/telemetry/app-instrumented.js +1 -1
- package/dist/telemetry/automation-hint.d.ts +1 -1
- package/dist/telemetry/automation-hint.js +1 -1
- package/dist/telemetry/cli-telemetry.js +1 -1
- package/dist/telemetry/connect-failure.d.ts +1 -1
- package/dist/telemetry/connect-failure.js +1 -1
- package/dist/telemetry/crash-cause.d.ts +3 -2
- package/dist/telemetry/crash-cause.js +1 -1
- package/dist/telemetry/daemon-telemetry.d.ts +3 -2
- package/dist/telemetry/daemon-telemetry.js +1 -1
- package/dist/telemetry/error-class.d.ts +3 -2
- package/dist/telemetry/error-class.js +1 -1
- package/dist/telemetry/feedback-cli.js +1 -1
- package/dist/telemetry/feedback-context.d.ts +3 -2
- package/dist/telemetry/feedback-context.js +5 -4
- package/dist/telemetry/feedback-local.d.ts +3 -2
- package/dist/telemetry/feedback.d.ts +4 -3
- package/dist/telemetry/feedback.js +1 -1
- package/dist/telemetry/git-facts.d.ts +2 -2
- package/dist/telemetry/git-facts.js +1 -1
- package/dist/telemetry/identify.d.ts +1 -1
- package/dist/telemetry/identify.js +1 -1
- package/dist/telemetry/init-telemetry.d.ts +2 -14
- package/dist/telemetry/init-telemetry.js +4 -13
- package/dist/telemetry/install-source.d.ts +7 -13
- package/dist/telemetry/install-source.js +7 -29
- package/dist/telemetry/license-activation.d.ts +3 -2
- package/dist/telemetry/license-activation.js +1 -1
- package/dist/telemetry/machine-snapshot.d.ts +1 -1
- package/dist/telemetry/mcp-connection.js +1 -1
- package/dist/telemetry/project-profile.d.ts +0 -14
- package/dist/telemetry/project-profile.js +1 -1
- package/dist/telemetry/proxy-telemetry.js +1 -1
- package/dist/telemetry/session-metrics.d.ts +1 -1
- package/dist/telemetry/session-metrics.js +1 -1
- package/dist/telemetry/telemetry.d.ts +1 -17
- package/dist/telemetry/telemetry.js +4 -4
- package/dist/telemetry/tool-refused.d.ts +1 -1
- package/dist/telemetry/tool-refused.js +1 -1
- package/dist/tools/act-observation.d.ts +3 -2
- package/dist/tools/act-preflight.js +8 -3
- package/dist/tools/act-target.d.ts +4 -0
- package/dist/tools/act-target.js +14 -5
- package/dist/tools/act-tools.d.ts +0 -2
- package/dist/tools/act-tools.js +45 -15
- package/dist/tools/assert-source.d.ts +30 -0
- package/dist/tools/assert-source.js +21 -0
- package/dist/tools/assert-verdict.d.ts +1 -1
- package/dist/tools/assert-verdict.js +14 -4
- package/dist/tools/browser-tools.js +28 -8
- package/dist/tools/complete-snapshot.d.ts +3 -2
- package/dist/tools/dynamic-tools.js +8 -0
- package/dist/tools/error-recovery.d.ts +10 -0
- package/dist/tools/error-recovery.js +23 -0
- package/dist/tools/feedback-tools.js +1 -1
- package/dist/tools/invoke-tool.js +2 -0
- package/dist/tools/lease-tools.d.ts +48 -20
- package/dist/tools/lease-tools.js +311 -76
- package/dist/tools/lineage-tools.d.ts +14 -0
- package/dist/tools/lineage-tools.js +64 -0
- package/dist/tools/merge-tools.js +1 -3
- package/dist/tools/navigate-arrival.d.ts +45 -1
- package/dist/tools/navigate-arrival.js +39 -6
- package/dist/tools/navigate-result.d.ts +8 -1
- package/dist/tools/navigate-result.js +14 -4
- package/dist/tools/numeric-bounds.d.ts +0 -11
- package/dist/tools/numeric-bounds.js +4 -4
- package/dist/tools/observe-tools.js +22 -26
- package/dist/tools/observed-nothing.d.ts +9 -0
- package/dist/tools/observed-nothing.js +2 -1
- package/dist/tools/read-tools.js +12 -17
- package/dist/tools/real-input-attempt.d.ts +14 -6
- package/dist/tools/real-input-attempt.js +75 -18
- package/dist/tools/reconcile-tools.js +2 -1
- package/dist/tools/reload-result.d.ts +6 -1
- package/dist/tools/reload-result.js +7 -2
- package/dist/tools/resolve-target.d.ts +7 -1
- package/dist/tools/resolve-target.js +72 -9
- package/dist/tools/settle-in-flight.d.ts +1 -1
- package/dist/tools/settle-in-flight.js +9 -2
- package/dist/tools/snapshot-delta.d.ts +24 -1
- package/dist/tools/snapshot-delta.js +66 -7
- package/dist/tools/tool-names.d.ts +1 -0
- package/dist/tools/tool-names.js +1 -0
- package/dist/tools/tool-surface.js +20 -2
- package/dist/tools/tools.js +120 -11
- package/dist/tools/verify-next-baton.d.ts +2 -1
- package/dist/update/sdk-sync.d.ts +1 -1
- package/dist/update/sdk-sync.js +1 -1
- package/dist/update/updater.js +1 -1
- package/dist/version/sdk-fix.d.ts +2 -1
- package/dist/version/version-skew.d.ts +0 -8
- package/dist/version/version-skew.js +1 -1
- package/docs/README.md +8 -6
- package/docs/actions.mdx +1 -1
- package/docs/agent-cheatsheet.md +4 -2
- package/docs/architecture.md +1 -1
- package/docs/cli/mcp.mdx +3 -1
- package/docs/cli/watch.mdx +1 -1
- package/docs/cli.mdx +1 -1
- package/docs/desktop.mdx +1 -1
- package/docs/docs.json +8 -3
- package/docs/faq.mdx +9 -0
- package/docs/first-drive.md +136 -0
- package/docs/frameworks.mdx +29 -7
- package/docs/gate-plan.md +2 -2
- package/docs/gates.md +19 -11
- package/docs/getting-started.md +7 -1
- package/docs/http-transport.md +164 -0
- package/docs/index.mdx +5 -3
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages.mdx +15 -3
- package/docs/platform-integration.md +1 -1
- package/docs/predicates.mdx +2 -0
- package/docs/system-map.md +2 -2
- package/docs/telemetry-contract.md +4 -4
- package/docs/telemetry-events.mdx +1 -1
- package/docs/telemetry.md +3 -3
- package/docs/tools-navigate.mdx +14 -6
- package/docs/usage.md +4 -4
- package/package.json +7 -4
- package/dist/init/agent-rules.d.ts +0 -116
- package/dist/init/agent-rules.js +0 -279
- package/dist/init/app-choice.d.ts +0 -20
- package/dist/init/app-choice.js +0 -25
- package/dist/init/astro-host.d.ts +0 -21
- package/dist/init/astro-host.js +0 -27
- package/dist/init/astro-patch.d.ts +0 -33
- package/dist/init/astro-patch.js +0 -300
- package/dist/init/capabilities.d.ts +0 -40
- package/dist/init/capabilities.js +0 -150
- package/dist/init/closing-hint.d.ts +0 -36
- package/dist/init/closing-hint.js +0 -120
- package/dist/init/connect-steps.d.ts +0 -2
- package/dist/init/connect-steps.js +0 -50
- package/dist/init/cra.d.ts +0 -79
- package/dist/init/cra.js +0 -178
- package/dist/init/csp-check.d.ts +0 -38
- package/dist/init/csp-check.js +0 -107
- package/dist/init/csp-doctor.d.ts +0 -32
- package/dist/init/csp-doctor.js +0 -54
- package/dist/init/desktop-doctor.d.ts +0 -41
- package/dist/init/desktop-doctor.js +0 -198
- package/dist/init/detect.d.ts +0 -96
- package/dist/init/detect.js +0 -209
- package/dist/init/dev-script.d.ts +0 -50
- package/dist/init/dev-script.js +0 -66
- package/dist/init/format-generated.d.ts +0 -18
- package/dist/init/format-generated.js +0 -39
- package/dist/init/install-hint.d.ts +0 -9
- package/dist/init/install-hint.js +0 -29
- package/dist/init/mcp-clients.d.ts +0 -89
- package/dist/init/mcp-clients.js +0 -299
- package/dist/init/mcp-registered.d.ts +0 -12
- package/dist/init/mcp-registered.js +0 -14
- package/dist/init/mcp.d.ts +0 -89
- package/dist/init/mcp.js +0 -129
- package/dist/init/next-patch.d.ts +0 -39
- package/dist/init/next-patch.js +0 -196
- package/dist/init/node-io.d.ts +0 -7
- package/dist/init/node-io.js +0 -117
- package/dist/init/non-js-project.d.ts +0 -27
- package/dist/init/non-js-project.js +0 -84
- package/dist/init/patch-kind.d.ts +0 -20
- package/dist/init/patch-kind.js +0 -10
- package/dist/init/plan-framework.d.ts +0 -64
- package/dist/init/plan-framework.js +0 -565
- package/dist/init/plan.d.ts +0 -242
- package/dist/init/plan.js +0 -703
- package/dist/init/preflight.d.ts +0 -28
- package/dist/init/preflight.js +0 -38
- package/dist/init/project-id.d.ts +0 -12
- package/dist/init/project-id.js +0 -25
- package/dist/init/refresh-rules.d.ts +0 -39
- package/dist/init/refresh-rules.js +0 -51
- package/dist/init/run.d.ts +0 -117
- package/dist/init/run.js +0 -806
- package/dist/init/slash-command.d.ts +0 -27
- package/dist/init/slash-command.js +0 -132
- package/dist/init/snippets.d.ts +0 -134
- package/dist/init/snippets.js +0 -572
- package/dist/init/vite-config.d.ts +0 -18
- package/dist/init/vite-config.js +0 -114
- package/dist/init/windows-quote.d.ts +0 -38
- package/dist/init/windows-quote.js +0 -70
- package/dist/init/workspace-apps.d.ts +0 -30
- package/dist/init/workspace-apps.js +0 -178
- package/dist/project/remember-project.d.ts +0 -24
- package/dist/project/remember-project.js +0 -40
- /package/dist/{init → setup}/confirm.d.ts +0 -0
package/dist/update/sdk-sync.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* stale registry cache and reinstall the skew being fixed. Measured once as pnpm taking 2.2.1 while
|
|
12
12
|
* npm took 2.3.0 in the next project over.
|
|
13
13
|
*/
|
|
14
|
-
import { installCommandParts } from '
|
|
14
|
+
import { installCommandParts } from '@reticlehq/init';
|
|
15
15
|
export { reticleDepsOf } from './reticle-deps.js';
|
|
16
16
|
/** The install to run, or null when this project has nothing of ours to sync. */
|
|
17
17
|
export function sdkSyncCommand(pm, packages, version) {
|
package/dist/update/updater.js
CHANGED
|
@@ -6,7 +6,7 @@ import { dirname, join } from 'node:path';
|
|
|
6
6
|
import { loadManifest, saveManifest } from './update-checker.js';
|
|
7
7
|
import { RETICLE_NPM_PACKAGE, SERVER_VERSION } from '../version/server-version.js';
|
|
8
8
|
import { log } from '../log.js';
|
|
9
|
-
import { TelemetryEventKind } from '@reticlehq/core';
|
|
9
|
+
import { TelemetryEventKind } from '@reticlehq/core/telemetry';
|
|
10
10
|
import { getTelemetry } from '../telemetry/telemetry.js';
|
|
11
11
|
import { wasNudged } from './nudge-credit.js';
|
|
12
12
|
/** Which way the installed version moved. A rollback means a release hurt someone enough to retreat. */
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* does not load the install plan.
|
|
12
12
|
*/
|
|
13
13
|
/** What a project contributes to the remedy, when we were able to read one. */
|
|
14
|
-
|
|
14
|
+
interface SdkFixContext {
|
|
15
15
|
/** `@reticlehq/*` packages declared in package.json. Empty / omitted means none yet. */
|
|
16
16
|
packages?: readonly string[];
|
|
17
17
|
packageManager: PackageManagerName;
|
|
@@ -45,3 +45,4 @@ export declare function sdkFixContextOf(pkgJson: unknown, lockfiles: ReadonlySet
|
|
|
45
45
|
* `read` is injected so the decision is testable without a filesystem; the daemon uses the default.
|
|
46
46
|
*/
|
|
47
47
|
export declare function sdkFixForDirectory(daemonVersion: string, directory: string, read?: (path: string) => string | undefined): string;
|
|
48
|
+
export {};
|
|
@@ -83,14 +83,6 @@ export declare function sdkFix(daemonVersion: string): string;
|
|
|
83
83
|
* and the advice depends on which piece is behind, not on who noticed.
|
|
84
84
|
*/
|
|
85
85
|
export declare function daemonFix(daemonVersion: string | undefined, agentVersion: string | undefined): string;
|
|
86
|
-
/**
|
|
87
|
-
* Playwright wording when a CDP call cannot bind to the page.
|
|
88
|
-
*
|
|
89
|
-
* Under SDK/daemon version skew this text is a LIE: the page is still connected (DOM tools work),
|
|
90
|
-
* and the agent spends turns re-acquiring leases and asking a human to sign into a fresh profile
|
|
91
|
-
* (#688). Matched only so we can replace it with the skew sentence already on the session.
|
|
92
|
-
*/
|
|
93
|
-
export declare const PLAYWRIGHT_CLOSED_ERROR: RegExp;
|
|
94
86
|
/** True when `error` is Playwright's closed-target class — not proof the tab is gone. */
|
|
95
87
|
export declare function isPlaywrightClosedError(error: unknown): boolean;
|
|
96
88
|
/**
|
|
@@ -130,7 +130,7 @@ export function daemonFix(daemonVersion, agentVersion) {
|
|
|
130
130
|
* and the agent spends turns re-acquiring leases and asking a human to sign into a fresh profile
|
|
131
131
|
* (#688). Matched only so we can replace it with the skew sentence already on the session.
|
|
132
132
|
*/
|
|
133
|
-
|
|
133
|
+
const PLAYWRIGHT_CLOSED_ERROR = /target (?:page|context|browser) has been closed|browser has been closed|browser has disconnected/i;
|
|
134
134
|
/** True when `error` is Playwright's closed-target class — not proof the tab is gone. */
|
|
135
135
|
export function isPlaywrightClosedError(error) {
|
|
136
136
|
const message = error instanceof Error ? error.message : String(error);
|
package/docs/README.md
CHANGED
|
@@ -50,6 +50,7 @@ Everything here is published to [docs.reticle.sh](https://docs.reticle.sh) by `d
|
|
|
50
50
|
| [for-agents.md](for-agents.md) | how to fetch these docs as Markdown or `llms.txt` |
|
|
51
51
|
| [architecture.md](architecture.md) | how it works, and why it is built this way |
|
|
52
52
|
| [platform-integration.md](platform-integration.md) | Vite, Next, Remix, Astro, plain HTML |
|
|
53
|
+
| [http-transport.md](http-transport.md) | driving the tools over plain HTTP/SSE, for clients that cannot reload MCP |
|
|
53
54
|
| [desktop.mdx](desktop.mdx) | Electron and Tauri in full: setup, IPC, screenshots, headless, troubleshooting |
|
|
54
55
|
| [frameworks.mdx](frameworks.mdx) | what is supported, what is wired-but-unverified, and the wiring |
|
|
55
56
|
| [state-management.mdx](state-management.mdx) | zustand, Redux, and eight adapters |
|
|
@@ -75,7 +76,7 @@ Everything here is published to [docs.reticle.sh](https://docs.reticle.sh) by `d
|
|
|
75
76
|
|
|
76
77
|
## For people working on Reticle
|
|
77
78
|
|
|
78
|
-
**Start:** [`CONTRIBUTING.md`](
|
|
79
|
+
**Start:** [`CONTRIBUTING.md`](https://github.com/reticlehq/reticle/blob/main/CONTRIBUTING.md) → [gates.md](gates.md).
|
|
79
80
|
|
|
80
81
|
| Page | What it answers |
|
|
81
82
|
| --- | --- |
|
|
@@ -84,13 +85,14 @@ Everything here is published to [docs.reticle.sh](https://docs.reticle.sh) by `d
|
|
|
84
85
|
| [system-map.md](system-map.md) | how a tool call reaches the app, and which failures are silent |
|
|
85
86
|
| [telemetry-contract.md](telemetry-contract.md) | required reading before touching anything that emits |
|
|
86
87
|
| [telemetry-events.mdx](telemetry-events.mdx) | every event kind and its payload, and the question each one exists to answer |
|
|
88
|
+
| [first-drive.md](first-drive.md) | clone to a real verdict in about fifteen minutes, and the traps on the way |
|
|
87
89
|
| [debugging.md](debugging.md) | debugging Reticle itself: the four signals and what each answers |
|
|
88
90
|
| [fixtures.md](fixtures.md) | the sibling `reticle-fixtures` repo: install complexity, not regressions |
|
|
89
|
-
| [matrix/README.md](matrix/README.md) | submitting an MCP-client compatibility record, the best first contribution |
|
|
90
|
-
| [matrix/MATRIX.md](matrix/MATRIX.md) | which clients are known to work (generated; do not hand-edit) |
|
|
91
|
-
| [`../apps/README.md`](
|
|
92
|
-
| [`../apps/e2e/harness-rules.md`](
|
|
93
|
-
| [`../bench/README.md`](
|
|
91
|
+
| [matrix/README.md](https://github.com/reticlehq/reticle/blob/main/docs/matrix/README.md) | submitting an MCP-client compatibility record, the best first contribution |
|
|
92
|
+
| [matrix/MATRIX.md](https://github.com/reticlehq/reticle/blob/main/docs/matrix/MATRIX.md) | which clients are known to work (generated; do not hand-edit) |
|
|
93
|
+
| [`../apps/README.md`](https://github.com/reticlehq/reticle/blob/main/apps/README.md) | what belongs in `apps/`, and what does not |
|
|
94
|
+
| [`../apps/e2e/harness-rules.md`](https://github.com/reticlehq/reticle/blob/main/apps/e2e/harness-rules.md) | the four rules every gate obeys, and the incident behind each |
|
|
95
|
+
| [`../bench/README.md`](https://github.com/reticlehq/reticle/blob/main/bench/README.md) | what in `bench/` is live and what is a kept one-off study |
|
|
94
96
|
|
|
95
97
|
`fixtures-dispatch-receiver.yml` is not a doc; it is the workflow template `reticle-fixtures` needs, kept in this repo so the two ends of the contract cannot drift apart.
|
|
96
98
|
|
package/docs/actions.mdx
CHANGED
|
@@ -24,7 +24,7 @@ Every action Reticle can perform takes the same shape: a `ref` from [`reticle_sn
|
|
|
24
24
|
| `submit` | none | Submits the element's `<form>` |
|
|
25
25
|
| `press` | `{ text }` | The key **name**: `Escape`, `Tab`, `Enter` |
|
|
26
26
|
| `scrollIntoView` | none | |
|
|
27
|
-
| `upload` | `{ content?, name?, type? }` | Sets a file on `<input type="file">`.
|
|
27
|
+
| `upload` | `{ content?, name?, type?, path? }` | Sets a file on `<input type="file">`. Inline bytes default to `"reticle test file"` / `"file.txt"` / `"text/plain"`. `path` reads a file from disk, scoped to the project root plus any opt-in directories listed in `.reticle.json` as `"uploadRoots": ["~/Downloads", "/Volumes/fixtures"]`. A refusal names every allowed root. |
|
|
28
28
|
| `drag` | `{ toRef }` | Pointer-based drag (dnd-kit, react-beautiful-dnd) plus HTML5 DnD. `target` is an alias |
|
|
29
29
|
| `webmcp` | `{ tool, params }` | Calls a `navigator.modelContext` tool, if the site exposes one |
|
|
30
30
|
|
package/docs/agent-cheatsheet.md
CHANGED
|
@@ -113,9 +113,11 @@ The tools advertised DIRECTLY, i.e. what you'll use 90% of the time. Everything
|
|
|
113
113
|
|
|
114
114
|
`reticle_sessions` · `reticle_navigate` · `reticle_snapshot` · `reticle_query` · `reticle_act` · `reticle_act_sequence` · `reticle_act_and_wait` · `reticle_observe` · `reticle_network` · `reticle_console` · `reticle_wait_for` · `reticle_assert` · `reticle_state` · `reticle_inspect` (DOM node → `src/App.tsx:104`) · `reticle_feedback` (tell the maintainers what is missing) · `reticle_session` (hand back: `{action:"yield"}` the moment you stop driving, `{action:"resume"}` after a human pause).
|
|
115
115
|
|
|
116
|
+
- `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".
|
|
117
|
+
|
|
116
118
|
Frequently useful but NOT core, so reach them through `reticle_run({ tool, args })`: `reticle_capabilities` (the app's whole testable surface in one call; `{fromDisk:true}` needs no browser), `reticle_domain` (learn the app + gaps), `reticle_baseline {action:"diff"}`, `reticle_project` (run history).
|
|
117
119
|
|
|
118
|
-
**Reach past core when…** you need to record/replay a journey (`reticle_record {action:"start"}/stop`, `reticle_replay`), persist a self-healing golden flow (`reticle_flow_save*` / `reticle_flow_replay` / `reticle_flow_heal`), compile annotations (`reticle_annotate`), explore autonomously (`reticle_explore` lists controls; `reticle_verify {action:"crawl"}` clicks them all and reports anomalies, and is **destructive**), reveal a virtualized off-screen row (`reticle_scroll_to`, for when `reticle_query` 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
|
|
120
|
+
**Reach past core when…** you need to record/replay a journey (`reticle_record {action:"start"}/stop`, `reticle_replay`), persist a self-healing golden flow (`reticle_flow_save*` / `reticle_flow_replay` / `reticle_flow_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_query` 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).
|
|
119
121
|
|
|
120
122
|
## flows vs baselines vs project.json (the persistence layers)
|
|
121
123
|
|
|
@@ -160,4 +162,4 @@ Recent additions, each of which answers a question agents were previously asking
|
|
|
160
162
|
- **Cap broad reads.** `reticle_query` takes `limit` (caps descriptors; reports `total`/`truncated`) and `count_only` (just the match count). `reticle_network` / `reticle_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.
|
|
161
163
|
- **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.
|
|
162
164
|
- **Predicate schema is not bloated.** The recursive predicate DSL used by `reticle_assert` / `reticle_wait_for` / `reticle_act_and_wait` is **factored, not inlined**: when converted to the JSON Schema MCP sends, the predicate body is emitted **once** (~2.7k chars ≈ **~685 tokens** per tool) and recursion is handled by self-`$ref` (`#/properties/predicate`), with no per-recursion duplication. No action needed.
|
|
163
|
-
- **One tool surface.** Reticle advertises the core set directly (sessions/navigate/snapshot/query/act/act_and_wait/observe/network/console/wait_for/assert/state/inspect/feedback/session: the whole detect loop, plus the file-pointer, the feedback channel
|
|
165
|
+
- **One tool surface.** Reticle advertises the core set directly (sessions/navigate/snapshot/query/act/act_and_wait/observe/network/console/wait_for/assert/state/inspect/feedback/session/verify: the whole detect loop, plus the file-pointer, the feedback channel, the handback, plus the one tool that CONCLUDES) PLUS two meta-tools that keep every other tool one call away: `reticle_tools` (discover; no args lists every tool name + summary, `names:[…]` loads full params on demand) and `reticle_run({ tool, args })` (invoke any tool by name; a top-level `sessionId` is forwarded to the target, so you need not nest it in `args`). So to record/replay a flow, call `reticle_run({ tool:"reticle_record", args:{ action:"start" }, sessionId })` (or `reticle_tools` first to see params). `reticle_verify` is advertised directly: `{ 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. There is nothing to pick. `RETICLE_ADVERTISE_ALL_TOOLS=1` (read by the daemon at startup, so restart it) advertises everything with output schemas: a verification switch for suites, not a way to run agents. **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
|
@@ -127,4 +127,4 @@ See [LICENSE](../LICENSE) and each package's own `LICENSE` file. The licensing _
|
|
|
127
127
|
- [getting-started.md](getting-started.md) wires Reticle into your app in a couple of minutes.
|
|
128
128
|
- [benchmarks.md](benchmarks.md) covers how we measure, and the honest results vs the alternatives.
|
|
129
129
|
- [usage.md](usage.md) is the full tool reference and advanced modes.
|
|
130
|
-
- [CONTRIBUTING.md](
|
|
130
|
+
- [CONTRIBUTING.md](https://github.com/reticlehq/reticle/blob/main/CONTRIBUTING.md) has the development loop and the rules.
|
package/docs/cli/mcp.mdx
CHANGED
|
@@ -31,6 +31,7 @@ The proxy **is** the MCP server the editor launched. Nothing respawns it, so an
|
|
|
31
31
|
- Crash handlers write to the proxy's own log file, not just stderr, because the editor swallows stderr.
|
|
32
32
|
- A daemon that is not there is not fatal. The proxy answers `initialize` itself, serves the cached tool catalog, and retries a daemon on every client request. Present and complaining beats absent, because absent needs a human.
|
|
33
33
|
- Reconnect is self-healing: if the daemon exited, crashed, was stopped, or shut itself down as idle, the reconnect path spawns a new one rather than retrying a dead port until the budget runs out.
|
|
34
|
+
- A proxy with no client traffic and no work in flight exits after 24 hours, so abandoned editor sessions do not leave process pairs behind forever. Set `RETICLE_MCP_PROXY_IDLE_MS=0` to disable that watcher, or set an explicit millisecond window.
|
|
34
35
|
|
|
35
36
|
## What it prints
|
|
36
37
|
|
|
@@ -41,10 +42,11 @@ Structured lines to the proxy log (`~/.reticle/`), not to your terminal, since s
|
|
|
41
42
|
| `reticle_mcp_daemon_started` | It spawned a daemon |
|
|
42
43
|
| `reticle_mcp_daemon_unavailable` | It could not, and is serving anyway |
|
|
43
44
|
| `reticle_mcp_proxy_first_connect_failed` | The first connect was refused. Expected when the daemon is still coming up |
|
|
45
|
+
| `reticle_mcp_proxy_idle_exit` | The client link stayed quiet for the full idle window and the proxy exited with no work in flight |
|
|
44
46
|
|
|
45
47
|
## Exit codes
|
|
46
48
|
|
|
47
|
-
Runs for the life of
|
|
49
|
+
Runs for the life of an active editor session. A fully quiet, abandoned link exits after the idle window above.
|
|
48
50
|
|
|
49
51
|
## Worked example
|
|
50
52
|
|
package/docs/cli/watch.mdx
CHANGED
|
@@ -34,7 +34,7 @@ Real capture, the first two lines of a run in this repository:
|
|
|
34
34
|
A save then produces a `reticle_watch_affected` line naming the changed files and the flows they put at risk, followed by a refreshed buddy line. Real capture, with both lists trimmed:
|
|
35
35
|
|
|
36
36
|
```json
|
|
37
|
-
{"t":"2026-08-15T18:44:09.317Z","event":"reticle_watch_affected","changed":["packages/
|
|
37
|
+
{"t":"2026-08-15T18:44:09.317Z","event":"reticle_watch_affected","changed":["packages/init/src/mcp-clients.ts"],"affected":["WEB-flow","deploy-journey","verify-route"]}
|
|
38
38
|
{"t":"2026-08-15T18:44:09.355Z","event":"reticle_buddy","status":"✗ 39 deviations: ELECTRON-1LINE-flow, ELECTRON-COLD-flow +37 more · 0 nominal · 9 flaky quarantined"}
|
|
39
39
|
```
|
|
40
40
|
|
package/docs/cli.mdx
CHANGED
|
@@ -153,7 +153,7 @@ npx @reticlehq/server affected --since HEAD~1
|
|
|
153
153
|
{
|
|
154
154
|
"t": "2026-08-15T18:42:57.431Z",
|
|
155
155
|
"event": "reticle_affected",
|
|
156
|
-
"changedFiles": ["SKILL.md", "docs/cli/doctor.mdx", "packages/
|
|
156
|
+
"changedFiles": ["SKILL.md", "docs/cli/doctor.mdx", "packages/init/src/agent-rules.ts"],
|
|
157
157
|
"affected": ["WEB-flow", "deploy-journey", "verify-modal", "verify-route"],
|
|
158
158
|
"unknownProvenance": ["WEB-flow", "deploy-journey", "verify-modal", "verify-route"]
|
|
159
159
|
}
|
package/docs/desktop.mdx
CHANGED
package/docs/docs.json
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"navigation": {
|
|
33
33
|
"versions": [
|
|
34
34
|
{
|
|
35
|
-
"version": "2.
|
|
35
|
+
"version": "2.14.0",
|
|
36
36
|
"default": true,
|
|
37
37
|
"tabs": [
|
|
38
38
|
{
|
|
@@ -62,7 +62,12 @@
|
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"group": "Working with agents",
|
|
65
|
-
"pages": [
|
|
65
|
+
"pages": [
|
|
66
|
+
"multi-agent-testing",
|
|
67
|
+
"human-control",
|
|
68
|
+
"platform-integration",
|
|
69
|
+
"http-transport"
|
|
70
|
+
]
|
|
66
71
|
},
|
|
67
72
|
{
|
|
68
73
|
"group": "When it goes wrong",
|
|
@@ -192,7 +197,7 @@
|
|
|
192
197
|
"groups": [
|
|
193
198
|
{
|
|
194
199
|
"group": "Working on Reticle",
|
|
195
|
-
"pages": ["gates", "gate-plan", "fixtures", "local-registry"]
|
|
200
|
+
"pages": ["first-drive", "gates", "gate-plan", "fixtures", "local-registry"]
|
|
196
201
|
},
|
|
197
202
|
{
|
|
198
203
|
"group": "Internals",
|
package/docs/faq.mdx
CHANGED
|
@@ -83,6 +83,15 @@ Anonymous usage telemetry is sent separately and can be turned off with `reticle
|
|
|
83
83
|
</Card>
|
|
84
84
|
</Accordion>
|
|
85
85
|
|
|
86
|
+
<Accordion title="Does it work with WebGL / react-three-fiber?">
|
|
87
|
+
Partially. Reticle's model of an app is DOM + store + network. A WebGL or react-three-fiber
|
|
88
|
+
subtree is a single `<canvas>` to `reticle_query` / `reticle_snapshot`: Reticle cannot pick faces
|
|
89
|
+
or drive the camera inside the scene.
|
|
90
|
+
|
|
91
|
+
DOM, registered store state, and network **around** the canvas still work, and that is often where the consequential bugs live (import counts, mesh stats, solver results that contradict the UI). `init` prints this limit when it detects react-three-fiber so an adopting team does not discover it only after trying to verify the feature they care about.
|
|
92
|
+
|
|
93
|
+
</Accordion>
|
|
94
|
+
|
|
86
95
|
<Accordion title="Is Reticle proven to make agents fix more bugs?">
|
|
87
96
|
No, and we are not going to claim it. A controlled test of fix-rate did **not** show an improvement. The benchmark was confounded in ways we can point at, and we consider the question open.
|
|
88
97
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Your first drive
|
|
3
|
+
description: 'Clone to a real verdict in about fifteen minutes, and the traps that cost other people a debugging session.'
|
|
4
|
+
icon: play
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
The goal of this page is narrow and deliberate: **end with a real verdict on screen**, produced by Reticle against a running app, in a checkout you just cloned. Not a passing unit test, the thing the project exists to do.
|
|
8
|
+
|
|
9
|
+
Everything here is written from a run of these exact steps, including the places they bite.
|
|
10
|
+
|
|
11
|
+
## Before you start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
node --version # 22 or newer
|
|
15
|
+
pnpm --version # this is a pnpm workspace; npm will not resolve it
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/reticlehq/reticle && cd reticle
|
|
20
|
+
pnpm install
|
|
21
|
+
pnpm build # required: the specs and the CLI run from dist/, not src/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`pnpm build` is not optional. Several things below load `packages/server/dist`, and a stale or absent `dist` produces errors that read as code faults rather than as a missing build.
|
|
25
|
+
|
|
26
|
+
## 1. Boot something to look at
|
|
27
|
+
|
|
28
|
+
Two processes: a demo API and the bench app that talks to it.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
node apps/api/server.mjs &
|
|
32
|
+
RETICLE_PORT=4400 VITE_RETICLE_TOKEN="$(cat ~/.reticle/pairing-token)" \
|
|
33
|
+
pnpm --filter @reticlehq/bench-app exec vite --port 4310 --strictPort &
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Check both answered before going on, because a readiness check now saves a confusing failure later:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
curl -s -o /dev/null -w "api=%{http_code} app=%{http_code}\n" \
|
|
40
|
+
http://localhost:8787/api/saved-items http://localhost:4310/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If `~/.reticle/pairing-token` does not exist yet, run any `reticle` command once and it will be minted.
|
|
44
|
+
|
|
45
|
+
## 2. Take a verdict from the command line
|
|
46
|
+
|
|
47
|
+
This is the shortest path to seeing Reticle work, and it needs no MCP client at all.
|
|
48
|
+
|
|
49
|
+
Open the app in a browser. Use a real one, or:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
node -e "require('playwright').chromium.launch({headless:true})
|
|
53
|
+
.then(b=>b.newPage().then(p=>p.goto('http://localhost:4310/')
|
|
54
|
+
.then(()=>new Promise(r=>setTimeout(r,60000)))))" &
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then ask for a verdict:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
node packages/server/dist/cli.js verify "" --port 4400 \
|
|
61
|
+
--expect '{"kind":"text","contains":"Reticle"}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
verified: yes
|
|
66
|
+
reason: proved
|
|
67
|
+
exit=0
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
That is the whole product in one line: a claim, checked against a running page, with an exit code you can put in CI. `verified: "yes"` is the only pass, `unknown` means Reticle could not tell, and it exits non-zero on purpose.
|
|
71
|
+
|
|
72
|
+
Try making it fail, because a tool that only ever says yes is not telling you anything:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
node packages/server/dist/cli.js verify "" --port 4400 \
|
|
76
|
+
--expect '{"kind":"text","contains":"definitely not on this page"}'
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 3. Drive it properly, with the tools
|
|
80
|
+
|
|
81
|
+
If your editor has the Reticle MCP server, the same app is now drivable. The four calls worth knowing, in the order you actually use them:
|
|
82
|
+
|
|
83
|
+
- `reticle_snapshot`: what is on the page
|
|
84
|
+
- `reticle_query { by: "testid", value: "..." }`: find one thing, cheaply
|
|
85
|
+
- `reticle_act_and_wait { ref, action, until }` (**the one that produces a verdict**)
|
|
86
|
+
- `reticle_observe`: everything the page did, when you need the evidence
|
|
87
|
+
|
|
88
|
+
`reticle_act` moves the app and proves nothing. A drive that ends without `act_and_wait` or `reticle_assert` has no result, however many calls it made.
|
|
89
|
+
|
|
90
|
+
## 4. Read a spec, then run one
|
|
91
|
+
|
|
92
|
+
The end-to-end specs are the best documentation of what Reticle guarantees, because each one is a property somebody was burned by. Short and readable:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
node apps/e2e/specs/awkward-controls-test.mjs # a file upload, an unnamed button, a canvas
|
|
96
|
+
node apps/e2e/specs/auth-retry-not-a-defect-test.mjs # a 401 the app recovered from
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Both need step 1's processes running, and both need port 4400 free. See the traps below.
|
|
100
|
+
|
|
101
|
+
## The things that will bite you
|
|
102
|
+
|
|
103
|
+
**Port 4400 is the bridge, and something is probably on it.** Every spec binds it. If your editor has an MCP client open, its daemon owns that port and a spec dies with `EADDRINUSE`. Do **not** `kill -9` the holder: on 4400 that list includes the `reticle mcp` proxy, and killing it cuts your own agent's link with no log, because the process that writes the log is the one that dies. Use the harness, which spares the proxy:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
node -e "import('./apps/e2e/gate-harness.mjs').then(m=>m.freePortSafely(4400,{onNote:console.log}))"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**The bench app self-assigns its session id.** Matching on a fixed name waits forever. Specs identify it by the URL it serves from. Copy that pattern.
|
|
110
|
+
|
|
111
|
+
**The bench app shows a login first, and views are reached from the nav.** A query parameter does not select a view. Log in, click the nav item, then drive.
|
|
112
|
+
|
|
113
|
+
**Fixtures are in a second repo.** The apps in `apps/` are all already instrumented, so none of them can tell you whether a fresh install still works. That question lives in [`reticle-fixtures`](https://github.com/reticlehq/reticle-fixtures), which keeps a pristine `clean` branch of real third-party apps plus `main` and `reticle/<version>`. See [`fixtures.md`](fixtures.md).
|
|
114
|
+
|
|
115
|
+
**Telemetry fails silently.** Nothing throws, no test reddens, the data is just permanently gone. Read [`telemetry-contract.md`](telemetry-contract.md) before touching anything that emits.
|
|
116
|
+
|
|
117
|
+
**`core` is the contract and may not gain dependencies.** Anything crossing browser ↔ bridge ↔ agent is defined there as a constant plus a zod schema. Never inline a wire string elsewhere.
|
|
118
|
+
|
|
119
|
+
## Gate durations, measured
|
|
120
|
+
|
|
121
|
+
Run the fast gate before every commit. The others only when you touch what they cover.
|
|
122
|
+
|
|
123
|
+
| gate | when | measured |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| `pnpm format:check && pnpm lint && pnpm typecheck && pnpm test:unit` | always | ~2 min |
|
|
126
|
+
| `pnpm test:e2e` | the tool surface, the wire contract, or an observer | ~8 min |
|
|
127
|
+
| `pnpm test:e2e:desktop` | Electron, Tauri, the IPC observer, desktop capture | ~3 min, needs a Rust toolchain |
|
|
128
|
+
| `pnpm gate:install` | `init`, `vite-plugin`, `next`, `babel-plugin` | ~15 min |
|
|
129
|
+
|
|
130
|
+
`format:check` is first because CI enforces it and `pnpm lint` does not run it, a branch with all four heavy gates green locally can still turn CI red on formatting alone.
|
|
131
|
+
|
|
132
|
+
## Where to go next
|
|
133
|
+
|
|
134
|
+
- [`CONTRIBUTING.md`](https://github.com/reticlehq/reticle/blob/main/CONTRIBUTING.md): the rules, the layout, and the PR flow
|
|
135
|
+
- [`architecture.md`](architecture.md): how the pieces fit
|
|
136
|
+
- Issues labelled **good first issue**. Each names the file to start in, how to reproduce, and how you will know you are done. If one is still too vague, say so on the issue; that feedback is worth more than a guess.
|
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, 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 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. SvelteKit, Nuxt,
|
|
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 Vue 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 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
|
|
|
@@ -27,9 +27,11 @@ Two columns say different things and it is worth keeping them apart. **CI gate**
|
|
|
27
27
|
| **Next.js** | yes | yes | yes | yes | Supported |
|
|
28
28
|
| **Remix** | yes | yes | yes | yes | Supported |
|
|
29
29
|
| **Astro** | yes | yes | yes | yes | Supported |
|
|
30
|
-
| **SvelteKit** | yes | no |
|
|
31
|
-
| **
|
|
32
|
-
| **
|
|
30
|
+
| **SvelteKit** | yes | no | install only | unproven | Install gated, drive unverified |
|
|
31
|
+
| **TanStack Start** | yes | no | no | unproven | Wired, unverified |
|
|
32
|
+
| **Nuxt** | yes | no | install only | unproven | Install gated, drive unverified |
|
|
33
|
+
| **React Router (framework mode)** | yes | no | install only | yes | Install gated, drive unverified |
|
|
34
|
+
| **Create React App** | yes | no | install only | unproven | Install gated, drive unverified |
|
|
33
35
|
| **Plain HTML** | yes | no | no | no | Wired, unverified |
|
|
34
36
|
| **Vue (non-Nuxt)** | as Vite | no | install only | no | Install gated, drive unverified |
|
|
35
37
|
| **Preact** | as Vite | no | no | unproven | Sensor, React adapter via `preact/compat` |
|
|
@@ -100,12 +102,32 @@ The Vite plugin still stamps `data-reticle-source` into `.svelte` components, so
|
|
|
100
102
|
|
|
101
103
|
For state, use the `svelteStore` adapter. See [State management](/state-management).
|
|
102
104
|
|
|
105
|
+
## TanStack Start
|
|
106
|
+
|
|
107
|
+
TanStack Start SSRs `<html>` from `src/routes/__root.tsx` and never sends Vite's `index.html`, so the plugin cannot auto-connect. Keep the plugin with `inject: false`: only the injection half is inapplicable, and the stamping half is what puts `file:line` on a verdict.
|
|
108
|
+
|
|
109
|
+
Connect from a client-only effect. A static import of the SDK on `__root.tsx` SSRs and 500s.
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (import.meta.env.DEV) {
|
|
114
|
+
const token = typeof __RETICLE_TOKEN__ !== 'undefined' ? __RETICLE_TOKEN__ : '';
|
|
115
|
+
void import('@reticlehq/react').then(({ reticle, install }) => {
|
|
116
|
+
install();
|
|
117
|
+
reticle.connect({ ...(token.length > 0 ? { token } : {}) });
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}, []);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`init` detects Start and prints this recipe. There is no example app and no CI gate, so treat a connected session as the proof, not the plan.
|
|
124
|
+
|
|
103
125
|
## Nuxt
|
|
104
126
|
|
|
105
|
-
Nuxt owns its own Vite instance and renders its own HTML. There is no `vite.config` to patch and no `index.html` to inject into
|
|
127
|
+
Nuxt owns its own Vite instance and renders its own HTML. There is no `vite.config` to patch and no `index.html` to inject into, so `reticle init` writes a dev-only client plugin and adds a `vite.define` block to `nuxt.config`. That block is the only place a Nuxt app can inline the pairing token, which the bridge requires even on localhost. What it writes is this, and the notes below are why each line is the way it is.
|
|
106
128
|
|
|
107
129
|
```ts
|
|
108
|
-
// plugins/reticle.client.ts
|
|
130
|
+
// app/plugins/reticle.client.ts (Nuxt 3: plugins/reticle.client.ts)
|
|
109
131
|
export default defineNuxtPlugin(() => {
|
|
110
132
|
if (!import.meta.dev) return;
|
|
111
133
|
void import('@reticlehq/browser').then(({ reticle }) => {
|
package/docs/gate-plan.md
CHANGED
|
@@ -6,7 +6,7 @@ icon: list-check
|
|
|
6
6
|
|
|
7
7
|
Two gates, not one: a **merge gate** that answers "does this PR break anything" and runs on every PR in minutes, and a **release gate** that answers "does this version work in the clients people use" and runs on a release candidate over hours. Phases 0, 1, 2 and 4 are built; Phase 3 (the client matrix) is blocked on `init` learning each client, and Tier 2 is blocked on a token that cannot be created from inside this repo.
|
|
8
8
|
|
|
9
|
-
> What has to be true before a PR merges and before a release ships, why each piece exists, and what is built so far. Derived from [`system-map.md`](./system-map.md); the harness rules every tier obeys are in [`harness-rules.md`](
|
|
9
|
+
> What has to be true before a PR merges and before a release ships, why each piece exists, and what is built so far. Derived from [`system-map.md`](./system-map.md); the harness rules every tier obeys are in [`harness-rules.md`](https://github.com/reticlehq/reticle/blob/main/apps/e2e/harness-rules.md).
|
|
10
10
|
|
|
11
11
|
## Two gates, not one
|
|
12
12
|
|
|
@@ -85,7 +85,7 @@ Nothing below is trustworthy until a gate result can be distinguished from a gat
|
|
|
85
85
|
- Codex is deliberately not auto-written. Editing TOML without a parser risks every _other_ server in the user's file; it returns MANUAL with an exact block.
|
|
86
86
|
- [x] **Per-client compat script**: `apps/e2e/client-compat.mjs`. Extracts the command from the config **exactly the way that client would**, runs it, and speaks MCP to it. 7/7 clients, 23 assertions, each advertising the default surface (the count is asserted in `surface-sizes.test.ts`, never restated here).
|
|
87
87
|
- It proves only the half a machine can prove, and the verdict is named `runnable-unverified` so the distinction survives into the matrix. Whether the client _reads_ that path needs the real client, which is the submitted half.
|
|
88
|
-
- [x] **Submission flow**: `apps/e2e/matrix.mjs --validate`, run by CI's `matrix-records` job on every PR. The validator refuses what cannot be acted on: `works` without `checks.toolsVisible` (the self-report the flow exists to replace), `broken` without the client's verbatim error, or any record with no host or version. Its self-check runs first, because a validator that has never refused anything is not a validator. Contributor guide in [`docs/matrix/README.md`](
|
|
88
|
+
- [x] **Submission flow**: `apps/e2e/matrix.mjs --validate`, run by CI's `matrix-records` job on every PR. The validator refuses what cannot be acted on: `works` without `checks.toolsVisible` (the self-report the flow exists to replace), `broken` without the client's verbatim error, or any record with no host or version. Its self-check runs first, because a validator that has never refused anything is not a validator. Contributor guide in [`docs/matrix/README.md`](https://github.com/reticlehq/reticle/blob/main/docs/matrix/README.md).
|
|
89
89
|
- [x] **Generated `MATRIX.md`**: built from submitted records, prettier-ignored because a generated file that fails `format:check` teaches people to skip the gate. **The current honest state is seven clients and ZERO ticks**: `◐` means a runnable entry was written where the client documents it and _nobody has run that client_, and the generated legend says so rather than rounding `◐` up to `✅`.
|
|
90
90
|
|
|
91
91
|
### Phase 4: rates, not booleans
|
package/docs/gates.md
CHANGED
|
@@ -16,22 +16,28 @@ If you changed anything at all, run `pnpm format:check && pnpm lint && pnpm type
|
|
|
16
16
|
|
|
17
17
|
Every gate below was executed end to end against `main` on **2026-08-12** (macOS, M-series, `v2.6.0`). A green row means somebody watched it go green, not that it is supposed to be green.
|
|
18
18
|
|
|
19
|
+
**Rows marked ↻ were re-measured on 2026-09-09** (macOS, M-series, this branch). The numbers they replace were wrong by a lot, and wrong in the way that is hardest to notice: `test:unit` was recorded here as "5,725 tests / 613 files" and, forty lines further down in the same file, as "4,315 tests". Two copies of one number, neither derived from anything. The battery was 33 in one row and 32 in another, against 38 spec files on disk.
|
|
20
|
+
|
|
21
|
+
A ↻ row's COUNT was re-derived; a ↻ row's ✅ is still the August sweep unless the row says otherwise. `test:unit` was actually re-run (`turbo run test:unit test:guards --force`, then `pnpm test:bench`, summed from vitest's own per-package output). The battery's spec count was recounted from `ORDER` and `DESKTOP` in `apps/e2e/run.mjs` cross-checked against `ls apps/e2e/specs`; **it was not re-run**, so its ✅ and its wall clock are still August's.
|
|
22
|
+
|
|
19
23
|
| Gate | Result | Wall clock |
|
|
20
24
|
| --- | --- | --- |
|
|
21
25
|
| `pnpm build` | ✅ | ~40s |
|
|
22
26
|
| `pnpm lint` (+ both guard self-tests) | ✅ | ~15s |
|
|
23
27
|
| `pnpm typecheck` | ✅ | ~10s |
|
|
24
|
-
| `pnpm test:unit` | ✅
|
|
28
|
+
| ↻ `pnpm test:unit` | ✅ **9,210 tests / 934 files** across 10 packages plus the bench harness | ~70s |
|
|
25
29
|
| `pnpm format:check` | ✅ | ~10s |
|
|
26
30
|
| `pnpm test:integration` | ✅ 12/12 | 17s |
|
|
27
|
-
| `pnpm test:e2e` | ✅
|
|
31
|
+
| ↻ `pnpm test:e2e` | ✅ (Aug). **36 web specs**, counted 2026-09-09 | **490s** (Aug) |
|
|
28
32
|
| `pnpm test:e2e:desktop` | ✅ 2/2 (Electron 20, Tauri 17) | 58s |
|
|
29
33
|
| `node apps/e2e/soak.mjs --self-check` | ✅ | `<1s` |
|
|
30
34
|
| `node apps/e2e/matrix.mjs --self-check` | ✅ | `<1s` |
|
|
31
35
|
| `pnpm matrix:compat --only cursor` | ✅ 4/4 | ~10s |
|
|
32
36
|
| `pnpm bench` | ✅ 10/10 (**was failing before this sweep**, see below) | 279s |
|
|
33
37
|
|
|
34
|
-
**`pnpm bench` was broken and nobody knew.** `suite-rre.mjs` recorded four flows that asserted no observable consequence and then demanded a `pass` verdict from whole-suite replay, which correctly grades an assertion-free suite `unverifiable`. The product got more honest about false greens; the benchmark measuring it did not follow, so the whole run aborted at script 9 of 10 and `replay-determinism` never ran at all. Each flow now carries a success oracle.
|
|
38
|
+
**`pnpm bench` was broken and nobody knew.** `suite-rre.mjs` recorded four flows that asserted no observable consequence and then demanded a `pass` verdict from whole-suite replay, which correctly grades an assertion-free suite `unverifiable`. The product got more honest about false greens; the benchmark measuring it did not follow, so the whole run aborted at script 9 of 10 and `replay-determinism` never ran at all. Each flow now carries a success oracle.
|
|
39
|
+
|
|
40
|
+
That paragraph used to end "**nothing in CI runs it**, so it can only rot silently", and it is left here because it is the reason the `bench` job below exists. It is no longer true: `ci.yml` has a `bench` job that runs `pnpm bench:full` then `pnpm bench:gate`, path-routed on the files that can move token cost. What is still true is the narrower claim in section 4: `bench/` as a whole is measurement, and only the replay + observation-cost numbers are gated.
|
|
35
41
|
|
|
36
42
|
`pnpm gate:install` (~15 min) and the Windows / Rust jobs were **not** run in this sweep; they are CI-only or network-bound. They are green on `main` per the last CI run, which is a weaker claim than every row above, and is stated that way on purpose.
|
|
37
43
|
|
|
@@ -64,15 +70,17 @@ Each gate exists because the ones above it are blind to something. That blindnes
|
|
|
64
70
|
| **Build** | `pnpm build` | every package compiles and emits | anything at runtime | `verify` |
|
|
65
71
|
| **Lint** | `pnpm lint` | style rules, plus the dependency-boundary and lossy-transform guards | anything not expressible as a rule | `verify` |
|
|
66
72
|
| **Typecheck** | `pnpm typecheck` | types agree across package boundaries | runtime behaviour | `verify` |
|
|
67
|
-
| **Unit** | `pnpm test:unit` |
|
|
73
|
+
| **Unit** | `pnpm test:unit` | 9,210 tests, per-package, no browser | anything crossing a package boundary at runtime | `verify` |
|
|
74
|
+
| **Repo guards** | `turbo run test:guards` | the 42 `@reticlehq/server` tests that scan OTHER trees (docs, `apps/`, `bench/`, the workflows, the skills), held apart from the unit suite so the wide cache key is 2 seconds rather than 40 | anything inside a package | `verify` (inside `pnpm test:unit`) |
|
|
68
75
|
| **Format** | `pnpm format:check` | Prettier | n/a | `verify` |
|
|
69
76
|
| **Integration** | `pnpm test:integration` | real headless Chromium: browser pool, crash isolation, framework adapters, `withReticle` | the MCP surface, the daemon | `e2e` |
|
|
70
|
-
| **Web e2e battery** | `pnpm test:e2e` |
|
|
71
|
-
| **Desktop battery** | `pnpm test:e2e:desktop` |
|
|
72
|
-
| **Install gate** | `pnpm gate:install` | scaffolds
|
|
77
|
+
| **Web e2e battery** | `pnpm test:e2e` | **39** specs against 3 booted servers and a real browser (the tool surface, the daemon lifecycle, transport faults, telemetry, trace shape), plus the soak | desktop runtimes; the install | `e2e` |
|
|
78
|
+
| **Desktop battery** | `pnpm test:e2e:desktop` | two real Electron main processes (plain Vite + electron-vite) and a **packaged** Tauri binary, driven headless | web-only paths | `desktop-e2e` |
|
|
79
|
+
| **Install gate** | `pnpm gate:install` | scaffolds **10** pristine apps across 2 OSes (20 cells), publishes this checkout to a local Verdaccio, lets `init` install itself, boots each app in a real browser, polls for a session that advertised capabilities | install _complexity_; see [`fixtures.md`](./fixtures.md) | `install-gate` |
|
|
73
80
|
| **Matrix records** | `pnpm matrix:validate` | every submitted client-compat record is well-formed | whether the client actually works | `matrix-records` |
|
|
74
81
|
| **Windows** | (CI only) | that the code runs at all on the majority platform | e2e; Windows is unit-only | `windows` |
|
|
75
|
-
| **
|
|
82
|
+
| **macOS** | (CI only) | the POSIX-but-not-Linux surface (paths, spawn, `lsof`, temp/state dirs) plus a real daemon's lifecycle | everything Linux already covers; it deliberately no longer re-runs the unit tier at a 10x billing multiplier | `macos` |
|
|
83
|
+
| **Rust** | `cargo fmt/clippy/check` | `packages/tauri` compiles and lints on Linux, macOS, and cross-checks Windows | everything JS | `rust` (always), `rust-macos` (only when Rust changes) |
|
|
76
84
|
|
|
77
85
|
**The single required status check is `gate`.** It passes when every job above either succeeded or was deliberately skipped by path routing, and fails on anything else. Adding a job to `ci.yml` is half the work; adding it to `gate`'s `needs:` list is the other half. A job missing from that list runs, reports, and is structurally incapable of blocking a merge.
|
|
78
86
|
|
|
@@ -105,7 +113,7 @@ These are real and they work; they are not on the PR path, so they only run when
|
|
|
105
113
|
|
|
106
114
|
## 4. `bench/` is not a gate
|
|
107
115
|
|
|
108
|
-
`bench/` is **measurement and research
|
|
116
|
+
`bench/` is **measurement and research**. Most of it blocks nothing and is allowed to bit-rot in a way a gate is not. But "nothing runs in CI" is no longer true, and was left standing here for a release after it stopped being: `ci.yml` has a `bench` job, gated on `changes.bench`, that runs `pnpm bench:full` and then `pnpm bench:gate`. It is the only thing in CI that measures TOKEN COST, which is how a release once shipped a measurable token regression with every other gate green. Read [`bench/README.md`](https://github.com/reticlehq/reticle/blob/main/bench/README.md) before touching it: it says which scripts are live and which are one-off studies kept as evidence for a published claim.
|
|
109
117
|
|
|
110
118
|
The one exception worth knowing: `pnpm bench` + `pnpm bench:gate` is a working regression gate for the replay numbers, and it is run by hand before a release.
|
|
111
119
|
|
|
@@ -117,7 +125,7 @@ Sometimes it is. The specific failures worth recognising:
|
|
|
117
125
|
|
|
118
126
|
- **`EADDRINUSE` / "died during boot".** A previous run left something on `:8787`, `:4310`, or `:3100`. `run-ci.sh` frees these on exit; if it was killed, free them by hand.
|
|
119
127
|
- **Killing port 4400 with `lsof -ti tcp:4400 | xargs kill -9`.** This SIGKILLs the `reticle mcp` proxy too, because the proxy holds a _client_ socket on the bridge port. Always add `-sTCP:LISTEN`. This is the root cause of most "the MCP went down" reports.
|
|
120
|
-
- **A timing assertion.** If a test asserts `Date.now() - t < N`, that is a bug in the test, not a flake to re-run. Assert the bound (output size, a truncation flag), or use a generous per-test timeout. See [`harness-rules.md`](
|
|
128
|
+
- **A timing assertion.** If a test asserts `Date.now() - t < N`, that is a bug in the test, not a flake to re-run. Assert the bound (output size, a truncation flag), or use a generous per-test timeout. See [`harness-rules.md`](https://github.com/reticlehq/reticle/blob/main/apps/e2e/harness-rules.md).
|
|
121
129
|
- **An `INCONCLUSIVE` verdict.** The harness is telling you the transport did not stay up, so it is claiming nothing about the product. That is the harness working, not the product failing.
|
|
122
130
|
|
|
123
|
-
The four rules every tier obeys, and the incident behind each, are in [`apps/e2e/harness-rules.md`](
|
|
131
|
+
The four rules every tier obeys, and the incident behind each, are in [`apps/e2e/harness-rules.md`](https://github.com/reticlehq/reticle/blob/main/apps/e2e/harness-rules.md).
|
package/docs/getting-started.md
CHANGED
|
@@ -88,7 +88,7 @@ Three flags carry what the command cannot work out for itself:
|
|
|
88
88
|
| `--env KEY=VALUE` | What your app needs to reach a usable state: the key from `.env.example`, the mock backend, the variable that skips an auth wall. Repeatable. |
|
|
89
89
|
| `--app <dir>` | Which app in a monorepo. It finds the servable ones; only you know which you are working in. |
|
|
90
90
|
|
|
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), `--no-open`, `--no-drive`, `--dry-run`, `--port N`, `--no-mcp`, `--no-install`.
|
|
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`, `--no-drive`, `--dry-run`, `--port N`, `--no-mcp`, `--no-install`.
|
|
92
92
|
|
|
93
93
|
Then restart your dev server and 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
|
|
|
@@ -223,6 +223,12 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
223
223
|
}
|
|
224
224
|
```
|
|
225
225
|
|
|
226
|
+
### Streamlit
|
|
227
|
+
|
|
228
|
+
Streamlit owns the top-level HTML document, so it has no template where the plain script tag below can be added. Scripts passed through `st.markdown(..., unsafe_allow_html=True)` are rendered but do not execute.
|
|
229
|
+
|
|
230
|
+
With Streamlit 1.63 or newer, run `npx @reticlehq/server init` from the project. It detects a `streamlit` dependency or import and prints a copy-pasteable `st.html(..., unsafe_allow_javascript=True)` helper that loads Reticle once in the app document. Keep that helper development-only and do not commit the pairing token printed inside it.
|
|
231
|
+
|
|
226
232
|
### Plain / other frameworks
|
|
227
233
|
|
|
228
234
|
Anywhere your app boots in dev:
|