@reticlehq/server 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-ENTERPRISE +1 -1
- package/README.md +3 -3
- package/SKILL.md +23 -22
- package/dist/chromium-launch-options.d.ts +4 -3
- package/dist/chromium-launch-options.js +6 -2
- package/dist/command/cli/adhoc-suite.d.ts +41 -0
- package/dist/command/cli/adhoc-suite.js +159 -0
- package/dist/command/cli/adhoc-verdict.d.ts +58 -2
- package/dist/command/cli/adhoc-verdict.js +108 -13
- package/dist/command/cli/answers/gate-hook-message.d.ts +6 -0
- package/dist/command/cli/answers/gate-hook-message.js +6 -0
- package/dist/command/cli/auth/cloud-keystore.d.ts +0 -2
- package/dist/command/cli/auth/cloud-keystore.js +0 -3
- package/dist/command/cli/auth/cloud-session.d.ts +4 -0
- package/dist/command/cli/auth/cloud-session.js +2 -0
- package/dist/command/cli/cli-doctor.js +30 -8
- package/dist/command/cli/cli-flow-commands.d.ts +3 -6
- package/dist/command/cli/cli-flow-commands.js +67 -4
- package/dist/command/cli/cli-parse-grammar.d.ts +7 -0
- package/dist/command/cli/cli-parse-grammar.js +7 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -5
- package/dist/command/cli/cli-parse-verify.js +86 -13
- package/dist/command/cli/cli-parse.d.ts +14 -1
- package/dist/command/cli/cli-parse.js +54 -8
- package/dist/command/cli/cli-update-commands.js +8 -1
- package/dist/command/cli/cli-verify.d.ts +80 -0
- package/dist/command/cli/cli-verify.js +181 -26
- package/dist/command/cli/cloud-cli.js +5 -2
- package/dist/command/cli/cloud-kit.d.ts +0 -2
- package/dist/command/cli/cloud-kit.js +3 -5
- package/dist/command/cli/cloud-login.js +21 -3
- package/dist/command/cli/demo/demo-page.js +6 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +5 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +5 -0
- package/dist/command/cli/doctor/doctor-sessions-line.d.ts +2 -1
- package/dist/command/cli/launch/cli-launch.d.ts +9 -29
- package/dist/command/cli/launch/cli-launch.js +27 -49
- package/dist/command/cli/launch/sdk-version-match.d.ts +84 -0
- package/dist/command/cli/launch/sdk-version-match.js +206 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +2 -16
- package/dist/command/cli/ports/resolve/cli-port.d.ts +38 -0
- package/dist/command/cli/ports/resolve/cli-port.js +169 -15
- package/dist/command/cli/report-command.d.ts +16 -0
- package/dist/command/cli/report-command.js +97 -0
- package/dist/command/cli/setup-mcp-cli.js +13 -13
- package/dist/command/cli/tutorial.d.ts +2 -2
- package/dist/command/cli/tutorial.js +21 -7
- package/dist/command/cli.js +67 -10
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +44 -2
- package/dist/command/daemon/binding/daemon-status-probe.js +79 -6
- package/dist/command/daemon/binding/port-presence.d.ts +1 -1
- package/dist/command/daemon/daemon-resolve.d.ts +9 -0
- package/dist/command/daemon/daemon-resolve.js +1 -1
- package/dist/command/daemon/idle-shutdown.d.ts +2 -1
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +7 -1
- package/dist/command/daemon/lifetime/daemon-usefulness.js +30 -7
- package/dist/command/dev/stale-issue-guard.d.ts +3 -4
- package/dist/command/dev/stale-issue-guard.js +8 -8
- package/dist/command/setup/bringup/connect-lease.d.ts +17 -0
- package/dist/command/setup/bringup/connect-lease.js +38 -0
- package/dist/command/setup/bringup/dev-server-files.d.ts +68 -0
- package/dist/command/setup/bringup/dev-server-files.js +131 -0
- package/dist/command/setup/bringup/dev-server-log-cap.d.ts +35 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +121 -0
- package/dist/command/setup/bringup/ensure-daemon.d.ts +65 -4
- package/dist/command/setup/bringup/ensure-daemon.js +135 -16
- package/dist/command/setup/bringup/static-page-server.d.ts +35 -0
- package/dist/command/setup/bringup/static-page-server.js +151 -0
- package/dist/command/setup/desktop-shape.d.ts +4 -0
- package/dist/command/setup/desktop-shape.js +18 -2
- package/dist/command/setup/init/init-host.js +8 -0
- package/dist/command/setup/init/init-port.d.ts +15 -0
- package/dist/command/setup/init/init-port.js +44 -0
- package/dist/command/setup/init/init-runtime.d.ts +1 -1
- package/dist/command/setup/init/init-runtime.js +39 -2
- package/dist/command/setup/node-effects.d.ts +27 -14
- package/dist/command/setup/node-effects.js +80 -44
- package/dist/command/setup/probe/loopback-probe-urls.d.ts +7 -0
- package/dist/command/setup/probe/loopback-probe-urls.js +40 -0
- package/dist/command/setup/probe/page-probe.d.ts +13 -2
- package/dist/command/setup/probe/page-probe.js +18 -3
- package/dist/command/setup/run-setup.d.ts +26 -1
- package/dist/command/setup/run-setup.js +96 -13
- package/dist/command/setup/session-pick.d.ts +13 -0
- package/dist/command/setup/session-pick.js +20 -0
- package/dist/command/setup/setup-command.d.ts +2 -14
- package/dist/command/setup/setup-command.js +105 -31
- package/dist/command/setup/setup-mcp.js +3 -3
- package/dist/command/setup/terminal/wait-progress.d.ts +8 -0
- package/dist/command/setup/terminal/wait-progress.js +17 -0
- package/dist/features/crawl/crawl-empty.js +1 -1
- package/dist/features/crawl/crawl-tools.d.ts +6 -0
- package/dist/features/crawl/crawl-tools.js +57 -0
- package/dist/features/crawl/crawl.d.ts +2 -0
- package/dist/features/crawl/crawl.js +171 -156
- package/dist/features/exhaust/app-coverage.d.ts +33 -0
- package/dist/features/exhaust/app-coverage.js +31 -0
- package/dist/features/exhaust/code-coverage.d.ts +47 -0
- package/dist/features/exhaust/code-coverage.js +77 -0
- package/dist/features/exhaust/exhaust-run.d.ts +33 -0
- package/dist/features/exhaust/exhaust-run.js +82 -0
- package/dist/features/exhaust/explorer.d.ts +103 -0
- package/dist/features/exhaust/explorer.js +195 -0
- package/dist/features/exhaust/failure-branches.d.ts +33 -0
- package/dist/features/exhaust/failure-branches.js +92 -0
- package/dist/features/exhaust/ledger.d.ts +202 -0
- package/dist/features/exhaust/ledger.js +252 -0
- package/dist/features/exhaust/session-fold.d.ts +31 -0
- package/dist/features/exhaust/session-fold.js +79 -0
- package/dist/features/exhaust/session-port.d.ts +36 -0
- package/dist/features/exhaust/session-port.js +102 -0
- package/dist/features/harness/drive-report.d.ts +0 -9
- package/dist/features/harness/drive-report.js +18 -0
- package/dist/features/harness/driver.js +4 -7
- package/dist/features/harness/fill-values.d.ts +6 -0
- package/dist/features/harness/fill-values.js +3 -0
- package/dist/features/harness/jev-driver.js +36 -22
- package/dist/features/harness/openai-driver.js +4 -7
- package/dist/features/harness/platform-config.d.ts +10 -0
- package/dist/features/harness/platform-config.js +13 -6
- package/dist/index.d.ts +10 -1
- package/dist/index.js +78 -104
- package/dist/judgement/capsule/capsule-store.d.ts +31 -2
- package/dist/judgement/capsule/capsule-store.js +58 -6
- package/dist/judgement/capsule/capsule.js +5 -0
- package/dist/judgement/capsule/causal-summary.d.ts +13 -1
- package/dist/judgement/capsule/causal-summary.js +7 -0
- package/dist/judgement/domain/domain-model.js +40 -9
- package/dist/judgement/oracles/self-instrument.js +4 -2
- package/dist/judgement/outcome/assertion-integrity.d.ts +3 -3
- package/dist/judgement/runs/artifact/gap-report.d.ts +17 -0
- package/dist/judgement/runs/artifact/gap-report.js +46 -0
- package/dist/judgement/runs/artifact/gap-summary.d.ts +58 -0
- package/dist/judgement/runs/artifact/gap-summary.js +85 -0
- package/dist/judgement/runs/artifact/render-report.js +4 -1
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +2 -2
- package/dist/judgement/runs/artifact/replay-mapping.js +44 -9
- package/dist/judgement/runs/artifact/to-artifact.d.ts +7 -2
- package/dist/judgement/runs/artifact/to-artifact.js +1 -1
- package/dist/judgement/runs/context-tools.js +21 -3
- package/dist/judgement/runs/drive-run.js +7 -2
- package/dist/judgement/runs/verification-sync.d.ts +3 -1
- package/dist/judgement/runs/verification-sync.js +1 -1
- package/dist/language/flows/annotate-notes/annotate.d.ts +0 -15
- package/dist/language/flows/annotate-notes/annotate.js +66 -18
- package/dist/language/flows/change/affected.d.ts +9 -0
- package/dist/language/flows/change/affected.js +35 -0
- package/dist/language/flows/change/gate.d.ts +20 -0
- package/dist/language/flows/change/gate.js +12 -1
- package/dist/language/flows/flow-anchor.d.ts +12 -0
- package/dist/language/flows/flow-anchor.js +20 -0
- package/dist/language/flows/flow-author.d.ts +7 -0
- package/dist/language/flows/flow-author.js +19 -0
- package/dist/language/flows/flow-expect-grammar.d.ts +2 -2
- package/dist/language/flows/flow-expect-grammar.js +92 -11
- package/dist/language/flows/flow-intent.js +1 -1
- package/dist/language/flows/flow-journey.d.ts +54 -0
- package/dist/language/flows/flow-journey.js +119 -0
- package/dist/language/flows/flow-learning.d.ts +3 -0
- package/dist/language/flows/flow-learning.js +39 -8
- package/dist/language/flows/flow-replay-run.d.ts +33 -12
- package/dist/language/flows/flow-replay-run.js +131 -52
- package/dist/language/flows/flow-replay-types.d.ts +9 -0
- package/dist/language/flows/flow-replay.d.ts +27 -12
- package/dist/language/flows/flow-replay.js +127 -111
- package/dist/language/flows/flow-result.d.ts +2 -0
- package/dist/language/flows/flow-result.js +25 -0
- package/dist/language/flows/flow-step-runners.d.ts +26 -10
- package/dist/language/flows/flow-step-runners.js +20 -4
- package/dist/language/flows/flow-success.d.ts +21 -6
- package/dist/language/flows/flow-success.js +50 -138
- package/dist/language/flows/flow-tools.js +17 -5
- package/dist/language/flows/flows.d.ts +18 -5
- package/dist/language/flows/flows.js +101 -16
- package/dist/language/flows/heal.d.ts +9 -1
- package/dist/language/flows/heal.js +24 -2
- package/dist/language/flows/learned-sources.d.ts +21 -0
- package/dist/language/flows/learned-sources.js +84 -0
- package/dist/language/flows/recording/recording-backtrack.d.ts +0 -7
- package/dist/language/flows/recording/recording-backtrack.js +1 -1
- package/dist/language/flows/recording/replay-halt.d.ts +2 -1
- package/dist/language/flows/recording/replay-halt.js +3 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +31 -2
- package/dist/language/flows/recording/tape/recordings.js +55 -1
- package/dist/language/flows/replay.d.ts +19 -0
- package/dist/language/flows/replay.js +53 -13
- package/dist/language/flows/stores/annotation-store.d.ts +5 -5
- package/dist/language/flows/stores/assertion-tiers-store.js +2 -3
- package/dist/language/flows/stores/flake-store.js +2 -3
- package/dist/language/flows/suite/coverage.d.ts +1 -1
- package/dist/language/flows/suite/parallel-suite.d.ts +2 -1
- package/dist/language/flows/verify-change-tools.js +19 -2
- package/dist/launch-chromium.d.ts +80 -0
- package/dist/launch-chromium.js +218 -0
- package/dist/memory/cloud/cloud-config.d.ts +11 -2
- package/dist/memory/cloud/cloud-config.js +47 -7
- package/dist/memory/cloud/cloud-sync.d.ts +4 -3
- package/dist/memory/cloud/cloud-sync.js +7 -10
- package/dist/memory/cloud/harness-config.d.ts +2 -0
- package/dist/memory/cloud/harness-offer.js +5 -6
- package/dist/memory/cloud/harness-switch.js +5 -6
- package/dist/memory/cloud/sync-cycle.d.ts +78 -1
- package/dist/memory/cloud/sync-cycle.js +321 -53
- package/dist/memory/cloud/sync-daemon.d.ts +13 -0
- package/dist/memory/cloud/sync-daemon.js +45 -20
- package/dist/memory/cloud/sync-disk.js +27 -8
- package/dist/memory/impact/impact-store.js +6 -0
- package/dist/memory/intent/inline-intent.js +8 -3
- package/dist/memory/intent/intent-shard-store.d.ts +33 -47
- package/dist/memory/intent/intent-shard-store.js +252 -140
- package/dist/memory/intent/intent-shard.d.ts +0 -23
- package/dist/memory/intent/intent-shard.js +1 -11
- package/dist/memory/intent/intent-store.d.ts +13 -8
- package/dist/memory/intent/intent-store.js +46 -90
- package/dist/memory/intent/intent-tools.js +34 -23
- package/dist/memory/journal/ambient-store.js +2 -3
- package/dist/memory/journal/deviation-report.js +4 -1
- package/dist/memory/journal/deviation-service.js +10 -2
- package/dist/memory/journal/drive-flow.d.ts +19 -14
- package/dist/memory/journal/drive-flow.js +65 -48
- package/dist/memory/journal/envelope-store.js +2 -3
- package/dist/memory/journal/journal-recorder.d.ts +21 -0
- package/dist/memory/journal/on-disk/retain-policy.d.ts +34 -0
- package/dist/memory/journal/on-disk/retain-policy.js +44 -0
- package/dist/memory/journal/on-disk/retention.d.ts +14 -10
- package/dist/memory/journal/on-disk/retention.js +13 -12
- package/dist/memory/journal/on-disk/startup-maintenance.d.ts +42 -0
- package/dist/memory/journal/on-disk/startup-maintenance.js +14 -0
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +0 -11
- package/dist/memory/journal/on-disk/workspace-gitignore.js +6 -45
- package/dist/memory/journal/on-disk/workspace-tiers.d.ts +52 -0
- package/dist/memory/journal/on-disk/workspace-tiers.js +90 -0
- package/dist/memory/journal/route-template.d.ts +22 -0
- package/dist/memory/journal/route-template.js +44 -0
- package/dist/memory/journal/session-end.d.ts +13 -2
- package/dist/memory/journal/session-end.js +88 -18
- package/dist/memory/journal/session-journal.d.ts +8 -1
- package/dist/memory/journal/session-journal.js +10 -0
- package/dist/memory/project/baselines.d.ts +1 -1
- package/dist/memory/project/dir/reticle-dir.d.ts +3 -1
- package/dist/memory/project/dir/reticle-dir.js +1 -0
- package/dist/memory/project/fs/fs-port.js +44 -5
- package/dist/memory/project/fs/write-atomic.d.ts +26 -0
- package/dist/memory/project/fs/write-atomic.js +48 -0
- package/dist/memory/project/project-tools.js +3 -1
- package/dist/memory/recall/prior/connection-memory.d.ts +6 -0
- package/dist/memory/recall/prior/connection-memory.js +8 -0
- package/dist/memory/recall/registered-projects.d.ts +2 -1
- package/dist/portal/bridge/auth-failure-reason.d.ts +1 -1
- package/dist/portal/bridge/auth-failure-reason.js +9 -4
- package/dist/portal/bridge/bridge.d.ts +8 -0
- package/dist/portal/bridge/bridge.js +43 -2
- package/dist/portal/input/js-coverage.d.ts +25 -0
- package/dist/portal/input/js-coverage.js +30 -0
- package/dist/portal/input/real-input.d.ts +11 -0
- package/dist/portal/input/real-input.js +31 -5
- package/dist/portal/pool/browser-pool.d.ts +10 -0
- package/dist/portal/pool/browser-pool.js +10 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +21 -13
- package/dist/portal/pool/pool-contract.d.ts +2 -0
- package/dist/portal/pool/storage-seed.d.ts +2 -1
- package/dist/portal/pool/zero-install.d.ts +27 -0
- package/dist/portal/pool/zero-install.js +54 -0
- package/dist/portal/realm/web-realm.js +6 -0
- package/dist/portal/session/dev-server/dev-command.d.ts +2 -2
- package/dist/portal/session/dev-server/dev-command.js +30 -12
- package/dist/portal/session/dev-server/dev-server-probe.d.ts +2 -1
- package/dist/portal/session/dev-server/dev-server-probe.js +17 -1
- package/dist/portal/session/dev-server/route-status-probe.d.ts +24 -0
- package/dist/portal/session/dev-server/route-status-probe.js +57 -0
- package/dist/portal/session/dev-server/served-document.d.ts +21 -0
- package/dist/portal/session/dev-server/served-document.js +57 -0
- package/dist/portal/session/facts/background-traffic.d.ts +9 -0
- package/dist/portal/session/facts/background-traffic.js +25 -0
- package/dist/portal/session/facts/observed-state.d.ts +11 -0
- package/dist/portal/session/facts/observed-state.js +34 -0
- package/dist/portal/session/live-control-tools.js +48 -3
- package/dist/portal/session/no-session-diagnosis.d.ts +29 -0
- package/dist/portal/session/no-session-diagnosis.js +62 -5
- package/dist/portal/session/no-session-next-action.d.ts +13 -0
- package/dist/portal/session/no-session-next-action.js +48 -9
- package/dist/portal/session/no-session-watch.d.ts +18 -0
- package/dist/portal/session/no-session-watch.js +88 -2
- package/dist/portal/session/presence/attachment-history.d.ts +13 -2
- package/dist/portal/session/session-health.d.ts +61 -0
- package/dist/portal/session/session-health.js +43 -3
- package/dist/portal/session/session-info.d.ts +6 -0
- package/dist/portal/session/session-manager.d.ts +29 -6
- package/dist/portal/session/session-manager.js +42 -5
- package/dist/portal/session/session-reaper.d.ts +28 -0
- package/dist/portal/session/session-reaper.js +49 -1
- package/dist/portal/session/session-successor.d.ts +11 -0
- package/dist/portal/session/session-successor.js +14 -1
- package/dist/portal/session/session-verdict-facts.d.ts +28 -0
- package/dist/portal/session/session-verdict-facts.js +15 -0
- package/dist/portal/session/session.d.ts +10 -0
- package/dist/portal/session/session.js +34 -26
- package/dist/surface/http-server.d.ts +2 -1
- package/dist/surface/http-server.js +4 -2
- package/dist/surface/mcp/mcp-proxy.d.ts +2 -2
- package/dist/surface/mcp/mcp-proxy.js +5 -5
- package/dist/surface/mcp/mcp.js +4 -2
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +13 -1
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +27 -2
- package/dist/surface/mcp/proxy-idle-exit.d.ts +2 -1
- package/dist/surface/mcp/server-instructions.js +21 -8
- package/dist/surface/tools/act/after-match.d.ts +17 -0
- package/dist/surface/tools/act/after-match.js +30 -0
- package/dist/surface/tools/act/already-true.d.ts +40 -0
- package/dist/surface/tools/act/already-true.js +36 -0
- package/dist/surface/tools/act/durable.d.ts +69 -0
- package/dist/surface/tools/act/durable.js +139 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +19 -6
- package/dist/surface/tools/act/navigation/navigate-arrival.js +60 -10
- package/dist/surface/tools/act/navigation/navigate-result.d.ts +1 -12
- package/dist/surface/tools/act/navigation/navigate-result.js +21 -3
- package/dist/surface/tools/act/proved-controls.d.ts +9 -0
- package/dist/surface/tools/act/proved-controls.js +11 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +5 -0
- package/dist/surface/tools/act/sequence-grade.js +32 -1
- package/dist/surface/tools/act/settle-in-flight.d.ts +6 -2
- package/dist/surface/tools/act/settle-in-flight.js +29 -6
- package/dist/surface/tools/act-capsule.d.ts +7 -0
- package/dist/surface/tools/act-capsule.js +68 -8
- package/dist/surface/tools/act-sequence-tool.js +25 -8
- package/dist/surface/tools/act-tools.js +51 -74
- package/dist/surface/tools/args/numeric-bounds.d.ts +15 -2
- package/dist/surface/tools/args/numeric-bounds.js +30 -3
- package/dist/surface/tools/assert/assert-grade.js +26 -3
- package/dist/surface/tools/assert/assert-verdict.js +32 -6
- package/dist/surface/tools/browser-tools.js +17 -4
- package/dist/surface/tools/coverage-tools.js +27 -1
- package/dist/surface/tools/dynamic-tools.js +6 -0
- package/dist/surface/tools/error-recovery.js +4 -4
- package/dist/surface/tools/feedback-invite.js +6 -4
- package/dist/surface/tools/feedback-tools.d.ts +2 -1
- package/dist/surface/tools/feedback-tools.js +1 -1
- package/dist/surface/tools/harness-explore.d.ts +3 -2
- package/dist/surface/tools/harness-explore.js +7 -6
- package/dist/surface/tools/invoke-tool.js +17 -4
- package/dist/surface/tools/lease-hint.d.ts +8 -0
- package/dist/surface/tools/lease-hint.js +10 -0
- package/dist/surface/tools/lease-tools.d.ts +16 -28
- package/dist/surface/tools/lease-tools.js +68 -11
- package/dist/surface/tools/lineage-tools.js +1 -1
- package/dist/surface/tools/live-call-text.js +4 -1
- package/dist/surface/tools/observe-tools.js +23 -7
- package/dist/surface/tools/real-input-attempt.d.ts +0 -5
- package/dist/surface/tools/real-input-attempt.js +1 -1
- package/dist/surface/tools/tool-kit.d.ts +5 -0
- package/dist/surface/tools/tool-kit.js +6 -1
- package/dist/surface/tools/tool-surface.js +17 -5
- package/dist/surface/tools/tools.js +68 -29
- package/dist/telemetry/argument-shape.d.ts +0 -2
- package/dist/telemetry/argument-shape.js +0 -4
- package/dist/telemetry/error-class.d.ts +2 -3
- package/dist/telemetry/error-class.js +2 -3
- package/dist/telemetry/feedback-local.d.ts +1 -0
- package/dist/telemetry/feedback-local.js +1 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/harness-drive.d.ts +0 -2
- package/dist/telemetry/harness-drive.js +0 -4
- package/dist/telemetry/hud-metrics.d.ts +32 -0
- package/dist/telemetry/hud-metrics.js +95 -0
- package/dist/telemetry/session-metrics.d.ts +5 -0
- package/dist/telemetry/session-metrics.js +15 -1
- package/dist/wire-journal.d.ts +34 -0
- package/dist/wire-journal.js +104 -0
- package/dist/workspace-packages.d.ts +0 -2
- package/dist/workspace-packages.js +1 -9
- package/docs/README.md +5 -2
- package/docs/actions.mdx +3 -3
- package/docs/agent-cheatsheet.md +4 -4
- package/docs/architecture.md +6 -6
- package/docs/best-practices.mdx +1 -1
- package/docs/capabilities.mdx +32 -1
- package/docs/cli/cloud.mdx +21 -9
- package/docs/cli/doctor.mdx +4 -0
- package/docs/cli/feedback.mdx +2 -2
- package/docs/cli/gate.mdx +9 -4
- package/docs/cli/init.mdx +1 -0
- package/docs/cli/report.mdx +44 -0
- package/docs/cli/update.mdx +10 -0
- package/docs/cli.mdx +9 -0
- package/docs/desktop.mdx +14 -10
- package/docs/environment.mdx +87 -0
- package/docs/faq.mdx +18 -16
- package/docs/first-drive.md +5 -13
- package/docs/flows.md +32 -2
- package/docs/frameworks.mdx +140 -9
- package/docs/getting-started.md +3 -3
- package/docs/http-transport.md +6 -3
- package/docs/human-control.md +2 -2
- package/docs/index.mdx +16 -6
- package/docs/install-agentic.mdx +37 -1
- package/docs/install-manual.mdx +1 -1
- package/docs/integration-patterns.md +3 -3
- package/docs/multi-agent-testing.md +1 -1
- package/docs/packages/babel-plugin.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/react.mdx +2 -2
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages/vite-plugin.mdx +2 -2
- package/docs/packages.mdx +9 -9
- package/docs/predicates.mdx +176 -7
- package/docs/quickstart.mdx +2 -2
- package/docs/recipes.mdx +2 -2
- package/docs/state-management.mdx +2 -2
- package/docs/system-map.md +1 -1
- package/docs/telemetry.md +1 -1
- package/docs/token-efficiency.md +3 -3
- package/docs/tools/act-and-wait.mdx +1 -0
- package/docs/tools/act-sequence.mdx +1 -1
- package/docs/tools/console.mdx +1 -1
- package/docs/tools/inspect.mdx +1 -1
- package/docs/tools/network.mdx +1 -1
- package/docs/tools/query.mdx +11 -11
- package/docs/tools/sessions.mdx +1 -1
- package/docs/tools/snapshot.mdx +1 -1
- package/docs/tools/state.mdx +1 -1
- package/docs/tools/wait-for.mdx +1 -1
- package/docs/usage.md +8 -7
- package/docs/use-cases.mdx +157 -0
- package/docs/vs-screenshots.mdx +3 -3
- package/docs/what-is-recorded.md +62 -0
- package/docs/what-is-reticle.mdx +17 -20
- package/docs/why-reticle.mdx +14 -21
- package/package.json +11 -10
- package/dist/judgement/capsule/minimize.d.ts +0 -12
- package/dist/judgement/capsule/minimize.js +0 -22
- package/dist/judgement/outcome/predicate-to-expect.d.ts +0 -44
- package/dist/judgement/outcome/predicate-to-expect.js +0 -148
- package/dist/judgement/phenomena/phenomena.d.ts +0 -26
- package/dist/judgement/phenomena/phenomena.js +0 -101
- package/dist/language/flows/flow-report.d.ts +0 -22
- package/dist/language/flows/flow-report.js +0 -106
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Verified } from '@reticlehq/core';
|
|
2
|
+
/**
|
|
3
|
+
* Remember the control an act_and_wait PROVED, for the coverage ledger's `proved` level.
|
|
4
|
+
*
|
|
5
|
+
* Structural rather than `Session`, and optional, so a test stub that never proves anything need not
|
|
6
|
+
* implement it — the same reason `beginAction` is optional on the crawl session.
|
|
7
|
+
*/
|
|
8
|
+
export function noteProved(session, verified, actPayload) {
|
|
9
|
+
if (Verified.YES === verified)
|
|
10
|
+
session.recordProvedFrom?.(actPayload);
|
|
11
|
+
}
|
|
@@ -35,6 +35,11 @@ export interface StepExpectation {
|
|
|
35
35
|
/** What was seen instead, on a miss — the half of the answer a repair actually needs. */
|
|
36
36
|
observed?: string;
|
|
37
37
|
expected?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Contradiction kinds positively observed in this step's window — deciding ones only, the same
|
|
40
|
+
* filter act_and_wait applies. A held step with one is a UI that advanced over a failed write.
|
|
41
|
+
*/
|
|
42
|
+
contradicted?: readonly string[];
|
|
38
43
|
}
|
|
39
44
|
export interface SequenceGrade {
|
|
40
45
|
verified: Verified;
|
|
@@ -27,7 +27,9 @@ export function gradeSequence(steps, plan = { planned: steps.length, dispatched:
|
|
|
27
27
|
const total = Math.max(plan.planned, steps.length);
|
|
28
28
|
const declaring = steps.filter((step) => step.declared);
|
|
29
29
|
const declared = declaring.length;
|
|
30
|
-
|
|
30
|
+
// `held: false` on an undeclared step means it could not be performed at all — the journey broke
|
|
31
|
+
// there whether or not anything was declared about it.
|
|
32
|
+
const missed = steps.find((step) => (step.declared ? true !== step.held : false === step.held));
|
|
31
33
|
// A miss decides the grade before coverage does. How much of the plan declared nothing is
|
|
32
34
|
// context on a red, never a softening of it.
|
|
33
35
|
if (missed !== undefined) {
|
|
@@ -39,6 +41,17 @@ export function gradeSequence(steps, plan = { planned: steps.length, dispatched:
|
|
|
39
41
|
because: `a declared consequence did not hold — observed ${observed}`,
|
|
40
42
|
};
|
|
41
43
|
}
|
|
44
|
+
// Same rule as a single action: an observed contradiction outranks a consequence that held.
|
|
45
|
+
const contradictedAt = steps.findIndex((step) => (step.contradicted ?? []).length > 0);
|
|
46
|
+
if (contradictedAt >= 0) {
|
|
47
|
+
const kinds = (steps[contradictedAt]?.contradicted ?? []).join(', ');
|
|
48
|
+
return {
|
|
49
|
+
verified: Verified.NO,
|
|
50
|
+
declared,
|
|
51
|
+
total,
|
|
52
|
+
because: `step ${String(contradictedAt + 1)}: channels disagree about this action (${kinds}) even though it went on`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
42
55
|
/*
|
|
43
56
|
* `unknown` rather than `no-fault`, and the distinction is load-bearing.
|
|
44
57
|
*
|
|
@@ -68,6 +81,24 @@ export function gradeSequence(steps, plan = { planned: steps.length, dispatched:
|
|
|
68
81
|
: `nothing was dispatched, so none of the ${String(total)} step(s) ran — read the per-step \`error\` for the one that was refused, and fix that before adding an \`expect\``,
|
|
69
82
|
};
|
|
70
83
|
}
|
|
84
|
+
// A journey is proved at its END. Declaring only early steps checks that it started, and a yes
|
|
85
|
+
// there was the one a single act_and_wait on the last step would never have given.
|
|
86
|
+
if (steps.length < total) {
|
|
87
|
+
return {
|
|
88
|
+
verified: Verified.UNKNOWN,
|
|
89
|
+
declared,
|
|
90
|
+
total,
|
|
91
|
+
because: `only ${String(steps.length)} of ${String(total)} steps ran, so the journey never reached its end`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (true !== steps.at(-1)?.declared) {
|
|
95
|
+
return {
|
|
96
|
+
verified: Verified.UNKNOWN,
|
|
97
|
+
declared,
|
|
98
|
+
total,
|
|
99
|
+
because: `the last step, where the journey ends, declared nothing — give it an \`expect\` naming the end state (${String(declared)} of ${String(total)} steps declared one)`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
71
102
|
return {
|
|
72
103
|
verified: Verified.YES,
|
|
73
104
|
declared,
|
|
@@ -34,6 +34,10 @@ export interface SettleSource {
|
|
|
34
34
|
data: Record<string, unknown>;
|
|
35
35
|
}[];
|
|
36
36
|
elapsed(): number;
|
|
37
|
+
/** The page under test — what makes a request third-party. Absent: nothing is foreign. */
|
|
38
|
+
url?: string;
|
|
39
|
+
/** Same-origin endpoints the project declared as background. Absent: nothing is excluded. */
|
|
40
|
+
background?: readonly string[];
|
|
37
41
|
}
|
|
38
42
|
interface WaitOpts {
|
|
39
43
|
/** Injected so the wait is testable without real time passing (rule: never call the clock inline). */
|
|
@@ -49,7 +53,7 @@ interface WaitOpts {
|
|
|
49
53
|
export declare function inFlightRequestIds(events: readonly {
|
|
50
54
|
type: string;
|
|
51
55
|
data: Record<string, unknown>;
|
|
52
|
-
}[]): string[];
|
|
56
|
+
}[], appOrigin?: string, background?: readonly string[]): string[];
|
|
53
57
|
/**
|
|
54
58
|
* The same outstanding requests, as "METHOD url" — what an unsettled verdict has to be able to name.
|
|
55
59
|
*
|
|
@@ -61,7 +65,7 @@ export declare function inFlightRequestIds(events: readonly {
|
|
|
61
65
|
export declare function inFlightRequestLabels(events: readonly {
|
|
62
66
|
type: string;
|
|
63
67
|
data: Record<string, unknown>;
|
|
64
|
-
}[]): string[];
|
|
68
|
+
}[], appOrigin?: string, background?: readonly string[]): string[];
|
|
65
69
|
/**
|
|
66
70
|
* Endpoints called MORE THAN ONCE in this window, busiest first, as "METHOD url ×N".
|
|
67
71
|
*
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* - still in flight when the budget genuinely runs out → `unsettled`, as before, but now an honest
|
|
28
28
|
* limit instead of an early exit.
|
|
29
29
|
*/
|
|
30
|
-
import { EventType, NetInitiator, isDevToolingUrl } from '@reticlehq/core';
|
|
30
|
+
import { EventType, NetInitiator, isDevToolingUrl, isForeignTraffic } from '@reticlehq/core';
|
|
31
31
|
/**
|
|
32
32
|
* The dev toolchain talking about ITSELF is not the app finishing its work.
|
|
33
33
|
*
|
|
@@ -37,6 +37,25 @@ import { EventType, NetInitiator, isDevToolingUrl } from '@reticlehq/core';
|
|
|
37
37
|
* was graded on the strength of a Next webpack hot-update the same payload printed as ignored.
|
|
38
38
|
*/
|
|
39
39
|
const isDevTooling = (data) => isDevToolingUrl('string' === typeof data['url'] ? data['url'] : undefined);
|
|
40
|
+
/**
|
|
41
|
+
* Somebody else's host is not the app finishing its work.
|
|
42
|
+
*
|
|
43
|
+
* The comment above makes this argument for dev tooling and it holds identically here:
|
|
44
|
+
* `splitForeignTraffic` drops dev tooling AND third-party traffic, and this file dropped only the
|
|
45
|
+
* first — so the exclusion stayed cosmetic exactly where it decides a verdict, for the other half.
|
|
46
|
+
*
|
|
47
|
+
* Reported from the field repeatedly: an app embedding a wallet SDK that continuously POSTs
|
|
48
|
+
* telemetry to its vendor host never settles, so EVERY assertion on that app returns
|
|
49
|
+
* `unknown / outcome_pending` whatever the feature under test was. A third-party beacon cannot
|
|
50
|
+
* answer "has the app finished?", and nothing makes it stop, so waiting for it is waiting forever.
|
|
51
|
+
*
|
|
52
|
+
* Fails OPEN: with no known app origin nothing is foreign, because suppressing a request we cannot
|
|
53
|
+
* classify is how a verdict starts resting on evidence it discarded.
|
|
54
|
+
*
|
|
55
|
+
* SAME-ORIGIN background traffic is never guessed: nothing in a URL separates the app's telemetry
|
|
56
|
+
* from the app's work. It is excluded only when the project DECLARED it (`background`).
|
|
57
|
+
*/
|
|
58
|
+
const isForeign = (data, appOrigin, background) => isForeignTraffic('string' === typeof data['url'] ? data['url'] : undefined, appOrigin, background);
|
|
40
59
|
/**
|
|
41
60
|
* A departure records where the browser was SENT, not a request whose result we will see — the
|
|
42
61
|
* response is delivered to a document this session does not live into. It can never be matched by a
|
|
@@ -54,7 +73,7 @@ const idOf = (data) => 'string' === typeof data['id'] ? data['id'] : undefined;
|
|
|
54
73
|
* the act cursor, so a response belonging to an earlier action can land inside it, and counting that
|
|
55
74
|
* as progress would let unrelated traffic close the window early.
|
|
56
75
|
*/
|
|
57
|
-
export function inFlightRequestIds(events) {
|
|
76
|
+
export function inFlightRequestIds(events, appOrigin, background = []) {
|
|
58
77
|
const settled = new Set();
|
|
59
78
|
for (const e of events) {
|
|
60
79
|
if (e.type !== EventType.NET_REQUEST)
|
|
@@ -67,6 +86,8 @@ export function inFlightRequestIds(events) {
|
|
|
67
86
|
for (const e of events) {
|
|
68
87
|
if (e.type !== EventType.NET_PENDING || isDevTooling(e.data) || isDeparture(e.data))
|
|
69
88
|
continue;
|
|
89
|
+
if (isForeign(e.data, appOrigin, background))
|
|
90
|
+
continue;
|
|
70
91
|
const id = idOf(e.data);
|
|
71
92
|
if (id !== undefined && !settled.has(id) && !open.includes(id))
|
|
72
93
|
open.push(id);
|
|
@@ -81,8 +102,8 @@ export function inFlightRequestIds(events) {
|
|
|
81
102
|
* directly. Read off the NET_PENDING the window already holds, so this costs one pass over events
|
|
82
103
|
* that are in hand.
|
|
83
104
|
*/
|
|
84
|
-
export function inFlightRequestLabels(events) {
|
|
85
|
-
const open = new Set(inFlightRequestIds(events));
|
|
105
|
+
export function inFlightRequestLabels(events, appOrigin, background = []) {
|
|
106
|
+
const open = new Set(inFlightRequestIds(events, appOrigin, background));
|
|
86
107
|
const labels = [];
|
|
87
108
|
for (const e of events) {
|
|
88
109
|
if (e.type !== EventType.NET_PENDING)
|
|
@@ -136,7 +157,9 @@ export function repeatedRequestLabels(events) {
|
|
|
136
157
|
* timeout reaching the predicate, and a negative deadline must mean "stop", never "loop forever".
|
|
137
158
|
*/
|
|
138
159
|
export async function waitForInFlight(session, since, budgetMs, opts) {
|
|
139
|
-
|
|
160
|
+
// The verdict's own scope: waiting on a request the verdict will not count is latency for nothing.
|
|
161
|
+
const outstanding = () => inFlightRequestIds(session.eventsSince(since), session.url, session.background);
|
|
162
|
+
let open = outstanding();
|
|
140
163
|
if (0 === open.length)
|
|
141
164
|
return { settled: true, stillInFlight: [] };
|
|
142
165
|
if (budgetMs <= 0)
|
|
@@ -145,7 +168,7 @@ export async function waitForInFlight(session, since, budgetMs, opts) {
|
|
|
145
168
|
while (session.elapsed() < deadline) {
|
|
146
169
|
// Never overshoot the budget: the last sleep is trimmed to whatever is actually left.
|
|
147
170
|
await opts.sleep(Math.min(POLL_MS, deadline - session.elapsed()));
|
|
148
|
-
open =
|
|
171
|
+
open = outstanding();
|
|
149
172
|
if (0 === open.length)
|
|
150
173
|
return { settled: true, stillInFlight: [] };
|
|
151
174
|
}
|
|
@@ -28,6 +28,13 @@ interface CapsuleSaveInputs {
|
|
|
28
28
|
*/
|
|
29
29
|
root?: string | undefined;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* What the act claimed would happen, in words: `route /settings`, `POST /v1/pay → 200`,
|
|
33
|
+
* `element "Issues"`. Read off the predicate the agent declared, because the causal links only name
|
|
34
|
+
* signals and requests: a failed route, element or text claim used to be filed as "declared
|
|
35
|
+
* consequence", which tells whoever reads the capsule nothing about what was expected.
|
|
36
|
+
*/
|
|
37
|
+
export declare function describeExpected(predicate: unknown): string | undefined;
|
|
31
38
|
/** Returns the capsule id when one was written, or undefined when there was nothing to save. */
|
|
32
39
|
export declare function saveFailedAssertCapsule(inputs: CapsuleSaveInputs): Promise<string | undefined>;
|
|
33
40
|
export {};
|
|
@@ -10,16 +10,59 @@
|
|
|
10
10
|
* must never fail the run that found it.
|
|
11
11
|
*/
|
|
12
12
|
import { ActionType, AnchorKind } from '@reticlehq/core';
|
|
13
|
-
import { CapsuleStore, capsuleId, CAPSULE_VERSION } from '../../judgement/capsule/capsule-store.js';
|
|
13
|
+
import { CapsuleStore, capsuleFingerprint, capsuleId, CAPSULE_VERSION, } from '../../judgement/capsule/capsule-store.js';
|
|
14
14
|
import { ReticleTool } from '@reticlehq/core';
|
|
15
15
|
import { asRecord, asString } from '@reticlehq/core';
|
|
16
16
|
import { sessionRoot } from '../../memory/project/session-root.js';
|
|
17
|
+
/**
|
|
18
|
+
* What the act claimed would happen, in words: `route /settings`, `POST /v1/pay → 200`,
|
|
19
|
+
* `element "Issues"`. Read off the predicate the agent declared, because the causal links only name
|
|
20
|
+
* signals and requests: a failed route, element or text claim used to be filed as "declared
|
|
21
|
+
* consequence", which tells whoever reads the capsule nothing about what was expected.
|
|
22
|
+
*/
|
|
23
|
+
export function describeExpected(predicate) {
|
|
24
|
+
const p = asRecord(predicate);
|
|
25
|
+
const kind = asString(p['kind']);
|
|
26
|
+
if (kind === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
const all = (key, joiner) => {
|
|
29
|
+
const parts = (Array.isArray(p[key]) ? p[key] : [])
|
|
30
|
+
.map(describeExpected)
|
|
31
|
+
.filter((d) => d !== undefined);
|
|
32
|
+
return 0 === parts.length ? undefined : parts.join(joiner);
|
|
33
|
+
};
|
|
34
|
+
const q = asRecord(p['query']);
|
|
35
|
+
const named = asString(p['name']) ?? asString(q['name']) ?? asString(q['value']) ?? asString(q['testid']);
|
|
36
|
+
switch (kind) {
|
|
37
|
+
case 'route':
|
|
38
|
+
return `route ${asString(p['pathname']) ?? asString(p['contains']) ?? '?'}`;
|
|
39
|
+
case 'net': {
|
|
40
|
+
const status = 'number' === typeof p['status'] ? ` → ${String(p['status'])}` : '';
|
|
41
|
+
return `${asString(p['method']) ?? 'a'} ${asString(p['urlContains']) ?? 'request'}${status}`;
|
|
42
|
+
}
|
|
43
|
+
case 'signal':
|
|
44
|
+
return `signal ${asString(p['name']) ?? '?'}`;
|
|
45
|
+
case 'element':
|
|
46
|
+
return `${true === p['absent'] ? 'no ' : ''}element ${named === undefined ? '?' : `"${named}"`}`;
|
|
47
|
+
case 'text':
|
|
48
|
+
return `${true === p['absent'] ? 'no ' : ''}text "${asString(p['contains']) ?? '?'}"`;
|
|
49
|
+
case 'allOf':
|
|
50
|
+
return all('predicates', ' AND ');
|
|
51
|
+
case 'anyOf':
|
|
52
|
+
return all('predicates', ' OR ');
|
|
53
|
+
case 'not': {
|
|
54
|
+
const inner = describeExpected(p['predicate']);
|
|
55
|
+
return inner === undefined ? undefined : `not ${inner}`;
|
|
56
|
+
}
|
|
57
|
+
default:
|
|
58
|
+
return kind;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
17
61
|
/** Returns the capsule id when one was written, or undefined when there was nothing to save. */
|
|
18
62
|
export async function saveFailedAssertCapsule(inputs) {
|
|
19
63
|
const { deps, verdict, capsule, links, args, actResult, actedSource, root: given } = inputs;
|
|
20
64
|
if (verdict.pass || capsule === undefined)
|
|
21
65
|
return undefined;
|
|
22
|
-
const id = capsuleId(deps.now(), asString(args['ref']) ?? 'assert');
|
|
23
66
|
const expectedText = links
|
|
24
67
|
.map((l) => ('name' in l ? `${l.kind} ${String(l.name)}` : l.kind))
|
|
25
68
|
.join(' AND ');
|
|
@@ -33,26 +76,43 @@ export async function saveFailedAssertCapsule(inputs) {
|
|
|
33
76
|
// verdict is already built, and losing the capsule must never also lose the verdict.
|
|
34
77
|
if (root === undefined)
|
|
35
78
|
return undefined;
|
|
36
|
-
|
|
79
|
+
// Built BEFORE the id, because the id carries the fingerprint of this body — that is what lets a
|
|
80
|
+
// retry of the same broken step fold into the capsule already on disk instead of adding a file.
|
|
81
|
+
/*
|
|
82
|
+
* What this capsule is ABOUT, for its filename and its anchor.
|
|
83
|
+
*
|
|
84
|
+
* The testid is the element said in a name a human chose; `args.ref` is a volatile handle minted
|
|
85
|
+
* per session, meaningless an hour later and anywhere else. The anchor may still fall back to the
|
|
86
|
+
* ref, because the anchor has to address the element and the ref is what addressed it. The NAME
|
|
87
|
+
* must not: a capsule is durable, meant to be committed, and read by somebody who was not there.
|
|
88
|
+
*/
|
|
89
|
+
const testid = asString(asRecord(actResult.result)['testid']);
|
|
90
|
+
const action = asString(args['action']) ?? ActionType.CLICK;
|
|
91
|
+
const body = {
|
|
37
92
|
version: CAPSULE_VERSION,
|
|
38
|
-
id,
|
|
39
|
-
createdAt: deps.now(),
|
|
40
93
|
origin: 'failed-assert',
|
|
41
|
-
expected:
|
|
94
|
+
expected: describeExpected(args['until'] ?? args['predicate']) ??
|
|
95
|
+
(expectedText.length > 0 ? expectedText : 'declared consequence'),
|
|
42
96
|
observed: capsule.firstDivergence?.observed ?? verdict.failureReason ?? 'not observed',
|
|
43
97
|
steps: [
|
|
44
98
|
{
|
|
45
99
|
tool: ReticleTool.ACT,
|
|
46
100
|
anchor: {
|
|
47
101
|
kind: AnchorKind.TESTID,
|
|
48
|
-
value:
|
|
102
|
+
value: testid ?? asString(args['ref']) ?? '',
|
|
49
103
|
// Carried so the saved capsule — which outlives this turn and becomes a regression flow
|
|
50
104
|
// when it goes green — still knows which file the failure came from.
|
|
51
105
|
...(actedSource === undefined ? {} : { source: actedSource }),
|
|
52
106
|
},
|
|
53
|
-
action:
|
|
107
|
+
action: action,
|
|
54
108
|
},
|
|
55
109
|
],
|
|
110
|
+
};
|
|
111
|
+
const id = capsuleId(deps.now(), testid ?? action, capsuleFingerprint(body));
|
|
112
|
+
const saved = await new CapsuleStore(deps.fs, root).save({
|
|
113
|
+
...body,
|
|
114
|
+
id,
|
|
115
|
+
createdAt: deps.now(),
|
|
56
116
|
});
|
|
57
117
|
return saved ? id : undefined;
|
|
58
118
|
}
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
import { timeoutMsSchema } from './args/numeric-bounds.js';
|
|
14
|
-
import { compileSequenceStep } from '../../language/flows/replay.js';
|
|
14
|
+
import { compileSequenceStep, pathOf } from '../../language/flows/replay.js';
|
|
15
15
|
import { sequenceStepArgs } from './act/act-preflight.js';
|
|
16
16
|
import { ReticleTool } from '@reticlehq/core';
|
|
17
17
|
import { healthEnvelope } from '../../portal/session/session-health.js';
|
|
18
18
|
import { pausedShortCircuit, pausedOutputShape, withControl, } from '../../portal/session/control-envelope.js';
|
|
19
|
-
import { asRecord } from '@reticlehq/core';
|
|
19
|
+
import { asRecord, isAbsenceDerived, isAdvisory } from '@reticlehq/core';
|
|
20
20
|
import { sessionIdFromArgs } from './tools-helpers.js';
|
|
21
21
|
import { describeStepResult, runStepWithStaleRetry } from './act/act-sequence-retry.js';
|
|
22
22
|
import { assertSequenceSteps } from './act/act-preflight.js';
|
|
@@ -59,10 +59,9 @@ function effectOf(session, since) {
|
|
|
59
59
|
const BURST_MAX_GAP_MS = 500;
|
|
60
60
|
export const ACT_SEQUENCE_TOOL = {
|
|
61
61
|
name: ReticleTool.ACT_SEQUENCE,
|
|
62
|
-
// The example is required for a core tool, and this one carries weight: the
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// exact shape an agent otherwise spends three round trips on.
|
|
62
|
+
// The example is required for a core tool, and this one carries weight: the loop it replaces is
|
|
63
|
+
// a login form driven as three separate reticle_act calls. Showing fill -> fill -> click is showing
|
|
64
|
+
// the exact shape an agent otherwise spends three round trips on.
|
|
66
65
|
example: {
|
|
67
66
|
steps: [
|
|
68
67
|
{ ref: 'e12', action: 'fill', args: { value: 'a@b.com' } },
|
|
@@ -133,6 +132,7 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
133
132
|
if (paused !== undefined)
|
|
134
133
|
return paused;
|
|
135
134
|
const since = session.elapsed();
|
|
135
|
+
const pageBefore = pathOf(session.url);
|
|
136
136
|
session.beginAction(ReticleTool.ACT_SEQUENCE, asRecord(args));
|
|
137
137
|
try {
|
|
138
138
|
const inputSteps = Array.isArray(args['steps']) ? args['steps'] : [];
|
|
@@ -230,8 +230,12 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
230
230
|
* satisfy step four's assertion, which is a false green built out of correct parts.
|
|
231
231
|
*/
|
|
232
232
|
const parsed = PredicateSchema.safeParse(step['expect']);
|
|
233
|
+
const contradicted = (described.contradictions ?? [])
|
|
234
|
+
.map((c) => c.kind)
|
|
235
|
+
.filter((kind) => !isAdvisory(kind) && !isAbsenceDerived(kind));
|
|
236
|
+
const disagreement = 0 === contradicted.length ? {} : { contradicted };
|
|
233
237
|
if (!parsed.success) {
|
|
234
|
-
expectations.push({ declared: false });
|
|
238
|
+
expectations.push({ declared: false, ...disagreement });
|
|
235
239
|
stepResults.push(described);
|
|
236
240
|
}
|
|
237
241
|
else {
|
|
@@ -240,6 +244,7 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
240
244
|
expectations.push({
|
|
241
245
|
declared: true,
|
|
242
246
|
held,
|
|
247
|
+
...disagreement,
|
|
243
248
|
...(verdict.observed === undefined ? {} : { observed: verdict.observed }),
|
|
244
249
|
...(verdict.expected === undefined ? {} : { expected: verdict.expected }),
|
|
245
250
|
});
|
|
@@ -287,7 +292,19 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
287
292
|
// Same as captureAct: no `active()` gate, so a sequence driven with nothing open still lands
|
|
288
293
|
// in the ambient tape. A stalled plan is still excluded — those steps never ran.
|
|
289
294
|
if (stalledAt === undefined) {
|
|
290
|
-
|
|
295
|
+
// A sub-step keeps its `expect` only if it held — same rule as act_and_wait, so a flow
|
|
296
|
+
// never replays an expectation that was never once observed to hold.
|
|
297
|
+
const proved = inputSteps.map((raw, i) => {
|
|
298
|
+
const step = asRecord(raw);
|
|
299
|
+
const { expect: _expect, ...rest } = step;
|
|
300
|
+
return true === expectations[i]?.held ? step : rest;
|
|
301
|
+
});
|
|
302
|
+
const recorded = compileSequenceStep({ ...args, steps: proved }, {
|
|
303
|
+
count: inputSteps.length,
|
|
304
|
+
steps: stepResults,
|
|
305
|
+
});
|
|
306
|
+
deps.recordings.capture(pageBefore === undefined ? recorded : { ...recorded, page: pageBefore });
|
|
307
|
+
deps.recordings.markEnded(pathOf(session.url));
|
|
291
308
|
}
|
|
292
309
|
/*
|
|
293
310
|
* The grade, and the coverage it is never allowed to hide.
|