@reticlehq/server 2.11.0 → 2.13.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 +93 -111
- package/dist/bridge/auth-failure-reason.d.ts +6 -2
- package/dist/bridge/auth-failure-reason.js +15 -8
- package/dist/bridge/bridge.d.ts +18 -14
- package/dist/bridge/bridge.js +248 -165
- package/dist/bridge/bridge.test-harness.d.ts +2 -0
- package/dist/bridge/bridge.test-harness.js +8 -1
- package/dist/bridge/pairing-token.d.ts +5 -0
- package/dist/bridge/pairing-token.js +28 -0
- package/dist/bridge/protocol-skew.d.ts +37 -0
- package/dist/bridge/protocol-skew.js +45 -0
- package/dist/capsule/capsule-store.d.ts +8 -7
- package/dist/capsule/capsule-store.js +1 -1
- package/dist/capsule/causal-summary.d.ts +2 -2
- package/dist/capsule/causal-summary.js +7 -2
- package/dist/chromium-launch-options.d.ts +28 -0
- package/dist/chromium-launch-options.js +29 -0
- package/dist/cli/cli-doctor.js +39 -1
- package/dist/cli/cli-flow-commands.d.ts +3 -1
- package/dist/cli/cli-flow-commands.js +34 -4
- package/dist/cli/cli-kill.d.ts +2 -1
- package/dist/cli/cli-launch.d.ts +11 -1
- package/dist/cli/cli-launch.js +59 -10
- package/dist/cli/cli-parse.d.ts +17 -1
- package/dist/cli/cli-parse.js +238 -12
- package/dist/cli/cli-update-commands.js +20 -1
- package/dist/cli/cli-verify.d.ts +2 -1
- package/dist/cli/cli-verify.js +5 -4
- package/dist/cli/cloud-cli.js +428 -253
- package/dist/cli/cloud-keystore.d.ts +37 -0
- package/dist/cli/cloud-keystore.js +97 -0
- package/dist/cli/cloud-kit.d.ts +37 -0
- package/dist/cli/cloud-kit.js +121 -0
- package/dist/cli/cloud-login.d.ts +17 -0
- package/dist/cli/cloud-login.js +183 -0
- package/dist/cli/cloud-session.d.ts +48 -0
- package/dist/cli/cloud-session.js +53 -0
- package/dist/cli/config-discovery.d.ts +2 -1
- package/dist/cli/config-discovery.js +1 -0
- package/dist/cli/daemon-start-options.d.ts +32 -0
- package/dist/cli/daemon-start-options.js +38 -0
- package/dist/cli/device-flow.d.ts +76 -0
- package/dist/cli/device-flow.js +56 -0
- package/dist/cli/doctor-rows.d.ts +12 -1
- package/dist/cli/doctor-rows.js +12 -1
- package/dist/cli/drive-attach.d.ts +13 -0
- package/dist/cli/drive-attach.js +18 -0
- package/dist/cli/drive-command.js +7 -3
- package/dist/cli/gate-exit.d.ts +21 -0
- package/dist/cli/gate-exit.js +21 -0
- package/dist/cli/gate-hook-message.d.ts +33 -0
- package/dist/cli/gate-hook-message.js +46 -0
- package/dist/cli/mcp-command.d.ts +25 -0
- package/dist/cli/mcp-command.js +174 -0
- package/dist/cli/project-name.d.ts +30 -0
- package/dist/cli/project-name.js +44 -0
- package/dist/cli/sibling-ports.d.ts +37 -0
- package/dist/cli/sibling-ports.js +56 -0
- package/dist/cli/status-next-action.d.ts +14 -0
- package/dist/cli/status-next-action.js +4 -4
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +167 -186
- package/dist/cloud/cloud-config.d.ts +24 -2
- package/dist/cloud/cloud-config.js +64 -5
- package/dist/cloud/cloud-sync.d.ts +16 -5
- package/dist/cloud/cloud-sync.js +64 -1
- package/dist/cloud/sync-cycle.d.ts +110 -0
- package/dist/cloud/sync-cycle.js +270 -0
- package/dist/cloud/sync-daemon.d.ts +69 -0
- package/dist/cloud/sync-daemon.js +260 -0
- package/dist/cloud/sync-disk.d.ts +9 -0
- package/dist/cloud/sync-disk.js +191 -0
- package/dist/cloud/sync-hash.d.ts +2 -0
- package/dist/cloud/sync-hash.js +35 -0
- package/dist/crawl/crawl-tools.js +5 -3
- package/dist/crawl/crawl.d.ts +12 -13
- package/dist/crawl/crawl.js +25 -3
- package/dist/daemon/daemon-resolve.d.ts +122 -0
- package/dist/daemon/daemon-resolve.js +187 -0
- package/dist/daemon/dev-servers.d.ts +15 -0
- package/dist/daemon/dev-servers.js +68 -0
- package/dist/daemon/free-port.d.ts +29 -0
- package/dist/daemon/free-port.js +55 -0
- package/dist/daemon/heartbeat.d.ts +0 -4
- package/dist/daemon/heartbeat.js +2 -2
- package/dist/daemon/wake-decision.d.ts +32 -0
- package/dist/daemon/wake-decision.js +38 -0
- package/dist/dev/stale-issue-guard.d.ts +0 -2
- package/dist/dev/stale-issue-guard.js +1 -1
- package/dist/domain/domain-tools.js +2 -2
- package/dist/events/contradictions.d.ts +59 -0
- package/dist/events/contradictions.js +253 -27
- package/dist/events/declared.d.ts +17 -0
- package/dist/events/declared.js +43 -1
- package/dist/events/echo-mismatch.js +65 -1
- package/dist/events/event-filters.d.ts +8 -0
- package/dist/events/event-filters.js +19 -2
- package/dist/events/observed-in-window.d.ts +12 -0
- package/dist/events/observed-in-window.js +17 -0
- package/dist/events/predicate-asks.d.ts +13 -0
- package/dist/events/predicate-asks.js +22 -0
- package/dist/events/predicate-eval.js +117 -27
- package/dist/events/predicate-parse.d.ts +0 -6
- package/dist/events/predicate-parse.js +43 -3
- package/dist/events/predicate-precheck.d.ts +8 -0
- package/dist/events/predicate-precheck.js +41 -0
- package/dist/events/predicate-route.d.ts +14 -0
- package/dist/events/predicate-route.js +36 -8
- package/dist/events/predicate-schema.d.ts +44 -0
- package/dist/events/predicate-schema.js +126 -23
- package/dist/events/predicate.d.ts +20 -0
- package/dist/events/predicate.js +77 -6
- package/dist/events/split-text-miss.d.ts +30 -0
- package/dist/events/split-text-miss.js +44 -0
- package/dist/flows/coverage.d.ts +0 -8
- package/dist/flows/coverage.js +1 -1
- package/dist/flows/decision.d.ts +5 -1
- package/dist/flows/decision.js +33 -7
- package/dist/flows/flake.d.ts +6 -8
- package/dist/flows/flake.js +1 -1
- package/dist/flows/flow-intent.d.ts +52 -0
- package/dist/flows/flow-intent.js +123 -0
- package/dist/flows/flow-memory-consult.d.ts +55 -0
- package/dist/flows/flow-memory-consult.js +38 -0
- package/dist/flows/flow-replay-run.d.ts +18 -7
- package/dist/flows/flow-replay-run.js +263 -23
- package/dist/flows/flow-replay.js +11 -2
- package/dist/flows/flow-step-runners.d.ts +8 -0
- package/dist/flows/flow-step-runners.js +8 -2
- package/dist/flows/flow-store-for-session.d.ts +31 -0
- package/dist/flows/flow-store-for-session.js +33 -0
- package/dist/flows/flow-success.js +15 -3
- package/dist/flows/flow-tools.js +87 -33
- package/dist/flows/flows.d.ts +14 -1
- package/dist/flows/flows.js +502 -24
- package/dist/flows/heal-run.js +5 -2
- package/dist/flows/predicate-to-expect.d.ts +17 -12
- package/dist/flows/predicate-to-expect.js +36 -15
- package/dist/flows/recordings.d.ts +13 -1
- package/dist/flows/recordings.js +17 -2
- package/dist/flows/replay.d.ts +22 -2
- package/dist/flows/replay.js +28 -2
- package/dist/flows/server-verify.js +16 -2
- package/dist/flows/verify-change-tools.js +9 -3
- package/dist/honesty/blind-spots.d.ts +51 -15
- package/dist/honesty/blind-spots.js +64 -4
- package/dist/honesty/feature-capture.d.ts +150 -0
- package/dist/honesty/feature-capture.js +233 -0
- package/dist/honesty/honesty.d.ts +24 -0
- package/dist/honesty/honesty.js +25 -1
- package/dist/honesty/instrumentation-gaps.d.ts +39 -6
- package/dist/honesty/instrumentation-gaps.js +88 -5
- package/dist/honesty/tool-hit-rate.d.ts +86 -0
- package/dist/honesty/tool-hit-rate.js +90 -0
- package/dist/honesty/undeclared-change.d.ts +51 -0
- package/dist/honesty/undeclared-change.js +56 -0
- package/dist/honesty/verified.d.ts +16 -0
- package/dist/honesty/verified.js +84 -5
- package/dist/http-server.d.ts +0 -1
- package/dist/http-server.js +13 -1
- package/dist/hunt/hunt-report.d.ts +0 -2
- package/dist/hunt/hunt-report.js +1 -1
- package/dist/impact/impact-recorder.d.ts +31 -8
- package/dist/impact/impact-recorder.js +104 -21
- package/dist/impact/impact-store.d.ts +13 -4
- package/dist/impact/impact-store.js +44 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.js +113 -7
- package/dist/init/agent-rules.d.ts +30 -6
- package/dist/init/agent-rules.js +54 -13
- package/dist/init/astro-patch.d.ts +16 -0
- package/dist/init/astro-patch.js +28 -0
- package/dist/init/capabilities.d.ts +4 -3
- package/dist/init/capabilities.js +23 -3
- package/dist/init/closing-hint.d.ts +36 -0
- package/dist/init/closing-hint.js +120 -0
- package/dist/init/confirm.d.ts +27 -28
- package/dist/init/confirm.js +51 -11
- package/dist/init/cra.d.ts +34 -5
- package/dist/init/cra.js +96 -25
- package/dist/init/csp-check.js +17 -2
- package/dist/init/csp-doctor.d.ts +8 -1
- package/dist/init/csp-doctor.js +8 -3
- package/dist/init/dev-script.d.ts +50 -0
- package/dist/init/dev-script.js +66 -0
- package/dist/init/format-generated.d.ts +18 -0
- package/dist/init/format-generated.js +39 -0
- package/dist/init/install-hint.d.ts +9 -0
- package/dist/init/install-hint.js +29 -0
- package/dist/init/mcp-clients.d.ts +7 -0
- package/dist/init/mcp-clients.js +7 -0
- package/dist/init/mcp.d.ts +17 -6
- package/dist/init/mcp.js +27 -11
- package/dist/init/node-io.js +11 -1
- package/dist/init/plan-framework.d.ts +0 -5
- package/dist/init/plan-framework.js +147 -37
- package/dist/init/plan.d.ts +30 -37
- package/dist/init/plan.js +50 -60
- package/dist/init/preflight.d.ts +28 -0
- package/dist/init/preflight.js +38 -0
- package/dist/init/refresh-rules.d.ts +39 -0
- package/dist/init/refresh-rules.js +51 -0
- package/dist/init/run.d.ts +32 -35
- package/dist/init/run.js +151 -202
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/snippets.js +90 -31
- package/dist/init/vite-config.d.ts +1 -1
- package/dist/init/vite-config.js +39 -25
- package/dist/init/workspace-apps.d.ts +17 -10
- package/dist/init/workspace-apps.js +110 -0
- package/dist/input/network-mock-tools.js +3 -6
- package/dist/input/real-input.d.ts +2 -0
- package/dist/input/real-input.js +28 -7
- package/dist/input/scroll-find.d.ts +7 -4
- package/dist/input/scroll-find.js +63 -25
- package/dist/input/scroll-tools.js +4 -6
- package/dist/input/viewport-tools.js +5 -4
- package/dist/intent/inline-intent.d.ts +37 -0
- package/dist/intent/inline-intent.js +193 -0
- package/dist/intent/intent-shard-store.d.ts +72 -0
- package/dist/intent/intent-shard-store.js +203 -0
- package/dist/intent/intent-shard.d.ts +411 -0
- package/dist/intent/intent-shard.js +176 -0
- package/dist/intent/intent-store.d.ts +49 -0
- package/dist/intent/intent-store.js +133 -0
- package/dist/intent/intent-subject.d.ts +45 -0
- package/dist/intent/intent-subject.js +177 -0
- package/dist/intent/intent-tools.d.ts +2 -0
- package/dist/intent/intent-tools.js +143 -0
- package/dist/intent/open-intents.d.ts +42 -0
- package/dist/intent/open-intents.js +40 -0
- package/dist/journal/envelope.d.ts +26 -26
- package/dist/journal/journal-recorder.d.ts +23 -0
- package/dist/journal/journal-recorder.js +35 -0
- package/dist/license/license-env.d.ts +29 -0
- package/dist/license/license-env.js +148 -0
- package/dist/loopback-agent.d.ts +31 -0
- package/dist/loopback-agent.js +57 -0
- package/dist/mcp/attach-memory.d.ts +83 -0
- package/dist/mcp/attach-memory.js +185 -0
- package/dist/mcp/client-identity.d.ts +31 -0
- package/dist/mcp/client-identity.js +51 -0
- package/dist/mcp/mcp-post-transport.d.ts +26 -0
- package/dist/mcp/mcp-post-transport.js +109 -0
- package/dist/mcp/mcp-proxy.d.ts +2 -8
- package/dist/mcp/mcp-proxy.js +64 -62
- package/dist/mcp/mcp.d.ts +2 -0
- package/dist/mcp/mcp.js +52 -24
- package/dist/mcp/proxy-backoff.d.ts +11 -0
- package/dist/mcp/proxy-backoff.js +13 -0
- package/dist/mcp/proxy-daemon-probe.d.ts +1 -0
- package/dist/mcp/proxy-daemon-probe.js +7 -1
- package/dist/mcp/proxy-handshake.d.ts +23 -0
- package/dist/mcp/proxy-handshake.js +31 -0
- package/dist/mcp/server-instructions.js +45 -3
- package/dist/mcp/tool-catalog-cache.d.ts +16 -0
- package/dist/mcp/tool-catalog-cache.js +22 -0
- package/dist/memory/memory-tools.d.ts +2 -0
- package/dist/memory/memory-tools.js +82 -0
- package/dist/memory/project-memory.d.ts +34 -0
- package/dist/memory/project-memory.js +96 -0
- package/dist/oracles/flow-instrument-gaps.d.ts +4 -4
- package/dist/oracles/flow-instrument-gaps.js +4 -5
- package/dist/oracles/propose-consequences.js +12 -3
- package/dist/oracles/self-instrument.d.ts +9 -9
- package/dist/oracles/self-instrument.js +19 -13
- package/dist/pool/browser-pool.d.ts +75 -5
- package/dist/pool/browser-pool.js +144 -5
- package/dist/pool/playwright-launcher.js +12 -1
- package/dist/project/fs-port.d.ts +3 -0
- package/dist/project/fs-port.js +3 -2
- package/dist/project/memory-fs.js +6 -1
- package/dist/project/project-tools.js +6 -35
- package/dist/project/reticle-dir.d.ts +17 -2
- package/dist/project/reticle-dir.js +22 -4
- package/dist/runs/context-tools.d.ts +2 -0
- package/dist/runs/context-tools.js +89 -0
- package/dist/runs/run-context.d.ts +40 -0
- package/dist/runs/run-context.js +158 -0
- package/dist/runs/run-diff.d.ts +2 -1
- package/dist/runs/run-store.d.ts +10 -0
- package/dist/runs/run-store.js +10 -0
- package/dist/runs/verification-sync.d.ts +0 -11
- package/dist/runs/verification-sync.js +24 -3
- package/dist/runs/verify-server.d.ts +8 -1
- package/dist/runs/verify-server.js +14 -2
- package/dist/session/command-timeout.d.ts +5 -2
- package/dist/session/command-timeout.js +5 -4
- package/dist/session/dev-server-probe.d.ts +0 -8
- package/dist/session/dev-server-probe.js +1 -1
- package/dist/session/last-act.d.ts +7 -1
- package/dist/session/last-act.js +2 -2
- package/dist/session/lease-visibility.d.ts +67 -0
- package/dist/session/lease-visibility.js +76 -0
- package/dist/session/live-control-tools.js +1 -42
- package/dist/session/no-session-diagnosis.d.ts +33 -0
- package/dist/session/no-session-diagnosis.js +82 -24
- package/dist/session/no-session-next-action.d.ts +12 -0
- package/dist/session/no-session-next-action.js +77 -6
- package/dist/session/no-session-watch.d.ts +18 -6
- package/dist/session/no-session-watch.js +125 -75
- package/dist/session/output-budget.js +4 -1
- package/dist/session/pending-commands.d.ts +11 -1
- package/dist/session/pending-commands.js +12 -2
- package/dist/session/resolve-within.d.ts +34 -0
- package/dist/session/resolve-within.js +53 -0
- package/dist/session/session-health.d.ts +9 -0
- package/dist/session/session-health.js +23 -0
- package/dist/session/session-info.d.ts +18 -0
- package/dist/session/session-info.js +11 -0
- package/dist/session/session-manager.d.ts +14 -0
- package/dist/session/session-manager.js +111 -4
- package/dist/session/session-mirror.d.ts +16 -0
- package/dist/session/session-mirror.js +22 -0
- package/dist/session/session-recommendation.d.ts +19 -5
- package/dist/session/session-recommendation.js +25 -9
- package/dist/session/session-successor.d.ts +37 -0
- package/dist/session/session-successor.js +113 -0
- package/dist/session/session-tools.js +2 -2
- package/dist/session/session.d.ts +53 -3
- package/dist/session/session.js +162 -9
- package/dist/session/wall-clock.d.ts +12 -0
- package/dist/session/wall-clock.js +14 -0
- package/dist/setup/agent-configs.d.ts +96 -0
- package/dist/setup/agent-configs.js +333 -0
- package/dist/setup/agent-io.d.ts +9 -0
- package/dist/setup/agent-io.js +16 -0
- package/dist/setup/agent-writer.d.ts +51 -0
- package/dist/setup/agent-writer.js +115 -0
- package/dist/setup/approval-migration.d.ts +47 -0
- package/dist/setup/approval-migration.js +68 -0
- package/dist/setup/auto-approve.d.ts +85 -0
- package/dist/setup/auto-approve.js +150 -0
- package/dist/setup/bridge-port.d.ts +15 -0
- package/dist/setup/bridge-port.js +24 -0
- package/dist/setup/desktop-shape.d.ts +57 -0
- package/dist/setup/desktop-shape.js +63 -0
- package/dist/setup/dev-server-wait.d.ts +60 -0
- package/dist/setup/dev-server-wait.js +65 -0
- package/dist/setup/drive-agent.d.ts +71 -0
- package/dist/setup/drive-agent.js +171 -0
- package/dist/setup/drive-plan.d.ts +68 -0
- package/dist/setup/drive-plan.js +130 -0
- package/dist/setup/ensure-daemon.d.ts +29 -0
- package/dist/setup/ensure-daemon.js +58 -0
- package/dist/setup/init-runtime.d.ts +47 -0
- package/dist/setup/init-runtime.js +160 -0
- package/dist/setup/interrupt.d.ts +25 -0
- package/dist/setup/interrupt.js +40 -0
- package/dist/setup/license-key.d.ts +39 -0
- package/dist/setup/license-key.js +72 -0
- package/dist/setup/listeners.d.ts +37 -0
- package/dist/setup/listeners.js +85 -0
- package/dist/setup/node-effects.d.ts +60 -0
- package/dist/setup/node-effects.js +210 -0
- package/dist/setup/page-probe.d.ts +39 -0
- package/dist/setup/page-probe.js +49 -0
- package/dist/setup/relaunch.d.ts +36 -0
- package/dist/setup/relaunch.js +57 -0
- package/dist/setup/remaining-steps.d.ts +19 -0
- package/dist/setup/remaining-steps.js +31 -0
- package/dist/setup/run-setup.d.ts +99 -0
- package/dist/setup/run-setup.js +187 -0
- package/dist/setup/session-pick.d.ts +47 -0
- package/dist/setup/session-pick.js +51 -0
- package/dist/setup/setup-command.d.ts +45 -0
- package/dist/setup/setup-command.js +199 -0
- package/dist/setup/setup-options.d.ts +74 -0
- package/dist/setup/setup-options.js +67 -0
- package/dist/setup/transcripts.d.ts +16 -0
- package/dist/setup/transcripts.js +43 -0
- package/dist/status-payload.d.ts +14 -1
- package/dist/status-payload.js +23 -1
- package/dist/telemetry/automation-hint.d.ts +2 -1
- package/dist/telemetry/daemon-telemetry.d.ts +8 -1
- package/dist/telemetry/daemon-telemetry.js +52 -5
- package/dist/telemetry/error-class.js +1 -1
- package/dist/telemetry/feedback-context.d.ts +9 -1
- package/dist/telemetry/feedback-context.js +60 -29
- package/dist/telemetry/feedback-local.d.ts +15 -0
- package/dist/telemetry/feedback-local.js +56 -0
- package/dist/telemetry/feedback-outbox.d.ts +2 -1
- package/dist/telemetry/feedback.d.ts +11 -0
- package/dist/telemetry/feedback.js +19 -6
- package/dist/telemetry/init-telemetry.d.ts +2 -0
- package/dist/telemetry/init-telemetry.js +2 -0
- package/dist/telemetry/install-source.d.ts +14 -0
- package/dist/telemetry/install-source.js +30 -0
- package/dist/telemetry/license-activation.d.ts +7 -1
- package/dist/telemetry/license-activation.js +9 -5
- package/dist/telemetry/mcp-connection.js +7 -0
- package/dist/telemetry/project-profile.d.ts +12 -9
- package/dist/telemetry/project-profile.js +12 -7
- package/dist/telemetry/proxy-telemetry.d.ts +3 -0
- package/dist/telemetry/proxy-telemetry.js +21 -0
- package/dist/telemetry/run-telemetry.d.ts +0 -2
- package/dist/telemetry/run-telemetry.js +1 -1
- package/dist/telemetry/session-metrics.d.ts +12 -0
- package/dist/telemetry/session-metrics.js +35 -1
- package/dist/telemetry/telemetry.js +17 -2
- package/dist/telemetry/tool-refused.d.ts +3 -1
- package/dist/telemetry/tool-refused.js +34 -2
- package/dist/telemetry/verification-of.js +2 -2
- package/dist/tools/act-capsule.d.ts +10 -0
- package/dist/tools/act-capsule.js +8 -2
- package/dist/tools/act-danger.d.ts +2 -1
- package/dist/tools/act-danger.js +11 -3
- package/dist/tools/act-observation.d.ts +41 -0
- package/dist/tools/act-observation.js +36 -0
- package/dist/tools/act-preflight.d.ts +20 -0
- package/dist/tools/act-preflight.js +98 -0
- package/dist/tools/act-sequence-retry.d.ts +45 -0
- package/dist/tools/act-sequence-retry.js +58 -0
- package/dist/tools/act-sequence-tool.d.ts +13 -0
- package/dist/tools/act-sequence-tool.js +135 -0
- package/dist/tools/act-target.d.ts +14 -0
- package/dist/tools/act-target.js +47 -0
- package/dist/tools/act-tools.d.ts +21 -1
- package/dist/tools/act-tools.js +196 -204
- package/dist/tools/assert-source.d.ts +22 -0
- package/dist/tools/assert-source.js +53 -0
- package/dist/tools/assert-verdict.d.ts +20 -3
- package/dist/tools/assert-verdict.js +58 -20
- package/dist/tools/browser-tools.js +6 -22
- package/dist/tools/complete-snapshot.d.ts +48 -0
- package/dist/tools/complete-snapshot.js +75 -0
- package/dist/tools/coverage-tools.d.ts +10 -1
- package/dist/tools/coverage-tools.js +123 -69
- package/dist/tools/dynamic-tools.js +53 -13
- package/dist/tools/error-recovery.d.ts +25 -14
- package/dist/tools/error-recovery.js +78 -9
- package/dist/tools/feedback-tools.d.ts +1 -1
- package/dist/tools/feedback-tools.js +2 -2
- package/dist/tools/invoke-tool.js +121 -11
- package/dist/tools/lease-hint.d.ts +10 -0
- package/dist/tools/lease-hint.js +53 -4
- package/dist/tools/lease-tools.d.ts +35 -5
- package/dist/tools/lease-tools.js +191 -13
- package/dist/tools/merged-name-redirect.d.ts +13 -0
- package/dist/tools/merged-name-redirect.js +22 -0
- package/dist/tools/navigate-arrival.d.ts +0 -2
- package/dist/tools/navigate-arrival.js +1 -1
- package/dist/tools/numeric-bounds.d.ts +100 -0
- package/dist/tools/numeric-bounds.js +125 -0
- package/dist/tools/observe-tools.js +109 -65
- package/dist/tools/read-tools.js +31 -8
- package/dist/tools/real-input-attempt.d.ts +32 -0
- package/dist/tools/real-input-attempt.js +212 -2
- package/dist/tools/reconcile-tools.js +22 -8
- package/dist/tools/resolve-target.d.ts +0 -7
- package/dist/tools/sdk-marker-probe.d.ts +29 -0
- package/dist/tools/sdk-marker-probe.js +57 -0
- package/dist/tools/snapshot-delta.d.ts +1 -1
- package/dist/tools/tool-kit.d.ts +24 -0
- package/dist/tools/tool-kit.js +21 -0
- package/dist/tools/tool-names.d.ts +5 -0
- package/dist/tools/tool-names.js +5 -0
- package/dist/tools/tool-surface.d.ts +85 -6
- package/dist/tools/tool-surface.js +122 -2
- package/dist/tools/tools-helpers.d.ts +19 -0
- package/dist/tools/tools-helpers.js +46 -0
- package/dist/tools/tools.d.ts +2 -0
- package/dist/tools/tools.js +78 -12
- package/dist/tools/unadvertised-help.js +4 -4
- package/dist/tools/verify-next-baton.d.ts +53 -0
- package/dist/tools/verify-next-baton.js +52 -0
- package/dist/update/reticle-deps.d.ts +9 -0
- package/dist/update/reticle-deps.js +27 -0
- package/dist/update/sdk-sync.d.ts +1 -2
- package/dist/update/sdk-sync.js +1 -21
- package/dist/update/update-nudge.d.ts +25 -10
- package/dist/update/update-nudge.js +32 -3
- package/dist/update/updater.d.ts +1 -1
- package/dist/version/peer-announce.js +4 -2
- package/dist/version/sdk-fix.d.ts +47 -0
- package/dist/version/sdk-fix.js +127 -0
- package/dist/version/version-nudge.d.ts +14 -0
- package/dist/version/version-nudge.js +21 -0
- package/dist/version/version-skew.d.ts +38 -3
- package/dist/version/version-skew.js +83 -7
- package/dist/visual/visual-store.d.ts +6 -6
- package/dist/visual/visual-store.js +18 -16
- package/dist/visual/visual-tools.js +57 -12
- package/docs/README.md +2 -1
- package/docs/cli/cloud.mdx +1 -1
- package/docs/cli/doctor.mdx +2 -0
- package/docs/cli/serve.mdx +4 -2
- package/docs/cli/verify.mdx +4 -5
- package/docs/cli.mdx +7 -3
- package/docs/desktop.mdx +1 -1
- package/docs/docs.json +2 -2
- package/docs/gates.md +1 -1
- package/docs/getting-started.md +19 -3
- package/docs/index.mdx +9 -6
- package/docs/install-agentic.mdx +38 -12
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/server.mdx +1 -1
- package/docs/packages.mdx +8 -6
- package/docs/platform-integration.md +17 -0
- package/docs/predicates.mdx +8 -0
- package/docs/reticle-manual.md +106 -0
- package/docs/skill-file.mdx +3 -3
- package/docs/telemetry-contract.md +108 -4
- package/docs/tools-act-sequence.mdx +16 -0
- package/docs/tools-tools-and-run.mdx +2 -4
- package/docs/troubleshooting.mdx +9 -0
- package/docs/usage.md +4 -3
- package/package.json +4 -3
- package/dist/init/cursor.d.ts +0 -24
- package/dist/init/cursor.js +0 -80
- package/dist/session/session-readiness.d.ts +0 -34
- package/dist/session/session-readiness.js +0 -36
|
@@ -5,21 +5,29 @@
|
|
|
5
5
|
import { noteEmptyRead } from './observed-nothing.js';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { aliasParam } from './alias-args.js';
|
|
8
|
-
import { CONSOLE_LEVELS, ReticleCommand, DEFAULT_ASSERT_TIMEOUT_MS, PredicateKind, } from '@reticlehq/core';
|
|
8
|
+
import { CONSOLE_LEVELS, ReticleCommand, DEFAULT_ASSERT_TIMEOUT_MS, PredicateKind, Verified, } from '@reticlehq/core';
|
|
9
9
|
import { ReticleTool } from './tool-names.js';
|
|
10
|
+
import { countSchema, cursorSchema, httpStatusSchema, timeoutMsSchema, windowMsSchema, } from './numeric-bounds.js';
|
|
10
11
|
import { buildReactionReport } from '../events/reaction.js';
|
|
11
12
|
import { findContradictions } from '../events/contradictions.js';
|
|
12
13
|
import { evaluatePredicate, waitForPredicate, PredicateSchema } from '../events/predicate.js';
|
|
14
|
+
import { resolveSessionWithin } from '../session/resolve-within.js';
|
|
15
|
+
import { WALL_CLOCK } from '../session/wall-clock.js';
|
|
13
16
|
import { parsePredicate } from '../events/predicate-parse.js';
|
|
14
|
-
import { matchNet, matchConsole, isConsoleEvent, eventMatchesFilters, netEmptyHint, consoleEmptyHint, reconcileNet, projectNetCall, projectConsoleLog, } from '../events/event-filters.js';
|
|
17
|
+
import { matchNet, matchConsole, isConsoleEvent, eventMatchesFilters, netEmptyHint, consoleEmptyHint, reconcileNet, projectNetCall, projectConsoleLog, withoutUrlRaw, } from '../events/event-filters.js';
|
|
15
18
|
import { applyEventBudget, costHint, withSizeCost, DEFAULT_QUERY_LIMIT, } from '../session/output-budget.js';
|
|
16
|
-
import { healthEnvelope, bufferEnvelope } from '../session/session-health.js';
|
|
19
|
+
import { annotateStarvedFailure, healthEnvelope, bufferEnvelope, } from '../session/session-health.js';
|
|
17
20
|
import { assertsDerivedIpcStatus, DERIVED_IPC_STATUS_ADVICE, isPresenceOnlyAssertion, PRESENCE_ONLY_ADVICE, } from './assert-grade.js';
|
|
18
21
|
import { assertVerdict } from './assert-verdict.js';
|
|
22
|
+
import { assertSource } from './assert-source.js';
|
|
23
|
+
import { isChangeUndeclared } from '../honesty/undeclared-change.js';
|
|
24
|
+
import { openSessionIntents } from '../intent/open-intents.js';
|
|
25
|
+
import { dischargeInlineIntent, inlineVerdictId, linkInlineIntent, } from '../intent/inline-intent.js';
|
|
19
26
|
import { bodiesNotCaptured } from '../honesty/uncaptured-bodies.js';
|
|
20
27
|
import { withControl } from '../session/control-envelope.js';
|
|
21
|
-
import { asString, asNumber } from './tools-helpers.js';
|
|
22
|
-
import { sessionIdShape, commandOrThrow } from './tool-kit.js';
|
|
28
|
+
import { asString, asNumber, asRecord } from './tools-helpers.js';
|
|
29
|
+
import { intentArg, sessionIdShape, commandOrThrow } from './tool-kit.js';
|
|
30
|
+
import { gradeOfPredicate } from './assert-grade.js';
|
|
23
31
|
/**
|
|
24
32
|
* Evidence-completeness block: present on observe/network/console only when the ring buffer has
|
|
25
33
|
* evicted events, so a "no such event" answer is distinguishable from "I dropped it" (issue #27).
|
|
@@ -31,20 +39,20 @@ const bufferOutputShape = {
|
|
|
31
39
|
.describe('Present only when the event buffer evicted events — a negative result may then be a false negative.'),
|
|
32
40
|
};
|
|
33
41
|
/**
|
|
34
|
-
*
|
|
42
|
+
* The file:line an assertion may report — see `assertSource`.
|
|
35
43
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* so a failing assertion can point there instead of at nothing.
|
|
41
|
-
*
|
|
42
|
-
* RED only: on a pass this is noise on the path the agent walks most.
|
|
44
|
+
* Neither `reticle_assert` nor `reticle_wait_for` drives anything, so the last act's source is about
|
|
45
|
+
* some earlier action and not about this verdict. The pointer comes from the assertion's own matched
|
|
46
|
+
* evidence; the last driven control is borrowed only for a RED whose predicate has no DOM clause at
|
|
47
|
+
* all, which is the failure that genuinely has no element to point at.
|
|
43
48
|
*/
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
function assertionSource(session, predicate, verdict) {
|
|
50
|
+
const source = assertSource({
|
|
51
|
+
predicate,
|
|
52
|
+
evidence: verdict.evidence,
|
|
53
|
+
pass: verdict.pass,
|
|
54
|
+
lastActSource: session.lastAct.source(),
|
|
55
|
+
});
|
|
48
56
|
return source === undefined ? {} : { source };
|
|
49
57
|
}
|
|
50
58
|
/**
|
|
@@ -78,21 +86,17 @@ export const OBSERVE_TOOLS = [
|
|
|
78
86
|
example: { since: 0 },
|
|
79
87
|
description: 'Return the timeline of everything the app did in a window (DOM/network/route/console/animation/signal), with a summary. Use after an action. Pass `max_events` to cap the timeline to the most recent N (older events are dropped and counted in cost.droppedOldest). Every result carries a `cost:{events,bytes}` hint so you can self-budget your next call.',
|
|
80
88
|
inputSchema: {
|
|
81
|
-
window_ms:
|
|
82
|
-
.number()
|
|
83
|
-
.positive()
|
|
89
|
+
window_ms: windowMsSchema
|
|
84
90
|
// A non-positive window silently produced a FUTURE cursor, so the tool returned zero events
|
|
85
91
|
// and echoed the nonsense value back — indistinguishable from a genuinely quiet page. An
|
|
86
92
|
// agent that fumbles this argument gets a clean "nothing happened" instead of being told the
|
|
87
93
|
// question was malformed, which is the exact confusion this layer exists to refuse.
|
|
88
94
|
.optional()
|
|
89
95
|
.describe('Time window to look back, in ms (must be > 0). Default: 2000. Ignored when `since` is provided.'),
|
|
90
|
-
since:
|
|
91
|
-
.number()
|
|
96
|
+
since: cursorSchema
|
|
92
97
|
.optional()
|
|
93
98
|
.describe('Cursor from a prior reticle_act or reticle_observe call. Scopes the event window to exactly that span.'),
|
|
94
|
-
until:
|
|
95
|
-
.number()
|
|
99
|
+
until: cursorSchema
|
|
96
100
|
.optional()
|
|
97
101
|
.describe('Upper cursor bound. With `since`, returns the span "between action A and B".'),
|
|
98
102
|
actionId: z
|
|
@@ -105,9 +109,7 @@ export const OBSERVE_TOOLS = [
|
|
|
105
109
|
.describe('Event type allowlist — the cheapest way to shrink a large timeline. Use a bucket name — ' +
|
|
106
110
|
'dom | net | route | console | animation | signal | perf | state | storage — or a raw ' +
|
|
107
111
|
'type (e.g. "net.request"). Omit to return all types.'),
|
|
108
|
-
max_events:
|
|
109
|
-
.number()
|
|
110
|
-
.nonnegative()
|
|
112
|
+
max_events: countSchema
|
|
111
113
|
.optional()
|
|
112
114
|
.describe('Cap the timeline to the most recent N events. Older events are counted in cost.droppedOldest.'),
|
|
113
115
|
...sessionIdShape,
|
|
@@ -179,11 +181,16 @@ export const OBSERVE_TOOLS = [
|
|
|
179
181
|
// never asked about.
|
|
180
182
|
const actCursor = session.lastAct.cursor();
|
|
181
183
|
const judgingTheAct = actCursor !== undefined && actCursor >= since;
|
|
182
|
-
const contradictions = findContradictions(filtered,
|
|
184
|
+
const contradictions = findContradictions(filtered, {
|
|
185
|
+
currentDocumentId: session.currentDocumentId,
|
|
186
|
+
currentEditEpoch: session.currentEditEpoch,
|
|
187
|
+
appOrigin: session.url,
|
|
188
|
+
...(judgingTheAct ? { ...session.lastAct.effect(), actionSince: actCursor } : {}),
|
|
189
|
+
});
|
|
183
190
|
// carry session health — a throttled tab means the observed timeline may be incomplete.
|
|
184
191
|
return withControl(session, {
|
|
185
192
|
...report,
|
|
186
|
-
events: report.events.map(withoutConstantSessionId),
|
|
193
|
+
events: report.events.map((e) => withoutUrlRaw(withoutConstantSessionId(e))),
|
|
187
194
|
...(contradictions.length > 0 ? { contradictions } : {}),
|
|
188
195
|
cost: costHint(report, budgeted.length, droppedOldest),
|
|
189
196
|
...healthEnvelope(session),
|
|
@@ -199,9 +206,10 @@ export const OBSERVE_TOOLS = [
|
|
|
199
206
|
predicate: PredicateSchema.optional().describe('Predicate to wait for: { signal }, { net }, { element }, { kind: "net", ok: false } (assert on the OUTCOME — the honest field for IPC, which has no status code), { kind: "state", store, path, equals } (assert a registered store\'s value directly — the source of truth no DOM read can reach; equals takes a literal or { $gte | $contains | $length } pattern), { kind: "settled", quietMs } (deterministic network + DOM idle — prefer this over a fixed sleep), or a combination via allOf/anyOf.'),
|
|
200
207
|
// Same concept, the neighbouring tool's name. See alias-args.ts.
|
|
201
208
|
until: PredicateSchema.optional().describe("Alias for `predicate` (act_and_wait's name)."),
|
|
202
|
-
timeout_ms:
|
|
203
|
-
|
|
204
|
-
.
|
|
209
|
+
timeout_ms: timeoutMsSchema
|
|
210
|
+
.optional()
|
|
211
|
+
.describe('Maximum wait in milliseconds. Default: 4000. Capped at 55000: your MCP client aborts the request before a longer wait can return, so a bound above this would be advertised and not deliverable. To outlast it, poll — several short waits, each of which returns a verdict.'),
|
|
212
|
+
since: cursorSchema
|
|
205
213
|
.optional()
|
|
206
214
|
.describe('Cursor from a prior reticle_act — scopes the wait to events after that act.'),
|
|
207
215
|
...sessionIdShape,
|
|
@@ -214,6 +222,10 @@ export const OBSERVE_TOOLS = [
|
|
|
214
222
|
.boolean()
|
|
215
223
|
.optional()
|
|
216
224
|
.describe('The tab disconnected mid-wait, so this was never observed — the verdict is UNKNOWN, not a failure of the app.'),
|
|
225
|
+
inconclusive: z
|
|
226
|
+
.string()
|
|
227
|
+
.optional()
|
|
228
|
+
.describe('The wait could not be graded as a product failure — e.g. the tab is throttled and may never have rendered. The verdict is UNKNOWN, not "the UI is absent".'),
|
|
217
229
|
session: z
|
|
218
230
|
.object({ lastSeenMs: z.number(), throttled: z.boolean(), focused: z.boolean() })
|
|
219
231
|
.optional(),
|
|
@@ -233,20 +245,25 @@ export const OBSERVE_TOOLS = [
|
|
|
233
245
|
source: z
|
|
234
246
|
.string()
|
|
235
247
|
.optional()
|
|
236
|
-
.describe('
|
|
248
|
+
.describe('Where the code behind this verdict lives, as `file:line`. For an element/text assertion it is the matched element itself; for a FAILING signal/net/state assertion — which has no element to point at — it is the control last acted on, where the handler that should have fired lives. OMITTED when neither is known: this tool never borrows an unrelated location.'),
|
|
237
249
|
},
|
|
238
250
|
handler: async (deps, args) => {
|
|
239
|
-
const
|
|
251
|
+
const waitBudget = asNumber(args['timeout_ms']) ?? DEFAULT_ASSERT_TIMEOUT_MS;
|
|
252
|
+
// Spend the budget waiting for the APP as well as for the predicate. See resolve-within.
|
|
253
|
+
const session = await resolveSessionWithin(deps.sessions, asString(args['sessionId']), waitBudget, WALL_CLOCK);
|
|
240
254
|
// `until` is act_and_wait's name for this — see alias-args.ts.
|
|
241
255
|
const predicate = parsePredicate(aliasParam(args, 'predicate', ['until'])['predicate']);
|
|
242
256
|
// Honesty: explicit since wins; else default to the last act's cursor; else the whole buffer.
|
|
243
257
|
const since = asNumber(args['since']) ?? session.lastAct.cursor() ?? 0;
|
|
244
|
-
const verdict = await waitForPredicate(session, predicate,
|
|
258
|
+
const verdict = await waitForPredicate(session, predicate, waitBudget, since);
|
|
245
259
|
// match reticle_assert — wrap with control + session health (throttle matters most while blocking)
|
|
246
260
|
// and the buffer envelope, so a verdict reached over an evicted window says so.
|
|
247
261
|
return withControl(session, {
|
|
248
|
-
|
|
249
|
-
|
|
262
|
+
// #537's starved-wait note wraps the verdict (it RETURNS the verdict), so it stands where
|
|
263
|
+
// `...verdict` did. The source line is #533's `assertionSource`, which superseded
|
|
264
|
+
// `lastActSourceOnFailure` — an assert used to be blamed on the previous act's file:line.
|
|
265
|
+
...annotateStarvedFailure(session, verdict),
|
|
266
|
+
...assertionSource(session, predicate, verdict),
|
|
250
267
|
...healthEnvelope(session),
|
|
251
268
|
...bufferEnvelope(session),
|
|
252
269
|
});
|
|
@@ -255,27 +272,27 @@ export const OBSERVE_TOOLS = [
|
|
|
255
272
|
{
|
|
256
273
|
name: ReticleTool.ASSERT,
|
|
257
274
|
example: { predicate: { kind: PredicateKind.SIGNAL, name: 'todos:loaded' } },
|
|
258
|
-
description: 'Evaluate a predicate (optionally waiting up to timeout_ms). Returns { pass, evidence, failureReason? }. The end of every verify loop. Prefer a { signal } or { net } consequence over { element }/{ text } presence — a passing presence-only assertion returns `advice` because a wrong/healed element can fake it. By default it only counts events since your last act, so a stale buffered signal can never fake a pass; pass `since` (an observe/act cursor) to set the window explicitly.',
|
|
275
|
+
description: 'Evaluate a predicate (optionally waiting up to timeout_ms). Returns { pass, evidence, failureReason? }. The end of every verify loop. CHECKING SEVERAL THINGS? Put them in ONE call with { kind: "allOf", predicates: [...] } — it returns one verdict naming whichever member failed, and one call costs one round trip where N calls cost N. Prefer a { signal } or { net } consequence over { element }/{ text } presence — a passing presence-only assertion returns `advice` because a wrong/healed element can fake it. By default it only counts events since your last act, so a stale buffered signal can never fake a pass; pass `since` (an observe/act cursor) to set the window explicitly.',
|
|
259
276
|
inputSchema: {
|
|
260
277
|
predicate: PredicateSchema.optional().describe(
|
|
261
278
|
// Every kind, each with the field that carries its argument. Five of the nine were
|
|
262
279
|
// undocumented here, including `route` — and "did submitting the login form navigate away"
|
|
263
280
|
// is the most common thing an agent wants to assert. A field report reached us from an agent
|
|
264
281
|
// that guessed `urlContains` on route (net's spelling) and got unrecognized_keys.
|
|
265
|
-
'Predicate to evaluate. Kinds: { signal, name
|
|
282
|
+
'Predicate to evaluate. Kinds: { signal, name|dataMatches|count } ' +
|
|
283
|
+
'{ net, urlContains|method|status|count|bodyContains } ' +
|
|
266
284
|
'{ state, path|equals } { route, pathname (exact) | contains (path+query+hash) } ' +
|
|
267
285
|
'{ element, testid|role|text } { text } { console, level|contains|absent } { animation, name } ' +
|
|
268
286
|
'{ settled } — combine with { allOf | anyOf | not }. Prefer a signal/net/state consequence ' +
|
|
269
287
|
'over element/text presence.'),
|
|
270
288
|
until: PredicateSchema.optional().describe("Alias for `predicate` (act_and_wait's name)."),
|
|
271
|
-
timeout_ms:
|
|
272
|
-
.number()
|
|
289
|
+
timeout_ms: timeoutMsSchema
|
|
273
290
|
.optional()
|
|
274
|
-
.describe('If > 0, wait up to this many milliseconds before failing. Default: 0 (evaluate once).'),
|
|
275
|
-
since:
|
|
276
|
-
.number()
|
|
291
|
+
.describe('If > 0, wait up to this many milliseconds before failing. Default: 0 (evaluate once). Capped at 55000: your MCP client aborts the request before a longer wait can return, so a bound above this would be advertised and not deliverable. To outlast it, poll — several short waits, each of which returns a verdict.'),
|
|
292
|
+
since: cursorSchema
|
|
277
293
|
.optional()
|
|
278
294
|
.describe('Cursor from a prior reticle_act — scopes the assertion to events after that act.'),
|
|
295
|
+
intent: intentArg,
|
|
279
296
|
...sessionIdShape,
|
|
280
297
|
},
|
|
281
298
|
outputSchema: {
|
|
@@ -286,6 +303,10 @@ export const OBSERVE_TOOLS = [
|
|
|
286
303
|
.boolean()
|
|
287
304
|
.optional()
|
|
288
305
|
.describe('The tab disconnected mid-wait, so this was never observed — the verdict is UNKNOWN, not a failure of the app.'),
|
|
306
|
+
inconclusive: z
|
|
307
|
+
.string()
|
|
308
|
+
.optional()
|
|
309
|
+
.describe('The assertion could not be graded as a product failure — e.g. the tab is throttled and may never have rendered. The verdict is UNKNOWN, not "the UI is absent".'),
|
|
289
310
|
advice: z
|
|
290
311
|
.string()
|
|
291
312
|
.optional()
|
|
@@ -309,7 +330,7 @@ export const OBSERVE_TOOLS = [
|
|
|
309
330
|
source: z
|
|
310
331
|
.string()
|
|
311
332
|
.optional()
|
|
312
|
-
.describe('
|
|
333
|
+
.describe('Where the code behind this verdict lives, as `file:line`. For an element/text assertion it is the matched element itself; for a FAILING signal/net/state assertion — which has no element to point at — it is the control last acted on, where the handler that should have fired lives. OMITTED when neither is known: this tool never borrows an unrelated location.'),
|
|
313
334
|
coverage: z
|
|
314
335
|
.string()
|
|
315
336
|
.optional()
|
|
@@ -324,12 +345,16 @@ export const OBSERVE_TOOLS = [
|
|
|
324
345
|
.describe('What the APP did not tell Reticle, and the one change that would fix it — each entry is { kind, missing, cost, fix, source?, ref? }. Reported ONLY where an absence made THIS verdict weaker: a failing assertion with no source to point at, or a state assertion against an app that registers no store. Never a survey of the page, so an entry is always work worth doing now. OMITTED when the app told Reticle everything it needed.'),
|
|
325
346
|
},
|
|
326
347
|
handler: async (deps, args) => {
|
|
327
|
-
const
|
|
348
|
+
const timeout = asNumber(args['timeout_ms']) ?? 0;
|
|
349
|
+
// Spend the budget waiting for the APP as well as for the predicate. See resolve-within.
|
|
350
|
+
const session = await resolveSessionWithin(deps.sessions, asString(args['sessionId']), timeout, WALL_CLOCK);
|
|
328
351
|
// `until` is act_and_wait's name for this — see alias-args.ts.
|
|
329
352
|
const predicate = parsePredicate(aliasParam(args, 'predicate', ['until'])['predicate']);
|
|
330
|
-
const timeout = asNumber(args['timeout_ms']) ?? 0;
|
|
331
353
|
// Honesty: explicit since wins; else default to the last act's cursor; else the whole buffer.
|
|
332
354
|
const since = asNumber(args['since']) ?? session.lastAct.cursor() ?? 0;
|
|
355
|
+
// Declared BEFORE the verdict, so the undeclared-change read below finds it open and stays
|
|
356
|
+
// quiet on THIS verdict rather than on the next one. Discharged after that read.
|
|
357
|
+
const intentId = await linkInlineIntent(deps, asString(args['sessionId']), asString(args['intent']), PredicateKind.SETTLED === predicate.kind ? undefined : predicate);
|
|
333
358
|
const verdict = timeout > 0
|
|
334
359
|
? await waitForPredicate(session, predicate, timeout, since)
|
|
335
360
|
: await evaluatePredicate(session, predicate, since);
|
|
@@ -345,16 +370,43 @@ export const OBSERVE_TOOLS = [
|
|
|
345
370
|
: assertsDerivedIpcStatus(predicate)
|
|
346
371
|
? { advice: DERIVED_IPC_STATUS_ADVICE }
|
|
347
372
|
: {};
|
|
348
|
-
|
|
373
|
+
// Asked of every verdict drawn after an observed edit, not once per edit — see
|
|
374
|
+
// isChangeUndeclared for why repeating it is disclosure rather than nagging.
|
|
375
|
+
const changeUndeclared = await isChangeUndeclared(session.currentEditEpoch, () => openSessionIntents(deps, asString(args['sessionId'])));
|
|
376
|
+
const { decision, contradictions, coverage, gaps, verdictEffect } = await assertVerdict(session, predicate, verdict.pass, verdict.evidence, since, verdict.inconclusive, verdict.observationLost, changeUndeclared);
|
|
377
|
+
// The assertion IS the proof attempt, so a green one discharges the intent it was drawn for. A
|
|
378
|
+
// red proved nothing, and an unbound intent refuses discharge anyway — see inline-intent.ts.
|
|
379
|
+
// The id is checked HERE rather than only inside the helper so a caller that declared no intent
|
|
380
|
+
// touches nothing at all, not even the clock.
|
|
381
|
+
if (intentId !== undefined && Verified.YES === decision['verified']) {
|
|
382
|
+
await dischargeInlineIntent(deps, asString(args['sessionId']), intentId, {
|
|
383
|
+
verdictId: inlineVerdictId(ReticleTool.ASSERT, deps.now()),
|
|
384
|
+
grade: gradeOfPredicate(predicate),
|
|
385
|
+
at: deps.now(),
|
|
386
|
+
},
|
|
387
|
+
/*
|
|
388
|
+
* An assertion has no element of its own — it observes, it does not act. The file it names
|
|
389
|
+
* is the one the LAST action touched, which is the code path that produced the state being
|
|
390
|
+
* asserted about. Already remembered on the session for exactly this reason: an assertion
|
|
391
|
+
* whose failure has nothing to point at still needs to name a file.
|
|
392
|
+
*/
|
|
393
|
+
session.lastAct.source());
|
|
394
|
+
}
|
|
395
|
+
// Journal the verdict so a LATER turn can read what this one proved. A verdict that lives only
|
|
396
|
+
// in the response lives only in the agent's context window, which is the copy a compaction
|
|
397
|
+
// destroys — see runs/run-context.ts. Recorded WITHOUT an attribution window: this tool drives
|
|
398
|
+
// nothing, so no event it observed was caused by it.
|
|
399
|
+
session.recordAction(ReticleTool.ASSERT, asRecord(args), verdictEffect);
|
|
349
400
|
return withControl(session, {
|
|
350
401
|
...decision,
|
|
351
|
-
...verdict,
|
|
402
|
+
...annotateStarvedFailure(session, verdict),
|
|
352
403
|
...(contradictions.length > 0 ? { contradictions } : {}),
|
|
353
404
|
// What the app did not tell Reticle, on the same rule the act path uses.
|
|
354
405
|
...(gaps.length > 0 ? { instrumentationGaps: gaps } : {}),
|
|
355
406
|
...advice,
|
|
356
407
|
...coverage,
|
|
357
|
-
|
|
408
|
+
// The SAME pointer the journal keeps, not a second lookup — one verdict, one file:line.
|
|
409
|
+
...(verdictEffect.source === undefined ? {} : { source: verdictEffect.source }),
|
|
358
410
|
...healthEnvelope(session),
|
|
359
411
|
...bufferEnvelope(session),
|
|
360
412
|
});
|
|
@@ -365,12 +417,10 @@ export const OBSERVE_TOOLS = [
|
|
|
365
417
|
example: { urlContains: '/api/todos', method: 'POST' },
|
|
366
418
|
description: 'Filtered list of network calls. Fast path for "did POST /x return 200?". A zero-match filter returns a `hint` { totalInWindow, present[] } of the calls that DID fire, so a miss is diagnosable. Desktop IPC (`ipc://`) has no status code — the 200/500 there is derived, so filter on `ok` for those.',
|
|
367
419
|
inputSchema: {
|
|
368
|
-
since:
|
|
369
|
-
.number()
|
|
420
|
+
since: cursorSchema
|
|
370
421
|
.optional()
|
|
371
422
|
.describe('Cursor from a prior reticle_act — scopes the query to requests fired after that act.'),
|
|
372
|
-
until:
|
|
373
|
-
.number()
|
|
423
|
+
until: cursorSchema
|
|
374
424
|
.optional()
|
|
375
425
|
.describe('Upper cursor bound — with `since`, the span between two acts.'),
|
|
376
426
|
actionId: z
|
|
@@ -382,14 +432,12 @@ export const OBSERVE_TOOLS = [
|
|
|
382
432
|
.optional()
|
|
383
433
|
.describe('HTTP method filter: GET | POST | PUT | DELETE | PATCH etc.'),
|
|
384
434
|
urlContains: z.string().optional().describe('Substring that the request URL must contain.'),
|
|
385
|
-
status:
|
|
435
|
+
status: httpStatusSchema.optional().describe('HTTP status code filter (e.g. 200, 404, 500).'),
|
|
386
436
|
ok: z
|
|
387
437
|
.boolean()
|
|
388
438
|
.optional()
|
|
389
439
|
.describe('Outcome filter: false keeps only calls that FAILED, true only those that succeeded. The filter to use for desktop IPC (`ipc://`), whose status code is derived. A still-pending call matches neither.'),
|
|
390
|
-
limit:
|
|
391
|
-
.number()
|
|
392
|
-
.nonnegative()
|
|
440
|
+
limit: countSchema
|
|
393
441
|
.optional()
|
|
394
442
|
.describe('Keep only the most recent N matching calls (older are dropped and counted in droppedOldest) — cuts tokens on a wide window. Defaults to 200 when omitted; pass a higher number for more, or scope with since/until.'),
|
|
395
443
|
bodies: z
|
|
@@ -457,21 +505,17 @@ export const OBSERVE_TOOLS = [
|
|
|
457
505
|
level: consoleLevelEnum
|
|
458
506
|
.optional()
|
|
459
507
|
.describe(`Log level filter: ${CONSOLE_LEVEL_LIST}. Omit to return all levels.`),
|
|
460
|
-
since:
|
|
461
|
-
.number()
|
|
508
|
+
since: cursorSchema
|
|
462
509
|
.optional()
|
|
463
510
|
.describe('Cursor from a prior reticle_act — scopes the query to log entries after that act.'),
|
|
464
|
-
until:
|
|
465
|
-
.number()
|
|
511
|
+
until: cursorSchema
|
|
466
512
|
.optional()
|
|
467
513
|
.describe('Upper cursor bound — with `since`, the span between two acts.'),
|
|
468
514
|
actionId: z
|
|
469
515
|
.string()
|
|
470
516
|
.optional()
|
|
471
517
|
.describe('Keep only log entries attributed to this action — "what did action N log".'),
|
|
472
|
-
limit:
|
|
473
|
-
.number()
|
|
474
|
-
.nonnegative()
|
|
518
|
+
limit: countSchema
|
|
475
519
|
.optional()
|
|
476
520
|
.describe('Keep only the most recent N matching entries (older are dropped and counted in droppedOldest) — cuts tokens when a page spams the console. Defaults to 200 when omitted; pass a higher number for more, or scope with since/until.'),
|
|
477
521
|
...sessionIdShape,
|
package/dist/tools/read-tools.js
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { resolveAnnotateTarget } from '../flows/annotate-target.js';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { EventType, ReticleCommand, REPLAY_PROGRAM_VERSION, SnapshotMode } from '@reticlehq/core';
|
|
7
|
+
import { EventType, ReticleCommand, REPLAY_PROGRAM_VERSION, SnapshotMode, StorageArea, } from '@reticlehq/core';
|
|
8
8
|
import { ReticleTool } from './tool-names.js';
|
|
9
|
+
import { advanceMsSchema, depthSchema } from './numeric-bounds.js';
|
|
9
10
|
import { proposeConsequences } from '../oracles/propose-consequences.js';
|
|
10
11
|
import { replayProgram } from '../flows/replay.js';
|
|
11
12
|
import { diffLines } from '../project/baselines.js';
|
|
@@ -15,6 +16,26 @@ import { buildReactionReport, summarizeReaction } from '../events/reaction.js';
|
|
|
15
16
|
import { asString, asNumber, parseInteractive } from './tools-helpers.js';
|
|
16
17
|
import { sessionIdShape, commandOrThrow, snapshotTree } from './tool-kit.js';
|
|
17
18
|
import { bufferEnvelope } from '../session/session-health.js';
|
|
19
|
+
/** The route part of a session URL. A host belongs to the machine, not to the journey. */
|
|
20
|
+
/**
|
|
21
|
+
* The page a recording started on, as a NAVIGABLE path: pathname + hash.
|
|
22
|
+
*
|
|
23
|
+
* The hash matters and the pathname alone is not enough. Under a hash router every page has the
|
|
24
|
+
* document pathname `/`, so a recording made on `#/posts/12` stored `/`, the replay's start-path
|
|
25
|
+
* comparison saw `/` on both sides and never warned about drift, and the navigate it suggests
|
|
26
|
+
* pointed at the default route rather than the recorded one.
|
|
27
|
+
*/
|
|
28
|
+
function pathnameOf(url) {
|
|
29
|
+
if (url === undefined)
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
const parsed = new URL(url);
|
|
33
|
+
return `${parsed.pathname}${parsed.hash}`;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
18
39
|
/**
|
|
19
40
|
* What record-stop says about a step that compiled to no anchor at all.
|
|
20
41
|
*
|
|
@@ -141,7 +162,10 @@ export const READ_TOOLS = [
|
|
|
141
162
|
const session = deps.sessions.resolve(asString(args['sessionId']));
|
|
142
163
|
const name = asString(args['recordingName']) ?? 'default';
|
|
143
164
|
const cursor = session.elapsed();
|
|
144
|
-
|
|
165
|
+
// Where the journey begins, so a saved flow can navigate here before step 1 instead of
|
|
166
|
+
// replaying from wherever the page happens to be. Pathname only: a host or port belongs to
|
|
167
|
+
// the machine that recorded it, not to the journey.
|
|
168
|
+
deps.recordings.start(name, cursor, pathnameOf(session.url));
|
|
145
169
|
return Promise.resolve({ recordingName: name, since: cursor });
|
|
146
170
|
},
|
|
147
171
|
},
|
|
@@ -181,6 +205,7 @@ export const READ_TOOLS = [
|
|
|
181
205
|
name,
|
|
182
206
|
version: REPLAY_PROGRAM_VERSION,
|
|
183
207
|
steps: rec.steps,
|
|
208
|
+
...(rec.startPath === undefined ? {} : { startPath: rec.startPath }),
|
|
184
209
|
};
|
|
185
210
|
deps.recordings.saveCompiled(program);
|
|
186
211
|
const unstable = rec.steps.filter((s) => !s.stable).length;
|
|
@@ -282,8 +307,7 @@ export const READ_TOOLS = [
|
|
|
282
307
|
.boolean()
|
|
283
308
|
.optional()
|
|
284
309
|
.describe('Freeze the fake clock. Time stops advancing until advanceMs or reset.'),
|
|
285
|
-
advanceMs:
|
|
286
|
-
.number()
|
|
310
|
+
advanceMs: advanceMsSchema
|
|
287
311
|
.optional()
|
|
288
312
|
.describe('Fast-forward time by this many milliseconds — triggers debounces, toasts, auto-dismiss timers.'),
|
|
289
313
|
reset: z.boolean().optional().describe('Restore the real clock.'),
|
|
@@ -318,10 +342,9 @@ export const READ_TOOLS = [
|
|
|
318
342
|
.string()
|
|
319
343
|
.optional()
|
|
320
344
|
.describe("Dot-path into the store (e.g. 'captionCache.v3'). Numeric array indices are supported."),
|
|
321
|
-
depth:
|
|
322
|
-
.number()
|
|
345
|
+
depth: depthSchema
|
|
323
346
|
.optional()
|
|
324
|
-
.describe('Collapse anything deeper than N levels to a size marker — avoids huge outputs for large stores.'),
|
|
347
|
+
.describe('Collapse anything deeper than N levels to a size marker — avoids huge outputs for large stores. A whole number of levels, 1 or more.'),
|
|
325
348
|
...sessionIdShape,
|
|
326
349
|
},
|
|
327
350
|
outputSchema: {
|
|
@@ -513,7 +536,7 @@ export const READ_TOOLS = [
|
|
|
513
536
|
'diagnosable.',
|
|
514
537
|
inputSchema: {
|
|
515
538
|
area: z
|
|
516
|
-
.
|
|
539
|
+
.nativeEnum(StorageArea)
|
|
517
540
|
.optional()
|
|
518
541
|
.describe('Scope to one storage area. Omit to read all three.'),
|
|
519
542
|
key: z
|
|
@@ -5,10 +5,32 @@
|
|
|
5
5
|
* Split out of act-tools.ts along its natural seam: the act tools care only about the outcome
|
|
6
6
|
* (`result` defined = it went native), never about provider availability, box resolution,
|
|
7
7
|
* drag-target inspection or the reason taxonomy.
|
|
8
|
+
*
|
|
9
|
+
* Also hosts `rewriteUploadArgs` — the daemon-side path that lets an agent name a file on disk
|
|
10
|
+
* and have its REAL bytes reach the browser's `<input type="file">`. The browser SDK cannot read
|
|
11
|
+
* the filesystem; the daemon can. The rewrite happens here, before the ACT command crosses the
|
|
12
|
+
* bridge, so the browser side sees a normal `{ content, name, type }` call and `assertUploadArgs`
|
|
13
|
+
* keeps its invariant (no fabricated bytes, no silently-dropped keys).
|
|
14
|
+
*
|
|
15
|
+
* Trust boundary: scoped to the project root (one level above `deps.reticleRoot`), resolved
|
|
16
|
+
* through `realpath` so symlinks cannot escape it. Sensitive files (.env*, .git/, *.pem, id_*,
|
|
17
|
+
* .npmrc) are denied with a message that says why. The cap is derived from the bridge's own
|
|
18
|
+
* MAX_MESSAGE_BYTES with the base64 4/3 inflation factor applied, so the encoded payload always
|
|
19
|
+
* fits in one WebSocket frame.
|
|
8
20
|
*/
|
|
9
21
|
import { ActionType, InputModeReason } from '@reticlehq/core';
|
|
10
22
|
import type { Session } from '../session/session.js';
|
|
11
23
|
import { type ToolDeps } from './tool-kit.js';
|
|
24
|
+
/**
|
|
25
|
+
* If the action is `upload` AND the inner args carry `path`, read the file from disk and rewrite
|
|
26
|
+
* the args to `{ content, name, type, __base64: true }` before the ACT command reaches the browser.
|
|
27
|
+
*
|
|
28
|
+
* Returns the (possibly rewritten) args object. All other actions are returned unchanged.
|
|
29
|
+
*
|
|
30
|
+
* This is the SINGLE interception point — called from session.command() so flow replay, crawl,
|
|
31
|
+
* and every other ACT dispatch site are covered without per-site wiring.
|
|
32
|
+
*/
|
|
33
|
+
export declare function rewriteUploadArgs(deps: Pick<ToolDeps, 'fs' | 'reticleRoot'>, action: string, innerArgs: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
12
34
|
interface RealActResult {
|
|
13
35
|
/** Defined only on a successful native action; `undefined` means the synthetic path runs. */
|
|
14
36
|
result: unknown;
|
|
@@ -18,11 +40,21 @@ interface RealActResult {
|
|
|
18
40
|
/** Why we went synthetic despite a configured provider (field bug #2: never a silent fallback). */
|
|
19
41
|
reason?: InputModeReason;
|
|
20
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Hover without a native pointer is a false success: synthetic mouseover reports dispatched and
|
|
45
|
+
* settled while CSS `:hover` never applies. Same refusal shape as contenteditable — name the gap
|
|
46
|
+
* rather than pretend the action ran.
|
|
47
|
+
*/
|
|
48
|
+
export declare const HOVER_NEEDS_POINTER_MSG = "cannot hover without a real pointer \u2014 CSS :hover only applies to a native mouse move, never to a synthetic mouseover";
|
|
21
49
|
/**
|
|
22
50
|
* Attempt to drive a pointer action via native input. Returns a synthetic outcome (with a
|
|
23
51
|
* `reason` when a provider is configured) whenever the synthetic path should run — no matching
|
|
24
52
|
* page, unresolvable box, declined, etc. A throw inside the provider becomes a synthetic fallback
|
|
25
53
|
* flagged with `fellBack`. `result` is defined only on a real success.
|
|
54
|
+
*
|
|
55
|
+
* Hover is the exception: it never returns synthetic. CSS `:hover` is not applied by
|
|
56
|
+
* `dispatchEvent`, so a synthetic success is the defect. The call either drives a real pointer
|
|
57
|
+
* or throws.
|
|
26
58
|
*/
|
|
27
59
|
export declare function tryRealInput(deps: ToolDeps, session: Session, ref: string, action: ActionType, args: Record<string, unknown>): Promise<RealActResult>;
|
|
28
60
|
export {};
|