@reticlehq/server 3.6.0 → 3.7.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 +122 -123
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +18 -2
- package/dist/command/cli/adhoc-verdict.js +70 -6
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +28 -105
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +34 -4
- package/dist/command/cli/cli-verify.js +81 -12
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +145 -333
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +15 -1
- package/dist/command/cli/cloud-login.js +67 -13
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.js +1 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +29 -8
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -178
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +14 -0
- package/dist/command/cli.js +103 -83
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +9 -1
- package/dist/command/daemon/daemon-resolve.js +49 -10
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +10 -1
- package/dist/command/setup/init/init-port.js +22 -2
- package/dist/command/setup/init/init-runtime.d.ts +12 -2
- package/dist/command/setup/init/init-runtime.js +96 -37
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +36 -8
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +1 -1
- package/dist/command/setup/run-setup.d.ts +29 -9
- package/dist/command/setup/run-setup.js +34 -28
- package/dist/command/setup/setup-command.d.ts +23 -0
- package/dist/command/setup/setup-command.js +57 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +38 -2
- package/dist/features/crawl/crawl.js +14 -1
- package/dist/features/exhaust/ledger.d.ts +14 -14
- package/dist/features/harness/drive-report.d.ts +39 -5
- package/dist/features/harness/drive-report.js +271 -54
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/goals.d.ts +68 -7
- package/dist/features/harness/goals.js +289 -36
- package/dist/features/harness/harness.d.ts +30 -1
- package/dist/features/harness/harness.js +141 -7
- package/dist/features/harness/platform/local-apps.d.ts +36 -3
- package/dist/features/harness/platform/local-apps.js +81 -5
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +8 -2
- package/dist/features/harness/platform/remote-drive.js +22 -9
- package/dist/features/harness/platform/script.d.ts +57 -11
- package/dist/features/harness/platform/script.js +144 -12
- package/dist/features/harness/platform/server-driver.d.ts +17 -4
- package/dist/features/harness/platform/server-driver.js +29 -26
- package/dist/features/harness/platform-config.d.ts +38 -5
- package/dist/features/harness/platform-config.js +93 -8
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/script-run.d.ts +30 -1
- package/dist/features/harness/script/script-run.js +355 -48
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.js +22 -14
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +21 -2
- package/dist/hooks/driven-by.js +42 -2
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -183
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
- package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
- package/dist/judgement/runs/artifact/run-store.js +175 -8
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +53 -5
- package/dist/judgement/runs/drive-run.js +234 -20
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +5 -2
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +2 -0
- package/dist/judgement/runs/verification-sync.js +36 -15
- package/dist/language/flows/decision.js +2 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +7 -2
- package/dist/language/flows/flow-anchor.js +10 -3
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +37 -3
- package/dist/language/flows/flow-replay-run.js +16 -18
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +18 -1
- package/dist/language/flows/flow-replay.js +22 -7
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-step-runners.d.ts +2 -0
- package/dist/language/flows/flow-step-runners.js +12 -6
- package/dist/language/flows/flow-store-for-session.js +5 -1
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +61 -62
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +69 -10
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
- package/dist/language/flows/recording/tape/recordings.js +60 -10
- package/dist/language/flows/replay.js +29 -6
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +200 -193
- package/dist/memory/cloud/cloud-config.d.ts +10 -1
- package/dist/memory/cloud/cloud-config.js +19 -5
- package/dist/memory/cloud/cloud-sync.js +3 -3
- package/dist/memory/cloud/harness-config.d.ts +49 -0
- package/dist/memory/cloud/harness-config.js +16 -20
- package/dist/memory/cloud/memory-scope.d.ts +17 -0
- package/dist/memory/cloud/memory-scope.js +22 -0
- package/dist/memory/cloud/sync-cycle.d.ts +32 -4
- package/dist/memory/cloud/sync-cycle.js +113 -12
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +114 -4
- package/dist/memory/cloud/sync-disk.js +26 -2
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +16 -1
- package/dist/memory/impact/account-watch.js +26 -1
- package/dist/memory/impact/impact-store.d.ts +1 -4
- package/dist/memory/impact/impact-store.js +32 -42
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +12 -0
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +42 -2
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/journal-recorder.js +46 -3
- package/dist/memory/journal/on-disk/retention.d.ts +5 -0
- package/dist/memory/journal/on-disk/retention.js +27 -2
- package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +38 -7
- package/dist/memory/project/artifact-root-resolver.js +33 -5
- package/dist/memory/project/artifact-root.d.ts +4 -3
- package/dist/memory/project/artifact-root.js +2 -2
- package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
- package/dist/memory/project/dir/reticle-dir.js +23 -2
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +2 -0
- package/dist/memory/project/session-root.js +9 -1
- package/dist/memory/project/sync-status.d.ts +46 -0
- package/dist/memory/project/sync-status.js +135 -1
- package/dist/memory/recall/memory-tools.js +46 -3
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.js +36 -8
- package/dist/portal/bridge/bridge.d.ts +9 -5
- package/dist/portal/bridge/bridge.js +66 -23
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +2 -0
- package/dist/portal/input/real-input.js +13 -10
- package/dist/portal/pool/browser-pool.d.ts +48 -0
- package/dist/portal/pool/browser-pool.js +120 -2
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +27 -5
- package/dist/portal/pool/playwright-launcher.js +59 -14
- package/dist/portal/pool/pool-contract.d.ts +21 -1
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.js +6 -1
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
- package/dist/portal/session/dev-server/dev-command.js +27 -1
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/live-control-tools.js +82 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
- package/dist/portal/session/no-session-diagnosis.js +31 -9
- package/dist/portal/session/no-session-next-action.d.ts +20 -0
- package/dist/portal/session/no-session-next-action.js +134 -61
- package/dist/portal/session/no-session-watch.js +179 -22
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/session-health.d.ts +11 -0
- package/dist/portal/session/session-health.js +3 -1
- package/dist/portal/session/session-info.js +2 -1
- package/dist/portal/session/session-manager.d.ts +18 -0
- package/dist/portal/session/session-manager.js +54 -3
- package/dist/portal/session/session-successor.d.ts +8 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session.d.ts +15 -28
- package/dist/portal/session/session.js +60 -61
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +7 -1
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +13 -1
- package/dist/status-payload.js +13 -1
- package/dist/surface/http-server.js +7 -1
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
- package/dist/surface/mcp/mcp-proxy.js +29 -8
- package/dist/surface/mcp/mcp.d.ts +23 -0
- package/dist/surface/mcp/mcp.js +34 -4
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.js +22 -14
- package/dist/surface/mcp/shared-params.js +1 -1
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act-sequence-tool.js +136 -27
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +48 -34
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.js +25 -15
- package/dist/surface/tools/browser-tools.js +43 -1
- package/dist/surface/tools/chat-drives.d.ts +75 -0
- package/dist/surface/tools/chat-drives.js +265 -21
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +10 -0
- package/dist/surface/tools/empty-session-list.js +45 -5
- package/dist/surface/tools/error-recovery.d.ts +8 -0
- package/dist/surface/tools/error-recovery.js +69 -5
- package/dist/surface/tools/explore-tools.d.ts +23 -2
- package/dist/surface/tools/explore-tools.js +377 -74
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +4 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +52 -73
- package/dist/surface/tools/harness-explore.js +177 -146
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +5 -0
- package/dist/surface/tools/harness-plan.js +7 -0
- package/dist/surface/tools/harness-script.d.ts +22 -0
- package/dist/surface/tools/harness-script.js +256 -38
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +8 -0
- package/dist/surface/tools/harness-toolset.js +27 -4
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +220 -93
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +20 -0
- package/dist/surface/tools/lease-seed.js +45 -1
- package/dist/surface/tools/lease-tools.d.ts +10 -1
- package/dist/surface/tools/lease-tools.js +119 -69
- package/dist/surface/tools/live-call-text.js +2 -2
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +11 -1
- package/dist/surface/tools/next-step.js +73 -18
- package/dist/surface/tools/observe-tools.js +43 -5
- package/dist/surface/tools/platform-moment.d.ts +60 -0
- package/dist/surface/tools/platform-moment.js +132 -4
- package/dist/surface/tools/read-tools.js +65 -14
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +68 -2
- package/dist/surface/tools/tool-kit.js +73 -1
- package/dist/surface/tools/tools.js +25 -13
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +27 -6
- package/dist/telemetry/hud-metrics.js +99 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +26 -2
- package/dist/telemetry/telemetry.js +102 -21
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +12 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +16 -5
- package/docs/README.md +2 -2
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +24 -27
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +13 -12
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +8 -3
- package/docs/cli/drive.mdx +12 -12
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +32 -15
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +13 -4
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +3 -2
- package/docs/cli.mdx +110 -41
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +5 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +5 -2
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +66 -64
- package/docs/human-control.md +15 -14
- package/docs/index.mdx +15 -43
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +22 -12
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +8 -8
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +11 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +58 -29
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +22 -24
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +13 -4
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +51 -45
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +7 -5
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +6 -5
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -249
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
|
@@ -8,15 +8,108 @@
|
|
|
8
8
|
* Barriers cannot deadlock: a journey only waits on one in an EARLIER lane (`checkScript`), lanes
|
|
9
9
|
* are started in order, so whatever is waited on has already started.
|
|
10
10
|
*/
|
|
11
|
-
import { PredicateKind, ReplayStatus, ReticleTool, ScriptStatus, Verified, asRecord, } from '@reticlehq/core';
|
|
12
|
-
import { ScriptStepKind, barriersOf, stepLabel, } from '@reticlehq/core/artifacts';
|
|
13
|
-
import { checkTally } from '../drive-report.js';
|
|
14
|
-
import {
|
|
11
|
+
import { PredicateKind, ReplayStatus, ReticleTool, ScriptStatus, Verified, asRecord, asString, } from '@reticlehq/core';
|
|
12
|
+
import { JourneyBy, JourneyOutcome, ScriptStepKind, barriersOf, stepLabel, } from '@reticlehq/core/artifacts';
|
|
13
|
+
import { ReplayOutcome, checkTally, replayedFlows } from '../drive-report.js';
|
|
14
|
+
import { endOf, lookFor } from '../goals.js';
|
|
15
15
|
import { DEFAULT_MAX_STEPS, StopReason, } from '../harness.js';
|
|
16
16
|
/** Why a journey failed when its goal, not a check, is what was missing. */
|
|
17
17
|
const GOAL_NOT_REACHED = 'the goal was not reached, though its checks may have held';
|
|
18
18
|
/** A planned open journey gets the same budget a named persona drive gets. */
|
|
19
19
|
const OPEN_GOAL_STEPS = DEFAULT_MAX_STEPS;
|
|
20
|
+
/** Fewer model turns left than this and a continuation could not take the step it is sent for. */
|
|
21
|
+
const MIN_CONTINUE_STEPS = 3;
|
|
22
|
+
/** Why a journey whose replays decided nothing was handed to the model. */
|
|
23
|
+
const FELL_BACK = 'its replays decided nothing, so the model drove its goal';
|
|
24
|
+
/** A replay that neither held nor failed: drifted, unverifiable, or a flow not on this computer. */
|
|
25
|
+
const UNDECIDED_REPLAY = new Set([
|
|
26
|
+
ReplayOutcome.DRIFT,
|
|
27
|
+
ReplayOutcome.MISSING,
|
|
28
|
+
ReplayStatus.UNVERIFIABLE,
|
|
29
|
+
undefined,
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* The journey's replays decided nothing about the app: one could not anchor or run, and none failed.
|
|
33
|
+
* A held sign-in beside a drifted mid-session flow is not a failure of the app, and read "Failed".
|
|
34
|
+
*/
|
|
35
|
+
function replaysDecidedNothing(calls) {
|
|
36
|
+
const replays = replayedFlows(calls);
|
|
37
|
+
return (replays.some((r) => UNDECIDED_REPLAY.has(r.status)) &&
|
|
38
|
+
!replays.some((r) => ReplayOutcome.ERROR === r.status));
|
|
39
|
+
}
|
|
40
|
+
/** Why a journey whose replay could not anchor or run is undecided, not failed. */
|
|
41
|
+
const msgReplayUndecided = (flow) => `the recording ${flow} could not anchor or run on this app, which decides nothing about the app`;
|
|
42
|
+
/** The flows a journey replayed or saved, each once, in the order it touched them. */
|
|
43
|
+
function flowsOf(calls) {
|
|
44
|
+
const names = calls.flatMap((call) => {
|
|
45
|
+
if (ReticleTool.FLOW_REPLAY === call.name)
|
|
46
|
+
return [asString(asRecord(call.args)['flowName'])];
|
|
47
|
+
if (ReticleTool.FLOW_SAVE !== call.name || call.isError)
|
|
48
|
+
return [];
|
|
49
|
+
const args = asRecord(call.args);
|
|
50
|
+
return [
|
|
51
|
+
asString(asRecord(call.result)['name']) ??
|
|
52
|
+
asString(args['saveAs']) ??
|
|
53
|
+
asString(args['flowName']),
|
|
54
|
+
];
|
|
55
|
+
});
|
|
56
|
+
return [...new Set(names.filter((n) => n !== undefined))];
|
|
57
|
+
}
|
|
58
|
+
/** What a journey's own model drives cost, and what it touched. */
|
|
59
|
+
function journeyRun(id, calls, own) {
|
|
60
|
+
const credits = own.flatMap((d) => (d.creditsSpent === undefined ? [] : [d.creditsSpent]));
|
|
61
|
+
// Replayed only when it replayed: a model goal the end-already-shown guard stopped spent no
|
|
62
|
+
// tokens and was called "replayed, no model tokens" on a journey that had no replay at all.
|
|
63
|
+
const by = 0 < own.length
|
|
64
|
+
? JourneyBy.MODEL
|
|
65
|
+
: 0 < replayedFlows(calls).length
|
|
66
|
+
? JourneyBy.REPLAY
|
|
67
|
+
: undefined;
|
|
68
|
+
return {
|
|
69
|
+
id,
|
|
70
|
+
...(by === undefined ? {} : { by }),
|
|
71
|
+
tokens: own.reduce((n, d) => n + d.usage.input + d.usage.output + d.usage.cacheRead + d.usage.cacheWrite, 0),
|
|
72
|
+
...(0 === credits.length ? {} : { credits: credits.reduce((a, b) => a + b, 0) }),
|
|
73
|
+
flows: flowsOf([...calls, ...own.flatMap((d) => d.toolCalls)]),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** Two lanes' runs of one journey, as one: the model's cost added, every flow kept. */
|
|
77
|
+
function mergeRuns(a, b) {
|
|
78
|
+
const credits = a.credits === undefined && b.credits === undefined
|
|
79
|
+
? undefined
|
|
80
|
+
: (a.credits ?? 0) + (b.credits ?? 0);
|
|
81
|
+
const by = [JourneyBy.MODEL, JourneyBy.REPLAY].find((k) => k === a.by || k === b.by);
|
|
82
|
+
return {
|
|
83
|
+
id: a.id,
|
|
84
|
+
...(by === undefined ? {} : { by }),
|
|
85
|
+
tokens: a.tokens + b.tokens,
|
|
86
|
+
...(credits === undefined ? {} : { credits }),
|
|
87
|
+
flows: [...new Set([...a.flows, ...b.flows])],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** How a journey was answered, as its line says it: only what was measured. */
|
|
91
|
+
function byText(run) {
|
|
92
|
+
if (run?.by === undefined)
|
|
93
|
+
return '';
|
|
94
|
+
return JourneyBy.REPLAY === run.by
|
|
95
|
+
? ' · replayed, no model tokens'
|
|
96
|
+
: ` · driven by the model, ${String(run.tokens)} tokens`;
|
|
97
|
+
}
|
|
98
|
+
/** Why a journey whose end the page showed before it acted is not credited with it. */
|
|
99
|
+
const msgEndAlreadyShown = (end) => `"${end}" was already on the page before this journey acted, so reaching it proves nothing`;
|
|
100
|
+
/**
|
|
101
|
+
* Whether a journey picks up where the one before it in its lane left off: it builds on one there
|
|
102
|
+
* (`dependsOn`), or it looks at how one failed. Every other journey starts from the lane's start.
|
|
103
|
+
*/
|
|
104
|
+
function continuesLane(journey, before) {
|
|
105
|
+
return (journey.dependsOn.some((id) => before.has(id)) ||
|
|
106
|
+
(journey.when !== undefined &&
|
|
107
|
+
JourneyOutcome.FAILED === journey.when.is &&
|
|
108
|
+
before.has(journey.when.journey)));
|
|
109
|
+
}
|
|
110
|
+
/** What a drive that stopped short of its end state is sent back with. */
|
|
111
|
+
const continueGoal = (goal, end) => `${goal}\n\nContinue from the page you are on: it does not show "${end}" yet. ` +
|
|
112
|
+
'Take the next step this journey names; do not start over.';
|
|
20
113
|
export async function runScript(script, ports, onChange = () => undefined) {
|
|
21
114
|
const view = planView(script, Math.min(ports.parallel, script.maxParallel ?? ports.parallel));
|
|
22
115
|
const toolCalls = [];
|
|
@@ -30,7 +123,8 @@ export async function runScript(script, ports, onChange = () => undefined) {
|
|
|
30
123
|
/* the picture of a drive is never a reason to stop it */
|
|
31
124
|
}
|
|
32
125
|
};
|
|
33
|
-
// A journey that sits in several lanes is answered by the FIRST lane holding it; barriers wait on
|
|
126
|
+
// A journey that sits in several lanes is answered by the FIRST lane holding it; barriers wait on
|
|
127
|
+
// that. It is answered with how it ended, because a condition can be waiting for a failure.
|
|
34
128
|
const outcome = new Map();
|
|
35
129
|
const firstLane = new Map();
|
|
36
130
|
for (const lane of script.lanes) {
|
|
@@ -47,45 +141,134 @@ export async function runScript(script, ports, onChange = () => undefined) {
|
|
|
47
141
|
/** Journeys whose checks may have held but whose goal the drive did not reach. */
|
|
48
142
|
const goalMissed = new Set();
|
|
49
143
|
const broken = new Map();
|
|
144
|
+
/** Per card, for its line; per id, for the platform. */
|
|
145
|
+
const runOf = new Map();
|
|
146
|
+
const runs = new Map();
|
|
50
147
|
tell();
|
|
51
148
|
const runLane = async (lane, laneIndex) => {
|
|
52
149
|
const cards = view.lanes[laneIndex]?.journeys ?? [];
|
|
53
|
-
const settleOwned = (id,
|
|
150
|
+
const settleOwned = (id, status) => {
|
|
54
151
|
if (firstLane.get(id) === lane.id)
|
|
55
|
-
outcome.get(id)?.settle(
|
|
152
|
+
outcome.get(id)?.settle(status);
|
|
56
153
|
};
|
|
57
154
|
let lease;
|
|
58
155
|
let blocked = false;
|
|
156
|
+
/** Where the lane's first journey started, and the journeys the lane has driven since. */
|
|
157
|
+
let start;
|
|
158
|
+
const driven = new Set();
|
|
59
159
|
try {
|
|
60
160
|
for (const [position, id] of lane.journeys.entries()) {
|
|
61
161
|
const card = cards[position];
|
|
62
162
|
const journey = journeyById.get(id);
|
|
63
163
|
if (card === undefined || journey === undefined)
|
|
64
164
|
continue;
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
165
|
+
const ended = (dep) => outcome.get(dep)?.promise ?? Promise.resolve(ScriptStatus.BLOCKED);
|
|
166
|
+
const waits = await Promise.all(barriersOf(script, lane.id, id).map(ended));
|
|
167
|
+
// A conditional journey is decided by how the journey it names ended, not by the lane: a
|
|
168
|
+
// failure earlier in the lane is often exactly what it is there to look at.
|
|
169
|
+
const when = journey.when;
|
|
170
|
+
const lanePast = when === undefined && blocked;
|
|
171
|
+
if (lanePast ||
|
|
172
|
+
stopped ||
|
|
173
|
+
ports.stopped() ||
|
|
174
|
+
waits.some((s) => ScriptStatus.PASSED !== s)) {
|
|
175
|
+
if (when === undefined)
|
|
176
|
+
blocked = true;
|
|
68
177
|
card.status = ScriptStatus.BLOCKED;
|
|
69
|
-
settleOwned(id,
|
|
178
|
+
settleOwned(id, ScriptStatus.BLOCKED);
|
|
179
|
+
tell();
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (when !== undefined && (await ended(when.journey)) !== when.is) {
|
|
183
|
+
card.status = ScriptStatus.NOT_TAKEN;
|
|
184
|
+
settleOwned(id, ScriptStatus.NOT_TAKEN);
|
|
70
185
|
tell();
|
|
71
186
|
continue;
|
|
72
187
|
}
|
|
73
188
|
lease ??= await ports.lease(lane.id);
|
|
74
|
-
const
|
|
189
|
+
const raw = ports.toolset(lease.sessionId, journey.persona);
|
|
190
|
+
// Unrecorded: where the journey starts is set-up, not something it drove or checked.
|
|
191
|
+
// Kept for a journey with a fallback too: its goal starts where the journey began, not
|
|
192
|
+
// on the page its own replays left (where the end may already show).
|
|
193
|
+
if (0 === driven.size && (1 < lane.journeys.length || journey.fallback !== undefined))
|
|
194
|
+
start = asString(asRecord(asRecord(await call(raw, ReticleTool.SNAPSHOT, {}))['status'])['route']);
|
|
195
|
+
else if (start !== undefined && !continuesLane(journey, driven))
|
|
196
|
+
await call(raw, ReticleTool.NAVIGATE, { url: start });
|
|
197
|
+
driven.add(id);
|
|
198
|
+
// This journey's calls alone too: lanes share `toolCalls`, and its replays decide its fallback.
|
|
199
|
+
const mine = [];
|
|
200
|
+
const tools = recording(recording(raw, toolCalls), mine);
|
|
75
201
|
card.status = ScriptStatus.RUNNING;
|
|
76
202
|
tell();
|
|
77
203
|
// This journey's own drives: lanes run side by side, so a slice of the shared list after the
|
|
78
204
|
// await could hold another lane's missed goal and blame it on this journey.
|
|
79
205
|
const own = [];
|
|
80
|
-
const
|
|
206
|
+
const stop = () => {
|
|
81
207
|
stopped = true;
|
|
82
|
-
}
|
|
83
|
-
|
|
208
|
+
};
|
|
209
|
+
// The end the fallback goal names, and whether the page showed it before anything ran: a
|
|
210
|
+
// replay can only be credited with an end it put there.
|
|
211
|
+
const end = journey.fallback === undefined ? undefined : endOf(journey.fallback.goal);
|
|
212
|
+
const endBefore = end !== undefined && (await lookFor(raw.invoke.bind(raw), end, ports.own));
|
|
213
|
+
let ran = await runJourney(journey, card.steps, tools, ports, own, tell, stop);
|
|
214
|
+
// Replay first: replays that decided nothing hand the journey's goal to the model. One that
|
|
215
|
+
// failed is a regression, and a regression is reported, never re-driven into a pass.
|
|
216
|
+
let refused;
|
|
217
|
+
if (!ran.ok &&
|
|
218
|
+
ran.notTaken === undefined &&
|
|
219
|
+
journey.fallback !== undefined &&
|
|
220
|
+
!ports.stopped() &&
|
|
221
|
+
replaysDecidedNothing(mine)) {
|
|
222
|
+
// Replays that decided nothing can still have driven the journey to its end. Driven
|
|
223
|
+
// over MCP: the replay pressed Generate and the page showed the goal's end text; the
|
|
224
|
+
// Harness threw that away, re-drove from a start that signed the app out, and failed a
|
|
225
|
+
// working app. The end is judged where the replay left it, by an assert kept as the
|
|
226
|
+
// run's check — and never when the page showed it before the journey ran.
|
|
227
|
+
const replayReachedEnd = end !== undefined &&
|
|
228
|
+
!endBefore &&
|
|
229
|
+
(await lookFor(raw.invoke.bind(raw), end, ports.own)) &&
|
|
230
|
+
(await holds(tools, { kind: PredicateKind.TEXT, contains: end }));
|
|
231
|
+
if (replayReachedEnd)
|
|
232
|
+
ran = { ok: true };
|
|
233
|
+
else
|
|
234
|
+
refused = await ports.fallbackRefused?.();
|
|
235
|
+
if (!replayReachedEnd && refused === undefined) {
|
|
236
|
+
if (start !== undefined)
|
|
237
|
+
await call(raw, ReticleTool.NAVIGATE, { url: start });
|
|
238
|
+
ran = await runFallback(journey.fallback.goal, tools, ports, own, stop);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const ok = ran.ok;
|
|
242
|
+
// A drive the platform cut off (credits gone, a refusal, a 5xx) judged nothing: blocked, and
|
|
243
|
+
// its reason said, never "failed" over an app nobody finished driving.
|
|
244
|
+
const cutDrive = own.find((d) => StopReason.BROKEN === d.stopReason);
|
|
245
|
+
const cut = refused === undefined ? cutDrive : { error: refused, stopReason: StopReason.BROKEN };
|
|
246
|
+
if (cut !== undefined)
|
|
247
|
+
broken.set(lane.id, cut.error ?? StopReason.BROKEN);
|
|
248
|
+
card.status = ok
|
|
249
|
+
? ScriptStatus.PASSED
|
|
250
|
+
: cut !== undefined
|
|
251
|
+
? ScriptStatus.BLOCKED
|
|
252
|
+
: ran.notTaken !== undefined
|
|
253
|
+
? ScriptStatus.NOT_TAKEN
|
|
254
|
+
: true === ran.undecided
|
|
255
|
+
? ScriptStatus.UNDECIDED
|
|
256
|
+
: ScriptStatus.FAILED;
|
|
257
|
+
if (ran.notTaken !== undefined)
|
|
258
|
+
card.why = ran.notTaken;
|
|
259
|
+
if (ran.why !== undefined)
|
|
260
|
+
card.why = ran.why;
|
|
84
261
|
drives.push(...own);
|
|
262
|
+
const thisRun = journeyRun(id, mine, own);
|
|
263
|
+
runOf.set(card, thisRun);
|
|
264
|
+
const before = runs.get(id);
|
|
265
|
+
runs.set(id, before === undefined ? thisRun : mergeRuns(before, thisRun));
|
|
85
266
|
if (!ok && own.some((d) => false === d.goalMet))
|
|
86
267
|
goalMissed.add(card);
|
|
87
|
-
|
|
88
|
-
|
|
268
|
+
// A conditional journey that failed leaves the lane as it found it: it was a side road.
|
|
269
|
+
if (when === undefined)
|
|
270
|
+
blocked = !ok;
|
|
271
|
+
settleOwned(id, card.status);
|
|
89
272
|
tell();
|
|
90
273
|
}
|
|
91
274
|
}
|
|
@@ -99,7 +282,7 @@ export async function runScript(script, ports, onChange = () => undefined) {
|
|
|
99
282
|
}
|
|
100
283
|
}
|
|
101
284
|
for (const id of lane.journeys)
|
|
102
|
-
settleOwned(id,
|
|
285
|
+
settleOwned(id, ScriptStatus.BLOCKED);
|
|
103
286
|
tell();
|
|
104
287
|
}
|
|
105
288
|
finally {
|
|
@@ -121,13 +304,22 @@ export async function runScript(script, ports, onChange = () => undefined) {
|
|
|
121
304
|
? broken.get(lane.id)
|
|
122
305
|
: goalMissed.has(card)
|
|
123
306
|
? GOAL_NOT_REACHED
|
|
124
|
-
:
|
|
125
|
-
return `${mark(card.status)} ${lane.id} · ${card.title} — ${card.status}${why === undefined ? '' : ` (${why.slice(0, 160)})`}`;
|
|
307
|
+
: card.why;
|
|
308
|
+
return `${mark(card.status)} ${lane.id} · ${card.title} — ${card.status}${why === undefined ? '' : ` (${why.slice(0, 160)})`}${byText(runOf.get(card))}`;
|
|
126
309
|
}));
|
|
127
|
-
return {
|
|
310
|
+
return {
|
|
311
|
+
view,
|
|
312
|
+
toolCalls,
|
|
313
|
+
drives,
|
|
314
|
+
stopped: stopped || ports.stopped(),
|
|
315
|
+
lines,
|
|
316
|
+
journeys: [...runs.values()],
|
|
317
|
+
};
|
|
128
318
|
}
|
|
129
319
|
async function runJourney(journey, cards, tools, ports, drives, tell, stop) {
|
|
130
320
|
const checkpoints = new Map();
|
|
321
|
+
// One journey is one chain: a replay after the first continues the page the one before it left.
|
|
322
|
+
let replayed = false;
|
|
131
323
|
for (const [index, step] of journey.steps.entries()) {
|
|
132
324
|
const card = cards[index];
|
|
133
325
|
if (card === undefined)
|
|
@@ -135,32 +327,87 @@ async function runJourney(journey, cards, tools, ports, drives, tell, stop) {
|
|
|
135
327
|
if (ports.stopped()) {
|
|
136
328
|
card.status = ScriptStatus.BLOCKED;
|
|
137
329
|
tell();
|
|
138
|
-
return false;
|
|
330
|
+
return { ok: false };
|
|
139
331
|
}
|
|
140
332
|
card.status = ScriptStatus.RUNNING;
|
|
141
333
|
tell();
|
|
142
334
|
let ok;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
335
|
+
let notTaken;
|
|
336
|
+
let why;
|
|
337
|
+
let undecided = false;
|
|
338
|
+
try {
|
|
339
|
+
if (ScriptStepKind.CHECKPOINT === step.kind) {
|
|
340
|
+
checkpoints.set(step.id, step.reenter);
|
|
341
|
+
ok = true;
|
|
342
|
+
}
|
|
343
|
+
else if (ScriptStepKind.BRANCH === step.kind) {
|
|
344
|
+
ok = await runBranch(step, checkpoints.get(step.at), tools, ports, drives, stop);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
ok = await runLeaf(step, tools, ports, drives, stop, replayed);
|
|
348
|
+
if (ScriptStepKind.REPLAY === step.kind)
|
|
349
|
+
replayed = true;
|
|
350
|
+
}
|
|
149
351
|
}
|
|
150
|
-
|
|
151
|
-
|
|
352
|
+
catch (error) {
|
|
353
|
+
if (error instanceof Undecided) {
|
|
354
|
+
why = error.message;
|
|
355
|
+
undecided = true;
|
|
356
|
+
}
|
|
357
|
+
else if (error instanceof StepNotTaken)
|
|
358
|
+
notTaken = error.message;
|
|
359
|
+
else
|
|
360
|
+
throw error;
|
|
361
|
+
ok = false;
|
|
152
362
|
}
|
|
153
|
-
card.status = ok
|
|
363
|
+
card.status = ok
|
|
364
|
+
? ScriptStatus.PASSED
|
|
365
|
+
: notTaken !== undefined
|
|
366
|
+
? ScriptStatus.NOT_TAKEN
|
|
367
|
+
: undecided
|
|
368
|
+
? ScriptStatus.UNDECIDED
|
|
369
|
+
: ScriptStatus.FAILED;
|
|
154
370
|
tell();
|
|
155
371
|
if (!ok) {
|
|
156
372
|
for (const rest of cards.slice(index + 1))
|
|
157
373
|
rest.status = ScriptStatus.BLOCKED;
|
|
158
374
|
tell();
|
|
159
|
-
return
|
|
375
|
+
return {
|
|
376
|
+
ok: false,
|
|
377
|
+
...(notTaken === undefined ? {} : { notTaken }),
|
|
378
|
+
...(why === undefined ? {} : { why }),
|
|
379
|
+
...(undecided ? { undecided: true } : {}),
|
|
380
|
+
};
|
|
160
381
|
}
|
|
161
382
|
}
|
|
162
|
-
return true;
|
|
383
|
+
return { ok: true };
|
|
384
|
+
}
|
|
385
|
+
/** The journey's goal, driven by the model in place of replays that decided nothing. */
|
|
386
|
+
async function runFallback(goal, tools, ports, drives, stop) {
|
|
387
|
+
try {
|
|
388
|
+
const ok = await runLeaf({ kind: ScriptStepKind.ACT, goal }, tools, ports, drives, stop);
|
|
389
|
+
return ok ? { ok } : { ok, why: FELL_BACK };
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
if (error instanceof Undecided)
|
|
393
|
+
return { ok: false, why: error.message, undecided: true };
|
|
394
|
+
throw error;
|
|
395
|
+
}
|
|
163
396
|
}
|
|
397
|
+
/** The guard stopped a destructive step nobody acknowledged: the step was not taken, not failed. */
|
|
398
|
+
class StepNotTaken extends Error {
|
|
399
|
+
}
|
|
400
|
+
/** The journey ran and decided nothing: neither proved nor a failure of the app. */
|
|
401
|
+
class Undecided extends Error {
|
|
402
|
+
}
|
|
403
|
+
/** The journey's end was on the page before it acted: undecided, never credited, no model spent. */
|
|
404
|
+
class EndAlreadyShown extends Undecided {
|
|
405
|
+
}
|
|
406
|
+
/** Why a journey that reached its goal with no check that could go red proves nothing. */
|
|
407
|
+
const MSG_GOAL_WITHOUT_CHECK = 'it reached its goal, and no check could have gone red there';
|
|
408
|
+
/** What the guard's refusal names, as `drive-report.ts` reads it too. */
|
|
409
|
+
const DESTRUCTIVE_REFUSAL = 'confirmDangerous';
|
|
410
|
+
const MSG_NOT_TAKEN = 'not taken: a step the flow marks destructive needs a person to acknowledge it (Run plan, Re-verify)';
|
|
164
411
|
/**
|
|
165
412
|
* Every case drives from the checkpoint. The first starts where the journey already is; each later
|
|
166
413
|
* one re-enters it first, so no case inherits the page the previous case left behind.
|
|
@@ -188,35 +435,73 @@ async function runBranch(step, reenter, tools, ports, drives, stop) {
|
|
|
188
435
|
}
|
|
189
436
|
return all;
|
|
190
437
|
}
|
|
191
|
-
async function runLeaf(step, tools, ports, drives, stop
|
|
438
|
+
async function runLeaf(step, tools, ports, drives, stop,
|
|
439
|
+
/** A replay ran before this one in the journey: continue its page, never reload it. */
|
|
440
|
+
chained = false) {
|
|
192
441
|
switch (step.kind) {
|
|
193
442
|
case ScriptStepKind.REPLAY:
|
|
194
443
|
return replay(tools, {
|
|
195
444
|
flowName: step.flow,
|
|
196
|
-
...(step.at === undefined ? {} : { at: step.at }),
|
|
445
|
+
...(step.at === undefined ? (chained ? { at: 0 } : {}) : { at: step.at }),
|
|
197
446
|
...(step.to === undefined ? {} : { to: step.to }),
|
|
447
|
+
// The flow's own steps, acknowledged by the person who started the run.
|
|
448
|
+
...(true === ports.confirmDangerous ? { [DESTRUCTIVE_REFUSAL]: true } : {}),
|
|
198
449
|
});
|
|
199
450
|
case ScriptStepKind.ASSERT:
|
|
200
451
|
return holds(tools, step.predicate);
|
|
201
452
|
case ScriptStepKind.ACT: {
|
|
202
453
|
if (step.goal !== undefined) {
|
|
203
|
-
const
|
|
454
|
+
const budget = step.maxSteps ?? OPEN_GOAL_STEPS;
|
|
455
|
+
// Parsed before the drive: an end the page already shows is already true, never proved.
|
|
456
|
+
const ending = endOf(step.goal);
|
|
457
|
+
if (ending !== undefined && (await lookFor(tools.invoke.bind(tools), ending, ports.own)))
|
|
458
|
+
throw new EndAlreadyShown(msgEndAlreadyShown(ending));
|
|
459
|
+
let drive = await ports.drive(tools, step.goal, budget);
|
|
204
460
|
drives.push(drive);
|
|
205
461
|
if (StopReason.STOPPED === drive.stopReason)
|
|
206
462
|
stop();
|
|
207
|
-
// Passed means its checks held, not that it ran one: a refund journey whose two checks both
|
|
208
|
-
// failed was marked passed because a check had run.
|
|
209
|
-
const tally = checkTally(drive.toolCalls);
|
|
210
|
-
if (0 < tally.failed || false === drive.goalMet)
|
|
211
|
-
return false;
|
|
212
463
|
// A goal that quotes where it ends is judged there, by an assert kept as the run's check:
|
|
213
464
|
// the model clicked a counter with no `until` and the journey failed on a counter that worked.
|
|
214
|
-
// ponytail: the LAST quote is the end state ("from "count: 0" to
|
|
215
|
-
// quotes its end first needs the planner to say which
|
|
216
|
-
const end =
|
|
217
|
-
if (end
|
|
218
|
-
|
|
219
|
-
|
|
465
|
+
// ponytail: the LAST quote the goal does not negate is the end state ("from "count: 0" to
|
|
466
|
+
// "count: 1""); a goal that quotes its end first needs the planner to say which is the end.
|
|
467
|
+
const end = ending;
|
|
468
|
+
if (end === undefined) {
|
|
469
|
+
// Passed means its checks held, not that it ran one: a refund journey whose two checks
|
|
470
|
+
// both failed was marked passed because a check had run.
|
|
471
|
+
if (0 < checkTally(drive.toolCalls).failed)
|
|
472
|
+
return false;
|
|
473
|
+
if (0 < checkTally(drive.toolCalls).held)
|
|
474
|
+
return false !== drive.goalMet;
|
|
475
|
+
// Reached, by its own word, with nothing checked: not proved, and not a failure either.
|
|
476
|
+
if (true === drive.goalMet)
|
|
477
|
+
throw new Undecided(MSG_GOAL_WITHOUT_CHECK);
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
// The drive's failures are judged after its end is: the model's own early look at the end
|
|
481
|
+
// ("Generated script for", asserted before the request that writes it had answered) is
|
|
482
|
+
// superseded when the end then holds, by the same rule as the run's verdict.
|
|
483
|
+
const failedBeside = (calls, endHeld) => 0 < checkTally(endHeld ? [...calls, endHeldCall(end)] : calls).failed;
|
|
484
|
+
let shown = await lookFor(tools.invoke.bind(tools), end, ports.own);
|
|
485
|
+
// A drive that finished with turns to spare, short of the end its own plan names (joined,
|
|
486
|
+
// opened Runs, never clicked Team), is sent on once from where it stands, not graded there.
|
|
487
|
+
const left = budget - drive.steps;
|
|
488
|
+
if (!shown && StopReason.FINISHED === drive.stopReason && MIN_CONTINUE_STEPS <= left) {
|
|
489
|
+
if (failedBeside(drive.toolCalls, false))
|
|
490
|
+
return false;
|
|
491
|
+
drive = await ports.drive(tools, continueGoal(step.goal, end), left);
|
|
492
|
+
drives.push(drive);
|
|
493
|
+
if (StopReason.STOPPED === drive.stopReason)
|
|
494
|
+
stop();
|
|
495
|
+
shown = await lookFor(tools.invoke.bind(tools), end, ports.own);
|
|
496
|
+
}
|
|
497
|
+
// Never reached is the journey's miss, not a failed check on the app: no assert is kept. The
|
|
498
|
+
// page decides it, not the driver's word: an end the page shows was reached, whatever the
|
|
499
|
+
// driver said (a drive started on a dead link reached it and was failed on its own "no").
|
|
500
|
+
if (!shown)
|
|
501
|
+
return false;
|
|
502
|
+
const endHeld = await holds(tools, { kind: PredicateKind.TEXT, contains: end });
|
|
503
|
+
// Passed means its checks held, not that it ran one.
|
|
504
|
+
return endHeld && !failedBeside(drive.toolCalls, true);
|
|
220
505
|
}
|
|
221
506
|
const result = await call(tools, ReticleTool.ACT_AND_WAIT, {
|
|
222
507
|
...(step.target === undefined ? {} : { target: step.target }),
|
|
@@ -229,11 +514,33 @@ async function runLeaf(step, tools, ports, drives, stop) {
|
|
|
229
514
|
}
|
|
230
515
|
}
|
|
231
516
|
async function replay(tools, args) {
|
|
232
|
-
|
|
517
|
+
const result = asRecord(await call(tools, ReticleTool.FLOW_REPLAY, args));
|
|
518
|
+
if (ReplayStatus.OK === result['status'])
|
|
519
|
+
return true;
|
|
520
|
+
const error = result['error'];
|
|
521
|
+
const message = asString(error) ?? asString(asRecord(error)['message']) ?? '';
|
|
522
|
+
if (message.includes(DESTRUCTIVE_REFUSAL))
|
|
523
|
+
throw new StepNotTaken(MSG_NOT_TAKEN);
|
|
524
|
+
const [outcome] = replayedFlows([
|
|
525
|
+
{ id: 'replay', name: ReticleTool.FLOW_REPLAY, args, result, isError: false },
|
|
526
|
+
]);
|
|
527
|
+
if (UNDECIDED_REPLAY.has(outcome?.status))
|
|
528
|
+
throw new Undecided(msgReplayUndecided(String(args['flowName'])));
|
|
529
|
+
return false;
|
|
233
530
|
}
|
|
234
531
|
async function holds(tools, predicate) {
|
|
235
532
|
return true === asRecord(await call(tools, ReticleTool.ASSERT, { predicate }))['pass'];
|
|
236
533
|
}
|
|
534
|
+
/** The end check `holds` keeps, as a call the drive's tally can read beside the model's own. */
|
|
535
|
+
function endHeldCall(end) {
|
|
536
|
+
return {
|
|
537
|
+
id: 'end',
|
|
538
|
+
name: ReticleTool.ASSERT,
|
|
539
|
+
args: { predicate: { kind: PredicateKind.TEXT, contains: end } },
|
|
540
|
+
result: { verified: Verified.YES },
|
|
541
|
+
isError: false,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
237
544
|
/** A tool that throws is a failed step, not a crashed run. */
|
|
238
545
|
async function call(tools, name, args) {
|
|
239
546
|
try {
|
|
@@ -39,14 +39,14 @@ declare const LicensePayloadSchema: z.ZodObject<{
|
|
|
39
39
|
exp: z.ZodNumber;
|
|
40
40
|
features: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
41
41
|
}, "strip", z.ZodTypeAny, {
|
|
42
|
-
org: string;
|
|
43
42
|
plan: string;
|
|
43
|
+
org: string;
|
|
44
44
|
lid: string;
|
|
45
45
|
exp: number;
|
|
46
46
|
features?: string[] | undefined;
|
|
47
47
|
}, {
|
|
48
|
-
org: string;
|
|
49
48
|
plan: string;
|
|
49
|
+
org: string;
|
|
50
50
|
lid: string;
|
|
51
51
|
exp: number;
|
|
52
52
|
features?: string[] | undefined;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ScreenshotSource, type FlowStepResult } from '@reticlehq/core';
|
|
2
|
+
import type { ToolDeps } from '../../surface/tools/tool-kit.js';
|
|
3
|
+
export interface ShotOptions {
|
|
4
|
+
step?: string;
|
|
5
|
+
verdict?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** What a tool result carries: where the picture is and how it was taken, or why there is none. */
|
|
8
|
+
export type ScreenshotField = {
|
|
9
|
+
path: string;
|
|
10
|
+
source: ScreenshotSource;
|
|
11
|
+
} | {
|
|
12
|
+
error: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Width and height from a JPEG's frame header, or undefined when the bytes are not a JPEG.
|
|
16
|
+
* Read rather than trusted: the run record and the upload both state the size.
|
|
17
|
+
*/
|
|
18
|
+
export declare function jpegSize(bytes: Uint8Array): {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Photograph the tab a step just ran on. Returns the result field; never throws, because a
|
|
24
|
+
* screenshot is evidence about a step and must never be the reason the step's answer is lost.
|
|
25
|
+
*
|
|
26
|
+
* `step` names the flow step a replay was on, as `<flow>#<index>`, so the run can pin the picture
|
|
27
|
+
* to it; `verdict` says the call produced a verdict, so the run can pair the picture with its check.
|
|
28
|
+
*/
|
|
29
|
+
export declare function takeStepShot(deps: ToolDeps, sessionId: string, tool: string, opts?: ShotOptions): Promise<ScreenshotField>;
|
|
30
|
+
/** The replay hook that gives every reported flow step its screenshot, filed as `<flow>#<step>`. */
|
|
31
|
+
export declare function replayStepShooter(deps: ToolDeps, sessionId: string): (result: FlowStepResult, flow: string) => Promise<void>;
|