@reticlehq/server 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/SKILL.md +123 -116
- package/dist/chromium-launch-options.d.ts +3 -1
- package/dist/chromium-launch-options.js +2 -1
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +19 -2
- package/dist/command/cli/adhoc-verdict.js +76 -9
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/answers/open-note.d.ts +2 -0
- package/dist/command/cli/answers/open-note.js +22 -0
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +31 -112
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +35 -5
- package/dist/command/cli/cli-verify.js +114 -35
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +192 -341
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +22 -0
- package/dist/command/cli/cloud-login.js +96 -8
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/drive/drive-attach.d.ts +27 -2
- package/dist/command/cli/drive/drive-attach.js +71 -4
- package/dist/command/cli/drive/drive-command.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +13 -7
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.d.ts +10 -0
- package/dist/command/cli/ports/port-holder.js +25 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +35 -12
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -181
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +20 -0
- package/dist/command/cli.js +130 -104
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +23 -1
- package/dist/command/daemon/daemon-resolve.js +79 -9
- package/dist/command/setup/agent-writer.d.ts +1 -1
- package/dist/command/setup/agent-writer.js +3 -2
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
- package/dist/command/setup/bringup/connect-lease.js +1 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
- package/dist/command/setup/bringup/dev-server-wait.js +19 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +14 -1
- package/dist/command/setup/init/init-port.js +32 -2
- package/dist/command/setup/init/init-runtime.d.ts +22 -2
- package/dist/command/setup/init/init-runtime.js +114 -38
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +38 -9
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +2 -1
- package/dist/command/setup/run-setup.d.ts +34 -9
- package/dist/command/setup/run-setup.js +65 -51
- package/dist/command/setup/setup-command.d.ts +25 -1
- package/dist/command/setup/setup-command.js +59 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +49 -4
- package/dist/features/crawl/crawl-tools.js +4 -0
- package/dist/features/crawl/crawl.d.ts +6 -0
- package/dist/features/crawl/crawl.js +23 -2
- package/dist/features/exhaust/ledger.d.ts +21 -14
- package/dist/features/exhaust/ledger.js +35 -9
- package/dist/features/harness/app-findings.d.ts +2 -0
- package/dist/features/harness/app-findings.js +52 -0
- package/dist/features/harness/drive-report.d.ts +61 -1
- package/dist/features/harness/drive-report.js +394 -26
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +10 -14
- package/dist/features/harness/drivers.js +10 -14
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/fill-values.d.ts +3 -73
- package/dist/features/harness/fill-values.js +3 -169
- package/dist/features/harness/goals.d.ts +82 -0
- package/dist/features/harness/goals.js +330 -0
- package/dist/features/harness/harness.d.ts +51 -1
- package/dist/features/harness/harness.js +207 -6
- package/dist/features/harness/platform/drive-target.d.ts +30 -0
- package/dist/features/harness/platform/drive-target.js +81 -0
- package/dist/features/harness/platform/local-apps.d.ts +127 -0
- package/dist/features/harness/platform/local-apps.js +280 -0
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +186 -0
- package/dist/features/harness/platform/remote-drive.js +378 -0
- package/dist/features/harness/platform/script.d.ts +94 -0
- package/dist/features/harness/platform/script.js +260 -0
- package/dist/features/harness/platform/server-driver.d.ts +54 -0
- package/dist/features/harness/platform/server-driver.js +182 -0
- package/dist/features/harness/platform-config.d.ts +41 -1
- package/dist/features/harness/platform-config.js +106 -9
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/app-controls.d.ts +5 -0
- package/dist/features/harness/script/app-controls.js +40 -0
- package/dist/features/harness/script/lane-ids.d.ts +14 -0
- package/dist/features/harness/script/lane-ids.js +16 -0
- package/dist/features/harness/script/script-run.d.ts +70 -0
- package/dist/features/harness/script/script-run.js +606 -0
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.d.ts +10 -1
- package/dist/features/visual/visual-tools.js +62 -17
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +23 -0
- package/dist/hooks/driven-by.js +56 -0
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/hooks/hook-commands.js +15 -4
- package/dist/hooks/tool-log.d.ts +9 -0
- package/dist/hooks/tool-log.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +80 -243
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
- package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
- package/dist/judgement/runs/artifact/run-store.js +195 -3
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +71 -1
- package/dist/judgement/runs/drive-run.js +317 -5
- package/dist/judgement/runs/repair-prompt.js +1 -1
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +13 -3
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +5 -2
- package/dist/judgement/runs/verification-sync.js +40 -18
- package/dist/language/flows/change/gate.d.ts +10 -0
- package/dist/language/flows/change/gate.js +22 -0
- package/dist/language/flows/decision.js +36 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +61 -10
- package/dist/language/flows/flow-anchor.js +98 -6
- package/dist/language/flows/flow-cross-step.d.ts +15 -0
- package/dist/language/flows/flow-cross-step.js +21 -0
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +45 -14
- package/dist/language/flows/flow-mutate-tools.js +5 -3
- package/dist/language/flows/flow-replay-run.d.ts +23 -9
- package/dist/language/flows/flow-replay-run.js +115 -110
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +40 -1
- package/dist/language/flows/flow-replay.js +110 -22
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-scope.js +5 -1
- package/dist/language/flows/flow-step-runners.d.ts +22 -2
- package/dist/language/flows/flow-step-runners.js +247 -47
- package/dist/language/flows/flow-store-for-session.d.ts +2 -2
- package/dist/language/flows/flow-store-for-session.js +7 -3
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +112 -89
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +74 -12
- package/dist/language/flows/heal-run.js +6 -4
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/flake.d.ts +2 -2
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
- package/dist/language/flows/recording/tape/recordings.js +95 -13
- package/dist/language/flows/replay-from-hud.d.ts +20 -0
- package/dist/language/flows/replay-from-hud.js +51 -0
- package/dist/language/flows/replay.d.ts +9 -5
- package/dist/language/flows/replay.js +56 -15
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/suite/suite-flakes.js +2 -0
- package/dist/language/flows/suite-selection.d.ts +2 -15
- package/dist/language/flows/suite-selection.js +4 -3
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +202 -191
- package/dist/launch-chromium.d.ts +27 -5
- package/dist/launch-chromium.js +38 -8
- package/dist/memory/cloud/cloud-config.d.ts +22 -1
- package/dist/memory/cloud/cloud-config.js +34 -5
- package/dist/memory/cloud/cloud-sync.d.ts +17 -14
- package/dist/memory/cloud/cloud-sync.js +15 -4
- package/dist/memory/cloud/harness-config.d.ts +75 -1
- package/dist/memory/cloud/harness-config.js +115 -24
- package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
- package/dist/memory/cloud/hud-notices-source.js +128 -0
- package/dist/memory/cloud/memory-scope.d.ts +161 -0
- package/dist/memory/cloud/memory-scope.js +227 -0
- package/dist/memory/cloud/sync-cycle.d.ts +44 -7
- package/dist/memory/cloud/sync-cycle.js +129 -15
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +121 -9
- package/dist/memory/cloud/sync-disk.d.ts +1 -1
- package/dist/memory/cloud/sync-disk.js +31 -10
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +34 -0
- package/dist/memory/impact/account-watch.js +59 -0
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +12 -2
- package/dist/memory/impact/impact-store.d.ts +17 -4
- package/dist/memory/impact/impact-store.js +169 -63
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +14 -2
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +122 -4
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/envelope.d.ts +8 -8
- package/dist/memory/journal/journal-recorder.js +52 -3
- package/dist/memory/journal/on-disk/retention.d.ts +8 -0
- package/dist/memory/journal/on-disk/retention.js +32 -2
- package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
- package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +42 -9
- package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
- package/dist/memory/project/artifact-root-resolver.js +125 -16
- package/dist/memory/project/artifact-root.d.ts +46 -8
- package/dist/memory/project/artifact-root.js +89 -10
- package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
- package/dist/memory/project/dir/reticle-dir.js +26 -3
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/project-tools.js +22 -3
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +26 -1
- package/dist/memory/project/session-root.js +49 -5
- package/dist/memory/project/sync-status.d.ts +85 -0
- package/dist/memory/project/sync-status.js +224 -0
- package/dist/memory/recall/memory-tools.js +47 -2
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.d.ts +19 -0
- package/dist/memory/recall/project-memory.js +80 -13
- package/dist/portal/bridge/bridge.d.ts +9 -3
- package/dist/portal/bridge/bridge.js +82 -22
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/pairing-token.d.ts +9 -0
- package/dist/portal/bridge/pairing-token.js +17 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +83 -10
- package/dist/portal/input/real-input.js +218 -30
- package/dist/portal/input/viewport-tools.js +3 -3
- package/dist/portal/pool/browser-pool.d.ts +70 -9
- package/dist/portal/pool/browser-pool.js +190 -37
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +35 -0
- package/dist/portal/pool/playwright-launcher.js +64 -3
- package/dist/portal/pool/pool-contract.d.ts +28 -5
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.d.ts +8 -0
- package/dist/portal/session/command-payload.js +24 -0
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
- package/dist/portal/session/dev-server/dev-command.js +87 -12
- package/dist/portal/session/facts/departure-note.d.ts +22 -0
- package/dist/portal/session/facts/departure-note.js +47 -0
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/facts/session-replaced.d.ts +5 -0
- package/dist/portal/session/facts/session-replaced.js +5 -0
- package/dist/portal/session/first-run-wiring.d.ts +42 -0
- package/dist/portal/session/first-run-wiring.js +132 -0
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/human/notes-ledger.d.ts +20 -0
- package/dist/portal/session/human/notes-ledger.js +55 -0
- package/dist/portal/session/human/review-store.d.ts +12 -0
- package/dist/portal/session/human/review-store.js +18 -10
- package/dist/portal/session/live-control-tools.d.ts +0 -13
- package/dist/portal/session/live-control-tools.js +107 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
- package/dist/portal/session/no-session-diagnosis.js +46 -9
- package/dist/portal/session/no-session-next-action.d.ts +31 -0
- package/dist/portal/session/no-session-next-action.js +159 -60
- package/dist/portal/session/no-session-watch.d.ts +14 -1
- package/dist/portal/session/no-session-watch.js +227 -17
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/presence/session-mirror.js +3 -0
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/serving-directory.d.ts +27 -0
- package/dist/portal/session/serving-directory.js +45 -0
- package/dist/portal/session/session-health.d.ts +18 -0
- package/dist/portal/session/session-health.js +9 -1
- package/dist/portal/session/session-info.d.ts +8 -1
- package/dist/portal/session/session-info.js +8 -1
- package/dist/portal/session/session-manager.d.ts +39 -0
- package/dist/portal/session/session-manager.js +98 -11
- package/dist/portal/session/session-reaper.js +4 -1
- package/dist/portal/session/session-successor.d.ts +13 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session-tools.js +26 -3
- package/dist/portal/session/session.d.ts +22 -30
- package/dist/portal/session/session.js +81 -79
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +12 -0
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +23 -1
- package/dist/status-payload.js +36 -1
- package/dist/surface/http-server.js +18 -2
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
- package/dist/surface/mcp/mcp-proxy.js +65 -13
- package/dist/surface/mcp/mcp.d.ts +34 -6
- package/dist/surface/mcp/mcp.js +61 -17
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.d.ts +4 -2
- package/dist/surface/mcp/server-instructions.js +32 -14
- package/dist/surface/mcp/shared-params.js +2 -2
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act/settle-in-flight.js +25 -3
- package/dist/surface/tools/act-sequence-tool.js +138 -29
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +71 -41
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +42 -17
- package/dist/surface/tools/browser-tools.js +51 -2
- package/dist/surface/tools/chat-drives.d.ts +101 -0
- package/dist/surface/tools/chat-drives.js +409 -0
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +51 -0
- package/dist/surface/tools/empty-session-list.js +120 -0
- package/dist/surface/tools/error-recovery.d.ts +14 -0
- package/dist/surface/tools/error-recovery.js +105 -8
- package/dist/surface/tools/explore-tools.d.ts +31 -1
- package/dist/surface/tools/explore-tools.js +438 -66
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +18 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +118 -57
- package/dist/surface/tools/harness-explore.js +344 -292
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +17 -0
- package/dist/surface/tools/harness-plan.js +38 -0
- package/dist/surface/tools/harness-script.d.ts +30 -0
- package/dist/surface/tools/harness-script.js +560 -0
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +22 -1
- package/dist/surface/tools/harness-toolset.js +101 -7
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +263 -85
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +49 -0
- package/dist/surface/tools/lease-seed.js +167 -0
- package/dist/surface/tools/lease-tools.d.ts +13 -24
- package/dist/surface/tools/lease-tools.js +146 -197
- package/dist/surface/tools/live-call-text.js +4 -4
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +29 -0
- package/dist/surface/tools/next-step.js +214 -0
- package/dist/surface/tools/observe-tools.js +45 -9
- package/dist/surface/tools/platform-moment.d.ts +72 -0
- package/dist/surface/tools/platform-moment.js +296 -0
- package/dist/surface/tools/query-hint-schema.d.ts +7 -0
- package/dist/surface/tools/query-hint-schema.js +10 -0
- package/dist/surface/tools/read-tools.js +71 -14
- package/dist/surface/tools/real-input-attempt.js +96 -13
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +83 -3
- package/dist/surface/tools/tool-kit.js +77 -7
- package/dist/surface/tools/tools.js +43 -59
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +29 -6
- package/dist/telemetry/hud-metrics.js +116 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +38 -2
- package/dist/telemetry/telemetry.js +144 -34
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +13 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +20 -6
- package/docs/README.md +3 -3
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +25 -28
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +33 -28
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +14 -3
- package/docs/cli/drive.mdx +20 -14
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +43 -28
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +18 -5
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +5 -4
- package/docs/cli.mdx +111 -42
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +9 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +7 -8
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +65 -61
- package/docs/human-control.md +16 -16
- package/docs/index.mdx +15 -42
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +23 -13
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +9 -9
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +32 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +69 -30
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +23 -25
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +22 -13
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +55 -46
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +17 -5
- package/docs/what-is-reticle.mdx +5 -3
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -241
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/features/harness/driver.d.ts +0 -50
- package/dist/features/harness/driver.js +0 -236
- package/dist/features/harness/jev-driver.d.ts +0 -188
- package/dist/features/harness/jev-driver.js +0 -678
- package/dist/features/harness/openai-driver.d.ts +0 -58
- package/dist/features/harness/openai-driver.js +0 -206
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
- package/dist/memory/project/dir/fill-value-store.js +0 -88
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
- package/docs/local-registry.md +0 -143
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
* the base64 4/3 inflation factor applied, so the encoded payload always fits in one WebSocket
|
|
20
20
|
* frame.
|
|
21
21
|
*/
|
|
22
|
-
import { ActionType, InputModeReason, ReticleCommand, TRANSPORT_LIMITS } from '@reticlehq/core';
|
|
23
|
-
import { boxCenter,
|
|
22
|
+
import { ActionType, DriveErrorCode, InputModeReason, ReticleCommand, TRANSPORT_LIMITS, } from '@reticlehq/core';
|
|
23
|
+
import { boxCenter, DriveError, isRealInputAction, unspellablePressReason, } from '../../portal/input/real-input.js';
|
|
24
24
|
import { assertDragNotDestructive, assertNotDestructive } from './act/act-danger.js';
|
|
25
25
|
import { NATIVE_INPUT_ARG } from '@reticlehq/core';
|
|
26
|
-
import { asRecord, asString } from '@reticlehq/core';
|
|
26
|
+
import { asNumber, asRecord, asString } from '@reticlehq/core';
|
|
27
27
|
import { commandOrThrow } from './tool-kit.js';
|
|
28
28
|
import { asBox } from './act/act-helpers.js';
|
|
29
29
|
import { isAbsolute, join, relative, extname, basename, resolve } from 'node:path';
|
|
@@ -228,6 +228,13 @@ function synthetic(reason) {
|
|
|
228
228
|
? { result: undefined, settled: false }
|
|
229
229
|
: { result: undefined, settled: false, reason };
|
|
230
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Filler for the provider signature, which demands a box on every action.
|
|
233
|
+
*
|
|
234
|
+
* No coordinate is derived from it and none is reported back: `performGesture` returns before it
|
|
235
|
+
* reads the box on a press, because a key addresses focus rather than a point.
|
|
236
|
+
*/
|
|
237
|
+
const PRESS_HAS_NO_BOX = { x: 0, y: 0, width: 0, height: 0 };
|
|
231
238
|
/**
|
|
232
239
|
* Hover without a native pointer is a false success: synthetic mouseover reports dispatched and
|
|
233
240
|
* settled while CSS `:hover` never applies. Same refusal shape as contenteditable — name the gap
|
|
@@ -258,8 +265,10 @@ async function hoverForReal(deps, session, ref, inner, provider) {
|
|
|
258
265
|
if (providerReady && provider !== undefined) {
|
|
259
266
|
try {
|
|
260
267
|
const performed = await provider.perform(session.url, ActionType.HOVER, box, {});
|
|
268
|
+
// Hover always has a resolved box, so there is always a center to report: the provider's own
|
|
269
|
+
// reading, or the box's if it reported none. Both are the same point, not a fabricated one.
|
|
261
270
|
if (performed.performed)
|
|
262
|
-
return hoverSucceeded(performed.center);
|
|
271
|
+
return hoverSucceeded(performed.center ?? boxCenter(box));
|
|
263
272
|
}
|
|
264
273
|
catch {
|
|
265
274
|
// A provider error used to fall back to synthetic dispatch. For hover that is a lie.
|
|
@@ -295,7 +304,14 @@ export async function tryRealInput(deps, session, ref, action, args) {
|
|
|
295
304
|
// real debugging time, because the tool description promises a reason is "never silent".
|
|
296
305
|
return askedForNative ? synthetic(InputModeReason.NOT_CONFIGURED) : synthetic();
|
|
297
306
|
}
|
|
298
|
-
|
|
307
|
+
// Two `press`es this module will NOT drive, and neither is a fallback — the reason says which
|
|
308
|
+
// one was asked for, instead of a different gesture being sent. See `unspellablePressReason`.
|
|
309
|
+
if (action === ActionType.PRESS) {
|
|
310
|
+
const unspellable = unspellablePressReason(ref, inner);
|
|
311
|
+
if (unspellable !== undefined)
|
|
312
|
+
return synthetic(unspellable);
|
|
313
|
+
}
|
|
314
|
+
if (!isRealInputAction(action))
|
|
299
315
|
return synthetic(InputModeReason.NOT_POINTER); // fill/type stay synthetic
|
|
300
316
|
// "Don't click, run the code": a click/dblclick runs the occlusion-honest SYNTHETIC path by default
|
|
301
317
|
// even with a provider configured — no coordinate gesture to be intercepted by the HUD or missed
|
|
@@ -307,11 +323,85 @@ export async function tryRealInput(deps, session, ref, action, args) {
|
|
|
307
323
|
// Under version skew CDP is unusable while DOM tools still work (#688). Surface the skew sentence
|
|
308
324
|
// rather than "page not correlated" / a silent provider-error fallback — those send the agent
|
|
309
325
|
// hunting a dead context that is not dead.
|
|
310
|
-
|
|
326
|
+
//
|
|
327
|
+
// `press` is exempt, and it is the one action where throwing would take something away: a
|
|
328
|
+
// document key is dispatched entirely in the page, so it does not need CDP at all and has always
|
|
329
|
+
// worked under skew. Routing it into real input made it reach this line for the first time, and
|
|
330
|
+
// throwing here would turn a working synthetic press into a hard failure. It falls through to
|
|
331
|
+
// `isAvailableFor` instead, and a driver that really is dead answers PROVIDER_ERROR with the
|
|
332
|
+
// usual `fellBack` — still a signal, just not a refusal.
|
|
333
|
+
if (action !== ActionType.PRESS && session.versionSkew !== undefined) {
|
|
311
334
|
throw new Error(session.versionSkew);
|
|
312
335
|
}
|
|
313
336
|
if (!(await provider.isAvailableFor(session.url)))
|
|
314
337
|
return synthetic(InputModeReason.PAGE_NOT_CORRELATED);
|
|
338
|
+
const performArgs = {};
|
|
339
|
+
const value = asString(inner['value']);
|
|
340
|
+
if (value !== undefined)
|
|
341
|
+
performArgs.value = value;
|
|
342
|
+
const text = asString(inner['text']);
|
|
343
|
+
if (text !== undefined)
|
|
344
|
+
performArgs.text = text;
|
|
345
|
+
const key = asString(inner['key']);
|
|
346
|
+
if (key !== undefined)
|
|
347
|
+
performArgs.key = key;
|
|
348
|
+
const modifiers = inner['modifiers'];
|
|
349
|
+
if (Array.isArray(modifiers)) {
|
|
350
|
+
performArgs.modifiers = modifiers.filter((m) => 'string' === typeof m);
|
|
351
|
+
}
|
|
352
|
+
// A held key is the whole point of a hold-to-confirm control, and the synthetic path has honoured
|
|
353
|
+
// `holdMs` all along. Not forwarding it made the real keyboard the WEAKER of the two paths: it
|
|
354
|
+
// drove the key instantly and reported a hold that never held.
|
|
355
|
+
const holdMs = asNumber(inner['holdMs']);
|
|
356
|
+
if (holdMs !== undefined)
|
|
357
|
+
performArgs.holdMs = holdMs;
|
|
358
|
+
// `keys` and `code` are read but not forwarded: both are routed away above — a multi-key sequence
|
|
359
|
+
// and an explicit physical code have no driver spelling — so carrying them into the provider would
|
|
360
|
+
// only invite it to guess at a gesture the caller did not ask for.
|
|
361
|
+
// A document key has no element of its own: skip INSPECT and the box entirely.
|
|
362
|
+
if (action === ActionType.PRESS) {
|
|
363
|
+
try {
|
|
364
|
+
const performed = await provider.perform(session.url, action, PRESS_HAS_NO_BOX, performArgs);
|
|
365
|
+
if (!performed.performed)
|
|
366
|
+
return synthetic(InputModeReason.PROVIDER_DECLINED);
|
|
367
|
+
// No `center`: a key addresses focus, not a point. The placeholder's zero happened nowhere.
|
|
368
|
+
//
|
|
369
|
+
// `heldMs` IS forwarded, and it is the whole reason this object is not just the three fields
|
|
370
|
+
// above: `reticle_act`'s description promises `effect.heldMs` reports the hold actually
|
|
371
|
+
// achieved, and on the real path the act result IS the `effect` block. Dropping it here made
|
|
372
|
+
// that promise true on the synthetic path and silently false on the one this release added
|
|
373
|
+
// `holdMs` to — an agent checking for an armed hold-to-confirm control read `undefined`.
|
|
374
|
+
return {
|
|
375
|
+
result: {
|
|
376
|
+
performed: true,
|
|
377
|
+
action,
|
|
378
|
+
inputMode: performed.inputMode,
|
|
379
|
+
...(performed.heldMs !== undefined ? { heldMs: performed.heldMs } : {}),
|
|
380
|
+
},
|
|
381
|
+
settled: true,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
// The ONE failure that must not fall back. Every other throw means the gesture did not
|
|
386
|
+
// happen, and the synthetic path is the honest answer. A release that failed means the
|
|
387
|
+
// gesture DID happen and the key may still be down — replaying it synthetically presses the
|
|
388
|
+
// same key a second time on top of a keyboard that is already holding something, which is
|
|
389
|
+
// the corruption the release exists to prevent. Refusing is the only answer that cannot
|
|
390
|
+
// make it worse.
|
|
391
|
+
if (error instanceof DriveError && error.code === DriveErrorCode.RELEASE_FAILED) {
|
|
392
|
+
throw error;
|
|
393
|
+
}
|
|
394
|
+
// No skew re-throw here, unlike the pointer path below: this action has a working synthetic
|
|
395
|
+
// route (see the skew check above), so the honest answer to a driver that threw is the
|
|
396
|
+
// fallback, not a refusal.
|
|
397
|
+
return {
|
|
398
|
+
result: undefined,
|
|
399
|
+
settled: false,
|
|
400
|
+
fellBack: true,
|
|
401
|
+
reason: InputModeReason.PROVIDER_ERROR,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
315
405
|
const inspected = await commandOrThrow(deps, session.id, ReticleCommand.INSPECT, { ref });
|
|
316
406
|
assertNotDestructive(action, inner, inspected);
|
|
317
407
|
const box = asBox(inspected);
|
|
@@ -332,13 +422,6 @@ export async function tryRealInput(deps, session, ref, action, args) {
|
|
|
332
422
|
if (toBox === undefined)
|
|
333
423
|
return synthetic(InputModeReason.DRAG_TARGET_UNRESOLVED);
|
|
334
424
|
}
|
|
335
|
-
const performArgs = {};
|
|
336
|
-
const value = asString(inner['value']);
|
|
337
|
-
if (value !== undefined)
|
|
338
|
-
performArgs.value = value;
|
|
339
|
-
const text = asString(inner['text']);
|
|
340
|
-
if (text !== undefined)
|
|
341
|
-
performArgs.text = text;
|
|
342
425
|
if (toBox !== undefined)
|
|
343
426
|
performArgs.toBox = toBox;
|
|
344
427
|
try {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Verified, VerdictStatus, type FlowReplayResult, type JournalAction, type SuiteVerdict } from '@reticlehq/core';
|
|
2
|
+
import type { TimedReplay } from '../../judgement/runs/verification-sync.js';
|
|
3
|
+
import type { ToolDeps } from './tool-kit.js';
|
|
4
|
+
export declare const ResultWord: {
|
|
5
|
+
readonly PROVED: "proved";
|
|
6
|
+
readonly NOT_PROVED: "not proved";
|
|
7
|
+
readonly FAILED: "failed";
|
|
8
|
+
};
|
|
9
|
+
export type ResultWord = (typeof ResultWord)[keyof typeof ResultWord];
|
|
10
|
+
/** The output field every result that ends a verification carries. */
|
|
11
|
+
export declare const RESULT_FIELD = "reticleResult";
|
|
12
|
+
export interface ResultFacts {
|
|
13
|
+
yes: number;
|
|
14
|
+
no: number;
|
|
15
|
+
undecided: number;
|
|
16
|
+
/** The journeys or flows the checks covered. */
|
|
17
|
+
covered?: readonly string[];
|
|
18
|
+
/** The journeys, flows or claims that did not hold. */
|
|
19
|
+
failed?: readonly string[];
|
|
20
|
+
flowsReplayed?: number;
|
|
21
|
+
/** Harness journeys answered by replaying saved flows (no model), and driven by the model. */
|
|
22
|
+
journeysReplayed?: number;
|
|
23
|
+
journeysDriven?: number;
|
|
24
|
+
wallMs?: number;
|
|
25
|
+
screenshots?: readonly string[];
|
|
26
|
+
/** From `platformLine`. */
|
|
27
|
+
platform: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Each fact once. The headline carries the check count, so the metrics do not repeat it; with one
|
|
31
|
+
* check the headline is the whole tally, so the per-word count line is left out.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildReticleResult(f: ResultFacts): string;
|
|
34
|
+
/**
|
|
35
|
+
* The same block under a verdict decided above the counts: `reticle_verify { change }` can turn a
|
|
36
|
+
* green suite into `no` (a channel disagreed) or `unknown` (the flows do not cover the files).
|
|
37
|
+
*/
|
|
38
|
+
export declare function retitleResult(block: string, verified: Verified, because: string): string;
|
|
39
|
+
/** The platform line when the key was refused: one true sentence, and the fix. */
|
|
40
|
+
export declare const KEY_REFUSED_HEAD = "Not on the platform: ";
|
|
41
|
+
/** The line for a key refused for no reason the platform named. */
|
|
42
|
+
export declare const KEY_REFUSED_LINE: string;
|
|
43
|
+
/** The platform line: where the run lives when linked, what linking adds when not. One line. */
|
|
44
|
+
export declare function platformLine(root: string, env: Record<string, string | undefined>, runId?: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* The block for a replayed suite: the flows are the journeys, each flow's verdict one check, decided
|
|
47
|
+
* as the run decides it (`mapReplayToFlowResult`): a green a channel contradicted is undecided, as
|
|
48
|
+
* the suite's `unverifiable` status says, never held.
|
|
49
|
+
*/
|
|
50
|
+
export declare function suiteResult(root: string, verdict: SuiteVerdict, timed: readonly TimedReplay[], runId: string | undefined): string;
|
|
51
|
+
/**
|
|
52
|
+
* `reticle_verify { change }`'s answer with the block on it. Its verdict is decided ABOVE the suite
|
|
53
|
+
* (uncovered files, a disagreeing channel), so the suite's own block is retitled with that verdict
|
|
54
|
+
* and moved to the top level: a nested block saying "proved" under an outer `no` is a false green.
|
|
55
|
+
*/
|
|
56
|
+
export declare function changeResult(root: string, out: unknown): unknown;
|
|
57
|
+
/**
|
|
58
|
+
* The block for one replayed flow: one check, decided as the synced run decides it — a pass whose
|
|
59
|
+
* flow asserts nothing, or whose channels disagreed, is undecided, never held.
|
|
60
|
+
*/
|
|
61
|
+
export declare function replayResult(root: string, replay: FlowReplayResult, durationMs: number, runId: string | undefined): string;
|
|
62
|
+
/** What a Harness drive's answer says about itself, as the block reads it. */
|
|
63
|
+
export interface DriveFacts {
|
|
64
|
+
checks: {
|
|
65
|
+
held: number;
|
|
66
|
+
failed: number;
|
|
67
|
+
undecided: number;
|
|
68
|
+
};
|
|
69
|
+
/** The end-state goals the Harness graded itself. */
|
|
70
|
+
goals: readonly {
|
|
71
|
+
verified: string;
|
|
72
|
+
}[];
|
|
73
|
+
goalMet?: boolean;
|
|
74
|
+
journeys?: readonly {
|
|
75
|
+
title: string;
|
|
76
|
+
status: string;
|
|
77
|
+
by?: string;
|
|
78
|
+
}[];
|
|
79
|
+
runIds?: readonly string[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The block for a Harness drive: its checks and its graded goals are the checks; a plan's journeys
|
|
83
|
+
* are what it covered, with how many were replayed and how many the model drove. Checks that held
|
|
84
|
+
* over a goal the drive did not reach are not proved, as the answer's own `proved` says.
|
|
85
|
+
*/
|
|
86
|
+
export declare function exploreResult(root: string, drive: DriveFacts): string;
|
|
87
|
+
/**
|
|
88
|
+
* The block for a session ending: every verdict the journal holds is one check. `no-fault` (nothing
|
|
89
|
+
* declared) counts as undecided, never as held — a session that proved nothing must not read as one
|
|
90
|
+
* that proved something.
|
|
91
|
+
*/
|
|
92
|
+
export declare function sessionResult(deps: ToolDeps, sessionId: string, actions: readonly JournalAction[], wallMs: number | undefined, runId?: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* What an ending agent session reports: its own calls since its previous end in the tab, never the
|
|
95
|
+
* Harness drives the tab also holds, and the run they are kept under.
|
|
96
|
+
*/
|
|
97
|
+
export declare function endedAgentSession(sessionId: string, actions: readonly JournalAction[], at: number | undefined, claim?: VerdictStatus): {
|
|
98
|
+
actions: JournalAction[];
|
|
99
|
+
runId: string;
|
|
100
|
+
wallMs?: number;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* The agent's own claim beside what grading the session's checks gave: the comparison a dashboard
|
|
104
|
+
* makes, said where the agent can read it. The claim never becomes the verdict.
|
|
105
|
+
*/
|
|
106
|
+
export declare function claimAgainstGrade(claim: VerdictStatus, actions: readonly JournalAction[]): {
|
|
107
|
+
claimed: VerdictStatus;
|
|
108
|
+
graded: VerdictStatus;
|
|
109
|
+
agrees: boolean;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* A verdict tool's call, remembered until it settles, so a session that ends meanwhile counts it.
|
|
113
|
+
* An agent ended its session while a `reticle_assert { wait }` was still waiting: the end folded
|
|
114
|
+
* first ("proved · 1 of 1"), a PASS on the dashboard, and the failure landed in the next run.
|
|
115
|
+
*/
|
|
116
|
+
export declare function trackVerdict<T>(tool: string, call: Promise<T>): Promise<T>;
|
|
117
|
+
/** Resolves once every verdict in flight now has been decided (and journaled). */
|
|
118
|
+
export declare function verdictsSettled(): Promise<void>;
|
|
119
|
+
/** The block as a field, or no field: the block is advice, never the reason a result throws. */
|
|
120
|
+
export declare function resultField(build: () => string): Partial<Record<typeof RESULT_FIELD, string>>;
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "Reticle result" block: what an agent pastes, verbatim, when it finishes verifying.
|
|
3
|
+
*
|
|
4
|
+
* Built by the server from facts it already holds, so the wording of a verdict is ours and not the
|
|
5
|
+
* agent's: an agent asked to summarise an `unknown` tends to summarise it into a pass. Three verdict
|
|
6
|
+
* words only — proved, not proved, failed — and an undecided check is never proved.
|
|
7
|
+
*
|
|
8
|
+
* The last line is the platform line, said once per result and never as a prompt: linked, where the
|
|
9
|
+
* run is on the dashboard; not linked, what the platform adds and the one command. Nothing here is
|
|
10
|
+
* measured that was not measured: a metric with no number is left out, never printed as a zero.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
13
|
+
import { dirname, join } from 'node:path';
|
|
14
|
+
import { JournalVerdictEffectSchema, ReticleDir, ReticleTool, RunFlowStatus, Verified, VerdictStatus, apiKeyFrom, } from '@reticlehq/core';
|
|
15
|
+
import { JourneyBy } from '@reticlehq/core/artifacts';
|
|
16
|
+
import { runVerdict } from '../../features/harness/drive-report.js';
|
|
17
|
+
import { mapReplayToFlowResult } from '../../judgement/runs/artifact/replay-mapping.js';
|
|
18
|
+
import { gapSummary } from '../../judgement/runs/artifact/gap-summary.js';
|
|
19
|
+
import { driveRunFrom, driveRunId, endAgentSession } from '../../judgement/runs/drive-run.js';
|
|
20
|
+
import { computeVerdict } from '../../judgement/runs/artifact/build-verification-run.js';
|
|
21
|
+
import { stepShotDir } from '../../memory/project/dir/reticle-dir.js';
|
|
22
|
+
import { TRIAL_OFFER } from '@reticlehq/core/hud';
|
|
23
|
+
import { KEY_REFUSED, dashboardRunUrl, keyRefusalAtLastSync, readDashboardUrl, } from '../../memory/project/sync-status.js';
|
|
24
|
+
import { CONNECT } from './platform-moment.js';
|
|
25
|
+
import { sessionRoot } from '../../memory/project/session-root.js';
|
|
26
|
+
export const ResultWord = {
|
|
27
|
+
PROVED: 'proved',
|
|
28
|
+
NOT_PROVED: 'not proved',
|
|
29
|
+
FAILED: 'failed',
|
|
30
|
+
};
|
|
31
|
+
/** The output field every result that ends a verification carries. */
|
|
32
|
+
export const RESULT_FIELD = 'reticleResult';
|
|
33
|
+
/** Paths shown before the rest are counted: enough to open one, not enough to flood a reply. */
|
|
34
|
+
const EVIDENCE_SHOWN = 3;
|
|
35
|
+
const SEP = ' · ';
|
|
36
|
+
const HEAD = '**Reticle result: ';
|
|
37
|
+
const Said = {
|
|
38
|
+
NOTHING_CHECKED: 'nothing was checked',
|
|
39
|
+
CHECKS: 'Checks',
|
|
40
|
+
COVERED: 'Covered',
|
|
41
|
+
DID_NOT_HOLD: 'Did not hold',
|
|
42
|
+
METRICS: 'Metrics',
|
|
43
|
+
EVIDENCE: 'Evidence',
|
|
44
|
+
RUN_LINK: 'Run on the dashboard',
|
|
45
|
+
DASHBOARD: 'On the dashboard',
|
|
46
|
+
SYNCED: 'Saved: the daemon syncs this run to the Reticle platform',
|
|
47
|
+
PITCH: 'Kept on this machine only. The Reticle platform adds run history, your team and Reticle Harness',
|
|
48
|
+
};
|
|
49
|
+
const plural = (n, word) => `${String(n)} ${word}${1 === n ? '' : 's'}`;
|
|
50
|
+
const seconds = (ms) => ms < 60_000
|
|
51
|
+
? `${(ms / 1000).toFixed(1)}s`
|
|
52
|
+
: `${String(Math.floor(ms / 60_000))}m ${String(Math.round((ms % 60_000) / 1000))}s`;
|
|
53
|
+
function headline(f) {
|
|
54
|
+
const total = f.yes + f.no + f.undecided;
|
|
55
|
+
if (0 < f.no)
|
|
56
|
+
return `${HEAD}${ResultWord.FAILED}**${SEP}${String(f.no)} of ${plural(total, 'check')} did not hold`;
|
|
57
|
+
if (0 === total)
|
|
58
|
+
return `${HEAD}${ResultWord.NOT_PROVED}**${SEP}${Said.NOTHING_CHECKED}`;
|
|
59
|
+
if (0 < f.undecided)
|
|
60
|
+
return `${HEAD}${ResultWord.NOT_PROVED}**${SEP}${String(f.undecided)} of ${plural(total, 'check')} undecided`;
|
|
61
|
+
return `${HEAD}${ResultWord.PROVED}**${SEP}${String(f.yes)} of ${plural(total, 'check')} held`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The evidence line. Screenshots filed under one run share one folder, so the folder is named once
|
|
65
|
+
* with the count: three long paths cost a single replay more tokens than its verdict, and its answer
|
|
66
|
+
* already lists each step's own path.
|
|
67
|
+
*/
|
|
68
|
+
function evidenceLine(shots) {
|
|
69
|
+
if (0 === shots.length)
|
|
70
|
+
return [];
|
|
71
|
+
const dirs = new Set(shots.map((s) => dirname(s)));
|
|
72
|
+
const [dir] = dirs;
|
|
73
|
+
if (1 < shots.length && 1 === dirs.size && dir !== undefined)
|
|
74
|
+
return [`- ${Said.EVIDENCE}: ${plural(shots.length, 'screenshot')} in ${dir}`];
|
|
75
|
+
const more = shots.length - EVIDENCE_SHOWN;
|
|
76
|
+
return [
|
|
77
|
+
`- ${Said.EVIDENCE}: ${shots.slice(0, EVIDENCE_SHOWN).join(', ')}${0 < more ? ` (+${String(more)} more)` : ''}`,
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Each fact once. The headline carries the check count, so the metrics do not repeat it; with one
|
|
82
|
+
* check the headline is the whole tally, so the per-word count line is left out.
|
|
83
|
+
*/
|
|
84
|
+
export function buildReticleResult(f) {
|
|
85
|
+
const total = f.yes + f.no + f.undecided;
|
|
86
|
+
const metrics = [
|
|
87
|
+
...(f.flowsReplayed === undefined ? [] : [`${plural(f.flowsReplayed, 'flow')} replayed`]),
|
|
88
|
+
...(f.journeysReplayed === undefined
|
|
89
|
+
? []
|
|
90
|
+
: [`${plural(f.journeysReplayed, 'journey')} replayed`]),
|
|
91
|
+
...(f.journeysDriven === undefined ? [] : [`${plural(f.journeysDriven, 'journey')} driven`]),
|
|
92
|
+
...(f.wallMs === undefined ? [] : [seconds(f.wallMs)]),
|
|
93
|
+
];
|
|
94
|
+
return [
|
|
95
|
+
headline(f),
|
|
96
|
+
...(1 < total
|
|
97
|
+
? [
|
|
98
|
+
`- ${Said.CHECKS}: ${String(f.yes)} yes${SEP}${String(f.no)} no${SEP}${String(f.undecided)} undecided`,
|
|
99
|
+
]
|
|
100
|
+
: []),
|
|
101
|
+
...(0 < (f.covered?.length ?? 0) ? [`- ${Said.COVERED}: ${(f.covered ?? []).join(', ')}`] : []),
|
|
102
|
+
...(0 < (f.failed?.length ?? 0)
|
|
103
|
+
? [`- ${Said.DID_NOT_HOLD}: ${(f.failed ?? []).join(', ')}`]
|
|
104
|
+
: []),
|
|
105
|
+
...(0 === metrics.length ? [] : [`- ${Said.METRICS}: ${metrics.join(SEP)}`]),
|
|
106
|
+
...evidenceLine(f.screenshots ?? []),
|
|
107
|
+
f.platform,
|
|
108
|
+
].join('\n');
|
|
109
|
+
}
|
|
110
|
+
const WORD_FOR = {
|
|
111
|
+
[Verified.YES]: ResultWord.PROVED,
|
|
112
|
+
[Verified.NO]: ResultWord.FAILED,
|
|
113
|
+
[Verified.UNKNOWN]: ResultWord.NOT_PROVED,
|
|
114
|
+
[Verified.NO_FAULT]: ResultWord.NOT_PROVED,
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* The same block under a verdict decided above the counts: `reticle_verify { change }` can turn a
|
|
118
|
+
* green suite into `no` (a channel disagreed) or `unknown` (the flows do not cover the files).
|
|
119
|
+
*/
|
|
120
|
+
export function retitleResult(block, verified, because) {
|
|
121
|
+
const [, ...rest] = block.split('\n');
|
|
122
|
+
return [`${HEAD}${WORD_FOR[verified]}**${SEP}${because}`, ...rest].join('\n');
|
|
123
|
+
}
|
|
124
|
+
/** The platform line when the key was refused: one true sentence, and the fix. */
|
|
125
|
+
export const KEY_REFUSED_HEAD = 'Not on the platform: ';
|
|
126
|
+
const keyRefusedLine = (why) => `${KEY_REFUSED_HEAD}${why.replace(/\.$/, '')}. Mint a new key in Settings → API keys; the run is kept on this machine`;
|
|
127
|
+
/** The line for a key refused for no reason the platform named. */
|
|
128
|
+
export const KEY_REFUSED_LINE = keyRefusedLine(KEY_REFUSED);
|
|
129
|
+
/** The platform line: where the run lives when linked, what linking adds when not. One line. */
|
|
130
|
+
export function platformLine(root, env, runId) {
|
|
131
|
+
// Before any link: a run the platform will refuse is not "saved" and not "on the dashboard".
|
|
132
|
+
const refusal = keyRefusalAtLastSync(root);
|
|
133
|
+
if (refusal !== undefined)
|
|
134
|
+
return `- ${keyRefusedLine(refusal)}`;
|
|
135
|
+
const dashboard = readDashboardUrl(root);
|
|
136
|
+
if (dashboard !== undefined)
|
|
137
|
+
return runId === undefined
|
|
138
|
+
? `- ${Said.DASHBOARD}: ${dashboard}`
|
|
139
|
+
: `- ${Said.RUN_LINK}: ${dashboardRunUrl(dashboard, runId)}`;
|
|
140
|
+
if (existsSync(join(root, ReticleDir.CLOUD_LINK_FILE)) || apiKeyFrom(env) !== undefined)
|
|
141
|
+
return `- ${Said.SYNCED}.`;
|
|
142
|
+
return `- ${Said.PITCH} (${TRIAL_OFFER}): ${CONNECT}.`;
|
|
143
|
+
}
|
|
144
|
+
/** Screenshot paths a replay filed, in step order. */
|
|
145
|
+
const replayShots = (replay) => replay.steps.flatMap((s) => s.screenshot !== undefined && 'path' in s.screenshot ? [s.screenshot.path] : []);
|
|
146
|
+
/**
|
|
147
|
+
* The block for a replayed suite: the flows are the journeys, each flow's verdict one check, decided
|
|
148
|
+
* as the run decides it (`mapReplayToFlowResult`): a green a channel contradicted is undecided, as
|
|
149
|
+
* the suite's `unverifiable` status says, never held.
|
|
150
|
+
*/
|
|
151
|
+
export function suiteResult(root, verdict, timed, runId) {
|
|
152
|
+
const statuses = timed.map((t) => mapReplayToFlowResult(t.replay, t.durationMs).status);
|
|
153
|
+
const count = (s) => statuses.filter((each) => s === each).length;
|
|
154
|
+
return buildReticleResult({
|
|
155
|
+
yes: count(RunFlowStatus.PASS),
|
|
156
|
+
no: count(RunFlowStatus.FAIL),
|
|
157
|
+
undecided: statuses.length - count(RunFlowStatus.PASS) - count(RunFlowStatus.FAIL),
|
|
158
|
+
covered: timed.map((t) => t.replay.name),
|
|
159
|
+
failed: verdict.failures.map((f) => f.flow),
|
|
160
|
+
flowsReplayed: timed.length,
|
|
161
|
+
wallMs: timed.reduce((sum, t) => sum + t.durationMs, 0),
|
|
162
|
+
screenshots: timed.flatMap((t) => replayShots(t.replay)),
|
|
163
|
+
platform: platformLine(root, process.env, runId),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* `reticle_verify { change }`'s answer with the block on it. Its verdict is decided ABOVE the suite
|
|
168
|
+
* (uncovered files, a disagreeing channel), so the suite's own block is retitled with that verdict
|
|
169
|
+
* and moved to the top level: a nested block saying "proved" under an outer `no` is a false green.
|
|
170
|
+
*/
|
|
171
|
+
export function changeResult(root, out) {
|
|
172
|
+
if (null === out || 'object' !== typeof out)
|
|
173
|
+
return out;
|
|
174
|
+
const answer = out;
|
|
175
|
+
const verified = answer['verified'];
|
|
176
|
+
if (!Object.values(Verified).includes(verified))
|
|
177
|
+
return out;
|
|
178
|
+
const suite = answer['suite'];
|
|
179
|
+
const inner = null !== suite && 'object' === typeof suite
|
|
180
|
+
? suite[RESULT_FIELD]
|
|
181
|
+
: undefined;
|
|
182
|
+
const block = 'string' === typeof inner
|
|
183
|
+
? inner
|
|
184
|
+
: buildReticleResult({
|
|
185
|
+
yes: 0,
|
|
186
|
+
no: 0,
|
|
187
|
+
undecided: 0,
|
|
188
|
+
platform: platformLine(root, process.env),
|
|
189
|
+
});
|
|
190
|
+
const because = 'string' === typeof answer['because'] ? answer['because'] : '';
|
|
191
|
+
return {
|
|
192
|
+
...answer,
|
|
193
|
+
...('string' === typeof inner
|
|
194
|
+
? {
|
|
195
|
+
suite: Object.fromEntries(Object.entries(suite).filter(([k]) => RESULT_FIELD !== k)),
|
|
196
|
+
}
|
|
197
|
+
: {}),
|
|
198
|
+
[RESULT_FIELD]: retitleResult(block, verified, because),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/** Claims named before the rest are counted: a session can hold dozens. */
|
|
202
|
+
const COVERED_SHOWN = 5;
|
|
203
|
+
const capped = (items, shown) => items.length <= shown
|
|
204
|
+
? [...items]
|
|
205
|
+
: [...items.slice(0, shown), `(+${String(items.length - shown)} more)`];
|
|
206
|
+
/** The step screenshots a drive filed under its run, or none: evidence is listed, never assumed. */
|
|
207
|
+
function shotsOf(root, runId) {
|
|
208
|
+
try {
|
|
209
|
+
const dir = stepShotDir(root, runId);
|
|
210
|
+
return readdirSync(dir)
|
|
211
|
+
.sort()
|
|
212
|
+
.map((f) => join(dir, f));
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The block for one replayed flow: one check, decided as the synced run decides it — a pass whose
|
|
220
|
+
* flow asserts nothing, or whose channels disagreed, is undecided, never held.
|
|
221
|
+
*/
|
|
222
|
+
export function replayResult(root, replay, durationMs, runId) {
|
|
223
|
+
const status = mapReplayToFlowResult(replay, durationMs).status;
|
|
224
|
+
const held = RunFlowStatus.PASS === status;
|
|
225
|
+
const failed = RunFlowStatus.FAIL === status;
|
|
226
|
+
return buildReticleResult({
|
|
227
|
+
yes: held ? 1 : 0,
|
|
228
|
+
no: failed ? 1 : 0,
|
|
229
|
+
undecided: held || failed ? 0 : 1,
|
|
230
|
+
covered: [replay.name],
|
|
231
|
+
...(failed ? { failed: [replay.name] } : {}),
|
|
232
|
+
flowsReplayed: 1,
|
|
233
|
+
wallMs: durationMs,
|
|
234
|
+
screenshots: replayShots(replay),
|
|
235
|
+
platform: platformLine(root, process.env, runId),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const MSG_GOAL_NOT_REACHED = 'the drive did not reach its goal';
|
|
239
|
+
/**
|
|
240
|
+
* The block for a Harness drive: its checks and its graded goals are the checks; a plan's journeys
|
|
241
|
+
* are what it covered, with how many were replayed and how many the model drove. Checks that held
|
|
242
|
+
* over a goal the drive did not reach are not proved, as the answer's own `proved` says.
|
|
243
|
+
*/
|
|
244
|
+
export function exploreResult(root, drive) {
|
|
245
|
+
// The checks, counted once and as the run's own summary counts them: the graded goals decide
|
|
246
|
+
// `goalMet` (and the headline below) and were added on top, so one run read "2 of 2 check(s)
|
|
247
|
+
// held" in its summary and "3 of 3" here.
|
|
248
|
+
const yes = drive.checks.held;
|
|
249
|
+
const no = drive.checks.failed;
|
|
250
|
+
const undecided = drive.checks.undecided;
|
|
251
|
+
const journeys = drive.journeys ?? [];
|
|
252
|
+
const by = (b) => journeys.filter((j) => b === j.by).length;
|
|
253
|
+
const answered = journeys.some((j) => j.by !== undefined);
|
|
254
|
+
const block = buildReticleResult({
|
|
255
|
+
yes,
|
|
256
|
+
no,
|
|
257
|
+
undecided,
|
|
258
|
+
...(0 === journeys.length
|
|
259
|
+
? {}
|
|
260
|
+
: {
|
|
261
|
+
covered: capped(journeys.map((j) => j.title), COVERED_SHOWN),
|
|
262
|
+
failed: journeys.filter((j) => 'failed' === j.status).map((j) => j.title),
|
|
263
|
+
}),
|
|
264
|
+
...(answered
|
|
265
|
+
? { journeysReplayed: by(JourneyBy.REPLAY), journeysDriven: by(JourneyBy.MODEL) }
|
|
266
|
+
: {}),
|
|
267
|
+
screenshots: (drive.runIds ?? []).flatMap((id) => shotsOf(root, id)),
|
|
268
|
+
platform: platformLine(root, process.env, drive.runIds?.[0]),
|
|
269
|
+
});
|
|
270
|
+
// A plan's verdict is its journeys' (the same line the run ends on), never a count beside it.
|
|
271
|
+
if (0 < journeys.length) {
|
|
272
|
+
const { verified: word, line } = runVerdict(drive.checks, drive.goalMet, journeys);
|
|
273
|
+
return WORD_FOR[word] === headWord(block)
|
|
274
|
+
? block
|
|
275
|
+
: retitleResult(block, word, (line.split(' — ')[1] ?? line).replace(/\.$/, ''));
|
|
276
|
+
}
|
|
277
|
+
return 0 === no && 0 === undecided && 0 < yes && false === drive.goalMet
|
|
278
|
+
? retitleResult(block, Verified.UNKNOWN, MSG_GOAL_NOT_REACHED)
|
|
279
|
+
: block;
|
|
280
|
+
}
|
|
281
|
+
/** The verdict word a block's headline carries. */
|
|
282
|
+
function headWord(block) {
|
|
283
|
+
return block.slice(HEAD.length).split('**')[0];
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The block for a session ending: every verdict the journal holds is one check. `no-fault` (nothing
|
|
287
|
+
* declared) counts as undecided, never as held — a session that proved nothing must not read as one
|
|
288
|
+
* that proved something.
|
|
289
|
+
*/
|
|
290
|
+
export function sessionResult(deps, sessionId, actions, wallMs, runId = driveRunId(sessionId)) {
|
|
291
|
+
const gap = gapSummary(actions);
|
|
292
|
+
const held = [
|
|
293
|
+
...new Set(actions.flatMap((a) => {
|
|
294
|
+
const v = JournalVerdictEffectSchema.safeParse(a.effect);
|
|
295
|
+
return v.success && Verified.YES === v.data.verified ? [v.data.claim] : [];
|
|
296
|
+
})),
|
|
297
|
+
];
|
|
298
|
+
// The session's project, never wherever the daemon was launched.
|
|
299
|
+
const root = sessionRoot(deps, sessionId);
|
|
300
|
+
return buildReticleResult({
|
|
301
|
+
yes: gap.held,
|
|
302
|
+
no: gap.failed,
|
|
303
|
+
undecided: gap.undecided + gap.nothingToProve,
|
|
304
|
+
covered: capped(held, COVERED_SHOWN),
|
|
305
|
+
failed: capped(gap.failures.map((f) => f.claim), COVERED_SHOWN),
|
|
306
|
+
...(wallMs === undefined ? {} : { wallMs }),
|
|
307
|
+
screenshots: shotsOf(root, runId),
|
|
308
|
+
platform: platformLine(root, process.env, 0 < gap.claims ? runId : undefined),
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* What an ending agent session reports: its own calls since its previous end in the tab, never the
|
|
313
|
+
* Harness drives the tab also holds, and the run they are kept under.
|
|
314
|
+
*/
|
|
315
|
+
export function endedAgentSession(sessionId, actions, at, claim) {
|
|
316
|
+
return endAgentSession(sessionId, actions, at, claim);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* The agent's own claim beside what grading the session's checks gave: the comparison a dashboard
|
|
320
|
+
* makes, said where the agent can read it. The claim never becomes the verdict.
|
|
321
|
+
*/
|
|
322
|
+
export function claimAgainstGrade(claim, actions) {
|
|
323
|
+
const run = driveRunFrom(actions, { runId: 'claim' });
|
|
324
|
+
// computeVerdict decides it, once: a failed check beside a passed one is a fail there too.
|
|
325
|
+
const graded = run === undefined ? VerdictStatus.UNKNOWN : computeVerdict(run).status;
|
|
326
|
+
return { claimed: claim, graded, agrees: claim === graded };
|
|
327
|
+
}
|
|
328
|
+
/** The tools whose verdicts an agent session's block counts: each one is one of its checks. */
|
|
329
|
+
const SESSION_VERDICT_TOOLS = new Set([
|
|
330
|
+
ReticleTool.ACT_AND_WAIT,
|
|
331
|
+
// `reticle_act { steps }` dispatches under ACT's name: a journey still grading is waited for too.
|
|
332
|
+
ReticleTool.ACT,
|
|
333
|
+
ReticleTool.ACT_SEQUENCE,
|
|
334
|
+
ReticleTool.ASSERT,
|
|
335
|
+
ReticleTool.WAIT_FOR,
|
|
336
|
+
]);
|
|
337
|
+
/** Verdicts being decided right now. ponytail: daemon-wide, not per tab; an end waits for all. */
|
|
338
|
+
const inFlight = new Set();
|
|
339
|
+
/**
|
|
340
|
+
* A verdict tool's call, remembered until it settles, so a session that ends meanwhile counts it.
|
|
341
|
+
* An agent ended its session while a `reticle_assert { wait }` was still waiting: the end folded
|
|
342
|
+
* first ("proved · 1 of 1"), a PASS on the dashboard, and the failure landed in the next run.
|
|
343
|
+
*/
|
|
344
|
+
export function trackVerdict(tool, call) {
|
|
345
|
+
if (!SESSION_VERDICT_TOOLS.has(tool))
|
|
346
|
+
return call;
|
|
347
|
+
const settled = call.then(() => undefined, () => undefined);
|
|
348
|
+
inFlight.add(settled);
|
|
349
|
+
void settled.then(() => inFlight.delete(settled));
|
|
350
|
+
return call;
|
|
351
|
+
}
|
|
352
|
+
/** Resolves once every verdict in flight now has been decided (and journaled). */
|
|
353
|
+
export async function verdictsSettled() {
|
|
354
|
+
await Promise.all([...inFlight]);
|
|
355
|
+
}
|
|
356
|
+
/** The block as a field, or no field: the block is advice, never the reason a result throws. */
|
|
357
|
+
export function resultField(build) {
|
|
358
|
+
try {
|
|
359
|
+
return { [RESULT_FIELD]: build() };
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return {};
|
|
363
|
+
}
|
|
364
|
+
}
|