@reticlehq/server 3.9.0 → 3.10.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 +13 -12
- package/dist/command/cli/adhoc-suite.js +2 -0
- package/dist/command/cli/adhoc-verdict.d.ts +2 -43
- package/dist/command/cli/adhoc-verdict.js +50 -187
- package/dist/command/cli/answers/mcp-connection-hint.d.ts +2 -0
- package/dist/command/cli/answers/mcp-connection-hint.js +6 -0
- package/dist/command/cli/cli-doctor.js +1 -1
- package/dist/command/cli/cli-flow-commands.js +2 -9
- package/dist/command/cli/cli-kill.js +1 -1
- package/dist/command/cli/cli-parse-compare.d.ts +22 -0
- package/dist/command/cli/cli-parse-compare.js +75 -0
- package/dist/command/cli/cli-parse-grade.d.ts +36 -0
- package/dist/command/cli/cli-parse-grade.js +75 -0
- package/dist/command/cli/cli-parse-grammar.d.ts +2 -0
- package/dist/command/cli/cli-parse-grammar.js +18 -20
- package/dist/command/cli/cli-parse-verify.d.ts +10 -0
- package/dist/command/cli/cli-parse-verify.js +63 -14
- package/dist/command/cli/cli-parse.d.ts +17 -15
- package/dist/command/cli/cli-parse.js +44 -27
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +29 -20
- package/dist/command/cli/cli-usage.js +58 -29
- package/dist/command/cli/cli-verify.d.ts +11 -2
- package/dist/command/cli/cli-verify.js +27 -8
- package/dist/command/cli/cloud-cli.js +2 -119
- package/dist/command/cli/daemon-link/daemon-client.d.ts +45 -0
- package/dist/command/cli/daemon-link/daemon-client.js +205 -0
- package/dist/command/cli/doctor/doctor-daemon-line.js +6 -3
- package/dist/command/cli/doctor-repairs.js +1 -1
- package/dist/command/cli/ensure-daemon.d.ts +26 -0
- package/dist/command/cli/ensure-daemon.js +57 -0
- package/dist/command/cli/finished-run/grade-command.d.ts +23 -0
- package/dist/command/cli/finished-run/grade-command.js +180 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.d.ts +1 -1
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +1 -1
- package/dist/command/cli/ports/port-holder.d.ts +9 -0
- package/dist/command/cli/ports/port-holder.js +27 -3
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +22 -0
- package/dist/command/cli/status-fields.d.ts +5 -1
- package/dist/command/cli/status-fields.js +7 -3
- package/dist/command/cli/two-builds/compare-command.d.ts +48 -0
- package/dist/command/cli/two-builds/compare-command.js +314 -0
- package/dist/command/cli/verify-against.d.ts +61 -0
- package/dist/command/cli/verify-against.js +187 -0
- package/dist/command/cli/verify-no-session.d.ts +2 -0
- package/dist/command/cli/verify-no-session.js +13 -0
- package/dist/command/cli/verify-results.d.ts +35 -2
- package/dist/command/cli/verify-results.js +76 -10
- package/dist/command/cli.js +46 -41
- package/dist/command/daemon/daemon-resolve.d.ts +8 -1
- package/dist/command/daemon/daemon-resolve.js +27 -1
- package/dist/command/daemon/daemon.d.ts +12 -1
- package/dist/command/daemon/daemon.js +35 -4
- package/dist/command/daemon/lifetime/death-cause.js +21 -2
- package/dist/command/daemon/lifetime/heartbeat.js +7 -2
- package/dist/command/daemon/lifetime/startup-failure.d.ts +29 -0
- package/dist/command/daemon/lifetime/startup-failure.js +62 -0
- package/dist/command/setup/bringup/dev-server-files.d.ts +9 -0
- package/dist/command/setup/bringup/dev-server-files.js +17 -0
- package/dist/command/setup/bringup/static-page-server.d.ts +14 -2
- package/dist/command/setup/bringup/static-page-server.js +43 -9
- package/dist/command/setup/init/init-runtime.js +6 -0
- package/dist/command/setup/node-effects.d.ts +3 -2
- package/dist/command/setup/node-effects.js +9 -3
- package/dist/command/setup/remaining-steps.d.ts +8 -0
- package/dist/command/setup/remaining-steps.js +10 -0
- package/dist/command/setup/run-setup.d.ts +2 -0
- package/dist/command/setup/run-setup.js +9 -1
- package/dist/command/setup/setup-command.js +6 -3
- package/dist/command/update/updater.js +6 -0
- package/dist/command/version/version-skew.js +1 -1
- package/dist/features/compare/action-plan.d.ts +260 -0
- package/dist/features/compare/action-plan.js +543 -0
- package/dist/features/compare/behaviour-compare.d.ts +24 -0
- package/dist/features/compare/behaviour-compare.js +85 -0
- package/dist/features/compare/behaviour-diff.d.ts +97 -0
- package/dist/features/compare/behaviour-diff.js +202 -0
- package/dist/features/compare/behaviour-report.d.ts +40 -0
- package/dist/features/compare/behaviour-report.js +128 -0
- package/dist/features/compare/build-readings.d.ts +106 -0
- package/dist/features/compare/build-readings.js +250 -0
- package/dist/features/compare/compare-diff.d.ts +62 -0
- package/dist/features/compare/compare-diff.js +177 -0
- package/dist/features/compare/compare-report-html.d.ts +6 -0
- package/dist/features/compare/compare-report-html.js +102 -0
- package/dist/features/compare/compare-report.d.ts +15 -0
- package/dist/features/compare/compare-report.js +73 -0
- package/dist/features/compare/compare-run.d.ts +60 -0
- package/dist/features/compare/compare-run.js +123 -0
- package/dist/features/compare/outside/effect-lines.d.ts +26 -0
- package/dist/features/compare/outside/effect-lines.js +103 -0
- package/dist/features/compare/outside/state-sources.d.ts +76 -0
- package/dist/features/compare/outside/state-sources.js +164 -0
- package/dist/features/compare/outside/value-dictionary.d.ts +51 -0
- package/dist/features/compare/outside/value-dictionary.js +227 -0
- package/dist/features/compare/visible-content.d.ts +20 -0
- package/dist/features/compare/visible-content.js +125 -0
- package/dist/features/crawl/crawl-empty.js +2 -1
- package/dist/features/crawl/crawl-exhaustive.d.ts +55 -0
- package/dist/features/crawl/crawl-exhaustive.js +138 -0
- package/dist/features/crawl/crawl-tools.d.ts +9 -2
- package/dist/features/crawl/crawl-tools.js +28 -12
- package/dist/features/crawl/crawl.d.ts +8 -9
- package/dist/features/crawl/crawl.js +61 -65
- package/dist/features/exhaust/app-coverage.d.ts +5 -1
- package/dist/features/exhaust/app-coverage.js +3 -1
- package/dist/features/exhaust/code-coverage.js +8 -4
- package/dist/features/exhaust/edge-cases.d.ts +133 -0
- package/dist/features/exhaust/edge-cases.js +310 -0
- package/dist/features/exhaust/edges/edge-drive.d.ts +42 -0
- package/dist/features/exhaust/edges/edge-drive.js +364 -0
- package/dist/features/exhaust/edges/edge-run.d.ts +59 -0
- package/dist/features/exhaust/edges/edge-run.js +169 -0
- package/dist/features/exhaust/explorer.d.ts +87 -14
- package/dist/features/exhaust/explorer.js +159 -25
- package/dist/features/exhaust/failure-branches.d.ts +5 -0
- package/dist/features/exhaust/failure-branches.js +29 -11
- package/dist/features/exhaust/invariants.d.ts +112 -0
- package/dist/features/exhaust/invariants.js +188 -0
- package/dist/features/exhaust/ledger.d.ts +68 -0
- package/dist/features/exhaust/ledger.js +121 -13
- package/dist/features/exhaust/session-fold.d.ts +10 -0
- package/dist/features/exhaust/session-fold.js +46 -3
- package/dist/features/exhaust/session-port.d.ts +3 -1
- package/dist/features/exhaust/session-port.js +97 -28
- package/dist/features/grade/grade-answer.d.ts +99 -0
- package/dist/features/grade/grade-answer.js +112 -0
- package/dist/features/grade/grade-noise.d.ts +27 -0
- package/dist/features/grade/grade-noise.js +55 -0
- package/dist/features/grade/grade-renumber.d.ts +12 -0
- package/dist/features/grade/grade-renumber.js +86 -0
- package/dist/features/grade/grade-state.d.ts +50 -0
- package/dist/features/grade/grade-state.js +93 -0
- package/dist/features/grade/grade-suggest.d.ts +33 -0
- package/dist/features/grade/grade-suggest.js +98 -0
- package/dist/features/visual/visual-tools.js +66 -19
- package/dist/index.js +7 -4
- package/dist/judgement/capsule/causal-summary.js +9 -2
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +13 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +1 -1
- package/dist/judgement/runs/reticle-runner.js +16 -2
- package/dist/judgement/runs/runner-port.d.ts +2 -0
- package/dist/judgement/runs/runner-port.js +23 -5
- package/dist/language/flows/affected-tools.d.ts +1 -1
- package/dist/language/flows/affected-tools.js +49 -30
- package/dist/language/flows/change/git-changed.d.ts +2 -1
- package/dist/language/flows/change/git-changed.js +19 -2
- package/dist/language/flows/fields/flow-secret-field.d.ts +1 -13
- package/dist/language/flows/fields/flow-secret-field.js +77 -21
- package/dist/language/flows/flow-anchor.d.ts +60 -2
- package/dist/language/flows/flow-anchor.js +125 -20
- package/dist/language/flows/flow-classify.d.ts +20 -0
- package/dist/language/flows/flow-classify.js +90 -12
- package/dist/language/flows/flow-cross-step.d.ts +7 -1
- package/dist/language/flows/flow-cross-step.js +25 -1
- package/dist/language/flows/flow-journey.d.ts +38 -4
- package/dist/language/flows/flow-journey.js +138 -8
- package/dist/language/flows/flow-replay-run.d.ts +0 -16
- package/dist/language/flows/flow-replay-run.js +76 -14
- package/dist/language/flows/flow-replay-types.d.ts +4 -2
- package/dist/language/flows/flow-replay.d.ts +19 -1
- package/dist/language/flows/flow-replay.js +169 -52
- package/dist/language/flows/flow-replayable.js +7 -1
- package/dist/language/flows/flow-start-path.d.ts +34 -5
- package/dist/language/flows/flow-start-path.js +202 -15
- package/dist/language/flows/flow-step-runners.d.ts +14 -13
- package/dist/language/flows/flow-step-runners.js +184 -109
- package/dist/language/flows/flow-store-for-session.d.ts +26 -25
- package/dist/language/flows/flow-store-for-session.js +44 -0
- package/dist/language/flows/flow-tools.js +46 -33
- package/dist/language/flows/flows.js +176 -76
- package/dist/language/flows/recording/tape/recordings.d.ts +19 -3
- package/dist/language/flows/recording/tape/recordings.js +71 -5
- package/dist/language/flows/replay.d.ts +19 -5
- package/dist/language/flows/replay.js +99 -7
- package/dist/language/flows/steps/page-steps.d.ts +68 -0
- package/dist/language/flows/steps/page-steps.js +198 -0
- package/dist/language/flows/suite/sequential-run.d.ts +68 -0
- package/dist/language/flows/suite/sequential-run.js +96 -0
- package/dist/language/flows/verify-change-tools.js +26 -15
- package/dist/memory/cloud/background-sync.d.ts +13 -0
- package/dist/memory/cloud/background-sync.js +24 -3
- package/dist/memory/cloud/sync-daemon.js +26 -27
- package/dist/memory/journal/attach-journal.js +2 -1
- package/dist/memory/journal/drive-flow.d.ts +7 -0
- package/dist/memory/journal/drive-flow.js +44 -13
- package/dist/memory/journal/journal-recorder.d.ts +4 -2
- package/dist/memory/journal/session-journal.d.ts +7 -0
- package/dist/memory/journal/session-journal.js +58 -10
- package/dist/memory/project/root-claims.d.ts +9 -0
- package/dist/memory/project/root-claims.js +9 -4
- package/dist/portal/input/download-capture.d.ts +7 -0
- package/dist/portal/input/download-capture.js +92 -0
- package/dist/portal/input/network-detail.d.ts +6 -0
- package/dist/portal/input/network-detail.js +12 -1
- package/dist/portal/input/network-mock-tools.js +49 -13
- package/dist/portal/input/network-mock.d.ts +8 -0
- package/dist/portal/input/network-mock.js +28 -9
- package/dist/portal/input/page-capture.d.ts +24 -0
- package/dist/portal/input/page-capture.js +33 -0
- package/dist/portal/input/real-input.d.ts +22 -20
- package/dist/portal/input/real-input.js +41 -31
- package/dist/portal/input/viewport-tools.d.ts +8 -0
- package/dist/portal/input/viewport-tools.js +75 -18
- package/dist/portal/pool/browser-pool.d.ts +11 -29
- package/dist/portal/pool/browser-pool.js +35 -17
- package/dist/portal/pool/context-permissions.d.ts +17 -3
- package/dist/portal/pool/context-permissions.js +36 -5
- package/dist/portal/pool/determinism.d.ts +52 -0
- package/dist/portal/pool/determinism.js +259 -0
- package/dist/portal/pool/lease-emulation.d.ts +34 -1
- package/dist/portal/pool/lease-emulation.js +18 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +6 -0
- package/dist/portal/pool/lease-marker-stamp.js +15 -1
- package/dist/portal/pool/lease-page-error.d.ts +44 -17
- package/dist/portal/pool/lease-page-error.js +147 -5
- package/dist/portal/pool/page-error-journal.d.ts +7 -1
- package/dist/portal/pool/page-error-journal.js +27 -0
- package/dist/portal/pool/playwright-launcher.js +51 -8
- package/dist/portal/pool/pool-contract.d.ts +27 -1
- package/dist/portal/pool/pool-lease.d.ts +36 -1
- package/dist/portal/pool/zero-install.d.ts +8 -0
- package/dist/portal/pool/zero-install.js +23 -1
- package/dist/portal/session/dev-server/dev-command.d.ts +7 -6
- package/dist/portal/session/dev-server/dev-command.js +61 -15
- package/dist/portal/session/dev-server/dev-server-probe.d.ts +7 -0
- package/dist/portal/session/dev-server/dev-server-probe.js +9 -0
- package/dist/portal/session/dev-server/project-ports.d.ts +21 -0
- package/dist/portal/session/dev-server/project-ports.js +62 -0
- package/dist/portal/session/facts/departed-network.d.ts +66 -0
- package/dist/portal/session/facts/departed-network.js +142 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +9 -0
- package/dist/portal/session/no-session-diagnosis.js +67 -25
- package/dist/portal/session/no-session-next-action.d.ts +2 -0
- package/dist/portal/session/no-session-next-action.js +12 -3
- package/dist/portal/session/no-session-watch.d.ts +6 -0
- package/dist/portal/session/no-session-watch.js +38 -3
- package/dist/portal/session/serving-directory.d.ts +10 -0
- package/dist/portal/session/serving-directory.js +39 -8
- package/dist/portal/session/session-manager.d.ts +10 -0
- package/dist/portal/session/session-manager.js +174 -63
- package/dist/start-wiring.d.ts +2 -1
- package/dist/start-wiring.js +2 -1
- package/dist/surface/mcp/mcp.js +3 -2
- package/dist/surface/mcp/shared-params.d.ts +2 -0
- package/dist/surface/mcp/shared-params.js +31 -0
- package/dist/surface/tools/act/act-observation.d.ts +40 -2
- package/dist/surface/tools/act/act-observation.js +118 -12
- package/dist/surface/tools/act/act-preflight.js +1 -1
- package/dist/surface/tools/act/act-sequence-retry.d.ts +23 -2
- package/dist/surface/tools/act/act-sequence-retry.js +61 -5
- package/dist/surface/tools/act/after-match.d.ts +4 -1
- package/dist/surface/tools/act/after-match.js +8 -1
- package/dist/surface/tools/act/already-true.js +1 -1
- package/dist/surface/tools/act/navigation/reload-result.d.ts +12 -1
- package/dist/surface/tools/act/navigation/reload-result.js +25 -2
- package/dist/surface/tools/act/resolve-target.d.ts +15 -1
- package/dist/surface/tools/act/resolve-target.js +24 -1
- package/dist/surface/tools/act/sequence-grade.d.ts +12 -0
- package/dist/surface/tools/act/sequence-grade.js +37 -26
- package/dist/surface/tools/act/settle-in-flight.js +27 -15
- package/dist/surface/tools/act-command.d.ts +23 -0
- package/dist/surface/tools/act-command.js +50 -0
- package/dist/surface/tools/act-sequence-tool.js +78 -50
- package/dist/surface/tools/act-tools.d.ts +1 -13
- package/dist/surface/tools/act-tools.js +74 -86
- package/dist/surface/tools/agent/build-staleness.d.ts +1 -1
- package/dist/surface/tools/agent/build-staleness.js +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +16 -37
- package/dist/surface/tools/browser-tools.js +12 -6
- package/dist/surface/tools/compare-tools.d.ts +11 -0
- package/dist/surface/tools/compare-tools.js +94 -0
- package/dist/surface/tools/coverage-tools.js +1 -1
- package/dist/surface/tools/dynamic-tools.js +9 -2
- package/dist/surface/tools/error-recovery.d.ts +12 -1
- package/dist/surface/tools/error-recovery.js +91 -21
- package/dist/surface/tools/explore-tools.js +1 -1
- package/dist/surface/tools/invoke-tool.js +3 -2
- package/dist/surface/tools/lease-coverage-tools.d.ts +49 -0
- package/dist/surface/tools/lease-coverage-tools.js +128 -0
- package/dist/surface/tools/lease-hint.d.ts +35 -1
- package/dist/surface/tools/lease-hint.js +42 -0
- package/dist/surface/tools/lease-readiness.d.ts +26 -0
- package/dist/surface/tools/lease-readiness.js +79 -0
- package/dist/surface/tools/lease-seed.d.ts +14 -1
- package/dist/surface/tools/lease-seed.js +35 -3
- package/dist/surface/tools/lease-tools.d.ts +3 -41
- package/dist/surface/tools/lease-tools.js +62 -110
- package/dist/surface/tools/lease-url-identity.d.ts +46 -0
- package/dist/surface/tools/lease-url-identity.js +97 -0
- package/dist/surface/tools/merge-tools.js +99 -2
- package/dist/surface/tools/merged-name-redirect.js +5 -1
- package/dist/surface/tools/observe-tools.js +15 -9
- package/dist/surface/tools/read/console-pre-attach.d.ts +19 -0
- package/dist/surface/tools/read/console-pre-attach.js +23 -0
- package/dist/surface/tools/read-tools.js +33 -30
- package/dist/surface/tools/real-input-attempt.d.ts +0 -8
- package/dist/surface/tools/real-input-attempt.js +143 -28
- package/dist/surface/tools/session-ports.d.ts +14 -0
- package/dist/surface/tools/session-ports.js +53 -0
- package/dist/surface/tools/tool-kit.d.ts +6 -0
- package/dist/surface/tools/tool-kit.js +2 -3
- package/dist/surface/tools/tool-surface.js +0 -1
- package/dist/surface/tools/tools.js +28 -5
- package/dist/surface/tools/type-spelling.d.ts +13 -0
- package/dist/surface/tools/type-spelling.js +36 -0
- package/dist/telemetry/agent-client.d.ts +6 -0
- package/dist/telemetry/agent-client.js +10 -0
- package/dist/telemetry/argument-shape.js +1 -0
- package/dist/telemetry/tool-refused.d.ts +6 -3
- package/dist/telemetry/tool-refused.js +8 -3
- package/docs/actions.mdx +3 -3
- package/docs/agent-cheatsheet.md +1 -1
- package/docs/capabilities.mdx +61 -1
- package/docs/cli/affected.mdx +9 -7
- package/docs/cli/cloud.mdx +3 -3
- package/docs/cli/compare.mdx +94 -0
- package/docs/cli/doctor.mdx +1 -1
- package/docs/cli/grade.mdx +97 -0
- package/docs/cli/license.mdx +9 -7
- package/docs/cli/restart.mdx +7 -5
- package/docs/cli/rollback.mdx +5 -5
- package/docs/cli/stop.mdx +3 -3
- package/docs/cli/update.mdx +2 -2
- package/docs/cli/verify.mdx +23 -1
- package/docs/cli.mdx +33 -23
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +1 -1
- package/docs/enterprise.md +2 -2
- package/docs/environment.mdx +1 -1
- package/docs/flows.md +11 -1
- package/docs/frameworks.mdx +9 -9
- package/docs/getting-started.md +1 -1
- package/docs/install-manual.mdx +1 -1
- package/docs/license-activation.mdx +3 -3
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages.mdx +1 -1
- package/docs/predicates.mdx +1 -1
- package/docs/quickstart.mdx +68 -49
- package/docs/skill-setup.md +1 -1
- package/docs/skill.md +14 -13
- package/docs/telemetry.md +2 -2
- package/docs/tools/navigate.mdx +1 -1
- package/docs/tools/verify.mdx +4 -1
- package/docs/troubleshooting.mdx +1 -1
- package/docs/usage.md +17 -14
- package/package.json +13 -13
- package/dist/features/exhaust/exhaust-run.d.ts +0 -33
- package/dist/features/exhaust/exhaust-run.js +0 -82
|
@@ -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,
|
|
30
|
+
import { EventType, isDevToolingUrl, isForeignTraffic, neverAnswered, urlForMatch, } from '@reticlehq/core';
|
|
31
31
|
/**
|
|
32
32
|
* What a URL is matched against, as opposed to what is shown.
|
|
33
33
|
*
|
|
@@ -81,10 +81,11 @@ const isForeign = (data, appOrigin, background) => isForeignTraffic(matchUrlOf(d
|
|
|
81
81
|
* NET_REQUEST, so counting it as outstanding would mean no page containing an outbound link or a
|
|
82
82
|
* download button ever settles again. See `NetInitiator.NAVIGATION`.
|
|
83
83
|
*
|
|
84
|
-
* The `settled` predicate asks the same question in `evalSettled
|
|
85
|
-
*
|
|
84
|
+
* The `settled` predicate asks the same question in `evalSettled`. Both read core's `neverAnswered`,
|
|
85
|
+
* which keeps the two answers one rule. It also covers a request whose page unloaded before its
|
|
86
|
+
* answer arrived (#1944).
|
|
86
87
|
*/
|
|
87
|
-
const isDeparture =
|
|
88
|
+
const isDeparture = neverAnswered;
|
|
88
89
|
/** How often to re-read the buffer. Short enough to return promptly, long enough not to spin. */
|
|
89
90
|
const POLL_MS = 50;
|
|
90
91
|
const idOf = (data) => 'string' === typeof data['id'] ? data['id'] : undefined;
|
|
@@ -98,21 +99,26 @@ const idOf = (data) => 'string' === typeof data['id'] ? data['id'] : undefined;
|
|
|
98
99
|
export function inFlightRequestIds(events, appOrigin, background = []) {
|
|
99
100
|
const settled = new Set();
|
|
100
101
|
for (const e of events) {
|
|
101
|
-
if (e.type !== EventType.NET_REQUEST)
|
|
102
|
+
if (e.type !== EventType.NET_REQUEST) {
|
|
102
103
|
continue;
|
|
104
|
+
}
|
|
103
105
|
const id = idOf(e.data);
|
|
104
|
-
if (id !== undefined)
|
|
106
|
+
if (id !== undefined) {
|
|
105
107
|
settled.add(id);
|
|
108
|
+
}
|
|
106
109
|
}
|
|
107
110
|
const open = [];
|
|
108
111
|
for (const e of events) {
|
|
109
|
-
if (e.type !== EventType.NET_PENDING || isDevTooling(e.data) || isDeparture(e.data))
|
|
112
|
+
if (e.type !== EventType.NET_PENDING || isDevTooling(e.data) || isDeparture(e.data)) {
|
|
110
113
|
continue;
|
|
111
|
-
|
|
114
|
+
}
|
|
115
|
+
if (isForeign(e.data, appOrigin, background)) {
|
|
112
116
|
continue;
|
|
117
|
+
}
|
|
113
118
|
const id = idOf(e.data);
|
|
114
|
-
if (id !== undefined && !settled.has(id) && !open.includes(id))
|
|
119
|
+
if (id !== undefined && !settled.has(id) && !open.includes(id)) {
|
|
115
120
|
open.push(id);
|
|
121
|
+
}
|
|
116
122
|
}
|
|
117
123
|
return open;
|
|
118
124
|
}
|
|
@@ -128,11 +134,13 @@ export function inFlightRequestLabels(events, appOrigin, background = []) {
|
|
|
128
134
|
const open = new Set(inFlightRequestIds(events, appOrigin, background));
|
|
129
135
|
const labels = [];
|
|
130
136
|
for (const e of events) {
|
|
131
|
-
if (e.type !== EventType.NET_PENDING)
|
|
137
|
+
if (e.type !== EventType.NET_PENDING) {
|
|
132
138
|
continue;
|
|
139
|
+
}
|
|
133
140
|
const id = idOf(e.data);
|
|
134
|
-
if (id === undefined || !open.has(id))
|
|
141
|
+
if (id === undefined || !open.has(id)) {
|
|
135
142
|
continue;
|
|
143
|
+
}
|
|
136
144
|
open.delete(id); // one label per request, however many times its start was recorded
|
|
137
145
|
const method = 'string' === typeof e.data['method'] ? e.data['method'] : 'request';
|
|
138
146
|
const url = 'string' === typeof e.data['url'] ? e.data['url'] : 'an unreported url';
|
|
@@ -158,8 +166,9 @@ const MIN_REPEATS = 2;
|
|
|
158
166
|
export function repeatedRequestLabels(events) {
|
|
159
167
|
const counts = new Map();
|
|
160
168
|
for (const e of events) {
|
|
161
|
-
if (e.type !== EventType.NET_REQUEST || isDevTooling(e.data))
|
|
169
|
+
if (e.type !== EventType.NET_REQUEST || isDevTooling(e.data)) {
|
|
162
170
|
continue;
|
|
171
|
+
}
|
|
163
172
|
const method = 'string' === typeof e.data['method'] ? e.data['method'] : 'request';
|
|
164
173
|
const url = 'string' === typeof e.data['url'] ? e.data['url'] : 'an unreported url';
|
|
165
174
|
const key = `${method} ${url}`;
|
|
@@ -182,17 +191,20 @@ export async function waitForInFlight(session, since, budgetMs, opts) {
|
|
|
182
191
|
// The verdict's own scope: waiting on a request the verdict will not count is latency for nothing.
|
|
183
192
|
const outstanding = () => inFlightRequestIds(session.eventsSince(since), session.url, session.background);
|
|
184
193
|
let open = outstanding();
|
|
185
|
-
if (0 === open.length)
|
|
194
|
+
if (0 === open.length) {
|
|
186
195
|
return { settled: true, stillInFlight: [] };
|
|
187
|
-
|
|
196
|
+
}
|
|
197
|
+
if (budgetMs <= 0) {
|
|
188
198
|
return { settled: false, stillInFlight: open };
|
|
199
|
+
}
|
|
189
200
|
const deadline = session.elapsed() + budgetMs;
|
|
190
201
|
while (session.elapsed() < deadline) {
|
|
191
202
|
// Never overshoot the budget: the last sleep is trimmed to whatever is actually left.
|
|
192
203
|
await opts.sleep(Math.min(POLL_MS, deadline - session.elapsed()));
|
|
193
204
|
open = outstanding();
|
|
194
|
-
if (0 === open.length)
|
|
205
|
+
if (0 === open.length) {
|
|
195
206
|
return { settled: true, stillInFlight: [] };
|
|
207
|
+
}
|
|
196
208
|
}
|
|
197
209
|
return { settled: false, stillInFlight: open };
|
|
198
210
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single dispatch point for every ACT and ACT_SEQUENCE command, extracted from
|
|
3
|
+
* act-tools.ts at the 1000-line cap.
|
|
4
|
+
*
|
|
5
|
+
* Attribution: this dispatch does NOT open its own window — the CALLER wraps it in
|
|
6
|
+
* `session.beginAction` / `finishAction` with the tool it serves (act, act_and_wait, act_sequence
|
|
7
|
+
* pass their own `command`), so the window covers the whole flow around the dispatch, not just
|
|
8
|
+
* the send.
|
|
9
|
+
*/
|
|
10
|
+
import { ReticleCommand } from '@reticlehq/core';
|
|
11
|
+
import type { Session } from '../../portal/session/session.js';
|
|
12
|
+
import type { ToolDeps } from './tool-kit.js';
|
|
13
|
+
/**
|
|
14
|
+
* Single dispatch point for every ACT and ACT_SEQUENCE command.
|
|
15
|
+
*
|
|
16
|
+
* reticle_act, act_and_wait and act_sequence rewrite uploads here, once. The path resolves against
|
|
17
|
+
* the session's project, not the daemon's folder, so a worktree uploads its own fixture (#1769).
|
|
18
|
+
*
|
|
19
|
+
* captureAct is called AFTER this, so the flow-recording captures the pre-rewrite args (the path
|
|
20
|
+
* the agent actually wrote) rather than the base64 blob — replay would otherwise send 750 KiB of
|
|
21
|
+
* base64 to the browser as if it were an inline content call.
|
|
22
|
+
*/
|
|
23
|
+
export declare function actCommand(deps: ToolDeps, session: Session, command: ReticleCommand, rawActArgs: Record<string, unknown>, timeoutMs?: number, realTried?: boolean): Promise<import('@reticlehq/core').CommandResult>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single dispatch point for every ACT and ACT_SEQUENCE command, extracted from
|
|
3
|
+
* act-tools.ts at the 1000-line cap.
|
|
4
|
+
*
|
|
5
|
+
* Attribution: this dispatch does NOT open its own window — the CALLER wraps it in
|
|
6
|
+
* `session.beginAction` / `finishAction` with the tool it serves (act, act_and_wait, act_sequence
|
|
7
|
+
* pass their own `command`), so the window covers the whole flow around the dispatch, not just
|
|
8
|
+
* the send.
|
|
9
|
+
*/
|
|
10
|
+
import { ActionType, ReticleCommand, asRecord, asString } from '@reticlehq/core';
|
|
11
|
+
import { rewriteUploadArgs, tryRealInput, HOVER_NEEDS_POINTER_MSG } from './real-input-attempt.js';
|
|
12
|
+
import { sessionRoot } from '../../memory/project/session-root.js';
|
|
13
|
+
import { normalizeTypeSpelling } from './type-spelling.js';
|
|
14
|
+
/**
|
|
15
|
+
* Single dispatch point for every ACT and ACT_SEQUENCE command.
|
|
16
|
+
*
|
|
17
|
+
* reticle_act, act_and_wait and act_sequence rewrite uploads here, once. The path resolves against
|
|
18
|
+
* the session's project, not the daemon's folder, so a worktree uploads its own fixture (#1769).
|
|
19
|
+
*
|
|
20
|
+
* captureAct is called AFTER this, so the flow-recording captures the pre-rewrite args (the path
|
|
21
|
+
* the agent actually wrote) rather than the base64 blob — replay would otherwise send 750 KiB of
|
|
22
|
+
* base64 to the browser as if it were an inline content call.
|
|
23
|
+
*/
|
|
24
|
+
export async function actCommand(deps, session, command, rawActArgs, timeoutMs, realTried = false) {
|
|
25
|
+
const actArgs = normalizeTypeSpelling(rawActArgs);
|
|
26
|
+
const rewritten = await rewriteUploadArgs({ fs: deps.fs, reticleRoot: sessionRoot(deps, session.id) }, 'string' === typeof actArgs['action'] ? actArgs['action'] : '', asRecord(actArgs['args']));
|
|
27
|
+
// Sequence and act_and_wait dispatch through here without the ACT handler's tryRealInput.
|
|
28
|
+
// A synthetic hover reports dispatched/settled while CSS :hover never applies — drive a real
|
|
29
|
+
// pointer when one is available, otherwise refuse rather than lie. A press on a lease takes its
|
|
30
|
+
// real keyboard, as reticle_act does: a synthetic Tab moves no focus.
|
|
31
|
+
const hover = ActionType.HOVER === actArgs['action'];
|
|
32
|
+
if (!realTried && (hover || ActionType.PRESS === actArgs['action'])) {
|
|
33
|
+
const ref = asString(actArgs['ref']);
|
|
34
|
+
if (hover && ref === undefined) {
|
|
35
|
+
throw new Error(HOVER_NEEDS_POINTER_MSG);
|
|
36
|
+
}
|
|
37
|
+
const action = hover ? ActionType.HOVER : ActionType.PRESS;
|
|
38
|
+
const real = await tryRealInput(deps, session, ref ?? '', action, actArgs);
|
|
39
|
+
if (hover && real.result === undefined) {
|
|
40
|
+
throw new Error(HOVER_NEEDS_POINTER_MSG);
|
|
41
|
+
}
|
|
42
|
+
if (real.result !== undefined) {
|
|
43
|
+
const result = { dispatched: true, settled: real.settled, ...asRecord(real.result) };
|
|
44
|
+
return { kind: 'command_result', id: action, ok: true, result };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const bridgeArgs = { ...actArgs, args: rewritten };
|
|
48
|
+
// What the acted element shows (test id, source) is noted in `Session.command`, Harness acts too.
|
|
49
|
+
return session.command(command, bridgeArgs, timeoutMs);
|
|
50
|
+
}
|
|
@@ -11,30 +11,32 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
import { timeoutMsSchema } from './args/numeric-bounds.js';
|
|
14
|
-
import { compileSequenceStep,
|
|
14
|
+
import { compileSequenceStep, pageOf, wroteSince } from '../../language/flows/replay.js';
|
|
15
15
|
import { DEFAULT_SEQUENCE_STEP_TIMEOUT_MS } from '../../language/flows/flow-step-runners.js';
|
|
16
16
|
import { sequenceStepArgs } from './act/act-preflight.js';
|
|
17
|
-
import { REPLAY_PROGRAM_VERSION, ReticleTool, Verified, VerifiedReason, checkIntent, } from '@reticlehq/core';
|
|
17
|
+
import { REPLAY_PROGRAM_VERSION, ReticleCommand, ReticleTool, Verified, VerifiedReason, checkIntent, } from '@reticlehq/core';
|
|
18
18
|
import { healthEnvelope } from '../../portal/session/session-health.js';
|
|
19
19
|
import { pausedShortCircuit, pausedOutputShape, withControl, } from '../../portal/session/control-envelope.js';
|
|
20
|
-
import { asRecord, isAbsenceDerived, isAdvisory } from '@reticlehq/core';
|
|
20
|
+
import { asRecord, asString, isAbsenceDerived, isAdvisory } from '@reticlehq/core';
|
|
21
|
+
import { couldNotEvaluate } from '@reticlehq/engine/evidence/verified.js';
|
|
21
22
|
import { sessionIdFromArgs } from './tools-helpers.js';
|
|
22
|
-
import { describeStepResult, runStepWithStaleRetry } from './act/act-sequence-retry.js';
|
|
23
|
+
import { BURST_MAX_GAP_MS, describeStepResult, runStepWithStaleRetry, } from './act/act-sequence-retry.js';
|
|
23
24
|
import { assertSequenceSteps } from './act/act-preflight.js';
|
|
24
25
|
import { EnvelopeKey, sessionIdShape } from './tool-kit.js';
|
|
25
26
|
import { takeStepShot } from '../../features/visual/step-shots.js';
|
|
26
|
-
import { actCommand } from './act-
|
|
27
|
+
import { actCommand } from './act-command.js';
|
|
27
28
|
import { PredicateSchema, waitForPredicate, } from '@reticlehq/engine/question/predicate/predicate.js';
|
|
28
29
|
import { DeviationMode, gradeSequence, JOURNEY_RECORDING, offerToKeep, } from './act/sequence-grade.js';
|
|
29
30
|
import { stepEffect, appScope } from '@reticlehq/engine/evidence/step-effect.js';
|
|
30
31
|
// resolveActTarget moved out of act-tools into its own module on this branch; #706 was written
|
|
31
32
|
// against the older layout where act-tools re-exported it.
|
|
32
33
|
import { resolveActTarget } from './act/act-target.js';
|
|
34
|
+
import { hiddenTargetField } from './act/resolve-target.js';
|
|
33
35
|
import { gradeOfPredicate } from './assert/assert-grade.js';
|
|
34
36
|
import { describeWaitTarget } from '@reticlehq/engine/evidence/unsettled.js';
|
|
35
37
|
import { sourceOf } from './tools-helpers.js';
|
|
36
38
|
import { confirmedByDeclaration } from './act/act-danger.js';
|
|
37
|
-
import { unreachableTargetNote } from './act/act-observation.js';
|
|
39
|
+
import { diagnoseTimeout, unreachableTargetNote } from './act/act-observation.js';
|
|
38
40
|
/**
|
|
39
41
|
* The step's effect record, best-effort.
|
|
40
42
|
*
|
|
@@ -54,20 +56,43 @@ function effectOf(session, since, expect) {
|
|
|
54
56
|
return {};
|
|
55
57
|
}
|
|
56
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Why a step's check decided nothing, when the target was reachable.
|
|
61
|
+
*
|
|
62
|
+
* A read that could not be evaluated gets the sentence `reticle_act_and_wait` gives for it, with the
|
|
63
|
+
* same diagnosis of a timed-out read. The plan gave the raw error only, so it named no fix (#2204).
|
|
64
|
+
*/
|
|
65
|
+
function whyUndecided(verdict, session) {
|
|
66
|
+
if (true === verdict.observationLost) {
|
|
67
|
+
return `${verdict.failureReason ?? 'the observation was lost'} (the page left)`;
|
|
68
|
+
}
|
|
69
|
+
const missing = diagnoseTimeout(verdict.inconclusive, session);
|
|
70
|
+
if (missing !== undefined) {
|
|
71
|
+
return couldNotEvaluate(missing);
|
|
72
|
+
}
|
|
73
|
+
return verdict.failureReason ?? 'the predicate could not be read';
|
|
74
|
+
}
|
|
75
|
+
/** The step's action, for the sentence that names a step nobody could judge. */
|
|
76
|
+
function actionOf(step) {
|
|
77
|
+
const action = asString(step['action']);
|
|
78
|
+
return action === undefined ? {} : { action };
|
|
79
|
+
}
|
|
80
|
+
/** One step's verdict and its reason. */
|
|
81
|
+
function stepVerdict(check) {
|
|
82
|
+
if (check.held) {
|
|
83
|
+
return 0 < check.contradicted.length
|
|
84
|
+
? { verified: Verified.NO, reason: VerifiedReason.CONTRADICTED }
|
|
85
|
+
: { verified: Verified.YES, reason: undefined };
|
|
86
|
+
}
|
|
87
|
+
if (check.undecided) {
|
|
88
|
+
const reason = true === check.unreachable ? VerifiedReason.INCONCLUSIVE : VerifiedReason.OBSERVATION_LOST;
|
|
89
|
+
return { verified: Verified.UNKNOWN, reason };
|
|
90
|
+
}
|
|
91
|
+
return { verified: Verified.NO, reason: VerifiedReason.ASSERTION_FAILED };
|
|
92
|
+
}
|
|
57
93
|
/** The verdict effect for one step: the same rules act_and_wait applies to one action. */
|
|
58
94
|
function stepVerdictEffect(check) {
|
|
59
|
-
const { verified, reason } = check
|
|
60
|
-
? 0 < check.contradicted.length
|
|
61
|
-
? { verified: Verified.NO, reason: VerifiedReason.CONTRADICTED }
|
|
62
|
-
: { verified: Verified.YES, reason: undefined }
|
|
63
|
-
: check.undecided
|
|
64
|
-
? {
|
|
65
|
-
verified: Verified.UNKNOWN,
|
|
66
|
-
reason: true === check.unreachable
|
|
67
|
-
? VerifiedReason.INCONCLUSIVE
|
|
68
|
-
: VerifiedReason.OBSERVATION_LOST,
|
|
69
|
-
}
|
|
70
|
-
: { verified: Verified.NO, reason: VerifiedReason.ASSERTION_FAILED };
|
|
95
|
+
const { verified, reason } = stepVerdict(check);
|
|
71
96
|
const source = sourceOf(check.source);
|
|
72
97
|
return {
|
|
73
98
|
claim: describeWaitTarget(check.expect),
|
|
@@ -93,18 +118,6 @@ function journalStep(session, args, effect) {
|
|
|
93
118
|
// ponytail: a session without a journal (a test double, journaling off) keeps no check.
|
|
94
119
|
}
|
|
95
120
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Ceiling for a burst gap. Past this it is not a burst, it is a paced walk.
|
|
98
|
-
*
|
|
99
|
-
* HOW TO PICK A GAP, because both edges are real and neither is guessable. It must outlast the
|
|
100
|
-
* handler committing and dispatching its request, and undercut the response it is racing.
|
|
101
|
-
* Measured against a superseded-filter race (the superseded query 700ms, the one replacing it 90ms):
|
|
102
|
-
* at 0ms the first request was never issued at all, and at the ordinary settle (~500ms in a
|
|
103
|
-
* throttled tab, where rAF never fires and the frame budget always times out) the two clicks
|
|
104
|
-
* serialised and never overlapped. 50ms sat in the window. A different app needs a different
|
|
105
|
-
* number: read its own slow endpoint.
|
|
106
|
-
*/
|
|
107
|
-
const BURST_MAX_GAP_MS = 500;
|
|
108
121
|
/** A step error that means nothing was acted on, or the page went away with the observation. */
|
|
109
122
|
const UNJUDGED_STEP = /matched no element|no longer resolves|session disconnected|session (was )?replaced/i;
|
|
110
123
|
export const ACT_SEQUENCE_TOOL = {
|
|
@@ -183,10 +196,11 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
183
196
|
handler: async (deps, args) => {
|
|
184
197
|
const session = deps.sessions.resolve(sessionIdFromArgs(args));
|
|
185
198
|
const paused = pausedShortCircuit(session);
|
|
186
|
-
if (paused !== undefined)
|
|
199
|
+
if (paused !== undefined) {
|
|
187
200
|
return paused;
|
|
201
|
+
}
|
|
188
202
|
const since = session.elapsed();
|
|
189
|
-
const pageBefore =
|
|
203
|
+
const pageBefore = pageOf(session.url);
|
|
190
204
|
session.beginAction(ReticleTool.ACT_SEQUENCE, asRecord(args));
|
|
191
205
|
try {
|
|
192
206
|
const inputSteps = Array.isArray(args['steps']) ? args['steps'] : [];
|
|
@@ -228,13 +242,17 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
228
242
|
// Resolve `target` with the same helper reticle_act uses, then dispatch by ref. Passing
|
|
229
243
|
// the unresolved step through used to send `ref: undefined` and the browser blamed a
|
|
230
244
|
// stale empty ref — the caller went looking for a re-render instead of a missing locator.
|
|
245
|
+
// Set by the resolve below, so the step row names a hidden match the step acted on.
|
|
246
|
+
let hidden = {};
|
|
231
247
|
const outcome = await runStepWithStaleRetry(async () => {
|
|
232
248
|
const resolved = await resolveActTarget(session, step, perStepTimeout);
|
|
233
|
-
if ('error' === resolved.kind)
|
|
249
|
+
if ('error' === resolved.kind) {
|
|
234
250
|
return { ok: false, error: resolved.message };
|
|
251
|
+
}
|
|
252
|
+
hidden = hiddenTargetField(resolved);
|
|
235
253
|
// In burst mode every step carries a zero settle budget, so step N+1 is dispatched
|
|
236
254
|
// while step N is still in flight. That overlap IS the test — see `burst` above.
|
|
237
|
-
return actCommand(deps, session, {
|
|
255
|
+
return actCommand(deps, session, ReticleCommand.ACT, {
|
|
238
256
|
ref: resolved.ref,
|
|
239
257
|
action: step['action'],
|
|
240
258
|
// `sequenceStepArgs` reads a step's arguments flat OR nested — keep it, it is the
|
|
@@ -255,8 +273,9 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
255
273
|
if (burstGapMs !== undefined && i < inputSteps.length - 1) {
|
|
256
274
|
const elapsed = session.elapsed() - stepSince;
|
|
257
275
|
const remaining = burstGapMs - elapsed;
|
|
258
|
-
if (remaining > 0)
|
|
276
|
+
if (remaining > 0) {
|
|
259
277
|
await new Promise((r) => setTimeout(r, remaining));
|
|
278
|
+
}
|
|
260
279
|
}
|
|
261
280
|
if (!outcome.ok) {
|
|
262
281
|
stalledAt = i;
|
|
@@ -268,6 +287,7 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
268
287
|
});
|
|
269
288
|
const error = outcome.error ?? 'the step could not be performed';
|
|
270
289
|
expectations.push({
|
|
290
|
+
...actionOf(step),
|
|
271
291
|
declared: undefined !== step['expect'],
|
|
272
292
|
held: false,
|
|
273
293
|
observed: error,
|
|
@@ -287,6 +307,7 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
287
307
|
const describe = () => ({
|
|
288
308
|
...describeStepResult(step, asRecord(outcome.result)),
|
|
289
309
|
...effectOf(session, stepSince, step['expect']),
|
|
310
|
+
...hidden,
|
|
290
311
|
});
|
|
291
312
|
const deciding = (step) => (step.contradictions ?? [])
|
|
292
313
|
.map((c) => c.kind)
|
|
@@ -304,8 +325,15 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
304
325
|
if (!parsed.success) {
|
|
305
326
|
const described = describe();
|
|
306
327
|
const contradicted = deciding(described);
|
|
328
|
+
// What a quiet, undeclared plan is graded on — see gradeSequence.
|
|
329
|
+
const doubted = (described.contradictions ?? [])
|
|
330
|
+
.map((c) => c.kind)
|
|
331
|
+
.filter((kind) => !isAdvisory(kind) && isAbsenceDerived(kind));
|
|
307
332
|
expectations.push({
|
|
333
|
+
...actionOf(step),
|
|
308
334
|
declared: false,
|
|
335
|
+
settled: true === asRecord(outcome.result)['settled'],
|
|
336
|
+
...(0 === doubted.length ? {} : { doubted }),
|
|
309
337
|
...(0 === contradicted.length ? {} : { contradicted }),
|
|
310
338
|
...(unreachable === undefined ? {} : { undecided: unreachable }),
|
|
311
339
|
});
|
|
@@ -339,15 +367,12 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
339
367
|
assertion: verdict.assertion,
|
|
340
368
|
}));
|
|
341
369
|
expectations.push({
|
|
370
|
+
...actionOf(step),
|
|
342
371
|
declared: true,
|
|
343
372
|
held,
|
|
344
373
|
...(undecided
|
|
345
374
|
? {
|
|
346
|
-
undecided: unreachable
|
|
347
|
-
? unreachable
|
|
348
|
-
: true === verdict.observationLost
|
|
349
|
-
? `${verdict.failureReason ?? 'the observation was lost'} (the page left)`
|
|
350
|
-
: (verdict.failureReason ?? 'the predicate could not be read'),
|
|
375
|
+
undecided: unreachable ?? whyUndecided(verdict, session),
|
|
351
376
|
}
|
|
352
377
|
: {}),
|
|
353
378
|
...disagreement,
|
|
@@ -366,8 +391,9 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
366
391
|
});
|
|
367
392
|
if (!held) {
|
|
368
393
|
stoppedAt ??= i;
|
|
369
|
-
if (DeviationMode.HALT === onDeviation)
|
|
394
|
+
if (DeviationMode.HALT === onDeviation) {
|
|
370
395
|
break;
|
|
396
|
+
}
|
|
371
397
|
}
|
|
372
398
|
}
|
|
373
399
|
}
|
|
@@ -395,11 +421,8 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
395
421
|
* The halted step counts: it WAS dispatched, and only the consequence it declared failed
|
|
396
422
|
* afterwards. A stalled step never ran, which is why that index stays exclusive.
|
|
397
423
|
*/
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
: stoppedAt !== undefined
|
|
401
|
-
? stoppedAt + 1
|
|
402
|
-
: (stalledAt ?? inputSteps.length);
|
|
424
|
+
const halted = DeviationMode.CONTINUE === onDeviation ? undefined : stoppedAt;
|
|
425
|
+
const completed = halted === undefined ? (stalledAt ?? inputSteps.length) : halted + 1;
|
|
403
426
|
if (completed > 0) {
|
|
404
427
|
session.lastAct.markActed(since, undefined, undefined);
|
|
405
428
|
}
|
|
@@ -419,8 +442,9 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
419
442
|
const compiled = (steps) => {
|
|
420
443
|
const step = compileSequenceStep({ ...args, steps }, { count: completed, steps: stepResults.slice(0, completed) });
|
|
421
444
|
// The journey sent a write request: saved `writes`, so a replay does not repeat it unasked.
|
|
422
|
-
if (wroteSince(session, since))
|
|
445
|
+
if (wroteSince(session, since)) {
|
|
423
446
|
step.writes = true;
|
|
447
|
+
}
|
|
424
448
|
return step;
|
|
425
449
|
};
|
|
426
450
|
const recorded = compiled(proved);
|
|
@@ -428,9 +452,12 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
428
452
|
const onPage = (step) => pageBefore === undefined ? step : { ...step, page: pageBefore };
|
|
429
453
|
// Every step was on Reticle's own panel: nothing of the app's journey to record.
|
|
430
454
|
const onApp = asRecord(recorded.args)['steps'];
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
455
|
+
// The route as act_and_wait gives it: the ambient tape is cut into journeys by route, and a
|
|
456
|
+
// step with none started a journey of its own and lost the act that came after it.
|
|
457
|
+
if (Array.isArray(onApp) && 0 < onApp.length) {
|
|
458
|
+
deps.recordings.capture(onPage(compiled(ran)), pageBefore, session.id, onPage(recorded));
|
|
459
|
+
}
|
|
460
|
+
deps.recordings.markEnded(pageOf(session.url), session.id);
|
|
434
461
|
}
|
|
435
462
|
/*
|
|
436
463
|
* The grade, and the coverage it is never allowed to hide.
|
|
@@ -442,6 +469,7 @@ export const ACT_SEQUENCE_TOOL = {
|
|
|
442
469
|
const grade = gradeSequence(expectations, {
|
|
443
470
|
planned: inputSteps.length,
|
|
444
471
|
dispatched: completed > 0,
|
|
472
|
+
captureLost: session.lostSince(since),
|
|
445
473
|
});
|
|
446
474
|
// The journey a `keep` offer names, held as a stopped recording so `reticle_flow_save
|
|
447
475
|
// { flowName: JOURNEY_RECORDING, saveAs }` saves exactly what was just driven. The offer used
|
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { type ToolDef, type ToolDeps } from './tool-kit.js';
|
|
3
|
-
/**
|
|
4
|
-
* Single dispatch point for every ACT and ACT_SEQUENCE command.
|
|
5
|
-
*
|
|
6
|
-
* reticle_act, act_and_wait and act_sequence rewrite uploads here, once. The path resolves against
|
|
7
|
-
* the session's project, not the daemon's folder, so a worktree uploads its own fixture (#1769).
|
|
8
|
-
*
|
|
9
|
-
* captureAct is called AFTER this, so the flow-recording captures the pre-rewrite args (the path
|
|
10
|
-
* the agent actually wrote) rather than the base64 blob — replay would otherwise send 750 KiB of
|
|
11
|
-
* base64 to the browser as if it were an inline content call.
|
|
12
|
-
*/
|
|
13
|
-
export declare function actCommand(deps: ToolDeps, session: Session, actArgs: Record<string, unknown>, timeoutMs?: number): Promise<import('@reticlehq/core').CommandResult>;
|
|
1
|
+
import { type ToolDef } from './tool-kit.js';
|
|
14
2
|
export declare const ACT_TOOLS: ToolDef[];
|