@reticlehq/server 3.8.2 → 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/LICENSE +201 -104
- package/NOTICE +5 -0
- package/README.md +1 -1
- package/SKILL.md +13 -12
- package/bin/launch.js +13 -0
- package/bin/package.json +3 -0
- package/bin/reticle.js +66 -8
- package/dist/chromium-launch-options.d.ts +25 -0
- package/dist/chromium-launch-options.js +21 -1
- 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 -160
- package/dist/command/cli/answers/gate-exit.d.ts +6 -2
- package/dist/command/cli/answers/gate-exit.js +12 -2
- 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/ci-hint.d.ts +44 -0
- package/dist/command/cli/ci-hint.js +72 -0
- package/dist/command/cli/cli-doctor.d.ts +6 -1
- package/dist/command/cli/cli-doctor.js +46 -5
- package/dist/command/cli/cli-flow-commands.d.ts +7 -1
- package/dist/command/cli/cli-flow-commands.js +39 -24
- package/dist/command/cli/cli-kill.d.ts +21 -0
- package/dist/command/cli/cli-kill.js +47 -4
- 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 +22 -17
- package/dist/command/cli/cli-parse.js +54 -32
- 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 +61 -31
- package/dist/command/cli/cli-verify.d.ts +17 -3
- package/dist/command/cli/cli-verify.js +59 -21
- 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/browser/chromium-hint.d.ts +6 -1
- package/dist/command/cli/doctor/browser/chromium-hint.js +11 -5
- package/dist/command/cli/doctor/doctor-daemon-line.js +6 -3
- package/dist/command/cli/doctor/doctor-fix.d.ts +44 -0
- package/dist/command/cli/doctor/doctor-fix.js +89 -0
- package/dist/command/cli/doctor/doctor-launcher-line.d.ts +23 -0
- package/dist/command/cli/doctor/doctor-launcher-line.js +60 -0
- package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
- package/dist/command/cli/doctor/doctor-rows.js +4 -0
- package/dist/command/cli/doctor-repairs.d.ts +64 -0
- package/dist/command/cli/doctor-repairs.js +214 -0
- package/dist/command/cli/drive/drive-command.js +3 -7
- 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/first-use-checks.d.ts +41 -0
- package/dist/command/cli/first-use-checks.js +127 -0
- package/dist/command/cli/first-verdict-node.d.ts +3 -0
- package/dist/command/cli/first-verdict-node.js +189 -0
- package/dist/command/cli/first-verdict.d.ts +126 -0
- package/dist/command/cli/first-verdict.js +267 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +3 -2
- package/dist/command/cli/launch/sdk-version-match.js +3 -2
- package/dist/command/cli/lifecycle/daemon-lifecycle.d.ts +1 -1
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +7 -6
- package/dist/command/cli/mcp-command.js +13 -4
- package/dist/command/cli/ports/port-holder.d.ts +11 -0
- package/dist/command/cli/ports/port-holder.js +36 -4
- package/dist/command/cli/setup-mcp-cli.d.ts +27 -1
- package/dist/command/cli/setup-mcp-cli.js +98 -23
- package/dist/command/cli/status/status-lines.d.ts +2 -0
- package/dist/command/cli/status/status-lines.js +72 -17
- package/dist/command/cli/status-fields.d.ts +5 -1
- package/dist/command/cli/status-fields.js +24 -6
- package/dist/command/cli/try-command.d.ts +7 -0
- package/dist/command/cli/try-command.js +11 -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 +112 -70
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +3 -1
- package/dist/command/daemon/binding/daemon-status-probe.js +4 -2
- package/dist/command/daemon/daemon-argv.d.ts +9 -0
- package/dist/command/daemon/daemon-argv.js +11 -0
- 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 +22 -4
- package/dist/command/daemon/daemon.js +52 -10
- package/dist/command/daemon/lifetime/daemon-exit.d.ts +24 -0
- package/dist/command/daemon/lifetime/daemon-exit.js +39 -0
- package/dist/command/daemon/lifetime/death-cause.d.ts +15 -0
- package/dist/command/daemon/lifetime/death-cause.js +149 -0
- package/dist/command/daemon/lifetime/heartbeat.d.ts +7 -15
- package/dist/command/daemon/lifetime/heartbeat.js +11 -15
- package/dist/command/daemon/lifetime/startup-failure.d.ts +29 -0
- package/dist/command/daemon/lifetime/startup-failure.js +62 -0
- package/dist/command/daemon/port-state.d.ts +14 -0
- package/dist/command/daemon/port-state.js +31 -0
- package/dist/command/setup/agent-configs.d.ts +2 -0
- package/dist/command/setup/agent-configs.js +42 -15
- package/dist/command/setup/agent-next-steps.d.ts +77 -0
- package/dist/command/setup/agent-next-steps.js +284 -0
- package/dist/command/setup/agent-writer.js +11 -6
- 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-host.js +2 -0
- package/dist/command/setup/init/init-runtime.d.ts +6 -1
- package/dist/command/setup/init/init-runtime.js +63 -21
- package/dist/command/setup/mcp-launcher.d.ts +3 -0
- package/dist/command/setup/mcp-launcher.js +11 -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 +36 -15
- package/dist/command/setup/setup-mcp.d.ts +8 -0
- package/dist/command/setup/setup-mcp.js +47 -20
- package/dist/command/setup/start-dev-server.d.ts +8 -0
- package/dist/command/setup/start-dev-server.js +43 -0
- package/dist/command/update/updater.js +6 -0
- package/dist/command/version/identity/server-version.d.ts +2 -0
- package/dist/command/version/identity/server-version.js +2 -0
- package/dist/command/version/version-skew.d.ts +7 -0
- package/dist/command/version/version-skew.js +14 -3
- 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/license/license.d.ts +11 -71
- package/dist/features/license/license.js +43 -136
- package/dist/features/visual/desktop-capture.d.ts +33 -0
- package/dist/features/visual/desktop-capture.js +94 -0
- package/dist/features/visual/step-shots.js +139 -35
- package/dist/features/visual/visual-tools.d.ts +0 -18
- package/dist/features/visual/visual-tools.js +67 -99
- package/dist/import-graph.js +5 -6
- package/dist/index.d.ts +3 -1
- package/dist/index.js +19 -7
- 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/run-ledger.d.ts +7 -5
- package/dist/judgement/runs/run-ledger.js +98 -69
- package/dist/judgement/runs/runner-port.d.ts +2 -0
- package/dist/judgement/runs/runner-port.js +23 -5
- package/dist/judgement/runs/verification-sync.d.ts +6 -3
- package/dist/judgement/runs/verification-sync.js +21 -10
- 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 +51 -5
- 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 +21 -16
- package/dist/language/flows/recording/tape/recordings.js +112 -49
- package/dist/language/flows/replay.d.ts +36 -12
- package/dist/language/flows/replay.js +193 -50
- 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/launch-chromium.d.ts +1 -0
- package/dist/launch-chromium.js +49 -12
- 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/cloud/sync-screenshots.js +6 -1
- 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/bridge/bridge.d.ts +13 -4
- package/dist/portal/bridge/bridge.js +10 -9
- 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 +30 -10
- 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 +35 -18
- package/dist/portal/input/real-input.js +99 -33
- package/dist/portal/input/viewport-tools.d.ts +8 -0
- package/dist/portal/input/viewport-tools.js +81 -21
- package/dist/portal/pool/browser-pool.d.ts +16 -30
- package/dist/portal/pool/browser-pool.js +64 -52
- package/dist/portal/pool/context-permissions.d.ts +34 -17
- package/dist/portal/pool/context-permissions.js +94 -1
- package/dist/portal/pool/csp-widen.d.ts +62 -0
- package/dist/portal/pool/csp-widen.js +132 -0
- 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 +56 -0
- package/dist/portal/pool/lease-page-error.js +160 -0
- package/dist/portal/pool/page-error-journal.d.ts +63 -0
- package/dist/portal/pool/page-error-journal.js +208 -0
- package/dist/portal/pool/playwright-launcher.js +71 -15
- package/dist/portal/pool/pool-contract.d.ts +49 -1
- package/dist/portal/pool/pool-lease.d.ts +70 -2
- package/dist/portal/pool/pool-lease.js +23 -0
- package/dist/portal/pool/zero-install.d.ts +8 -0
- package/dist/portal/pool/zero-install.js +91 -1
- package/dist/portal/session/dev-server/dev-command.d.ts +11 -2
- package/dist/portal/session/dev-server/dev-command.js +110 -16
- 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 +76 -27
- package/dist/portal/session/no-session-next-action.d.ts +14 -0
- package/dist/portal/session/no-session-next-action.js +56 -7
- package/dist/portal/session/no-session-watch.d.ts +6 -0
- package/dist/portal/session/no-session-watch.js +41 -4
- package/dist/portal/session/page-commands/undeclared-command.d.ts +9 -3
- package/dist/portal/session/page-commands/undeclared-command.js +16 -7
- package/dist/portal/session/recorded-gaps.d.ts +1 -1
- package/dist/portal/session/recorded-gaps.js +5 -2
- 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 +211 -81
- package/dist/portal/session/session.js +4 -3
- package/dist/portal/session/zero-install-first-call.d.ts +20 -1
- package/dist/portal/session/zero-install-first-call.js +34 -2
- package/dist/start-wiring.d.ts +30 -2
- package/dist/start-wiring.js +74 -9
- package/dist/surface/mcp/mcp-proxy.js +10 -2
- package/dist/surface/mcp/mcp.js +8 -5
- package/dist/surface/mcp/peer/agents-connected.d.ts +6 -0
- package/dist/surface/mcp/peer/agents-connected.js +58 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +17 -5
- 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 +38 -18
- 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/act-target.js +3 -1
- package/dist/surface/tools/act/after-match.d.ts +10 -0
- package/dist/surface/tools/act/after-match.js +40 -0
- 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 +17 -1
- package/dist/surface/tools/act/resolve-target.js +59 -9
- package/dist/surface/tools/act/sequence-grade.d.ts +15 -1
- package/dist/surface/tools/act/sequence-grade.js +45 -27
- 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 +81 -50
- package/dist/surface/tools/act-tools.d.ts +1 -13
- package/dist/surface/tools/act-tools.js +83 -95
- 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 +18 -12
- package/dist/surface/tools/browser-tools.js +87 -13
- 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 +11 -3
- package/dist/surface/tools/empty-session-list.d.ts +2 -0
- package/dist/surface/tools/empty-session-list.js +4 -2
- package/dist/surface/tools/error-recovery.d.ts +12 -1
- package/dist/surface/tools/error-recovery.js +131 -40
- package/dist/surface/tools/explore-tools.js +1 -1
- package/dist/surface/tools/invoke-tool.js +29 -21
- 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 +42 -1
- package/dist/surface/tools/lease-hint.js +52 -3
- package/dist/surface/tools/lease-readiness.d.ts +47 -0
- package/dist/surface/tools/lease-readiness.js +126 -0
- package/dist/surface/tools/lease-seed.d.ts +16 -1
- package/dist/surface/tools/lease-seed.js +37 -4
- package/dist/surface/tools/lease-tools.d.ts +3 -41
- package/dist/surface/tools/lease-tools.js +104 -124
- 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/repeat-hint.d.ts +40 -0
- package/dist/surface/tools/repeat-hint.js +171 -0
- package/dist/surface/tools/run-report.d.ts +2 -2
- package/dist/surface/tools/run-report.js +27 -15
- 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 +18 -0
- package/dist/surface/tools/tool-kit.js +9 -3
- package/dist/surface/tools/tool-surface.js +0 -1
- package/dist/surface/tools/tools.js +54 -18
- 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 +17 -7
- package/dist/telemetry/cli-telemetry.d.ts +10 -1
- package/dist/telemetry/cli-telemetry.js +15 -0
- package/dist/telemetry/init-telemetry.d.ts +2 -1
- package/dist/telemetry/init-telemetry.js +47 -2
- package/dist/telemetry/install-trace.js +23 -4
- package/dist/telemetry/onboarding-funnel.d.ts +19 -2
- package/dist/telemetry/onboarding-funnel.js +25 -3
- package/dist/telemetry/proxy-telemetry.d.ts +2 -1
- package/dist/telemetry/proxy-telemetry.js +2 -2
- package/dist/telemetry/session-metrics.d.ts +1 -1
- package/dist/telemetry/session-metrics.js +67 -27
- package/dist/telemetry/telemetry.d.ts +3 -1
- package/dist/telemetry/telemetry.js +60 -28
- package/dist/telemetry/tool-refused.d.ts +6 -3
- package/dist/telemetry/tool-refused.js +15 -3
- package/docs/actions.mdx +3 -3
- package/docs/agent-cheatsheet.md +1 -1
- package/docs/architecture.md +3 -6
- 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 +41 -2
- package/docs/cli/grade.mdx +97 -0
- package/docs/cli/help.mdx +4 -2
- package/docs/cli/license.mdx +13 -12
- package/docs/cli/restart.mdx +7 -5
- package/docs/cli/rollback.mdx +5 -5
- package/docs/cli/setup.mdx +13 -2
- package/docs/cli/status.mdx +4 -0
- 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 +34 -24
- package/docs/deploy-checks.md +25 -0
- package/docs/desktop.mdx +1 -1
- package/docs/enterprise.md +17 -22
- package/docs/environment.mdx +1 -0
- package/docs/first-drive.md +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 +16 -1
- package/docs/license-activation.mdx +3 -3
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/server.mdx +1 -1
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages/test.mdx +1 -1
- package/docs/packages.mdx +1 -1
- package/docs/platform-integration.md +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 +6 -4
- 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 +18 -14
- package/LICENSE-ENTERPRISE +0 -37
- package/dist/features/ee/audit-log.d.ts +0 -14
- package/dist/features/ee/audit-log.js +0 -11
- package/dist/features/exhaust/exhaust-run.d.ts +0 -33
- package/dist/features/exhaust/exhaust-run.js +0 -82
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** The call in a streak that gets the hint. Two calls can be a deliberate retry; three is a loop. */
|
|
2
|
+
export declare const REPEAT_HINT_AT = 3;
|
|
3
|
+
export declare const RepeatHint: {
|
|
4
|
+
readonly NO_MATCH: string;
|
|
5
|
+
/** A no_match whose refusal listed the nearest targets: the retry is one of those refs. */
|
|
6
|
+
readonly noMatchNearest: (ref: string) => string;
|
|
7
|
+
readonly LOOK_SAME: string;
|
|
8
|
+
readonly RECOVERY: string;
|
|
9
|
+
readonly SAME: `You made this call ${string} times in a row with the same result.`;
|
|
10
|
+
/** A verdict repeated: name its own reason, the only thing the result says about why. */
|
|
11
|
+
readonly verdict: (verified: string, because: string | undefined) => string;
|
|
12
|
+
};
|
|
13
|
+
/** What a call came back with, as far as a repeat is concerned: an identity and the line to say. */
|
|
14
|
+
export interface RepeatOutcome {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly hint: string;
|
|
17
|
+
}
|
|
18
|
+
/** The outcome of a call that threw: its refusal reason. */
|
|
19
|
+
export declare function outcomeOfError(error: unknown): RepeatOutcome;
|
|
20
|
+
/** The outcome of a call that answered: its refusal reason, its verdict, or its whole answer. */
|
|
21
|
+
export declare function outcomeOfResult(tool: string, result: unknown): RepeatOutcome;
|
|
22
|
+
/** Tests only. */
|
|
23
|
+
export declare function resetRepeatHints(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Note one call of one connection, and answer the hint when this call is the third in a streak.
|
|
26
|
+
* `owner` is the agent connection; undefined (the Harness, the HUD, an embedding) is never counted.
|
|
27
|
+
*/
|
|
28
|
+
export declare function noteRepeat(owner: string | undefined, tool: string, args: Record<string, unknown>, outcome: RepeatOutcome): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Run one call of one connection inside its repeat streak. Answers the result and, on the third
|
|
31
|
+
* identical call, the hint. A call that throws keeps its hint beside the error (`withRepeatHint`).
|
|
32
|
+
*/
|
|
33
|
+
export declare function inRepeatStreak(owner: string | undefined, tool: string, args: Record<string, unknown>, run: () => Promise<unknown>): Promise<{
|
|
34
|
+
raw: unknown;
|
|
35
|
+
hint: string | undefined;
|
|
36
|
+
}>;
|
|
37
|
+
/** The answer with the hint beside it. Extra text only: the verdict and every field stay as they are. */
|
|
38
|
+
export declare function withHintOn(answer: unknown, hint: string | undefined): unknown;
|
|
39
|
+
/** The error payload with the hint its call earned, if any. */
|
|
40
|
+
export declare function withRepeatHint<T extends object>(payload: T, error: unknown): T;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One hint when an agent makes the same call, with the same result, for the third time in a row.
|
|
3
|
+
*
|
|
4
|
+
* Agents in the field made the same call five times or more in a row. Each answer was the same, and
|
|
5
|
+
* nothing in it said so. This module remembers the LAST call of each agent connection and gives one
|
|
6
|
+
* line, on the third identical call, that says what to try instead.
|
|
7
|
+
*
|
|
8
|
+
* Advice only: it reads a result that is already decided and never changes or blocks it. A hint says
|
|
9
|
+
* only what the result supports. When there is nothing specific to say, it says that the call was
|
|
10
|
+
* repeated with the same result.
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from 'node:crypto';
|
|
13
|
+
import { RefusalReason, ReticleTool, isPlainRecord } from '@reticlehq/core';
|
|
14
|
+
import { resultIsError } from '../mcp/faults/mcp-is-error.js';
|
|
15
|
+
import { buildErrorPayload, codedRefusalOf, refusalReasonFor } from './error-recovery.js';
|
|
16
|
+
import { EnvelopeKey } from './tool-kit.js';
|
|
17
|
+
import { NEAREST_TARGETS_LEAD } from './act/resolve-target.js';
|
|
18
|
+
/** The call in a streak that gets the hint. Two calls can be a deliberate retry; three is a loop. */
|
|
19
|
+
export const REPEAT_HINT_AT = 3;
|
|
20
|
+
const COUNT = String(REPEAT_HINT_AT);
|
|
21
|
+
export const RepeatHint = {
|
|
22
|
+
NO_MATCH: `You made this call ${COUNT} times and each time no element matched. Do not send it again. ` +
|
|
23
|
+
'Take one reticle_look { action: "find" } and use a ref from its answer.',
|
|
24
|
+
/** A no_match whose refusal listed the nearest targets: the retry is one of those refs. */
|
|
25
|
+
noMatchNearest: (ref) => `You made this call ${COUNT} times and each time no element matched. Do not send it again. ` +
|
|
26
|
+
`The refusal lists the nearest targets. Pass one of their refs as \`ref\`, for example "${ref}".`,
|
|
27
|
+
LOOK_SAME: `You made this look ${COUNT} times and each answer was the same, so the page did not change. ` +
|
|
28
|
+
'Act on the page, or wait for a change with reticle_assert { action: "wait" }.',
|
|
29
|
+
RECOVERY: `You made this call ${COUNT} times and it was refused for the same reason each time. ` +
|
|
30
|
+
'Do the step in `recovery` before you send it again.',
|
|
31
|
+
SAME: `You made this call ${COUNT} times in a row with the same result.`,
|
|
32
|
+
/** A verdict repeated: name its own reason, the only thing the result says about why. */
|
|
33
|
+
verdict: (verified, because) => `You made this call ${COUNT} times and each verdict was "${verified}".` +
|
|
34
|
+
(because === undefined ? '' : ` Its reason: "${because}".`) +
|
|
35
|
+
' The same call gives the same verdict. Change the target, the action or the `until`.',
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Result keys that change from call to call when nothing else did: the dispatcher's own advisories,
|
|
39
|
+
* the screenshot path, and the clock. A key that is missed here only means no hint fires.
|
|
40
|
+
*/
|
|
41
|
+
const VOLATILE_KEYS = new Set([
|
|
42
|
+
...Object.values(EnvelopeKey),
|
|
43
|
+
'cursor',
|
|
44
|
+
'since',
|
|
45
|
+
'at',
|
|
46
|
+
'ms',
|
|
47
|
+
'elapsedMs',
|
|
48
|
+
'durationMs',
|
|
49
|
+
]);
|
|
50
|
+
/** The same JSON for the same value, whatever the key order. */
|
|
51
|
+
function stableJson(value) {
|
|
52
|
+
if (Array.isArray(value)) {
|
|
53
|
+
return `[${value.map(stableJson).join(',')}]`;
|
|
54
|
+
}
|
|
55
|
+
if (isPlainRecord(value)) {
|
|
56
|
+
const keys = Object.keys(value)
|
|
57
|
+
.filter((key) => value[key] !== undefined)
|
|
58
|
+
.sort();
|
|
59
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(',')}}`;
|
|
60
|
+
}
|
|
61
|
+
return JSON.stringify(value) ?? 'undefined';
|
|
62
|
+
}
|
|
63
|
+
/** A short digest, so a connection keeps a few bytes and not a whole page tree. */
|
|
64
|
+
function digest(text) {
|
|
65
|
+
return createHash('sha256').update(text).digest('hex').slice(0, 16);
|
|
66
|
+
}
|
|
67
|
+
/** The first ref in a no_match refusal's nearest-target list, or undefined when it has no list. */
|
|
68
|
+
function firstNearestRef(message) {
|
|
69
|
+
const at = message.indexOf(NEAREST_TARGETS_LEAD);
|
|
70
|
+
if (-1 === at) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return /^(\S+) \(/.exec(message.slice(at + NEAREST_TARGETS_LEAD.length))?.[1];
|
|
74
|
+
}
|
|
75
|
+
function refusal(reason, recovery, message) {
|
|
76
|
+
const id = `refused:${reason}`;
|
|
77
|
+
if (RefusalReason.NO_MATCH === reason) {
|
|
78
|
+
const ref = firstNearestRef(message);
|
|
79
|
+
return { id, hint: ref === undefined ? RepeatHint.NO_MATCH : RepeatHint.noMatchNearest(ref) };
|
|
80
|
+
}
|
|
81
|
+
return { id, hint: 'string' === typeof recovery ? RepeatHint.RECOVERY : RepeatHint.SAME };
|
|
82
|
+
}
|
|
83
|
+
/** The outcome of a call that threw: its refusal reason. */
|
|
84
|
+
export function outcomeOfError(error) {
|
|
85
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
86
|
+
const coded = codedRefusalOf(error);
|
|
87
|
+
return refusal(refusalReasonFor(message, coded), buildErrorPayload(message, coded).recovery, message);
|
|
88
|
+
}
|
|
89
|
+
/** The outcome of a call that answered: its refusal reason, its verdict, or its whole answer. */
|
|
90
|
+
export function outcomeOfResult(tool, result) {
|
|
91
|
+
if (!isPlainRecord(result)) {
|
|
92
|
+
return { id: `value:${digest(stableJson(result))}`, hint: RepeatHint.SAME };
|
|
93
|
+
}
|
|
94
|
+
if (resultIsError(result)) {
|
|
95
|
+
const message = String(result['error']);
|
|
96
|
+
return refusal(refusalReasonFor(message), result['recovery'], message);
|
|
97
|
+
}
|
|
98
|
+
if ('verified' in result) {
|
|
99
|
+
const verified = String(result['verified']);
|
|
100
|
+
const because = 'string' === typeof result['because'] ? result['because'] : undefined;
|
|
101
|
+
return {
|
|
102
|
+
id: `verdict:${verified}:${because ?? ''}`,
|
|
103
|
+
hint: RepeatHint.verdict(verified, because),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const kept = Object.fromEntries(Object.entries(result).filter(([key]) => !VOLATILE_KEYS.has(key)));
|
|
107
|
+
return {
|
|
108
|
+
id: `answer:${digest(stableJson(kept))}`,
|
|
109
|
+
hint: ReticleTool.LOOK === tool ? RepeatHint.LOOK_SAME : RepeatHint.SAME,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** Bound on remembered connections: a daemon outlives them. Each keeps only its last call. */
|
|
113
|
+
const MAX_CONNECTIONS = 500;
|
|
114
|
+
const lastByConnection = new Map();
|
|
115
|
+
/** Tests only. */
|
|
116
|
+
export function resetRepeatHints() {
|
|
117
|
+
lastByConnection.clear();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Note one call of one connection, and answer the hint when this call is the third in a streak.
|
|
121
|
+
* `owner` is the agent connection; undefined (the Harness, the HUD, an embedding) is never counted.
|
|
122
|
+
*/
|
|
123
|
+
export function noteRepeat(owner, tool, args, outcome) {
|
|
124
|
+
if (owner === undefined) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
const call = digest(`${tool}:${stableJson(args)}`);
|
|
128
|
+
const last = lastByConnection.get(owner);
|
|
129
|
+
const count = last?.call === call && last.outcome === outcome.id ? last.count + 1 : 1;
|
|
130
|
+
// Delete first, so the map order is last use and the oldest connection is the one that goes.
|
|
131
|
+
lastByConnection.delete(owner);
|
|
132
|
+
if (lastByConnection.size >= MAX_CONNECTIONS) {
|
|
133
|
+
const oldest = lastByConnection.keys().next().value;
|
|
134
|
+
if (oldest !== undefined) {
|
|
135
|
+
lastByConnection.delete(oldest);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
lastByConnection.set(owner, { call, outcome: outcome.id, count });
|
|
139
|
+
return REPEAT_HINT_AT === count ? outcome.hint : undefined;
|
|
140
|
+
}
|
|
141
|
+
/** Hints for calls that threw, kept beside the error so the boundary that answers can read them. */
|
|
142
|
+
const hintByError = new WeakMap();
|
|
143
|
+
/**
|
|
144
|
+
* Run one call of one connection inside its repeat streak. Answers the result and, on the third
|
|
145
|
+
* identical call, the hint. A call that throws keeps its hint beside the error (`withRepeatHint`).
|
|
146
|
+
*/
|
|
147
|
+
export async function inRepeatStreak(owner, tool, args, run) {
|
|
148
|
+
let raw;
|
|
149
|
+
try {
|
|
150
|
+
raw = await run();
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
const hint = noteRepeat(owner, tool, args, outcomeOfError(error));
|
|
154
|
+
if (hint !== undefined && 'object' === typeof error && null !== error) {
|
|
155
|
+
hintByError.set(error, hint);
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
return { raw, hint: noteRepeat(owner, tool, args, outcomeOfResult(tool, raw)) };
|
|
160
|
+
}
|
|
161
|
+
/** The answer with the hint beside it. Extra text only: the verdict and every field stay as they are. */
|
|
162
|
+
export function withHintOn(answer, hint) {
|
|
163
|
+
return hint !== undefined && isPlainRecord(answer)
|
|
164
|
+
? { ...answer, [EnvelopeKey.REPEAT_HINT]: hint }
|
|
165
|
+
: answer;
|
|
166
|
+
}
|
|
167
|
+
/** The error payload with the hint its call earned, if any. */
|
|
168
|
+
export function withRepeatHint(payload, error) {
|
|
169
|
+
const hint = 'object' === typeof error && null !== error ? hintByError.get(error) : undefined;
|
|
170
|
+
return hint === undefined ? payload : { ...payload, [EnvelopeKey.REPEAT_HINT]: hint };
|
|
171
|
+
}
|
|
@@ -14,8 +14,8 @@ export declare function renderRunReport(report: RunReport): string;
|
|
|
14
14
|
export declare function endsRun(tool: string, args: Record<string, unknown>): boolean;
|
|
15
15
|
/** What an answer says the run saved or read. An answer that refused counts for nothing. */
|
|
16
16
|
export declare function noteToolResult(ledger: RunLedger, tool: string, args: Record<string, unknown>, result: unknown): void;
|
|
17
|
-
/** The report as an answer field, or no field when the
|
|
18
|
-
export declare function runReportField(ledger: RunLedger, root: string | undefined, env: Record<string, string | undefined>, now: number): Partial<Record<typeof RUN_REPORT_FIELD, {
|
|
17
|
+
/** The owner's report as an answer field, or no field when the owner has no run. Ends that run. */
|
|
18
|
+
export declare function runReportField(ledger: RunLedger, root: string | undefined, env: Record<string, string | undefined>, now: number, owner?: string): Partial<Record<typeof RUN_REPORT_FIELD, {
|
|
19
19
|
report: RunReport;
|
|
20
20
|
markdown: string;
|
|
21
21
|
instruction: string;
|
|
@@ -34,12 +34,15 @@ function headline(report) {
|
|
|
34
34
|
const count = (v) => all.filter((each) => v === each).length;
|
|
35
35
|
const total = all.length;
|
|
36
36
|
const word = `${HEAD}${WORD[report.verified]}**${SEP}`;
|
|
37
|
-
if (0 === total)
|
|
37
|
+
if (0 === total) {
|
|
38
38
|
return `${word}${Said.NOTHING_CHECKED}`;
|
|
39
|
-
|
|
39
|
+
}
|
|
40
|
+
if (Verified.NO === report.verified) {
|
|
40
41
|
return `${word}${String(count(Verified.NO))} of ${plural(total, 'check')} did not hold`;
|
|
41
|
-
|
|
42
|
+
}
|
|
43
|
+
if (Verified.YES === report.verified) {
|
|
42
44
|
return `${word}${String(total)} of ${plural(total, 'check')} held`;
|
|
45
|
+
}
|
|
43
46
|
return `${word}${String(total - count(Verified.YES) - count(Verified.NO))} of ${plural(total, 'check')} undecided`;
|
|
44
47
|
}
|
|
45
48
|
/** The report as markdown: the verdict, each claim with its evidence, then what the run left. */
|
|
@@ -95,39 +98,48 @@ const INTENT_READS = new Set(['list', 'index', 'subject', 'get']);
|
|
|
95
98
|
const isRecord = (value) => null !== value && 'object' === typeof value && !Array.isArray(value);
|
|
96
99
|
/** What an answer says the run saved or read. An answer that refused counts for nothing. */
|
|
97
100
|
export function noteToolResult(ledger, tool, args, result) {
|
|
98
|
-
if (!isRecord(result) || result['error'] !== undefined)
|
|
101
|
+
if (!isRecord(result) || result['error'] !== undefined) {
|
|
99
102
|
return;
|
|
103
|
+
}
|
|
100
104
|
if (ReticleTool.FLOW_SAVE === tool || ReticleTool.FLOW_SAVE_RECORDED === tool) {
|
|
101
105
|
const name = result['name'];
|
|
102
|
-
if ('string' === typeof name)
|
|
106
|
+
if ('string' === typeof name) {
|
|
103
107
|
ledger.flowSaved(name);
|
|
108
|
+
}
|
|
104
109
|
return;
|
|
105
110
|
}
|
|
106
111
|
const action = asString(args['action']);
|
|
107
112
|
if (ReticleTool.INTENT === tool) {
|
|
108
113
|
// The intent ledger in `.reticle/intent/` is the memory an unlinked project has.
|
|
109
|
-
if (IntentWrite.RECORD === action)
|
|
114
|
+
if (IntentWrite.RECORD === action) {
|
|
110
115
|
ledger.memoryWritten();
|
|
116
|
+
}
|
|
111
117
|
const declared = args['intents'];
|
|
112
|
-
if (IntentWrite.DECLARE === action && Array.isArray(declared))
|
|
118
|
+
if (IntentWrite.DECLARE === action && Array.isArray(declared)) {
|
|
113
119
|
ledger.memoryWritten(declared.length);
|
|
114
|
-
|
|
120
|
+
}
|
|
121
|
+
if (action !== undefined && INTENT_READS.has(action)) {
|
|
115
122
|
ledger.memoryRead([JSON.stringify(result)]);
|
|
123
|
+
}
|
|
116
124
|
return;
|
|
117
125
|
}
|
|
118
|
-
if (ReticleTool.MEMORY !== tool)
|
|
126
|
+
if (ReticleTool.MEMORY !== tool) {
|
|
119
127
|
return;
|
|
120
|
-
|
|
128
|
+
}
|
|
129
|
+
if ('add' === action && result['added'] !== undefined) {
|
|
121
130
|
ledger.memoryWritten();
|
|
131
|
+
}
|
|
122
132
|
const known = result['known'];
|
|
123
|
-
if (Array.isArray(known))
|
|
133
|
+
if (Array.isArray(known)) {
|
|
124
134
|
ledger.memoryRead(known.map((entry) => JSON.stringify(entry)));
|
|
135
|
+
}
|
|
125
136
|
}
|
|
126
|
-
/** The report as an answer field, or no field when the
|
|
127
|
-
export function runReportField(ledger, root, env, now) {
|
|
128
|
-
if (ledger.isEmpty())
|
|
137
|
+
/** The owner's report as an answer field, or no field when the owner has no run. Ends that run. */
|
|
138
|
+
export function runReportField(ledger, root, env, now, owner) {
|
|
139
|
+
if (ledger.isEmpty(owner)) {
|
|
129
140
|
return {};
|
|
130
|
-
|
|
141
|
+
}
|
|
142
|
+
const taken = ledger.take(now, owner);
|
|
131
143
|
const silenced = env[UPGRADE_HINT_SILENCE_ENV] !== undefined;
|
|
132
144
|
const linked = root === undefined || linkedToPlatform(root, env);
|
|
133
145
|
const report = silenced || linked ? taken : { ...taken, cloud: CLOUD_VALUE_LINE };
|
|
@@ -55,3 +55,17 @@ export declare function suiteFixturePort(realInput: RealInputProvider | undefine
|
|
|
55
55
|
* is the reach the boundary guard exists to ask about.
|
|
56
56
|
*/
|
|
57
57
|
export declare function sessionMutationPort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<NetworkMutationPort | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* The state a verify run started in, put back before each flow after the first.
|
|
60
|
+
*
|
|
61
|
+
* `reticle verify` replays every flow in ONE driven page. A flow that signs out (an auto-saved
|
|
62
|
+
* "log out" fragment, or a journey that ends on the logout link) left every later flow signed out,
|
|
63
|
+
* and each of them then failed for a reason none of them named. The leased suite path never had
|
|
64
|
+
* this: each flow boots its own context from one captured seed. This gives the single-page path
|
|
65
|
+
* the same start.
|
|
66
|
+
*
|
|
67
|
+
* Call it before each flow. It answers `undefined` to go on, or the reason the flow cannot start
|
|
68
|
+
* where the run started, which the caller reports as not proved. Nothing to capture (no driven
|
|
69
|
+
* page, no storage support) means the run goes on as before.
|
|
70
|
+
*/
|
|
71
|
+
export declare function flowStartState(provider: RealInputProvider | undefined, currentUrl: () => string | undefined): () => Promise<string | undefined>;
|
|
@@ -100,3 +100,56 @@ export async function sessionMutationPort(realInput, appUrl) {
|
|
|
100
100
|
return undefined;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* The state a verify run started in, put back before each flow after the first.
|
|
105
|
+
*
|
|
106
|
+
* `reticle verify` replays every flow in ONE driven page. A flow that signs out (an auto-saved
|
|
107
|
+
* "log out" fragment, or a journey that ends on the logout link) left every later flow signed out,
|
|
108
|
+
* and each of them then failed for a reason none of them named. The leased suite path never had
|
|
109
|
+
* this: each flow boots its own context from one captured seed. This gives the single-page path
|
|
110
|
+
* the same start.
|
|
111
|
+
*
|
|
112
|
+
* Call it before each flow. It answers `undefined` to go on, or the reason the flow cannot start
|
|
113
|
+
* where the run started, which the caller reports as not proved. Nothing to capture (no driven
|
|
114
|
+
* page, no storage support) means the run goes on as before.
|
|
115
|
+
*/
|
|
116
|
+
export function flowStartState(provider, currentUrl) {
|
|
117
|
+
let first = true;
|
|
118
|
+
let saved;
|
|
119
|
+
return async () => {
|
|
120
|
+
const url = currentUrl();
|
|
121
|
+
if (first) {
|
|
122
|
+
first = false;
|
|
123
|
+
if (provider === undefined || url === undefined) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const port = await fixturePortFor(provider, url);
|
|
128
|
+
saved = port === undefined ? undefined : { state: await port.capture(), url };
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
saved = undefined;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
if (saved === undefined || provider === undefined) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
// Straight to the provider, not through `fixturePortFor`: its address check compares the
|
|
140
|
+
// session's recorded address with the page's, and a flow that reloaded or signed out leaves
|
|
141
|
+
// the two different while the page is the same. The provider still refuses a page it does
|
|
142
|
+
// not drive (it answers false), so nothing is restored into a stranger's page.
|
|
143
|
+
// Tabs first: a tab the previous flow opened is a second connected session otherwise.
|
|
144
|
+
await provider.closeOtherPages?.();
|
|
145
|
+
const restored = await provider.applyStorageState?.(url ?? saved.url, saved.state);
|
|
146
|
+
return true === restored
|
|
147
|
+
? undefined
|
|
148
|
+
: 'could not put the page back in the state the run started with: no driven page matched';
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
152
|
+
return `could not put the page back in the state the run started with: ${message}`;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -31,6 +31,12 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
31
31
|
* the fake-pool lease tests are deliberately runnable without a real Chromium.
|
|
32
32
|
*/
|
|
33
33
|
browserProbe?: () => Promise<ChromiumProbe>;
|
|
34
|
+
/**
|
|
35
|
+
* Whether something on this loopback port accepted a connection. Asked only after a lease
|
|
36
|
+
* navigation timed out, to tell a dev server compiling its first route from no server (#2005).
|
|
37
|
+
* Optional: absent ⇒ the timeout keeps its generic advice.
|
|
38
|
+
*/
|
|
39
|
+
portAccepts?: (port: number) => Promise<boolean>;
|
|
34
40
|
baselines: BaselineStore;
|
|
35
41
|
recordings: RecordingStore;
|
|
36
42
|
/** on-disk anchored-flow store (.reticle/flows/). */
|
|
@@ -96,6 +102,11 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
96
102
|
} | undefined>;
|
|
97
103
|
/** The one dev server running in the caller's project folder, for a lease that names no url. */
|
|
98
104
|
projectAppUrl?: () => Promise<string | undefined>;
|
|
105
|
+
/**
|
|
106
|
+
* The first-session offer for this attach id's first call, when no app is attached and the
|
|
107
|
+
* project is not wired (see zero-install-first-call.ts). Absent: no offer.
|
|
108
|
+
*/
|
|
109
|
+
firstSessionOffer?: (attachId: string) => string | undefined;
|
|
99
110
|
/** cross-run outcome memory (.reticle/project.json). */
|
|
100
111
|
project: ProjectStore;
|
|
101
112
|
/** optional native-input provider. undefined ⇒ everything stays synthetic. */
|
|
@@ -303,10 +314,17 @@ export declare const EnvelopeKey: {
|
|
|
303
314
|
* what it cannot see, and the command that wires the app for good. See zero-install-first-call.ts.
|
|
304
315
|
*/
|
|
305
316
|
readonly ZERO_INSTALL: "zero_install";
|
|
317
|
+
/**
|
|
318
|
+
* Once per agent connection, on its first call: this unwired web app can be checked now with the
|
|
319
|
+
* lease, and `init` needs the user's consent. See zero-install-first-call.ts.
|
|
320
|
+
*/
|
|
321
|
+
readonly FIRST_SESSION_OFFER: "first_session_offer";
|
|
306
322
|
/** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
|
|
307
323
|
readonly NOTICES: "notices";
|
|
308
324
|
/** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
|
|
309
325
|
readonly RUN_REPORT: "runReport";
|
|
326
|
+
/** On the third identical call with the same result: what to try instead. See repeat-hint.ts. */
|
|
327
|
+
readonly REPEAT_HINT: "repeatHint";
|
|
310
328
|
};
|
|
311
329
|
export type EnvelopeKey = (typeof EnvelopeKey)[keyof typeof EnvelopeKey];
|
|
312
330
|
/**
|
|
@@ -99,10 +99,17 @@ export const EnvelopeKey = {
|
|
|
99
99
|
* what it cannot see, and the command that wires the app for good. See zero-install-first-call.ts.
|
|
100
100
|
*/
|
|
101
101
|
ZERO_INSTALL: 'zero_install',
|
|
102
|
+
/**
|
|
103
|
+
* Once per agent connection, on its first call: this unwired web app can be checked now with the
|
|
104
|
+
* lease, and `init` needs the user's consent. See zero-install-first-call.ts.
|
|
105
|
+
*/
|
|
106
|
+
FIRST_SESSION_OFFER: 'first_session_offer',
|
|
102
107
|
/** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
|
|
103
108
|
NOTICES: 'notices',
|
|
104
109
|
/** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
|
|
105
110
|
RUN_REPORT: RUN_REPORT_FIELD,
|
|
111
|
+
/** On the third identical call with the same result: what to try instead. See repeat-hint.ts. */
|
|
112
|
+
REPEAT_HINT: 'repeatHint',
|
|
106
113
|
};
|
|
107
114
|
/**
|
|
108
115
|
* The sentence every session-bound result carries while its leased tab runs on a stubbed shell.
|
|
@@ -149,6 +156,8 @@ export const CDP_TOOLS = new Set([
|
|
|
149
156
|
// Breaks a request through the same Playwright route `reticle_network_mock` uses, so it fails the
|
|
150
157
|
// same way under version skew and must be refused with the same sentence.
|
|
151
158
|
ReticleTool.FLOW_MUTATE,
|
|
159
|
+
// Reads JS coverage through the lease's Playwright page, the way `reticle_network_mock` reaches it.
|
|
160
|
+
ReticleTool.LEASE_COVERAGE,
|
|
152
161
|
]);
|
|
153
162
|
/**
|
|
154
163
|
* Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
|
|
@@ -164,7 +173,6 @@ export const REF_MINTING_TOOLS = new Set([
|
|
|
164
173
|
// The same three merged, on the `merged` surface. Its `state` action mints nothing, and
|
|
165
174
|
// over-inclusion is the safe direction here: the worst case is a refusal naming two tabs.
|
|
166
175
|
ReticleTool.LOOK,
|
|
167
|
-
ReticleTool.EXPLORE,
|
|
168
176
|
// `crawl` mints refs for the controls it drives and `coverage` for the ones it reports untouched.
|
|
169
177
|
// Both are actions on the merged verify tool now.
|
|
170
178
|
ReticleTool.VERIFY,
|
|
@@ -205,11 +213,9 @@ export const SESSION_BOUND_TOOLS = new Set([
|
|
|
205
213
|
ReticleTool.ANIMATIONS,
|
|
206
214
|
ReticleTool.BASELINE, // merged save/list/diff — save+diff are live reads
|
|
207
215
|
ReticleTool.RECORD, // merged start/stop — both live
|
|
208
|
-
ReticleTool.REPLAY,
|
|
209
216
|
ReticleTool.CLOCK,
|
|
210
217
|
ReticleTool.STATE,
|
|
211
218
|
ReticleTool.STORAGE,
|
|
212
|
-
ReticleTool.EXPLORE,
|
|
213
219
|
ReticleTool.SCROLL_TO,
|
|
214
220
|
ReticleTool.NAVIGATE,
|
|
215
221
|
]);
|