@reticlehq/server 2.13.1 → 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/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 +141 -50
- 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
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'HTTP transport'
|
|
3
|
+
description: 'Drive the full reticle_* tool surface over plain HTTP and SSE, from a client that cannot hot-reload MCP tools or that is not an MCP client at all.'
|
|
4
|
+
icon: 'plug'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Most clients reach Reticle over stdio: they spawn `reticle mcp`, and the tools appear in the agent's surface. That has one property you cannot always live with. **Many clients read their MCP tool list once, at startup**. If the daemon was not running when the client launched, the `reticle_*` tools are absent for the rest of that session, and the fix is to restart the client.
|
|
8
|
+
|
|
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
|
+
|
|
11
|
+
It is the same tool surface. Not a subset, not a simplified one. `reticle_snapshot`, `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
|
+
|
|
13
|
+
## The two endpoints
|
|
14
|
+
|
|
15
|
+
| Method | Path | What it does |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| `GET` | `/mcp/sse` | Opens a session. The response is an SSE stream that stays open, and every reply the server sends comes back on it. |
|
|
18
|
+
| `POST` | `/mcp/message?sessionId=<id>` | Sends one JSON-RPC message into an open session. |
|
|
19
|
+
|
|
20
|
+
The daemon listens on port **4400** by default (`RETICLE_PORT`, or `reticle serve --port N`). Run `reticle status` to confirm which port is live.
|
|
21
|
+
|
|
22
|
+
## The handshake
|
|
23
|
+
|
|
24
|
+
The one shape worth reading before you write any code: **the POST does not answer your request.** It replies `202 Accepted` with no result in it, and the actual JSON-RPC reply arrives on the SSE stream you opened first. A client that waits on the POST body waits forever.
|
|
25
|
+
|
|
26
|
+
1. `GET /mcp/sse`. Hold the response open.
|
|
27
|
+
2. The first frame is the endpoint announcement, and it carries the session id:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
event: endpoint
|
|
31
|
+
data: /mcp/message?sessionId=6f1c2b7e-1f4a-4a8e-9d5f-3f7a1b2c3d4e
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use that `data` value verbatim as the path you POST to. Do not build it yourself: the session id is minted per connection.
|
|
35
|
+
|
|
36
|
+
3. `POST` the `initialize` request there, then the `notifications/initialized` notification.
|
|
37
|
+
4. `POST` `tools/list`, `tools/call`, and anything else. Match each reply to its request by the JSON-RPC `id`, off the SSE stream.
|
|
38
|
+
|
|
39
|
+
When the daemon shuts down it writes a shutdown frame on the stream before the socket closes, so a client can tell a planned stop from a dropped connection.
|
|
40
|
+
|
|
41
|
+
## Errors
|
|
42
|
+
|
|
43
|
+
| Status | Meaning | What to do |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `400 missing sessionId` | The POST had no `sessionId` query parameter. | Use the path from the `endpoint` frame. |
|
|
46
|
+
| `404 session not found` | That session is not open, usually because the SSE stream dropped. | Reconnect to `/mcp/sse` and handshake again. |
|
|
47
|
+
| `503 MCP server not ready` | The daemon is up but the MCP server is not attached yet. | Retry. Unlike a `404`, the endpoint is real and coming. |
|
|
48
|
+
|
|
49
|
+
`404` and `400` are kept apart on purpose: reconnecting fixes one and nothing about the other.
|
|
50
|
+
|
|
51
|
+
## Authorization
|
|
52
|
+
|
|
53
|
+
Two tiers, the same ones the WebSocket bridge uses.
|
|
54
|
+
|
|
55
|
+
**Local clients need no token.** A request is trusted when its peer address, its `Host` header, and its `Origin`/`Referer` (when present) are all loopback. All three are required, because a DNS-rebound page reaches the daemon _as_ a loopback peer while carrying the attacker's `Host`, so peer address alone would not be a check.
|
|
56
|
+
|
|
57
|
+
**Anything else must present the pairing token**, which is required whenever you bind beyond loopback with `RETICLE_HOST`. Either form works:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Authorization: Bearer <token>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
/mcp/sse?token=<token>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Set it with `RETICLE_TOKEN`. With no token configured, the daemon binds loopback-only and non-local requests are refused outright rather than falling back to trust.
|
|
68
|
+
|
|
69
|
+
## A minimal client
|
|
70
|
+
|
|
71
|
+
No MCP library. Node's standard library is enough. This opens a session, lists the tools, and takes a snapshot.
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
import http from 'node:http';
|
|
75
|
+
|
|
76
|
+
const PORT = 4400;
|
|
77
|
+
let endpoint = null;
|
|
78
|
+
let next = 1;
|
|
79
|
+
const pending = new Map();
|
|
80
|
+
|
|
81
|
+
// 1. Open the stream and keep it open. Every reply arrives here.
|
|
82
|
+
http.get({ port: PORT, path: '/mcp/sse', agent: false }, (res) => {
|
|
83
|
+
let buffer = '';
|
|
84
|
+
res.setEncoding('utf8');
|
|
85
|
+
res.on('data', (chunk) => {
|
|
86
|
+
buffer += chunk;
|
|
87
|
+
const frames = buffer.split('\n\n');
|
|
88
|
+
buffer = frames.pop();
|
|
89
|
+
for (const frame of frames) {
|
|
90
|
+
const event = /^event: (.*)$/m.exec(frame)?.[1] ?? 'message';
|
|
91
|
+
const data = /^data: (.*)$/m.exec(frame)?.[1] ?? '';
|
|
92
|
+
if (event === 'endpoint') {
|
|
93
|
+
endpoint = data; // "/mcp/message?sessionId=…", used verbatim
|
|
94
|
+
start();
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const message = JSON.parse(data);
|
|
98
|
+
pending.get(message.id)?.(message); // match the reply to its request by id
|
|
99
|
+
pending.delete(message.id);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// 2. POST a request; resolve when its reply comes back on the stream.
|
|
105
|
+
function send(method, params) {
|
|
106
|
+
const id = next++;
|
|
107
|
+
const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
pending.set(id, resolve);
|
|
110
|
+
const req = http.request(
|
|
111
|
+
{
|
|
112
|
+
port: PORT,
|
|
113
|
+
path: endpoint,
|
|
114
|
+
method: 'POST',
|
|
115
|
+
headers: { 'Content-Type': 'application/json' },
|
|
116
|
+
},
|
|
117
|
+
(res) => res.resume(), // 202 Accepted; the answer is on the SSE stream
|
|
118
|
+
);
|
|
119
|
+
req.end(body);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function start() {
|
|
124
|
+
await send('initialize', {
|
|
125
|
+
protocolVersion: '2024-11-05',
|
|
126
|
+
capabilities: {},
|
|
127
|
+
clientInfo: { name: 'my-client', version: '1.0.0' },
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const notify = http.request(
|
|
131
|
+
{ port: PORT, path: endpoint, method: 'POST', headers: { 'Content-Type': 'application/json' } },
|
|
132
|
+
(res) => res.resume(),
|
|
133
|
+
);
|
|
134
|
+
notify.end(JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }));
|
|
135
|
+
|
|
136
|
+
const listed = await send('tools/list', {});
|
|
137
|
+
console.log(listed.result.tools.map((t) => t.name).join(', '));
|
|
138
|
+
|
|
139
|
+
const snapshot = await send('tools/call', { name: 'reticle_snapshot', arguments: {} });
|
|
140
|
+
console.log(snapshot.result.content[0].text);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
To watch the raw frames instead, `curl` is enough for the first half:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
curl -N http://127.0.0.1:4400/mcp/sse
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Then, from a second shell, POST to the path that stream printed:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
curl -X POST 'http://127.0.0.1:4400/mcp/message?sessionId=<id>' \
|
|
154
|
+
-H 'Content-Type: application/json' \
|
|
155
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The `202` comes back here; the tool list appears in the first shell.
|
|
159
|
+
|
|
160
|
+
## What this does not change
|
|
161
|
+
|
|
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 `reticle_sessions` 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
|
+
|
|
164
|
+
The endpoints, the handshake, the three status codes and the `202`-then-SSE shape are pinned by `packages/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/index.mdx
CHANGED
|
@@ -44,9 +44,11 @@ Afterwards, use it whenever you change any user-facing behaviour.
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
<Tip>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
The plugin and the skills CLI are alternatives to the *registration* half only, not to `init`:
|
|
48
|
+
neither one touches your app, so you still run the command above afterwards to instrument it. On
|
|
49
|
+
Claude Code, `/plugin marketplace add reticlehq/reticle` then `/plugin install reticle@reticlehq`
|
|
50
|
+
registers the MCP server and the skills in one step; on most other agents, `npx skills add
|
|
51
|
+
reticlehq/reticle`.
|
|
50
52
|
</Tip>
|
|
51
53
|
|
|
52
54
|
<Card title="What that command actually changes" icon="wand-magic-sparkles" href="/install-agentic">
|
package/docs/install-manual.mdx
CHANGED
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 = "
|
|
24
|
+
reticle-tauri = "2.14"
|
|
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.
|
package/docs/packages.mdx
CHANGED
|
@@ -5,7 +5,7 @@ description: Every Reticle package. What it does, why it exists, when you actual
|
|
|
5
5
|
icon: cubes
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Reticle is
|
|
8
|
+
Reticle is twelve packages, and most people install two. This page exists so you can tell which two, and so that the ones you skip stop looking mysterious.
|
|
9
9
|
|
|
10
10
|
<Note>
|
|
11
11
|
Everything ships together at one version: whatever `npm view @reticlehq/core version` says, every
|
|
@@ -89,7 +89,7 @@ if (import.meta.env.DEV) reticle.connect();
|
|
|
89
89
|
|
|
90
90
|
**Why it exists:** agents speak MCP; browsers speak WebSocket; somebody has to be fluent in both and own the `.reticle/` directory where flows, baselines and runs are stored.
|
|
91
91
|
|
|
92
|
-
**Depends on:** `@modelcontextprotocol/sdk`, `@reticlehq/core`, `ws`, `zod`.
|
|
92
|
+
**Depends on:** `@modelcontextprotocol/sdk`, `@reticlehq/core`, `@reticlehq/init`, `ws`, `zod`.
|
|
93
93
|
|
|
94
94
|
**Do you install it?** Not into your project. Your agent launches it:
|
|
95
95
|
|
|
@@ -99,6 +99,18 @@ npx @reticlehq/server mcp
|
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
102
|
+
## @reticlehq/init
|
|
103
|
+
|
|
104
|
+
**The project scaffolder behind `reticle init`.** Detects the framework and package manager, writes `.reticle.json`, patches the build config, generates the connect snippet and the agent rules, and registers the MCP server with whichever clients are on the machine.
|
|
105
|
+
|
|
106
|
+
**Why it exists:** nothing in it observes a running app. It is a build-time codemod that runs once. While it lived inside `@reticlehq/server`, a typo in a generated snippet forced a republish of the MCP server, and every MCP user downloaded a scaffolder they run once or never. It reaches back into the daemon for nothing: the version it stamps, the tracer, the outcome reporter and the bridge pairing token all arrive through one injected `InitHost`.
|
|
107
|
+
|
|
108
|
+
**Depends on:** `@reticlehq/core`, and nothing else.
|
|
109
|
+
|
|
110
|
+
**Do you install it?** No. `@reticlehq/server` depends on it at the same version, and the `reticle` CLI drives it.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
102
114
|
## @reticlehq/react
|
|
103
115
|
|
|
104
116
|
**The kit most React users install.** It re-exports the browser sensor, so one install gives you `reticle`, `registerCapabilities` and everything else, and it maps a DOM node to its React component and source file through the fiber tree.
|
|
@@ -207,7 +219,7 @@ A lint rule makes the signal layer self-enforcing, which is the only way a conve
|
|
|
207
219
|
|
|
208
220
|
```toml
|
|
209
221
|
[dependencies]
|
|
210
|
-
reticle-tauri = "2.
|
|
222
|
+
reticle-tauri = "2.14"
|
|
211
223
|
```
|
|
212
224
|
|
|
213
225
|
<Warning>
|
|
@@ -133,7 +133,7 @@ The shape is identical (in-app SDK in the template → verify in the sandbox →
|
|
|
133
133
|
2. Since the runtime is in-browser, drive via the connected session (the SDK dials the bridge) rather than `--drive`; call verify from the Bolt agent after a build.
|
|
134
134
|
3. Same act-on-verdict: gate + self-heal with the repair packets. (Bolt already detects terminal/compile errors; Reticle adds the _runtime program-truth_ layer it's blind to.)
|
|
135
135
|
|
|
136
|
-
> Honest note: a platform can build a verification step itself. Reticle's case is the depth (program-state and source mapping), the determinism (0% flake, no LLM in the loop), the un-hallucinatable verdict, and a stable drop-in artifact. The reproducible benchmark in [`bench/`](
|
|
136
|
+
> Honest note: a platform can build a verification step itself. Reticle's case is the depth (program-state and source mapping), the determinism (0% flake, no LLM in the loop), the un-hallucinatable verdict, and a stable drop-in artifact. The reproducible benchmark in [`bench/`](https://github.com/reticlehq/reticle/blob/main/bench/README.md) measures the observation-cost and detection differences against other browser-automation MCPs.
|
|
137
137
|
|
|
138
138
|
---
|
|
139
139
|
|
package/docs/predicates.mdx
CHANGED
|
@@ -60,6 +60,8 @@ Add `"absent": true` to assert something is **gone**. The predicate for a remova
|
|
|
60
60
|
|
|
61
61
|
`contains` is the field the published schema declares. `value` and `text` are accepted as aliases and rewritten to it. `absent: true` asserts the text is not present, and `visible: true` requires it to be on screen rather than merely in the DOM.
|
|
62
62
|
|
|
63
|
+
Use `scope` to restrict the search to a CSS selector or element ref. If Reticle reports that the text is split across the scope's children, retry its generated predicate with `"self": true`; that checks the scope root's combined subtree text while still enforcing `contains`.
|
|
64
|
+
|
|
63
65
|
### net
|
|
64
66
|
|
|
65
67
|
```json
|
package/docs/system-map.md
CHANGED
|
@@ -8,7 +8,7 @@ A tool call crosses five processes and four hops: coding agent → `reticle mcp`
|
|
|
8
8
|
|
|
9
9
|
> How a tool call gets from a coding agent to your app and back, what each hop can do wrong, and which of those failures are **silent**. Written for anyone touching the transport, the daemon, the bridge, or a gate, and for contributors trying to work out where their change lives.
|
|
10
10
|
>
|
|
11
|
-
> Companion pages: [`harness-rules.md`](
|
|
11
|
+
> Companion pages: [`harness-rules.md`](https://github.com/reticlehq/reticle/blob/main/apps/e2e/harness-rules.md) (what a gate must do about all this) and [`telemetry-contract.md`](./telemetry-contract.md) (the rules for anything that emits).
|
|
12
12
|
|
|
13
13
|
## 1. Topology: 5 processes, 4 hops
|
|
14
14
|
|
|
@@ -87,7 +87,7 @@ Two structural facts:
|
|
|
87
87
|
|
|
88
88
|
| Failure | Silent | Guarded by |
|
|
89
89
|
| --- | --- | --- |
|
|
90
|
-
| proxy killed externally (the `lsof -ti` recipe) | **yes, total** | `reticle kill` frees the port and leaves the agent's own proxy alone. See [harness rule 1](
|
|
90
|
+
| proxy killed externally (the `lsof -ti` recipe) | **yes, total** | `reticle kill` frees the port and leaves the agent's own proxy alone. See [harness rule 1](https://github.com/reticlehq/reticle/blob/main/apps/e2e/harness-rules.md) |
|
|
91
91
|
| proxy uncaught exception | no | `installProxyResilience` + `proxyLog` |
|
|
92
92
|
| proxy exits when the reconnect budget is spent | _was the worst bug in the product_ | `onReconnectBudgetSpent` → DORMANT, never exit |
|
|
93
93
|
| client closes stdin with calls in flight | no | `SHUTDOWN_DRAIN_MS` (5s) |
|
|
@@ -152,7 +152,7 @@ Two questions get asked of `verification_completed` constantly and both have exa
|
|
|
152
152
|
**"A large share of verdicts come back `unknown`."** `verified` has three values and the rule that produces it has eleven clauses, so `unknown` on its own is seven different situations belonging to three different owners. **Always break `unknown` down by `verification.reason`** before treating it as a quality number:
|
|
153
153
|
|
|
154
154
|
- `inconclusive`, `nothing_declared`, `vacuous_grade` -- the agent's own call. Teach the agent; the product worked.
|
|
155
|
-
- `outcome_pending`, `outcome_unread`, `unsettled`, `evidence_incomplete` -- the app had not finished. Wait and re-check; often a budget that ended early.
|
|
155
|
+
- `outcome_pending`, `outcome_unread`, `unsettled`, `evidence_incomplete`, `window_closed_early` -- the app had not finished. Wait and re-check; often a budget that ended early.
|
|
156
156
|
- `observation_lost`, `unclean_capture`, `absence_blind_spot` -- **ours**. Ship a fix. `uncleanLoss` names which of the three owners inside that one.
|
|
157
157
|
|
|
158
158
|
An `unknown` rate quoted without this split is a number about all three at once and actionable by none of them.
|
|
@@ -188,7 +188,7 @@ Four counters and one flag were added because the data could not answer question
|
|
|
188
188
|
| `endedWithVerdict` | session summary (final only) | did this session ever produce a verdict. The headline metric, and previously the only thing in the payload that had to be COMPUTED, from lifetime counters sitting next to windowed ones, which is a subtraction that gets read wrong. Sent as `false` rather than omitted: a session that drove an app and never asked whether it worked is the finding. |
|
|
189
189
|
| `verification.browser` | `verification_completed` | `headless` \| `headed` \| `attached`: who DROVE the browser. `attached` (Reticle launched nothing, the SDK connected from a browser somebody else opened) is the common case in production, so on its own this is mostly "somebody's own browser". |
|
|
190
190
|
| `verification.brand` | `verification_completed` | WHICH browser it was: `chrome` \| `edge` \| `arc` \| `dia` \| `brave` \| `opera` \| `firefox` \| `safari` \| `other`, the closed `BrowserBrand` list in core. The axis `engine` cannot answer, since Chrome, Edge, Arc, Dia and Brave are all `blink`. The SDK reads `navigator.userAgentData.brands` (and the UA string on Firefox/Safari, which expose no `userAgentData`) and normalises IN THE PAGE: a raw brand or UA string is unbounded and fingerprintable and never leaves. Anything unrecognised is `other`. **Omitted rather than `"unknown"`** when the page did not say. A desktop webview has no brand and an older SDK does not report one, and a guess is indistinguishable from a measurement on a dashboard. |
|
|
191
|
-
| `verification.reason` | `verification_completed` | WHICH clause of `decideVerified` produced the verdict, from core's closed `VerifiedReason`: `inconclusive` \| `observation_lost` \| `assertion_failed` \| `contradicted` \| `already_true` \| `unclean_capture` \| `vacuous_grade` \| `outcome_pending` \| `outcome_unread` \| `unsettled` (the page never went idle and no consequence was declared) \| `evidence_incomplete` (the assertion held, but a channel's outcome had not arrived when the window closed) \| `proved`. See below. |
|
|
191
|
+
| `verification.reason` | `verification_completed` | WHICH clause of `decideVerified` produced the verdict, from core's closed `VerifiedReason`: `inconclusive` \| `observation_lost` \| `window_closed_early` \| `assertion_failed` \| `contradicted` \| `already_true` \| `unclean_capture` \| `vacuous_grade` \| `outcome_pending` \| `outcome_unread` \| `unsettled` (the page never went idle and no consequence was declared) \| `evidence_incomplete` (the assertion held, but a channel's outcome had not arrived when the window closed) \| `proved`. See below. |
|
|
192
192
|
| `verification.uncleanLoss` | `verification_completed` | WHAT was lost when `reason` is `unclean_capture`, from core's closed `CaptureLoss`: `buffer_loss` (our server ring buffer evicted evidence from the window) \| `transport_gap` (our browser queue overflowed) \| `blind_spot` (a boundary in the page, such as a cross-origin frame or a closed shadow root) \| `other`. Three owners, three fixes, and one bar on a dashboard until this existed. ONE value, not a list: a multi-value property is not something a breakdown can group by, so the first is sent, ours before the page's. **Absent whenever the capture was clean**, so its presence is itself the signal. Reported as `other` rather than omitted when the block says dirty and names nothing: a gap there would read as "no unclean verdicts happened". |
|
|
193
193
|
| `project.stackUnknownReason` | `project_profiled` | WHY there is no `stack`, from core's closed `StackUnknownReason`: `no_app_found` \| `manifest_unrecognised` (we READ an app's manifest and knew nothing in it, which one line in `STACK_BY_DEP` fixes) \| `workspace_apps_unrecognised` \| `workspace_root_no_apps` (a monorepo root where discovery surfaced no app at all) \| `discovery_failed`. `stack` unknown is one of the largest buckets and an empty field is not a cause: it collapsed four facts with four different fixes. **Absent whenever a stack WAS found**, so its presence marks the unknown bucket. Note `workspace_root_no_apps` is expected to dominate over `workspace_apps_unrecognised`: `findWorkspaceApps` admits a directory only on a Vite/Next config file or a literal `next`/`vite` dependency, so a workspace app on any other framework is never surfaced and its manifest is never read. |
|
|
194
194
|
| `bug.attribution` | `bug_found` | `app` \| `request` \| `reticle`: whose fault the defect was. **Absent means unclassified**, never `app`. See below. |
|
|
@@ -361,8 +361,8 @@ One deliberate exception to the rules above: `RETICLE_TELEMETRY_FILE` keeps tele
|
|
|
361
361
|
|
|
362
362
|
| You are adding | Do this | Enforced by |
|
|
363
363
|
| --- | --- | --- |
|
|
364
|
-
| **A tool** | Add it to `TOOLS`. Nothing else. If its name implies a verdict (`assert`/`verify`), also add it to `
|
|
365
|
-
| **A verdict-producing tool** | Add it to `
|
|
364
|
+
| **A tool** | Add it to `TOOLS`. Nothing else. If its name implies a verdict (`assert`/`verify`), also add it to `VERDICT_TOOLS` | `telemetry-contract.test.ts` |
|
|
365
|
+
| **A verdict-producing tool** | Add it to `VERDICT_TOOLS` (`packages/server/src/tools/feedback-tools.ts`). Otherwise it emits no `verification_completed` and stops counting toward the product's headline metric | ✓ |
|
|
366
366
|
| **A contradiction / anomaly kind** | Add it to core's enum only. `bug-found.ts` derives from it | ✓ |
|
|
367
367
|
| **A new finding shape** in a tool result | Teach `bugsInResult` the field. Add a case to the contract test | ✓ |
|
|
368
368
|
| **A failure path** (connect, install, crash) | Classify it into an enum with an explicit `OTHER` bucket; a classifier that cannot say "I don't know" lies instead | ✓ |
|
|
@@ -427,7 +427,7 @@ Read [`docs/telemetry-contract.md`](/telemetry-contract) before you touch anythi
|
|
|
427
427
|
3. Add the payload key to `TelemetryEventSchema`.
|
|
428
428
|
4. Add it to the emitter's key allowlist, or it will be silently dropped.
|
|
429
429
|
5. Decide whether it is session-scoped and add it to `SESSION_SCOPED` if so.
|
|
430
|
-
6. If it produces a verdict, add the tool to `
|
|
430
|
+
6. If it produces a verdict, add the tool to `VERDICT_TOOLS` (`packages/server/src/tools/feedback-tools.ts`). If it introduces a finding kind, add that to core's enum and never re-list it locally.
|
|
431
431
|
|
|
432
432
|
`telemetry-contract.test.ts` enforces the parts that can be enforced, and `pnpm test:e2e` runs a spec that fires every event kind against a real capture endpoint and asserts each one lands.
|
|
433
433
|
|
package/docs/telemetry.md
CHANGED
|
@@ -45,7 +45,7 @@ Eighteen kinds of events, each a single small JSON object. This is the whole lis
|
|
|
45
45
|
|
|
46
46
|
**There is no per-tool-call event.** Tool usage is counted in memory and leaves once, inside `daemon_stopped`, as a histogram like `{"reticle_act": 40, "reticle_assert": 12}`. That is counts of tool NAMES from a fixed list we define, never arguments, results, selectors, or URLs.
|
|
47
47
|
|
|
48
|
-
**Parameter and flag NAMES are collected; their VALUES are not.** We record that `reticle_act` was called with `ref` and `action`, and that you ran `reticle serve --headed --port`. We do not record what you set them to. This distinction is the whole safety property, and it is absolute for CLI flags: `--http-token` holds a secret, `--drive` holds a URL, `--storage-state` holds a file path, so no flag value is ever sent. For tool parameters there is one narrow exception: a short, explicit allowlist of parameters whose values are enums _we_ defined (`action: "click"`), listed in [`argument-shape.ts`](
|
|
48
|
+
**Parameter and flag NAMES are collected; their VALUES are not.** We record that `reticle_act` was called with `ref` and `action`, and that you ran `reticle serve --headed --port`. We do not record what you set them to. This distinction is the whole safety property, and it is absolute for CLI flags: `--http-token` holds a secret, `--drive` holds a URL, `--storage-state` holds a file path, so no flag value is ever sent. For tool parameters there is one narrow exception: a short, explicit allowlist of parameters whose values are enums _we_ defined (`action: "click"`), listed in [`argument-shape.ts`](https://github.com/reticlehq/reticle/blob/main/packages/server/src/telemetry/argument-shape.ts). A value outside that allowlist reports as `other`, so a future schema change cannot quietly start forwarding free text. `reticle_act`'s `args` (the text being typed into your app, which on a login form is a password) is **never** in that allowlist.
|
|
49
49
|
|
|
50
50
|
`daemon_stopped` carries: how long the session ran, how many tool calls and of which tools, how long each tool took (total and worst case), how many failed, how many verifications ran, browser/lease connection attempts with their failure causes, and which MCP clients connected (`claude-code`, `cursor`).
|
|
51
51
|
|
|
@@ -53,7 +53,7 @@ It also carries a snapshot of the **machine's** state (our own process's memory,
|
|
|
53
53
|
|
|
54
54
|
### Why a verdict came out that way
|
|
55
55
|
|
|
56
|
-
`verification_completed` carries the **clause** that decided the verdict, from a fixed list we define: `proved`, `contradicted`, `assertion_failed`, `already_true`, `unclean_capture`, `vacuous_grade`, `outcome_pending`, `outcome_unread`, `unsettled`, `evidence_incomplete`, `observation_lost`, `inconclusive`.
|
|
56
|
+
`verification_completed` carries the **clause** that decided the verdict, from a fixed list we define: `proved`, `contradicted`, `assertion_failed`, `already_true`, `unclean_capture`, `vacuous_grade`, `outcome_pending`, `outcome_unread`, `unsettled`, `evidence_incomplete`, `observation_lost`, `window_closed_early`, `inconclusive`.
|
|
57
57
|
|
|
58
58
|
It exists because `verified: "unknown"` covered seven different situations belonging to three different owners (your app, your agent, and Reticle's own blind spots), and they arrived as one value. It is a **name from our own vocabulary**, never a description of your app: `contradicted` says two channels disagreed, not which ones, about what, or on which page.
|
|
59
59
|
|
|
@@ -127,7 +127,7 @@ Reticle verifies apps for AI agents, and for a long time it had no way to hear w
|
|
|
127
127
|
|
|
128
128
|
Agents are instructed, in the tool description itself, never to include app source, secrets, or user data, and to describe the failure in their own words instead.
|
|
129
129
|
|
|
130
|
-
**It is redacted before it leaves your machine.** Emails, credentials in URLs, `Authorization` headers and API-key assignments, recognizable vendor tokens (`sk-…`, `ghp_…`, `AKIA…`, `xoxb-…`, JWTs), and home-directory paths are stripped and replaced with `[redacted]`. This runs client-side, in [`feedback.ts`](
|
|
130
|
+
**It is redacted before it leaves your machine.** Emails, credentials in URLs, `Authorization` headers and API-key assignments, recognizable vendor tokens (`sk-…`, `ghp_…`, `AKIA…`, `xoxb-…`, JWTs), and home-directory paths are stripped and replaced with `[redacted]`. This runs client-side, in [`feedback.ts`](https://github.com/reticlehq/reticle/blob/main/packages/server/src/telemetry/feedback.ts), so you can read exactly what it removes rather than take our word for it. It is a safety net, not a guarantee: it cannot catch a secret that looks like an ordinary sentence, which is why the instruction above comes first.
|
|
131
131
|
|
|
132
132
|
**It shows you what it sends.** `reticle feedback` prints the exact payload before transmitting, and names any redaction rule that fired.
|
|
133
133
|
|
package/docs/tools-navigate.mdx
CHANGED
|
@@ -17,13 +17,14 @@ Real response, with the throttled-tab `session` and `warning` fields trimmed off
|
|
|
17
17
|
"ok": true,
|
|
18
18
|
"url": "http://localhost:4310/deployments",
|
|
19
19
|
"confirmed": false,
|
|
20
|
-
"
|
|
20
|
+
"waitedMs": 5000,
|
|
21
|
+
"note": "ok means the navigation was DISPATCHED, not that the page arrived. The SDK is torn down by the navigation itself, so nothing here can see the new document, and no session reconnected at the new URL within 5000ms. A slow app may still be on its way (an SPA reattaching under HMR can take 30-60s): navigate again with a larger timeout_ms, or call reticle_sessions to confirm a session reconnected before acting; if none appears, the page did not load or is not instrumented."
|
|
21
22
|
}
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
## `confirmed: true` when the page comes back in time
|
|
25
26
|
|
|
26
|
-
The daemon waits
|
|
27
|
+
The daemon waits up to `timeout_ms` (default 5000) for the SDK to re-announce itself. When it does, you are told so and can act immediately without a `reticle_sessions` round trip. This is a real reload response:
|
|
27
28
|
|
|
28
29
|
```json
|
|
29
30
|
{
|
|
@@ -41,6 +42,12 @@ A full navigation destroys the document the SDK was living in. Reticle cannot re
|
|
|
41
42
|
|
|
42
43
|
Most tools would return `ok: true` and let you assume arrival. When the page then fails to load, or loads without instrumentation, you get a confusing cascade of "element not found" errors several calls later, with nothing pointing at the real cause.
|
|
43
44
|
|
|
45
|
+
`waitedMs` says which of two things you are looking at. Reticle stopped waiting at the budget it had, or the page never came back. The first is fixed by asking for more: a single-page app reattaching under HMR has been measured at 30–60s, which no default should wait for on every call, but which the caller who knows the app can grant.
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{ "url": "/deployments", "timeout_ms": 45000 }
|
|
49
|
+
```
|
|
50
|
+
|
|
44
51
|
## The pattern after navigating
|
|
45
52
|
|
|
46
53
|
```json
|
|
@@ -64,11 +71,12 @@ with [`reticle_sessions`](/tools-sessions), and only then snapshot. If no sessio
|
|
|
64
71
|
|
|
65
72
|
## Arguments
|
|
66
73
|
|
|
67
|
-
| Argument | What it does
|
|
68
|
-
|
|
|
69
|
-
| `url`
|
|
74
|
+
| Argument | What it does |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `url` | Where to go. Relative paths work |
|
|
70
77
|
| `reload` | Reload in place instead of navigating |
|
|
71
|
-
| `hard`
|
|
78
|
+
| `hard` | With `reload`, bypass the cache |
|
|
79
|
+
| `timeout_ms` | How long to wait for the page to come back before `confirmed: false`. Default 5000; 0 looks once |
|
|
72
80
|
|
|
73
81
|
## Client-side routing is different
|
|
74
82
|
|
package/docs/usage.md
CHANGED
|
@@ -310,9 +310,9 @@ reticle_session {action:"review"}({ sessionId })
|
|
|
310
310
|
|
|
311
311
|
Each pending mark carries the human note, the element label, the source **`file:line`** (when the framework stamped one), and a ready-to-act `fix` hint. Open the file, apply the fix, then `reticle_session {action:"review"}({ resolve: "m1" })`. The human watching the panel sees **"✓ fixed: …"** land. Reading never consumes a mark, so you can list → fix → verify → resolve. `reticle_sessions` also reports `pendingMarks` so you notice flagged bugs during normal orientation.
|
|
312
312
|
|
|
313
|
-
### `reticle_network_mock`: stub the network for error-state testing
|
|
313
|
+
### `reticle_network_mock`: stub the network for error-state testing
|
|
314
314
|
|
|
315
|
-
On a page Reticle drives (`reticle drive`), make a request return a 500, force it offline, or delay it, so testing error/edge states is one declared rule, no backend changes:
|
|
315
|
+
On a page Reticle drives (`reticle drive`) or a leased Playwright tab (`reticle_lease acquire`), make a request return a 500, force it offline, or delay it, so testing error/edge states is one declared rule, no backend changes:
|
|
316
316
|
|
|
317
317
|
```
|
|
318
318
|
reticle_network_mock({ mocks: [{ urlContains: "/api/pay", method: "POST", status: 500 }] })
|
|
@@ -321,7 +321,7 @@ reticle_network_mock({ mocks: [{ urlContains: "/api/feed", abort: true }] }) /
|
|
|
321
321
|
reticle_network_mock({ clear: true }) // turn mocking off
|
|
322
322
|
```
|
|
323
323
|
|
|
324
|
-
First matching rule wins (`urlContains` + optional case-insensitive `method`). Needs a driven browser; without one it returns a `recommendation` pointing at `reticle drive`.
|
|
324
|
+
First matching rule wins (`urlContains` + optional case-insensitive `method`). Needs a driven or leased browser; without one it returns a `recommendation` pointing at `reticle drive`.
|
|
325
325
|
|
|
326
326
|
### `reticle_viewport`: reproducible visual baselines (driven mode)
|
|
327
327
|
|
|
@@ -597,7 +597,7 @@ export default [
|
|
|
597
597
|
];
|
|
598
598
|
```
|
|
599
599
|
|
|
600
|
-
`mutators` lists the callee names that change state; `signalCallee` (default `['reticleSignal', 'signal']`) is the name that counts as firing a signal. See [`packages/eslint-plugin/README.md`](
|
|
600
|
+
`mutators` lists the callee names that change state; `signalCallee` (default `['reticleSignal', 'signal']`) is the name that counts as firing a signal. See [`packages/eslint-plugin/README.md`](https://github.com/reticlehq/reticle/blob/main/packages/eslint-plugin/README.md) for scoping and matching details.
|
|
601
601
|
|
|
602
602
|
---
|
|
603
603
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reticlehq/server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "Reticle bridge + MCP server. Hosts the browser WS endpoint and exposes MCP tools to the coding agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"reticle": "./
|
|
9
|
+
"reticle": "./bin/reticle.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
23
23
|
"ws": "^8.21.3",
|
|
24
24
|
"zod": "^3.24.1",
|
|
25
|
-
"@reticlehq/core": "2.
|
|
25
|
+
"@reticlehq/core": "2.14.0",
|
|
26
|
+
"@reticlehq/init": "2.14.0"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@types/pngjs": "^6.0.5",
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
"homepage": "https://github.com/reticlehq/reticle#readme",
|
|
45
46
|
"bugs": "https://github.com/reticlehq/reticle/issues",
|
|
46
47
|
"files": [
|
|
48
|
+
"bin",
|
|
47
49
|
"dist",
|
|
48
50
|
"README.md",
|
|
49
51
|
"LICENSE-ENTERPRISE",
|
|
@@ -71,7 +73,8 @@
|
|
|
71
73
|
"dev": "tsc -b --watch",
|
|
72
74
|
"typecheck": "tsc -b",
|
|
73
75
|
"lint": "eslint src",
|
|
74
|
-
"test:unit": "
|
|
76
|
+
"test:unit": "node ../../scripts/guard-tests.mjs unit",
|
|
77
|
+
"test:guards": "node ../../scripts/guard-tests.mjs guards",
|
|
75
78
|
"test:coverage": "vitest run src --passWithNoTests --coverage.enabled --coverage.provider=v8 --coverage.reporter=text-summary --coverage.include='src/**/*.ts' --coverage.exclude='src/**/*.test.ts'"
|
|
76
79
|
}
|
|
77
80
|
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `reticle init` writes a behavioral rule into the coding agent's instruction file so the agent
|
|
3
|
-
* VERIFIES a feature with Reticle after building it — not only when the user remembers to say "test
|
|
4
|
-
* it with reticle". Registering the MCP server (mcp.ts / mcp-clients.ts) only makes the tools AVAILABLE;
|
|
5
|
-
* this is the piece that makes the agent reach for them, every session, unprompted.
|
|
6
|
-
*
|
|
7
|
-
* It carries a SECOND standing instruction, and that one is not about this project at all: send
|
|
8
|
-
* feedback to the Reticle maintainers, from the moment instrumentation starts. The agent is the party
|
|
9
|
-
* that experiences Reticle, and the only one who can say what it cost — and by the time anyone would
|
|
10
|
-
* think to ask, the context that knew is gone. Written into the same block, because the moment the
|
|
11
|
-
* rule lands (init, before any framework wiring) is the moment the setup itself is being lived
|
|
12
|
-
* through, which is when the reports we hear least about are actually generated.
|
|
13
|
-
*
|
|
14
|
-
* The rule is framed as a definition-of-done (WHEN to verify, HOW, and the anti-reward-hacking guard),
|
|
15
|
-
* written into whichever instruction file the detected agent reads: `CLAUDE.md` (Claude Code),
|
|
16
|
-
* `.cursor/rules/reticle.mdc` (Cursor, `alwaysApply` so it stays in context), or `AGENTS.md` as the
|
|
17
|
-
* cross-agent fallback. Idempotent via a marker block — safe to append to an existing file and a
|
|
18
|
-
* re-run is a no-op. Mirrors the apply/already result shape used across init (see mcp-clients.ts).
|
|
19
|
-
*/
|
|
20
|
-
/** Project-root instruction files the agent re-reads every session. */
|
|
21
|
-
export declare const CLAUDE_MD_PATH = "CLAUDE.md";
|
|
22
|
-
export declare const AGENTS_MD_PATH = "AGENTS.md";
|
|
23
|
-
/**
|
|
24
|
-
* The full rules, written once and pointed at from every always-loaded file.
|
|
25
|
-
*
|
|
26
|
-
* Two problems it solves at the same time. The rule text is dense and most of it is REFERENCE (what
|
|
27
|
-
* to do when the tools are missing, what a `version_skew` field means, how to file feedback), which
|
|
28
|
-
* an agent needs on the turn it hits that situation and never before — so carrying all of it in
|
|
29
|
-
* `CLAUDE.md` taxed every session for text almost every session did not read. And `AGENTS.md` was
|
|
30
|
-
* only written when NO agent was detected, so a repo set up on a Claude Code machine told Codex,
|
|
31
|
-
* Copilot, Amp and every other agent nothing at all.
|
|
32
|
-
*
|
|
33
|
-
* So: the operative rules (when to verify, WHEN NOT TO, how, and the honesty guards) go in the files
|
|
34
|
-
* that load every turn, and this file holds the rest, one hop away and named in that block.
|
|
35
|
-
*/
|
|
36
|
-
export declare const RETICLE_MD_PATH = "RETICLE.md";
|
|
37
|
-
/** Cursor project rule; the frontmatter `alwaysApply` keeps it in context on every turn. */
|
|
38
|
-
export declare const CURSOR_RULE_PATH = ".cursor/rules/reticle.mdc";
|
|
39
|
-
/**
|
|
40
|
-
* Does this file already carry the managed block?
|
|
41
|
-
*
|
|
42
|
-
* Exported so callers cannot invent their own looser test. The begin marker carries explanatory
|
|
43
|
-
* text inside the comment, so a substring check for `reticle:begin` matches files that
|
|
44
|
-
* `mergeMarkedInstruction` would treat as having NO block — and the two disagreeing means a refresh
|
|
45
|
-
* silently appends a second copy instead of updating the first.
|
|
46
|
-
*/
|
|
47
|
-
export declare function hasManagedBlock(text: string): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* How the agent must INVOKE the CLI.
|
|
50
|
-
*
|
|
51
|
-
* `reticle init` installs the SDK packages, never the server — so there is no `reticle` on the
|
|
52
|
-
* agent's PATH, and every bare `reticle <cmd>` this rule named was an instruction that could not be
|
|
53
|
-
* followed. Reported from a field sweep: three of them, in the file the agent re-reads every session.
|
|
54
|
-
*
|
|
55
|
-
* `npx @reticlehq/server` is the same invocation the MCP registration uses, and it is derived from
|
|
56
|
-
* the package's own name so the two can never drift apart.
|
|
57
|
-
*/
|
|
58
|
-
export declare const CLI: string;
|
|
59
|
-
/**
|
|
60
|
-
* Who starts the dev server, stated once and rendered everywhere it is needed.
|
|
61
|
-
*
|
|
62
|
-
* The old rule was "Reticle never starts the dev server for you — that's your job", and agents obeyed
|
|
63
|
-
* it exactly: they read it, declined to start anything, and ended the turn with nothing verified. An
|
|
64
|
-
* instruction that reliably produces no verification is a defect in the instruction.
|
|
65
|
-
*
|
|
66
|
-
* The AGENT starts it, not the daemon. A daemon that spawns a build process is invisible to the
|
|
67
|
-
* person whose machine it is running on, was never consented to, and orphans when the daemon exits.
|
|
68
|
-
* The agent already has shell access in this repo, already runs install and build commands, and runs
|
|
69
|
-
* inside a host that asks the human for permission — so a dev server it starts is visible in the
|
|
70
|
-
* transcript, attributable, and stoppable.
|
|
71
|
-
*
|
|
72
|
-
* The guards are the whole reason this is safe, so no renderer may drop them: one server at a time,
|
|
73
|
-
* read the command rather than invent one, never kill anything you did not start, and leave the
|
|
74
|
-
* permission prompt to the host. "Background it and say so" is no longer among them because the
|
|
75
|
-
* branch above now states it at the point of action, and this text is read every turn — a rule
|
|
76
|
-
* stated twice costs every agent tokens forever and is the first thing to drift.
|
|
77
|
-
*
|
|
78
|
-
* The RESTART branch outranks the rest and is stated first. It used to be an aside, while "if a dev
|
|
79
|
-
* server is already listening, use it" was a numbered guard — so an agent resolving the two
|
|
80
|
-
* reasonably reused a server started before `init` edited the build config, served a bundle with no
|
|
81
|
-
* SDK in it, and landed on an empty session list with every other step done correctly.
|
|
82
|
-
*
|
|
83
|
-
* Exported because slash-command.ts renders the same rule; there must not be two versions of it.
|
|
84
|
-
*/
|
|
85
|
-
export declare const DEV_SERVER_POLICY = "**A dev server already running when `reticle init` ran does not have Reticle in its bundle.** It read the build config at boot; `init` edited it afterwards. It serves the old bundle and no session appears. In order:\n\n1. **A dev server was already running?** Restart it, then hard-reload the tab. \"Something is listening\" does not mean the right bundle is served.\n2. **Nothing was running?** Start it in the BACKGROUND and say so in one line. `reticle_sessions` gives you this project's own dev command in `next_action`; use that, never compose one. Started after `init`, it needs no restart.\n\nStopping to ask is how a verification turn ends with nothing verified.\n\nFour guards, none optional:\n\n1. **Never run two at once.** One dev server on the app's port. Restarting a stale one means stopping it first, not starting a second alongside it.\n2. **Never guess the command.** It comes from `package.json` scripts. No recognisable dev script means say so and stop, not invent one.\n3. **Never kill anything you did not start**, and never a daemon or a port holder. The one exception is the restart above, and say in one line that you did it.\n4. **The permission prompt belongs to your host.** Never bypass, suppress or auto-approve it, and take a refusal as the answer.";
|
|
86
|
-
/**
|
|
87
|
-
* The operative rules, carried by every file that loads on every turn.
|
|
88
|
-
*
|
|
89
|
-
* Short on purpose. This is the text that has to CHANGE BEHAVIOUR, so it states when to verify, when
|
|
90
|
-
* NOT to, how, and the guards against calling something proven when it is not. Everything an agent
|
|
91
|
-
* needs only at the moment it hits a specific situation lives in RETICLE.md, named at the end.
|
|
92
|
-
*/
|
|
93
|
-
export declare const RULE_BODY: string;
|
|
94
|
-
/** The full-rules file, written verbatim (no markers: `init` owns this file entirely). */
|
|
95
|
-
export declare function reticleMdFile(): string;
|
|
96
|
-
export declare const AgentRuleStatus: {
|
|
97
|
-
readonly APPLY: "apply";
|
|
98
|
-
readonly ALREADY: "already";
|
|
99
|
-
};
|
|
100
|
-
export type AgentRuleStatus = (typeof AgentRuleStatus)[keyof typeof AgentRuleStatus];
|
|
101
|
-
interface AgentRuleResult {
|
|
102
|
-
status: AgentRuleStatus;
|
|
103
|
-
/** Full file content to write when status is APPLY; the unchanged input otherwise. */
|
|
104
|
-
content: string;
|
|
105
|
-
}
|
|
106
|
-
/** The marker-wrapped block appended to a CLAUDE.md / AGENTS.md instruction file. */
|
|
107
|
-
export declare function markedBlock(): string;
|
|
108
|
-
/**
|
|
109
|
-
* Merge the managed block into a marker-delimited instruction file. Already present ⇒ no change
|
|
110
|
-
* (idempotent re-run). Absent/empty ⇒ the block alone. Otherwise append the block, preserving the
|
|
111
|
-
* existing content and a clean separating blank line.
|
|
112
|
-
*/
|
|
113
|
-
export declare function mergeMarkedInstruction(existing: string | null | undefined): AgentRuleResult;
|
|
114
|
-
/** The Cursor rule file (.mdc): `alwaysApply` keeps the rule in every turn's context. */
|
|
115
|
-
export declare function cursorRuleFile(): string;
|
|
116
|
-
export {};
|