@reticlehq/server 3.7.0 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +59 -68
- package/bin/reticle.js +9 -2
- package/dist/command/cli/adhoc-suite.js +1 -1
- package/dist/command/cli/adhoc-verdict.d.ts +12 -0
- package/dist/command/cli/adhoc-verdict.js +62 -4
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +5 -1
- package/dist/command/cli/auth/cloud-session.d.ts +11 -19
- package/dist/command/cli/auth/cloud-session.js +23 -0
- package/dist/command/cli/auth/device-flow.d.ts +3 -37
- package/dist/command/cli/cli-doctor.js +66 -21
- package/dist/command/cli/cli-flow-commands.js +53 -11
- package/dist/command/cli/cli-kill.d.ts +8 -0
- package/dist/command/cli/cli-kill.js +43 -3
- package/dist/command/cli/cli-parse-feedback.d.ts +4 -0
- package/dist/command/cli/cli-parse-feedback.js +13 -1
- package/dist/command/cli/cli-parse-grammar.d.ts +1 -2
- package/dist/command/cli/cli-parse-grammar.js +1 -6
- package/dist/command/cli/cli-parse-serve.d.ts +24 -0
- package/dist/command/cli/cli-parse-serve.js +124 -0
- package/dist/command/cli/cli-parse.d.ts +12 -11
- package/dist/command/cli/cli-parse.js +100 -123
- package/dist/command/cli/cli-usage.d.ts +0 -11
- package/dist/command/cli/cli-usage.js +43 -16
- package/dist/command/cli/cli-verify.d.ts +1 -1
- package/dist/command/cli/cli-verify.js +29 -14
- package/dist/command/cli/cloud-cli.js +27 -9
- package/dist/command/cli/cloud-kit.js +3 -3
- package/dist/command/cli/cloud-link.d.ts +1 -20
- package/dist/command/cli/cloud-link.js +2 -0
- package/dist/command/cli/cloud-login.d.ts +6 -2
- package/dist/command/cli/cloud-login.js +13 -41
- package/dist/command/cli/config/checkout.d.ts +10 -0
- package/dist/command/cli/config/checkout.js +78 -0
- package/dist/command/cli/doctor/doctor-agent-link.d.ts +23 -0
- package/dist/command/cli/doctor/doctor-agent-link.js +28 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +1 -7
- 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/drive/drive-attach.d.ts +5 -0
- package/dist/command/cli/drive/drive-attach.js +21 -1
- package/dist/command/cli/hook/codex-transcript.d.ts +20 -0
- package/dist/command/cli/hook/codex-transcript.js +224 -0
- package/dist/command/cli/hook/episode-structure.d.ts +24 -0
- package/dist/command/cli/hook/episode-structure.js +138 -0
- package/dist/command/cli/hook/hook-command.d.ts +9 -0
- package/dist/command/cli/hook/hook-command.js +211 -0
- package/dist/command/cli/hook/hook-fast.d.ts +31 -0
- package/dist/command/cli/hook/hook-fast.js +136 -0
- package/dist/command/cli/hook/prompt-hook.d.ts +30 -0
- package/dist/command/cli/hook/prompt-hook.js +199 -0
- package/dist/command/cli/hook/tool-hook.d.ts +21 -0
- package/dist/command/cli/hook/tool-hook.js +259 -0
- package/dist/command/cli/launch/cli-launch.d.ts +2 -0
- package/dist/command/cli/launch/cli-launch.js +22 -2
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +28 -2
- package/dist/command/cli/mcp-command.d.ts +9 -0
- package/dist/command/cli/mcp-command.js +127 -41
- package/dist/command/cli/open-navigate.d.ts +43 -0
- package/dist/command/cli/open-navigate.js +85 -0
- package/dist/command/cli/ports/port-holder.d.ts +16 -4
- package/dist/command/cli/ports/port-holder.js +58 -12
- package/dist/command/cli/ports/resolve/cli-port.js +18 -2
- package/dist/command/cli/project-name.d.ts +1 -7
- package/dist/command/cli/project-name.js +1 -0
- package/dist/command/cli/report-command.d.ts +8 -2
- package/dist/command/cli/report-command.js +95 -18
- package/dist/command/cli/status-fields.d.ts +9 -2
- package/dist/command/cli/status-fields.js +148 -4
- package/dist/command/cli/try-command.d.ts +3 -4
- package/dist/command/cli/try-command.js +6 -11
- package/dist/command/cli/verify-results.d.ts +4 -1
- package/dist/command/cli/verify-results.js +3 -1
- package/dist/command/cli.d.ts +1 -7
- package/dist/command/cli.js +79 -160
- package/dist/command/daemon/daemon-resilience.d.ts +6 -1
- package/dist/command/daemon/daemon-resilience.js +31 -18
- package/dist/command/daemon/daemon.d.ts +11 -0
- package/dist/command/daemon/daemon.js +70 -2
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +2 -0
- package/dist/command/daemon/lifetime/daemon-usefulness.js +13 -2
- package/dist/command/daemon/wake-decision.js +4 -2
- package/dist/command/daemon/win32-escape.d.ts +32 -0
- package/dist/command/daemon/win32-escape.js +119 -0
- package/dist/command/setup/agent-configs.d.ts +9 -0
- package/dist/command/setup/agent-configs.js +9 -0
- package/dist/command/setup/auto-approve.d.ts +10 -3
- package/dist/command/setup/auto-approve.js +51 -3
- package/dist/command/setup/bringup/dev-server-files.d.ts +1 -9
- package/dist/command/setup/bringup/dev-server-wait.js +5 -1
- package/dist/command/setup/bringup/ensure-daemon.js +4 -7
- package/dist/command/setup/init/init-host.js +6 -0
- package/dist/command/setup/init/init-port.js +5 -4
- package/dist/command/setup/init/init-runtime.js +7 -1
- package/dist/command/setup/node-effects.d.ts +8 -0
- package/dist/command/setup/node-effects.js +36 -4
- package/dist/command/setup/probe/dev-port.d.ts +26 -0
- package/dist/command/setup/probe/dev-port.js +117 -0
- package/dist/command/setup/probe/page-probe.d.ts +1 -1
- package/dist/command/setup/probe/page-probe.js +11 -3
- package/dist/command/setup/remaining-steps.d.ts +0 -7
- package/dist/command/setup/remaining-steps.js +3 -2
- package/dist/command/setup/run-setup.d.ts +11 -0
- package/dist/command/setup/run-setup.js +33 -5
- package/dist/command/setup/setup-command.d.ts +2 -0
- package/dist/command/setup/setup-command.js +22 -4
- package/dist/command/update/updater.d.ts +1 -6
- package/dist/command/update/updater.js +4 -5
- package/dist/command/update/version-seen.d.ts +24 -0
- package/dist/command/update/version-seen.js +65 -0
- package/dist/command/version/peer-announce.d.ts +9 -1
- package/dist/command/version/peer-announce.js +25 -2
- package/dist/command/version/sdk-fix.d.ts +5 -6
- package/dist/command/version/sdk-fix.js +17 -32
- package/dist/command/version/version-skew.d.ts +16 -1
- package/dist/command/version/version-skew.js +84 -10
- package/dist/features/crawl/crawl-tools.js +2 -2
- package/dist/features/crawl/crawl.js +2 -0
- package/dist/features/exhaust/ledger.d.ts +15 -96
- package/dist/features/exhaust/ledger.js +3 -3
- package/dist/features/harness/drive-runs.d.ts +28 -4
- package/dist/features/harness/drive-runs.js +99 -7
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/harness.d.ts +5 -0
- package/dist/features/harness/harness.js +24 -12
- package/dist/features/harness/platform/platform-drives.d.ts +7 -1
- package/dist/features/harness/platform/platform-drives.js +12 -7
- package/dist/features/harness/platform/refusal.d.ts +1 -1
- package/dist/features/harness/platform/refusal.js +4 -4
- package/dist/features/harness/platform/remote-drive.js +70 -28
- package/dist/features/harness/platform/server-driver.js +22 -1
- package/dist/features/harness/platform-config.d.ts +1 -10
- package/dist/features/harness/platform-config.js +0 -20
- package/dist/features/license/license.d.ts +2 -14
- package/dist/features/visual/step-shots.d.ts +33 -1
- package/dist/features/visual/step-shots.js +155 -1
- package/dist/features/visual/visual-tools.js +12 -4
- package/dist/hooks/coding-agents.d.ts +6 -0
- package/dist/hooks/coding-agents.js +24 -3
- package/dist/hooks/episode-stamp.d.ts +32 -0
- package/dist/hooks/episode-stamp.js +61 -0
- package/dist/hooks/hook-commands.js +19 -9
- package/dist/index.d.ts +5 -1
- package/dist/index.js +66 -24
- package/dist/judgement/app-graph/journal-steps.d.ts +8 -0
- package/dist/judgement/app-graph/journal-steps.js +92 -0
- package/dist/judgement/capsule/capsule-store.d.ts +2 -39
- package/dist/judgement/domain/domain-model.js +1 -10
- package/dist/judgement/domain/domain-tools.js +4 -2
- package/dist/judgement/runs/artifact/run-store.d.ts +28 -8
- package/dist/judgement/runs/artifact/run-store.js +153 -28
- package/dist/judgement/runs/default-run-id.d.ts +3 -1
- package/dist/judgement/runs/default-run-id.js +15 -3
- package/dist/judgement/runs/drive-run.d.ts +3 -3
- package/dist/judgement/runs/drive-run.js +11 -7
- package/dist/judgement/runs/run-ledger.d.ts +21 -0
- package/dist/judgement/runs/run-ledger.js +143 -0
- package/dist/judgement/runs/runner-port.d.ts +1 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +4 -3
- package/dist/judgement/runs/verification-sync.js +27 -5
- package/dist/language/flows/affected-tools.js +2 -1
- package/dist/language/flows/annotate-notes/annotate.js +8 -3
- package/dist/language/flows/annotate-tools.js +1 -1
- package/dist/language/flows/change/affected.d.ts +8 -0
- package/dist/language/flows/change/affected.js +20 -7
- package/dist/language/flows/decision.js +19 -4
- package/dist/language/flows/fields/flow-secret-field.d.ts +9 -0
- package/dist/language/flows/fields/flow-secret-field.js +67 -5
- package/dist/language/flows/flow-anchor.d.ts +5 -0
- package/dist/language/flows/flow-anchor.js +4 -0
- package/dist/language/flows/flow-cross-step.d.ts +7 -1
- package/dist/language/flows/flow-cross-step.js +9 -0
- package/dist/language/flows/flow-expect-grammar.js +15 -10
- package/dist/language/flows/flow-intent.js +6 -1
- package/dist/language/flows/flow-journey.d.ts +8 -0
- package/dist/language/flows/flow-journey.js +13 -0
- package/dist/language/flows/flow-lease.d.ts +27 -0
- package/dist/language/flows/flow-lease.js +59 -0
- package/dist/language/flows/flow-replay-run.d.ts +1 -87
- package/dist/language/flows/flow-replay-run.js +111 -310
- package/dist/language/flows/flow-replay.js +21 -19
- package/dist/language/flows/flow-replayable.d.ts +38 -0
- package/dist/language/flows/flow-replayable.js +179 -0
- package/dist/language/flows/flow-start-path.d.ts +108 -0
- package/dist/language/flows/flow-start-path.js +313 -0
- package/dist/language/flows/flow-step-runners.d.ts +23 -2
- package/dist/language/flows/flow-step-runners.js +191 -32
- package/dist/language/flows/flow-store-for-session.d.ts +8 -1
- package/dist/language/flows/flow-store-for-session.js +6 -0
- package/dist/language/flows/flow-tools.d.ts +2 -23
- package/dist/language/flows/flow-tools.js +63 -113
- package/dist/language/flows/flows.d.ts +4 -6
- package/dist/language/flows/flows.js +90 -15
- package/dist/language/flows/heal-run.d.ts +10 -4
- package/dist/language/flows/heal-run.js +26 -9
- package/dist/language/flows/recording/flake.d.ts +3 -27
- package/dist/language/flows/recording/flake.js +1 -1
- package/dist/language/flows/recording/recording-backtrack.js +1 -4
- package/dist/language/flows/recording/tape/recordings.d.ts +11 -1
- package/dist/language/flows/recording/tape/recordings.js +9 -3
- package/dist/language/flows/replay.d.ts +25 -5
- package/dist/language/flows/replay.js +83 -16
- package/dist/language/flows/stores/assertion-tiers-store.js +1 -1
- package/dist/language/flows/suite/coverage.d.ts +9 -0
- package/dist/language/flows/suite/coverage.js +12 -1
- package/dist/language/flows/suite-selection.d.ts +25 -0
- package/dist/language/flows/suite-selection.js +41 -9
- package/dist/machine/git-tracks.d.ts +6 -0
- package/dist/machine/git-tracks.js +36 -0
- package/dist/memory/cloud/background-sync.d.ts +25 -0
- package/dist/memory/cloud/background-sync.js +79 -0
- package/dist/memory/cloud/cloud-config.d.ts +12 -1
- package/dist/memory/cloud/cloud-config.js +39 -13
- package/dist/memory/cloud/cloud-sync.d.ts +3 -24
- package/dist/memory/cloud/cloud-sync.js +5 -2
- package/dist/memory/cloud/harness-config.d.ts +0 -7
- package/dist/memory/cloud/memory-scope.d.ts +19 -0
- package/dist/memory/cloud/memory-scope.js +48 -0
- package/dist/memory/cloud/sync-answer.d.ts +43 -0
- package/dist/memory/cloud/sync-answer.js +42 -0
- package/dist/memory/cloud/sync-cycle.d.ts +40 -10
- package/dist/memory/cloud/sync-cycle.js +97 -144
- package/dist/memory/cloud/sync-daemon.d.ts +50 -3
- package/dist/memory/cloud/sync-daemon.js +473 -83
- package/dist/memory/cloud/sync-describe.d.ts +28 -0
- package/dist/memory/cloud/sync-describe.js +92 -0
- package/dist/memory/cloud/sync-disk.d.ts +9 -1
- package/dist/memory/cloud/sync-disk.js +137 -33
- package/dist/memory/cloud/sync-flow-versions.d.ts +26 -0
- package/dist/memory/cloud/sync-flow-versions.js +42 -0
- package/dist/memory/impact/impact-store.js +32 -15
- package/dist/memory/intent/intent-shard.d.ts +41 -266
- package/dist/memory/intent/intent-tools.js +20 -61
- package/dist/memory/intent/record-request.d.ts +27 -0
- package/dist/memory/intent/record-request.js +88 -0
- package/dist/memory/intent/settled-words.js +9 -1
- package/dist/memory/journal/drive-flow.d.ts +3 -0
- package/dist/memory/journal/drive-flow.js +11 -41
- package/dist/memory/journal/envelope-store.js +1 -1
- package/dist/memory/journal/envelope.d.ts +6 -154
- package/dist/memory/journal/episode-log.d.ts +107 -0
- package/dist/memory/journal/episode-log.js +302 -0
- package/dist/memory/journal/journal-recorder.d.ts +7 -0
- package/dist/memory/journal/journal-recorder.js +22 -9
- package/dist/memory/journal/on-disk/ambient-file.d.ts +1 -7
- package/dist/memory/journal/on-disk/ambient-file.js +1 -1
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +24 -3
- package/dist/memory/journal/on-disk/workspace-gitignore.js +38 -7
- package/dist/memory/journal/on-disk/workspace-tiers.js +7 -0
- package/dist/memory/journal/self-observation.js +3 -1
- package/dist/memory/journal/session-end.js +23 -9
- package/dist/memory/journal/session-journal.js +39 -20
- package/dist/memory/project/artifact-root-resolver.d.ts +14 -1
- package/dist/memory/project/artifact-root-resolver.js +68 -23
- package/dist/memory/project/artifact-root.d.ts +17 -3
- package/dist/memory/project/artifact-root.js +47 -9
- package/dist/memory/project/fs/fs-port.d.ts +5 -0
- package/dist/memory/project/fs/fs-port.js +13 -0
- package/dist/memory/project/learned-routes.d.ts +3 -4
- package/dist/memory/project/learned-routes.js +3 -11
- package/dist/memory/project/link-directory.js +5 -2
- package/dist/memory/project/root-claims.d.ts +3 -1
- package/dist/memory/project/root-claims.js +41 -7
- package/dist/memory/project/session-root.d.ts +1 -1
- package/dist/memory/project/session-root.js +1 -15
- package/dist/memory/project/sync-status.js +5 -6
- package/dist/memory/recall/memory-tools.js +2 -2
- package/dist/memory/recall/platform-memory.d.ts +3 -1
- package/dist/memory/recall/platform-memory.js +9 -1
- package/dist/memory/recall/project-memory.js +15 -19
- package/dist/portal/bridge/auth-failure-reason.d.ts +13 -0
- package/dist/portal/bridge/auth-failure-reason.js +19 -0
- package/dist/portal/bridge/bridge.d.ts +19 -4
- package/dist/portal/bridge/bridge.js +150 -177
- package/dist/portal/bridge/harness-request.d.ts +15 -0
- package/dist/portal/bridge/harness-request.js +19 -0
- package/dist/portal/bridge/origin/origin-follow.d.ts +46 -0
- package/dist/portal/bridge/origin/origin-follow.js +110 -0
- package/dist/portal/bridge/pairing-token.d.ts +6 -0
- package/dist/portal/bridge/pairing-token.js +47 -16
- package/dist/portal/bridge/protocol-skew.d.ts +27 -2
- package/dist/portal/bridge/protocol-skew.js +66 -2
- package/dist/portal/bridge/session-nonces.d.ts +46 -0
- package/dist/portal/bridge/session-nonces.js +72 -0
- package/dist/portal/input/viewport-tools.d.ts +31 -0
- package/dist/portal/input/viewport-tools.js +106 -15
- package/dist/portal/pool/bounded-close.d.ts +23 -0
- package/dist/portal/pool/bounded-close.js +38 -0
- package/dist/portal/pool/browser-pool.d.ts +44 -39
- package/dist/portal/pool/browser-pool.js +247 -95
- package/dist/portal/pool/context-permissions.d.ts +9 -1
- package/dist/portal/pool/context-permissions.js +26 -0
- package/dist/portal/pool/lease-emulation.d.ts +37 -0
- package/dist/portal/pool/lease-emulation.js +29 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +74 -7
- package/dist/portal/pool/pool-contract.d.ts +23 -1
- package/dist/portal/pool/pool-lease.d.ts +128 -0
- package/dist/portal/pool/pool-lease.js +49 -0
- package/dist/portal/pool/zero-install.d.ts +8 -1
- package/dist/portal/pool/zero-install.js +24 -2
- package/dist/portal/production/production-activation.d.ts +136 -0
- package/dist/portal/production/production-activation.js +173 -0
- package/dist/portal/production/production-drive.d.ts +52 -0
- package/dist/portal/production/production-drive.js +301 -0
- package/dist/portal/production/production-hello.d.ts +23 -0
- package/dist/portal/production/production-hello.js +23 -0
- package/dist/portal/realm/web-realm.js +42 -15
- package/dist/portal/session/control-envelope.d.ts +1 -1
- package/dist/portal/session/dev-server/served-document.d.ts +0 -5
- package/dist/portal/session/dev-server/served-document.js +6 -8
- package/dist/portal/session/facts/handshake-facts.d.ts +8 -1
- package/dist/portal/session/first-run-wiring.d.ts +3 -36
- package/dist/portal/session/first-run-wiring.js +10 -103
- package/dist/portal/session/live-control-tools.js +61 -19
- package/dist/portal/session/no-session-next-action.d.ts +11 -0
- package/dist/portal/session/no-session-next-action.js +40 -15
- package/dist/portal/session/no-session-watch.d.ts +7 -0
- package/dist/portal/session/no-session-watch.js +67 -23
- package/dist/portal/session/output-budget.d.ts +10 -0
- package/dist/portal/session/output-budget.js +16 -0
- package/dist/portal/session/presence/session-lease.d.ts +2 -0
- package/dist/portal/session/presence/session-lease.js +8 -0
- package/dist/portal/session/recorded-gaps.d.ts +15 -11
- package/dist/portal/session/recorded-gaps.js +39 -18
- package/dist/portal/session/serving-directory.d.ts +24 -2
- package/dist/portal/session/serving-directory.js +93 -5
- package/dist/portal/session/session-info.d.ts +26 -0
- package/dist/portal/session/session-info.js +20 -0
- package/dist/portal/session/session-manager.d.ts +35 -3
- package/dist/portal/session/session-manager.js +69 -14
- package/dist/portal/session/session-successor.js +1 -9
- package/dist/portal/session/session-tools.js +22 -4
- package/dist/portal/session/session.d.ts +10 -10
- package/dist/portal/session/session.js +37 -29
- package/dist/portal/session/zero-install-first-call.d.ts +7 -2
- package/dist/portal/session/zero-install-first-call.js +43 -20
- package/dist/start-wiring.d.ts +2 -2
- package/dist/start-wiring.js +17 -3
- package/dist/status-payload.d.ts +11 -1
- package/dist/status-payload.js +7 -1
- package/dist/surface/agent-presence-grace.d.ts +11 -0
- package/dist/surface/agent-presence-grace.js +34 -0
- package/dist/surface/http-server.d.ts +12 -1
- package/dist/surface/http-server.js +64 -15
- package/dist/surface/mcp/faults/mcp-outage.d.ts +12 -2
- package/dist/surface/mcp/faults/mcp-outage.js +19 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +17 -74
- package/dist/surface/mcp/mcp-proxy.js +194 -267
- package/dist/surface/mcp/mcp.d.ts +20 -3
- package/dist/surface/mcp/mcp.js +88 -25
- package/dist/surface/mcp/proxy/drive-calls.d.ts +44 -0
- package/dist/surface/mcp/proxy/drive-calls.js +114 -5
- package/dist/surface/mcp/proxy/proxy-boot.d.ts +11 -0
- package/dist/surface/mcp/proxy/proxy-boot.js +1 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +6 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +14 -1
- package/dist/surface/mcp/proxy/proxy-handshake.d.ts +34 -2
- package/dist/surface/mcp/proxy/proxy-handshake.js +76 -8
- package/dist/surface/mcp/server-instructions.js +35 -16
- package/dist/surface/mcp/shared-params.d.ts +8 -0
- package/dist/surface/mcp/shared-params.js +15 -1
- package/dist/surface/mcp/sse-frame-parser.d.ts +11 -0
- package/dist/surface/mcp/sse-frame-parser.js +18 -0
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +13 -0
- package/dist/surface/mcp/tool-catalog-cache.d.ts +2 -0
- package/dist/surface/mcp/tool-catalog-cache.js +14 -4
- package/dist/surface/tools/account-tool.d.ts +4 -3
- package/dist/surface/tools/account-tool.js +20 -31
- package/dist/surface/tools/act/act-danger.d.ts +2 -0
- package/dist/surface/tools/act/act-danger.js +41 -14
- package/dist/surface/tools/act/act-observation.d.ts +11 -0
- package/dist/surface/tools/act/act-observation.js +33 -0
- package/dist/surface/tools/act/act-preflight.js +10 -3
- package/dist/surface/tools/act/act-sequence-retry.js +2 -1
- package/dist/surface/tools/act/act-target.js +19 -5
- package/dist/surface/tools/act/durable.js +1 -1
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +9 -7
- package/dist/surface/tools/act/navigation/navigate-arrival.js +11 -14
- package/dist/surface/tools/act/unsettled-find.d.ts +36 -0
- package/dist/surface/tools/act/unsettled-find.js +71 -0
- package/dist/surface/tools/act-sequence-tool.js +53 -24
- package/dist/surface/tools/act-tools.d.ts +2 -3
- package/dist/surface/tools/act-tools.js +49 -47
- package/dist/surface/tools/agent/compact-envelope.d.ts +2 -2
- package/dist/surface/tools/agent/for-the-agent.js +41 -3
- package/dist/surface/tools/assert/assert-grade.js +8 -3
- package/dist/surface/tools/assert/assert-verdict.js +4 -2
- package/dist/surface/tools/browser-tools.js +7 -4
- package/dist/surface/tools/chat-drives.js +50 -25
- package/dist/surface/tools/coverage-tools.js +1 -1
- package/dist/surface/tools/dynamic-tools.d.ts +8 -0
- package/dist/surface/tools/dynamic-tools.js +89 -34
- package/dist/surface/tools/empty-session-list.d.ts +18 -25
- package/dist/surface/tools/empty-session-list.js +67 -38
- package/dist/surface/tools/error-recovery.d.ts +17 -7
- package/dist/surface/tools/error-recovery.js +53 -20
- package/dist/surface/tools/explore-tools.d.ts +10 -0
- package/dist/surface/tools/explore-tools.js +72 -19
- package/dist/surface/tools/feedback-tools.js +23 -2
- package/dist/surface/tools/gap-novelty.d.ts +6 -0
- package/dist/surface/tools/gap-novelty.js +9 -0
- package/dist/surface/tools/gaps/capability-absences.js +4 -3
- package/dist/surface/tools/harness-explore.d.ts +1 -1
- package/dist/surface/tools/harness-explore.js +6 -4
- package/dist/surface/tools/harness-gate.d.ts +43 -21
- package/dist/surface/tools/harness-gate.js +55 -81
- package/dist/surface/tools/harness-script.d.ts +2 -0
- package/dist/surface/tools/harness-script.js +11 -6
- package/dist/surface/tools/harness-toolset.js +3 -4
- package/dist/surface/tools/invoke-tool.d.ts +0 -8
- package/dist/surface/tools/invoke-tool.js +164 -178
- package/dist/surface/tools/lease-hint.d.ts +9 -0
- package/dist/surface/tools/lease-hint.js +22 -3
- package/dist/surface/tools/lease-permissions.d.ts +1 -1
- package/dist/surface/tools/lease-readiness.d.ts +55 -0
- package/dist/surface/tools/lease-readiness.js +150 -2
- package/dist/surface/tools/lease-tools.d.ts +3 -75
- package/dist/surface/tools/lease-tools.js +124 -188
- package/dist/surface/tools/map-tools.d.ts +20 -0
- package/dist/surface/tools/map-tools.js +145 -0
- package/dist/surface/tools/merge-tools.js +11 -7
- package/dist/surface/tools/next-step.js +6 -3
- package/dist/surface/tools/observe-tools.js +46 -35
- package/dist/surface/tools/platform-moment.d.ts +3 -12
- package/dist/surface/tools/platform-moment.js +12 -24
- package/dist/surface/tools/read/complete-snapshot.d.ts +7 -1
- package/dist/surface/tools/read/complete-snapshot.js +13 -2
- package/dist/surface/tools/read/query-paginate.js +6 -0
- package/dist/surface/tools/read/query-shape.d.ts +9 -0
- package/dist/surface/tools/read/query-shape.js +15 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.d.ts +1 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.js +73 -0
- package/dist/surface/tools/read-tools.js +5 -5
- package/dist/surface/tools/real-input-attempt.d.ts +11 -0
- package/dist/surface/tools/real-input-attempt.js +206 -38
- package/dist/surface/tools/reconcile-tools.js +21 -8
- package/dist/surface/tools/reticle-result.d.ts +3 -0
- package/dist/surface/tools/reticle-result.js +8 -1
- package/dist/surface/tools/run-report.d.ts +22 -0
- package/dist/surface/tools/run-report.js +141 -0
- package/dist/surface/tools/session-ports.d.ts +57 -0
- package/dist/surface/tools/session-ports.js +102 -0
- package/dist/surface/tools/tool-kit.d.ts +58 -4
- package/dist/surface/tools/tool-kit.js +140 -6
- package/dist/surface/tools/tool-surface.d.ts +2 -0
- package/dist/surface/tools/tool-surface.js +45 -0
- package/dist/surface/tools/tools.js +49 -87
- package/dist/telemetry/automation-hint.d.ts +5 -0
- package/dist/telemetry/automation-hint.js +7 -0
- package/dist/telemetry/cli-telemetry.d.ts +22 -0
- package/dist/telemetry/cli-telemetry.js +80 -11
- package/dist/telemetry/daemon-telemetry.d.ts +3 -1
- package/dist/telemetry/daemon-telemetry.js +9 -2
- package/dist/telemetry/feedback-cli.d.ts +1 -1
- package/dist/telemetry/feedback-cli.js +8 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/feedback.js +51 -4
- package/dist/telemetry/harness-run.d.ts +3 -3
- package/dist/telemetry/harness-run.js +18 -7
- package/dist/telemetry/hud-events.d.ts +1 -1
- package/dist/telemetry/hud-metrics.d.ts +6 -3
- package/dist/telemetry/hud-metrics.js +20 -8
- package/dist/telemetry/install-source.js +1 -1
- package/dist/telemetry/mcp-connection.d.ts +1 -1
- package/dist/telemetry/mcp-connection.js +21 -2
- package/dist/telemetry/onboarding-firsts.d.ts +6 -1
- package/dist/telemetry/onboarding-firsts.js +41 -1
- package/dist/telemetry/proxy-telemetry.d.ts +42 -0
- package/dist/telemetry/proxy-telemetry.js +70 -1
- package/dist/telemetry/session-metrics.d.ts +1 -3
- package/dist/telemetry/session-metrics.js +16 -12
- package/dist/telemetry/telemetry.d.ts +9 -1
- package/dist/telemetry/telemetry.js +16 -1
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +7 -1
- package/dist/wire-journal.js +12 -2
- package/docs/README.md +4 -2
- package/docs/actions.mdx +7 -6
- package/docs/adapters.md +2 -1
- package/docs/agent-cheatsheet.md +19 -5
- package/docs/architecture.md +13 -10
- package/docs/autodrive.md +6 -5
- package/docs/benchmarks.md +2 -2
- package/docs/capabilities.mdx +1 -1
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +6 -6
- package/docs/cli/doctor.mdx +3 -1
- package/docs/cli/feedback.mdx +11 -7
- package/docs/cli/gate.mdx +1 -1
- package/docs/cli/help.mdx +1 -1
- package/docs/cli/init.mdx +20 -16
- package/docs/cli/mcp.mdx +5 -2
- package/docs/cli/open.mdx +5 -2
- package/docs/cli/report.mdx +1 -1
- package/docs/cli/restart.mdx +1 -1
- package/docs/cli/rollback.mdx +4 -4
- package/docs/cli/serve.mdx +7 -5
- package/docs/cli/setup.mdx +1 -1
- package/docs/cli/status.mdx +6 -2
- package/docs/cli/stop.mdx +3 -3
- package/docs/cli/telemetry.mdx +5 -1
- package/docs/cli/try.mdx +8 -8
- package/docs/cli/update.mdx +8 -5
- package/docs/cli/verify.mdx +12 -5
- package/docs/cli/version.mdx +1 -1
- package/docs/cli.mdx +10 -6
- package/docs/debugging.md +1 -1
- package/docs/deploy-checks.md +8 -6
- package/docs/desktop.mdx +14 -18
- package/docs/enterprise.md +6 -6
- package/docs/environment.mdx +5 -3
- package/docs/faq.mdx +9 -6
- package/docs/first-drive.md +19 -9
- package/docs/flows.md +3 -4
- package/docs/for-agents.md +1 -1
- package/docs/frameworks.mdx +34 -11
- package/docs/getting-started.md +46 -29
- package/docs/http-transport.md +2 -2
- package/docs/human-control.md +8 -8
- package/docs/index.mdx +2 -2
- package/docs/install-agentic.mdx +18 -19
- package/docs/install-manual.mdx +8 -4
- package/docs/integration-patterns.md +5 -5
- package/docs/multi-agent-testing.md +7 -5
- package/docs/packages/browser.mdx +34 -2
- package/docs/packages/core.mdx +2 -1
- package/docs/packages/electron.mdx +15 -3
- package/docs/packages/eslint-plugin.mdx +1 -1
- package/docs/packages/next.mdx +17 -5
- package/docs/packages/react.mdx +8 -1
- package/docs/packages/server.mdx +3 -3
- package/docs/packages/tauri.mdx +3 -3
- package/docs/packages/vite-plugin.mdx +1 -1
- package/docs/packages.mdx +19 -6
- package/docs/platform-integration.md +12 -4
- package/docs/predicates.mdx +18 -7
- package/docs/production-mode.md +108 -0
- package/docs/prompt-capture.md +99 -0
- package/docs/quickstart.mdx +14 -12
- package/docs/recipes.mdx +9 -8
- package/docs/required-checks.md +3 -2
- package/docs/skill-file.mdx +4 -3
- package/docs/skill-setup.md +2 -2
- package/docs/skill.md +62 -70
- package/docs/state-files.md +1 -0
- package/docs/state-management.mdx +11 -9
- package/docs/system-map.md +14 -13
- package/docs/telemetry.md +32 -24
- package/docs/testing.md +9 -5
- package/docs/tools/act-and-wait.mdx +17 -13
- package/docs/tools/act-sequence.mdx +40 -66
- package/docs/tools/act.mdx +7 -5
- package/docs/tools/assert.mdx +1 -1
- package/docs/tools/look.mdx +1 -1
- package/docs/tools/navigate.mdx +1 -1
- package/docs/tools/network.mdx +13 -11
- package/docs/tools/overview.mdx +3 -3
- package/docs/tools/query.mdx +3 -3
- package/docs/tools/session-and-feedback.mdx +9 -6
- package/docs/tools/sessions.mdx +7 -0
- package/docs/tools/snapshot.mdx +9 -7
- package/docs/tools/tools-and-run.mdx +11 -10
- package/docs/tools/verify.mdx +1 -1
- package/docs/troubleshooting.mdx +21 -9
- package/docs/usage.md +58 -43
- package/docs/use-cases.mdx +2 -2
- package/docs/vs-chrome-devtools-mcp.mdx +5 -5
- package/docs/vs-playwright-mcp.mdx +5 -4
- package/docs/what-is-recorded.md +12 -7
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/dev/stale-issue-guard.d.ts +0 -34
- package/dist/command/dev/stale-issue-guard.js +0 -69
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { takeCallSecrets, withCallSecrets } from './tool-kit.js';
|
|
2
2
|
import { healthEnvelope } from '../../portal/session/session-health.js';
|
|
3
|
+
import { sdkBehindNote } from '../../portal/session/session-info.js';
|
|
3
4
|
import { logToolCall, toolLogPath } from '../../hooks/tool-log.js';
|
|
4
5
|
import { nextStep } from './next-step.js';
|
|
5
6
|
import { currentDrivenBy } from '../../hooks/driven-by.js';
|
|
6
|
-
import { runAsAgent } from '../../hooks/coding-agents.js';
|
|
7
|
+
import { agentNameOf, agentSessionOf, runAsAgent } from '../../hooks/coding-agents.js';
|
|
8
|
+
import { recordEpisodeCall } from '../../memory/journal/episode-log.js';
|
|
7
9
|
import { takeHumanNotes } from './human-notes.js';
|
|
8
10
|
import { takeDriveNotes } from '../../features/harness/drive-runs.js';
|
|
9
11
|
import { harnessDriving, msgHarnessHasTheTab } from './harness-tab-guard.js';
|
|
@@ -11,6 +13,9 @@ import { sessionRoot, sessionTarget } from '../../memory/project/session-root.js
|
|
|
11
13
|
import { ArtifactRootReason } from '../../memory/project/artifact-root.js';
|
|
12
14
|
import { agentNudge, takePlatformMoment } from './platform-moment.js';
|
|
13
15
|
import { RESULT_FIELD, trackVerdict } from './reticle-result.js';
|
|
16
|
+
import { endsRun, noteToolResult, runReportField } from './run-report.js';
|
|
17
|
+
import { runLedger } from '../../judgement/runs/run-ledger.js';
|
|
18
|
+
import { readAppNotes } from './agent/app-notes.js';
|
|
14
19
|
import { forTheAgent } from './agent/for-the-agent.js';
|
|
15
20
|
import { feedbackAlreadyAsked, noteFeedbackAsked } from './agent/notices.js';
|
|
16
21
|
import { SKEW_SHORT_WARNING, SKEW_VERDICT_WARNING } from '../../portal/session/session-health.js';
|
|
@@ -24,14 +29,14 @@ import { rewriteClosedAsSkew } from '../../command/version/version-skew.js';
|
|
|
24
29
|
import { noteToolCall } from '../../command/daemon/lifetime/daemon-usefulness.js';
|
|
25
30
|
import { bugsInResult, routeOf } from '../../telemetry/bug-found.js';
|
|
26
31
|
import { noteToolServed, reportToolRefused } from '../../telemetry/tool-refused.js';
|
|
27
|
-
import { buildErrorPayload, refusalReasonFor } from './error-recovery.js';
|
|
32
|
+
import { buildErrorPayload, codedRefusalOf, refusalReasonFor } from './error-recovery.js';
|
|
28
33
|
import { resultIsError } from '../mcp/faults/mcp-is-error.js';
|
|
29
34
|
import { verificationOf } from '../../telemetry/verification-of.js';
|
|
30
35
|
import { emitBugFoundHook, emitVerdictHook } from '../../hooks/hook-emit.js';
|
|
31
|
-
import { noteActed, noteFirstVerdict, noteOnboardingFirst, noteVerdictProduced, } from '../../telemetry/onboarding-firsts.js';
|
|
32
|
-
import { DiscoveryInvite } from '@reticlehq/core';
|
|
36
|
+
import { noteActed, noteFirstVerdict, noteNextCall, noteOnboardingFirst, noteVerdictProduced, } from '../../telemetry/onboarding-firsts.js';
|
|
37
|
+
import { DiscoveryInvite, isPlainRecord as isPlainObject } from '@reticlehq/core';
|
|
33
38
|
import { SESSION_ID_ARG, sessionIdFromArgs, spentRefFromArgs } from './tools-helpers.js';
|
|
34
|
-
import { EnvelopeKey, HOST_STUB_NOTE, STEP_SHOT_TOOLS } from './tool-kit.js';
|
|
39
|
+
import { ACTION_TOOLS, CDP_TOOLS, EnvelopeKey, HOST_STUB_NOTE, REF_MINTING_TOOLS, SESSION_BOUND_TOOLS, STEP_SHOT_TOOLS, } from './tool-kit.js';
|
|
35
40
|
import { ReticleTool } from '@reticlehq/core';
|
|
36
41
|
import { takeFeedbackPrompt } from './feedback-tools.js';
|
|
37
42
|
import { takeFeedbackUndelivered } from '../../telemetry/feedback-delivery.js';
|
|
@@ -41,134 +46,6 @@ import { takeStepShot } from '../../features/visual/step-shots.js';
|
|
|
41
46
|
import { defectForToolResult, deltaForToolResult, impactSnapshot, initImpact, recordImpact, } from '../../memory/impact/impact-recorder.js';
|
|
42
47
|
import { FrictionKind, frictionOf, inviteFor } from './feedback-invite.js';
|
|
43
48
|
import { VACUOUS_BECAUSE } from '@reticlehq/engine/evidence/verified.js';
|
|
44
|
-
/**
|
|
45
|
-
* The live-session tools whose result MUST carry the
|
|
46
|
-
* session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
|
|
47
|
-
* can never return a healthy-looking result from any of these. `runTool` is the single choke point
|
|
48
|
-
* (mcp.ts + tool-invoker.ts) that splices health on; the guard test asserts the set is exhaustive.
|
|
49
|
-
*/
|
|
50
|
-
/**
|
|
51
|
-
* Tools that DRIVE the page. An action with no verdict after it is the signature of the loop
|
|
52
|
-
* breaking mid-task — see `abandonedActions`. `act_and_wait` is one of these AND a verification, so
|
|
53
|
-
* it settles its own action, which is exactly right: it is the tool that does both.
|
|
54
|
-
*/
|
|
55
|
-
const ACTION_TOOLS = new Set([
|
|
56
|
-
ReticleTool.ACT,
|
|
57
|
-
ReticleTool.ACT_SEQUENCE,
|
|
58
|
-
ReticleTool.ACT_AND_WAIT,
|
|
59
|
-
]);
|
|
60
|
-
/**
|
|
61
|
-
* Tools that go through Playwright CDP rather than the page SDK.
|
|
62
|
-
*
|
|
63
|
-
* Under version skew these fail with "Target page, context or browser has been closed" while every
|
|
64
|
-
* DOM tool against the same tab still works (#688). They are session-EXEMPT (own result contracts),
|
|
65
|
-
* so the bound-tool resolve above never runs for them — resolve again here so we can refuse with
|
|
66
|
-
* the skew sentence before Playwright lies about a closed page.
|
|
67
|
-
*/
|
|
68
|
-
const CDP_TOOLS = new Set([
|
|
69
|
-
ReticleTool.SCREENSHOT,
|
|
70
|
-
ReticleTool.VISUAL_DIFF,
|
|
71
|
-
ReticleTool.NETWORK_MOCK,
|
|
72
|
-
ReticleTool.VIEWPORT,
|
|
73
|
-
// Breaks a request through the same Playwright route `reticle_network_mock` uses, so it fails the
|
|
74
|
-
// same way under version skew and must be refused with the same sentence.
|
|
75
|
-
ReticleTool.FLOW_MUTATE,
|
|
76
|
-
]);
|
|
77
|
-
/**
|
|
78
|
-
* Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
|
|
79
|
-
* that spends one cannot be routed to a different tab without saying so — see ref-provenance.ts.
|
|
80
|
-
*
|
|
81
|
-
* Over-inclusion is the safe direction here and under-inclusion is not dangerous either: both ends
|
|
82
|
-
* produce a REFUSAL naming the two tabs, never a silent drive against the wrong one.
|
|
83
|
-
*/
|
|
84
|
-
const REF_MINTING_TOOLS = new Set([
|
|
85
|
-
ReticleTool.SNAPSHOT,
|
|
86
|
-
ReticleTool.QUERY,
|
|
87
|
-
ReticleTool.INSPECT,
|
|
88
|
-
// The same three merged, on the `merged` surface. Its `state` action mints nothing, and
|
|
89
|
-
// over-inclusion is the safe direction here: the worst case is a refusal naming two tabs.
|
|
90
|
-
ReticleTool.LOOK,
|
|
91
|
-
ReticleTool.EXPLORE,
|
|
92
|
-
// `crawl` mints refs for the controls it drives and `coverage` for the ones it reports untouched.
|
|
93
|
-
// Both are actions on the merged verify tool now.
|
|
94
|
-
ReticleTool.VERIFY,
|
|
95
|
-
]);
|
|
96
|
-
export const SESSION_BOUND_TOOLS = new Set([
|
|
97
|
-
// Resolves a session and reads its event window (`session.eventsSince`), exactly as OBSERVE and
|
|
98
|
-
// NETWORK do. Without this it runs with no session and answers from nothing.
|
|
99
|
-
ReticleTool.SNAPSHOT,
|
|
100
|
-
ReticleTool.QUERY,
|
|
101
|
-
ReticleTool.INSPECT,
|
|
102
|
-
// All four merged. Every member here is session-bound, so unlike `verify` there is no split to
|
|
103
|
-
// adjudicate — the merged tool inherits the only answer its members ever gave.
|
|
104
|
-
ReticleTool.LOOK,
|
|
105
|
-
// Merged change/flows/affected/coverage/crawl. Its members were SPLIT across bound and exempt —
|
|
106
|
-
// coverage/change/crawl bound, flow_verify exempt because it returns its own suite contract — and
|
|
107
|
-
// a merged tool has to be one or the other. Bound is the right side: `crawl` drives the app
|
|
108
|
-
// itself, so a throttled or event-dropping tab is exactly the condition its verdict depends on,
|
|
109
|
-
// and dropping the health disclosure there to protect a sibling's output shape would trade an
|
|
110
|
-
// honesty signal for a formatting preference.
|
|
111
|
-
ReticleTool.VERIFY,
|
|
112
|
-
ReticleTool.ACT,
|
|
113
|
-
ReticleTool.ACT_SEQUENCE,
|
|
114
|
-
ReticleTool.ACT_AND_WAIT,
|
|
115
|
-
ReticleTool.OBSERVE,
|
|
116
|
-
ReticleTool.WAIT_FOR,
|
|
117
|
-
ReticleTool.ASSERT,
|
|
118
|
-
// Reads the live page as well as the event window, so a throttled tab can make it compare a stale
|
|
119
|
-
// render against fresh data — exactly the case the health envelope exists to disclose.
|
|
120
|
-
ReticleTool.RECONCILE,
|
|
121
|
-
ReticleTool.NETWORK,
|
|
122
|
-
ReticleTool.CONSOLE,
|
|
123
|
-
ReticleTool.ANIMATIONS,
|
|
124
|
-
ReticleTool.BASELINE, // merged save/list/diff — save+diff are live reads
|
|
125
|
-
ReticleTool.RECORD, // merged start/stop — both live
|
|
126
|
-
ReticleTool.REPLAY,
|
|
127
|
-
ReticleTool.CLOCK,
|
|
128
|
-
ReticleTool.STATE,
|
|
129
|
-
ReticleTool.STORAGE,
|
|
130
|
-
ReticleTool.EXPLORE,
|
|
131
|
-
ReticleTool.SCROLL_TO,
|
|
132
|
-
ReticleTool.NAVIGATE,
|
|
133
|
-
]);
|
|
134
|
-
/**
|
|
135
|
-
* Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
|
|
136
|
-
* disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
|
|
137
|
-
* exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
|
|
138
|
-
* `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
|
|
139
|
-
*/
|
|
140
|
-
export const SESSION_EXEMPT_TOOLS = new Set([
|
|
141
|
-
ReticleTool.CAPABILITIES, // has a fromDisk mode with no live session
|
|
142
|
-
ReticleTool.CONTRACT_SAVE, // persists the registry to disk
|
|
143
|
-
ReticleTool.FLOW_SAVE, // sessionId only scopes the write to the app's flow subdir; disk-side
|
|
144
|
-
ReticleTool.FLOW, // merged list/load/delete — sessionId only scopes the project; all disk-side
|
|
145
|
-
ReticleTool.FLOW_REPLAY, // returns its own FlowReplayResult contract (+ auto-records a run)
|
|
146
|
-
ReticleTool.FLOW_SAVE_RECORDED, // reads the recording buffer, writes disk
|
|
147
|
-
// FLOW_HEAL is no longer a name runTool ever sees: it became `reticle_verify {action:"heal"}`,
|
|
148
|
-
// and VERIFY is already listed here, so the exemption is inherited from the parent. Left as a
|
|
149
|
-
// dangling name it would be a lie this file's own test 6 is written to catch.
|
|
150
|
-
ReticleTool.INTENT, // reads/writes .reticle/intent/; sessionId only picks the project
|
|
151
|
-
ReticleTool.CONTEXT, // folds the journal + intent ledger; must still answer when nothing is connected
|
|
152
|
-
ReticleTool.PROJECT, // reads .reticle/project.json
|
|
153
|
-
// Reads the team's shared memory over HTTP; sessionId only resolves WHICH project's link file to
|
|
154
|
-
// use. It must answer with no tab connected — "what does this project know?" is a question an
|
|
155
|
-
// agent asks before it has opened anything.
|
|
156
|
-
ReticleTool.MEMORY,
|
|
157
|
-
ReticleTool.RUN_EXPORT, // reads .reticle/runs/<id>.json (verification-run artifact)
|
|
158
|
-
ReticleTool.SESSION, // merged lifecycle/human-channel family (tune/yield/end/resume/messages/review/narrate)
|
|
159
|
-
ReticleTool.SCREENSHOT, // own contract; provider-driven, not a live-DOM-health read
|
|
160
|
-
ReticleTool.VISUAL_DIFF, // own contract (matched/ratio/region)
|
|
161
|
-
ReticleTool.NETWORK_MOCK, // own contract (applied/count); provider-driven, not a live-DOM read
|
|
162
|
-
ReticleTool.VIEWPORT, // own contract (applied/width/height); provider-driven, not a live-DOM read
|
|
163
|
-
ReticleTool.ANNOTATE, // annotates a recording's steps; pure disk-side metadata, no live DOM read
|
|
164
|
-
ReticleTool.LEASE, // merged acquire/release — its sessionId is a pool lease id, not a live session
|
|
165
|
-
// Its sessionId only enriches the report with the tab's runtime/engine, and it must stay callable
|
|
166
|
-
// when NO session exists — "nothing ever connected" is feedback we especially want.
|
|
167
|
-
ReticleTool.FEEDBACK,
|
|
168
|
-
]);
|
|
169
|
-
function isPlainObject(value) {
|
|
170
|
-
return 'object' === typeof value && value !== null && !Array.isArray(value);
|
|
171
|
-
}
|
|
172
49
|
/**
|
|
173
50
|
* Emit `verification_completed` when a verification tool produced a verdict.
|
|
174
51
|
*
|
|
@@ -179,10 +56,11 @@ function isPlainObject(value) {
|
|
|
179
56
|
*
|
|
180
57
|
* The RULE itself lives in verification-of.ts, because getting it wrong fails silently.
|
|
181
58
|
*/
|
|
182
|
-
function recordVerification(toolName, result, durationMs, brand, sessionId) {
|
|
183
|
-
const verification = verificationOf(toolName, result, durationMs, brand, currentDrivenBy() !== undefined);
|
|
184
|
-
if (verification === undefined)
|
|
185
|
-
return;
|
|
59
|
+
function recordVerification(toolName, result, durationMs, brand, sessionId, sdkVersion) {
|
|
60
|
+
const verification = verificationOf(toolName, result, durationMs, brand, currentDrivenBy() !== undefined, sdkVersion);
|
|
61
|
+
if (verification === undefined) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
186
64
|
getSessionMetrics().recordVerification();
|
|
187
65
|
void getTelemetry().emit(TelemetryEventKind.VERIFICATION_COMPLETED, {
|
|
188
66
|
actor: TelemetryActor.AGENT,
|
|
@@ -201,6 +79,7 @@ function recordVerification(toolName, result, durationMs, brand, sessionId) {
|
|
|
201
79
|
noteFirstVerdict();
|
|
202
80
|
// The FIRST_RUN rung: once per machine + project, not once per verdict.
|
|
203
81
|
noteVerdictProduced(durationMs);
|
|
82
|
+
return true;
|
|
204
83
|
}
|
|
205
84
|
/**
|
|
206
85
|
* Emit one `bug_found` per defect in a tool result, and count it into the session.
|
|
@@ -211,8 +90,9 @@ function recordVerification(toolName, result, durationMs, brand, sessionId) {
|
|
|
211
90
|
*/
|
|
212
91
|
function reportBugsFound(toolName, result, sessionId) {
|
|
213
92
|
const bugs = bugsInResult(toolName, result);
|
|
214
|
-
if (0 === bugs.length)
|
|
93
|
+
if (0 === bugs.length) {
|
|
215
94
|
return;
|
|
95
|
+
}
|
|
216
96
|
const metrics = getSessionMetrics();
|
|
217
97
|
const route = routeOf(result);
|
|
218
98
|
for (const bug of bugs) {
|
|
@@ -254,10 +134,11 @@ function reportBugsFound(toolName, result, sessionId) {
|
|
|
254
134
|
* tool's name, and then hands the same failure back out to be reported a second time as
|
|
255
135
|
* `reticle_run`. A count that doubles because of HOW a tool was reached is not a measurement.
|
|
256
136
|
*/
|
|
257
|
-
function reportRefusal(toolName, message) {
|
|
258
|
-
if (toolName === ReticleTool.RUN)
|
|
137
|
+
function reportRefusal(toolName, message, error) {
|
|
138
|
+
if (toolName === ReticleTool.RUN) {
|
|
259
139
|
return;
|
|
260
|
-
|
|
140
|
+
}
|
|
141
|
+
reportToolRefused(toolName, refusalReasonFor(message, codedRefusalOf(error)));
|
|
261
142
|
}
|
|
262
143
|
/**
|
|
263
144
|
* Which friction this result represents, counting the invitation if there is one.
|
|
@@ -273,8 +154,9 @@ function reportRefusal(toolName, message) {
|
|
|
273
154
|
* feedback rate read half.
|
|
274
155
|
*/
|
|
275
156
|
function frictionInviteFor(toolName, raw) {
|
|
276
|
-
if (!isPlainObject(raw) || toolName === ReticleTool.RUN)
|
|
157
|
+
if (!isPlainObject(raw) || toolName === ReticleTool.RUN) {
|
|
277
158
|
return undefined;
|
|
159
|
+
}
|
|
278
160
|
const friction = frictionOf({
|
|
279
161
|
unknownTool: false,
|
|
280
162
|
// A vacuous unknown is the caller's: it asserted nothing real (a bare `settled` wait, which the
|
|
@@ -286,8 +168,9 @@ function frictionInviteFor(toolName, raw) {
|
|
|
286
168
|
// loop this release exists to encourage — get told they are stuck.
|
|
287
169
|
producedVerdict: 'verified' in raw,
|
|
288
170
|
});
|
|
289
|
-
if (friction !== undefined)
|
|
171
|
+
if (friction !== undefined) {
|
|
290
172
|
getSessionMetrics().recordFeedbackPrompt();
|
|
173
|
+
}
|
|
291
174
|
return friction;
|
|
292
175
|
}
|
|
293
176
|
/**
|
|
@@ -306,12 +189,14 @@ function frictionInviteFor(toolName, raw) {
|
|
|
306
189
|
function firstOversizedArg(args) {
|
|
307
190
|
const tooLong = (value) => 'string' === typeof value && value.length > TRANSPORT_LIMITS.MAX_STRING_LENGTH;
|
|
308
191
|
for (const [key, value] of Object.entries(args)) {
|
|
309
|
-
if (tooLong(value))
|
|
192
|
+
if (tooLong(value)) {
|
|
310
193
|
return key;
|
|
194
|
+
}
|
|
311
195
|
if ('object' === typeof value && null !== value && !Array.isArray(value)) {
|
|
312
196
|
for (const [inner, nested] of Object.entries(value)) {
|
|
313
|
-
if (tooLong(nested))
|
|
197
|
+
if (tooLong(nested)) {
|
|
314
198
|
return `${key}.${inner}`;
|
|
199
|
+
}
|
|
315
200
|
}
|
|
316
201
|
}
|
|
317
202
|
}
|
|
@@ -341,8 +226,9 @@ function firstOversizedArg(args) {
|
|
|
341
226
|
* unscoped, so it answers as it always did.
|
|
342
227
|
*/
|
|
343
228
|
function pinnedArgs(args, explicitSessionId, session) {
|
|
344
|
-
if (explicitSessionId !== undefined || session === undefined)
|
|
229
|
+
if (explicitSessionId !== undefined || session === undefined) {
|
|
345
230
|
return args;
|
|
231
|
+
}
|
|
346
232
|
return { ...args, [SESSION_ID_ARG]: session.id };
|
|
347
233
|
}
|
|
348
234
|
export async function runTool(tool, deps, given, call) {
|
|
@@ -352,12 +238,51 @@ export async function runTool(tool, deps, given, call) {
|
|
|
352
238
|
// A verdict still being decided is waited for by a session end (`trackVerdict`); the result is
|
|
353
239
|
// compacted for the agent last, after telemetry and the tool log have read the full result.
|
|
354
240
|
return trackVerdict(tool.name, withCallSecrets(secrets, async () => {
|
|
355
|
-
|
|
241
|
+
// The agent's own calls make its run; `reticle_run` is counted once, as the tool it reached.
|
|
242
|
+
// A host that wires no clock (an embedding, a test double) gets no report, never an error.
|
|
243
|
+
const agentCall = currentDrivenBy() === undefined &&
|
|
244
|
+
deps.attachId !== undefined &&
|
|
245
|
+
ReticleTool.RUN !== tool.name &&
|
|
246
|
+
'function' === typeof deps.now;
|
|
247
|
+
// Closes the offer of an earlier first session call: did the agent do the offered step?
|
|
248
|
+
if (agentCall) {
|
|
249
|
+
noteNextCall(tool.name, args);
|
|
250
|
+
}
|
|
251
|
+
const ends = endsRun(tool.name, args);
|
|
252
|
+
// A call that only ends a run starts none: a second yield in a row carries no empty report.
|
|
253
|
+
if (agentCall && !ends && deps.attachId !== undefined) {
|
|
254
|
+
runLedger.begin(deps.now(), deps.attachId);
|
|
255
|
+
}
|
|
256
|
+
// The project of the session a call ends, read while the session still exists: releasing a
|
|
257
|
+
// tab removes it, and an unreadable project lost an unlinked user's cloud line.
|
|
258
|
+
const endedIn = agentCall && ends ? safeRoot(() => sessionRoot(deps, sessionIdFromArgs(args))) : undefined;
|
|
259
|
+
const raw = await loggedTool(tool, deps, args, call);
|
|
356
260
|
const attach = currentDrivenBy() === undefined ? deps.attachId : undefined;
|
|
357
261
|
const root = attach === undefined
|
|
358
262
|
? undefined
|
|
359
263
|
: safeRoot(() => sessionRoot(deps, sessionIdFromArgs(args)));
|
|
360
|
-
|
|
264
|
+
// The app notes before this call, so a note it learns counts as memory written.
|
|
265
|
+
const notesBefore = agentCall && root !== undefined ? readAppNotes(root) : [];
|
|
266
|
+
const answer = forTheAgent({
|
|
267
|
+
name: tool.name,
|
|
268
|
+
args,
|
|
269
|
+
result: raw,
|
|
270
|
+
attach,
|
|
271
|
+
root,
|
|
272
|
+
fold: NOTICE_FOLD,
|
|
273
|
+
});
|
|
274
|
+
if (!agentCall) {
|
|
275
|
+
return answer;
|
|
276
|
+
}
|
|
277
|
+
runLedger.after(deps.now());
|
|
278
|
+
noteToolResult(runLedger, tool.name, args, raw);
|
|
279
|
+
const notesAfter = root === undefined ? [] : readAppNotes(root);
|
|
280
|
+
runLedger.memoryWritten(notesAfter.filter((note) => !notesBefore.includes(note)).length);
|
|
281
|
+
runLedger.memoryRead(notesBefore);
|
|
282
|
+
if (!ends || null === answer || 'object' !== typeof answer) {
|
|
283
|
+
return answer;
|
|
284
|
+
}
|
|
285
|
+
return { ...answer, ...runReportField(runLedger, endedIn ?? root, process.env, deps.now()) };
|
|
361
286
|
}));
|
|
362
287
|
}
|
|
363
288
|
/** Advisories that become once-per-session notice lines. See agent/notices.ts. */
|
|
@@ -386,21 +311,51 @@ export const NOTICE_FOLD = {
|
|
|
386
311
|
};
|
|
387
312
|
async function loggedTool(tool, deps, args, call) {
|
|
388
313
|
const logPath = toolLogPath();
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const
|
|
314
|
+
const at = Date.now();
|
|
315
|
+
// The tab this call drove, and where its events start: the call's effect on the page.
|
|
316
|
+
const seen = {};
|
|
317
|
+
const episode = (outcome) => {
|
|
318
|
+
// A record that cannot be built never fails the call it describes.
|
|
319
|
+
safeRoot(() => {
|
|
320
|
+
const from = seen.from;
|
|
321
|
+
const effect = seen.session === undefined || from === undefined
|
|
322
|
+
? undefined
|
|
323
|
+
: seen.session.eventsSince(from);
|
|
324
|
+
const drivenBy = currentDrivenBy();
|
|
325
|
+
const agent = agentNameOf(deps.attachId);
|
|
326
|
+
const agentSession = agentSessionOf(deps.attachId);
|
|
327
|
+
recordEpisodeCall(seen.session?.artifactRoot ?? deps.reticleRoot, deps.attachId, Date.now, {
|
|
328
|
+
tool: tool.name,
|
|
329
|
+
args,
|
|
330
|
+
startedAt: at,
|
|
331
|
+
endedAt: Date.now(),
|
|
332
|
+
...outcome,
|
|
333
|
+
...(seen.session === undefined ? {} : { sessionId: seen.session.id }),
|
|
334
|
+
...(agent === undefined ? {} : { agent }),
|
|
335
|
+
...(agentSession === undefined ? {} : { agentSession }),
|
|
336
|
+
...(drivenBy === undefined ? {} : { drivenBy }),
|
|
337
|
+
...(effect === undefined ? {} : { effect }),
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
};
|
|
392
341
|
try {
|
|
393
|
-
const result = await dispatchTool(tool, deps, args, call);
|
|
394
|
-
|
|
342
|
+
const result = await dispatchTool(tool, deps, args, call, seen);
|
|
343
|
+
if (logPath !== undefined) {
|
|
344
|
+
logToolCall(logPath, { tool: tool.name, args, at, ms: Date.now() - at, result });
|
|
345
|
+
}
|
|
346
|
+
episode({ result });
|
|
395
347
|
return result;
|
|
396
348
|
}
|
|
397
349
|
catch (error) {
|
|
398
350
|
const message = error instanceof Error ? error.message : String(error);
|
|
399
|
-
|
|
351
|
+
if (logPath !== undefined) {
|
|
352
|
+
logToolCall(logPath, { tool: tool.name, args, at, ms: Date.now() - at, error: message });
|
|
353
|
+
}
|
|
354
|
+
episode({ error: message });
|
|
400
355
|
throw error;
|
|
401
356
|
}
|
|
402
357
|
}
|
|
403
|
-
async function dispatchTool(tool, deps, args, call) {
|
|
358
|
+
async function dispatchTool(tool, deps, args, call, seen = {}) {
|
|
404
359
|
// Both dispatch paths (MCP + programmatic) pass through here — the one place "which tool is mostly
|
|
405
360
|
// used" can be counted. This used to EMIT an event per call; it now increments an in-process counter
|
|
406
361
|
// that leaves once, with the session summary. A verification loop is 50–200 calls, and PostHog bills
|
|
@@ -516,11 +471,16 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
516
471
|
}
|
|
517
472
|
}
|
|
518
473
|
const leaseId = session?.id ?? rawSessionId;
|
|
519
|
-
if (leaseId !== undefined)
|
|
474
|
+
if (leaseId !== undefined) {
|
|
520
475
|
deps.pool?.touch(leaseId);
|
|
476
|
+
}
|
|
521
477
|
// One identity for the whole call: the handler drives the session everything above is attributed
|
|
522
478
|
// to, rather than resolving again against a registry that can have changed underneath it.
|
|
523
479
|
const dispatchArgs = pinnedArgs(args, rawSessionId, session);
|
|
480
|
+
if (session !== undefined) {
|
|
481
|
+
seen.session = session;
|
|
482
|
+
seen.from = safeRoot(() => session?.elapsed());
|
|
483
|
+
}
|
|
524
484
|
let raw;
|
|
525
485
|
try {
|
|
526
486
|
// The one dispatch point every tool call passes through, so it is where the trace's root span
|
|
@@ -556,12 +516,13 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
556
516
|
const rewritten = rewriteClosedAsSkew(error, skewText);
|
|
557
517
|
const toThrow = rewritten ?? error;
|
|
558
518
|
const message = toThrow instanceof Error ? toThrow.message : String(toThrow);
|
|
559
|
-
reportRefusal(tool.name, message);
|
|
519
|
+
reportRefusal(tool.name, message, toThrow);
|
|
560
520
|
// The invitation on THIS path is the one `buildErrorPayload` attaches when it does not recognise
|
|
561
521
|
// the error, and it was never counted — so the denominator excluded the commonest friction there
|
|
562
522
|
// is. Gated on the payload actually carrying the ask, because a recognised error gets a recovery
|
|
563
523
|
// instead and counting an invitation nobody was shown breaks the ratio in the other direction.
|
|
564
|
-
|
|
524
|
+
const payload = buildErrorPayload(message, codedRefusalOf(toThrow));
|
|
525
|
+
if (tool.name !== ReticleTool.RUN && payload.feedback !== undefined) {
|
|
565
526
|
getSessionMetrics().recordFeedbackPrompt();
|
|
566
527
|
}
|
|
567
528
|
throw toThrow;
|
|
@@ -580,18 +541,20 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
580
541
|
const acted = raw['dispatched'] !== false &&
|
|
581
542
|
(!isPlainObject(effect) || effect['dispatched'] !== false) &&
|
|
582
543
|
(tool.name !== ReticleTool.ACT_AND_WAIT || isPlainObject(effect));
|
|
583
|
-
if (ACTION_TOOLS.has(tool.name) && acted)
|
|
544
|
+
if (ACTION_TOOLS.has(tool.name) && acted) {
|
|
584
545
|
noteActed(args);
|
|
546
|
+
}
|
|
585
547
|
}
|
|
586
548
|
// The human-feedback ask rides out on the first VERIFICATION that completes — the one moment the
|
|
587
549
|
// experience is fresh and there is something concrete to react to. It is spliced BEFORE the
|
|
588
550
|
// session-bound early return, because two of the four verification tools (flow_verify,
|
|
589
551
|
// verify_change) are session-EXEMPT and would otherwise never carry it.
|
|
552
|
+
let verdict = false;
|
|
590
553
|
if (isPlainObject(raw)) {
|
|
591
554
|
// The brand comes from the session's own PAGE_HEALTH report, so it is present for the four
|
|
592
555
|
// session-bound verification tools and absent for flow_verify (session-exempt) — which replays
|
|
593
556
|
// into a browser Reticle launched, where `browser` already says what happened.
|
|
594
|
-
recordVerification(tool.name, raw, Date.now() - startedAt, session?.brand, session?.id);
|
|
557
|
+
verdict = recordVerification(tool.name, raw, Date.now() - startedAt, session?.brand, session?.id, session?.sdkVersion);
|
|
595
558
|
reportBugsFound(tool.name, raw, session?.id);
|
|
596
559
|
}
|
|
597
560
|
// The other half of the refusal surface. A top-level `error` string IS this codebase's refusal
|
|
@@ -616,19 +579,22 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
616
579
|
// Bound to THIS session's root: a tab must be shown its own project's numbers, not whichever
|
|
617
580
|
// project the daemon was started in.
|
|
618
581
|
session?.pushImpact?.(() => impactSnapshot(artifactRoot));
|
|
619
|
-
if (resultIsError(raw))
|
|
582
|
+
if (resultIsError(raw)) {
|
|
620
583
|
reportRefusal(tool.name, raw.error);
|
|
584
|
+
}
|
|
621
585
|
else {
|
|
622
586
|
noteToolServed();
|
|
623
587
|
// Which tab these refs belong to. Recorded on the way OUT, so the next call that spends one is
|
|
624
588
|
// measured against the tab that actually produced it.
|
|
625
|
-
if (session !== undefined && REF_MINTING_TOOLS.has(tool.name))
|
|
589
|
+
if (session !== undefined && REF_MINTING_TOOLS.has(tool.name)) {
|
|
626
590
|
noteRefsMinted(session.id);
|
|
591
|
+
}
|
|
627
592
|
}
|
|
628
593
|
// The feedback family is asked at most once per agent session (agent/notices.ts): gated here, at
|
|
629
594
|
// the take, so a suppressed ask is never counted as one that was made.
|
|
630
595
|
const asked = feedbackAlreadyAsked(currentDrivenBy() === undefined ? deps.attachId : undefined);
|
|
631
|
-
|
|
596
|
+
// Only a call that produced a verdict asks: `reticle_act` is a verdict tool for its `steps` form.
|
|
597
|
+
const prompt = verdict && !asked ? takeFeedbackPrompt(tool.name) : undefined;
|
|
632
598
|
// Same one-shot channel as the feedback ask: the agent is mid-task, so anything it would have to go
|
|
633
599
|
// and ASK for is something it will never ask for. Spliced on ANY tool result, not just a
|
|
634
600
|
// verification, because an out-of-date install is worth mentioning whatever the agent is doing.
|
|
@@ -654,8 +620,9 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
654
620
|
// RETURN an error. So the denominator was counting a small, unrepresentative slice of the
|
|
655
621
|
// invitations and reading near-empty, which looks identical to a nudge that never fires.
|
|
656
622
|
const friction = asked || prompt !== undefined ? undefined : frictionInviteFor(tool.name, raw);
|
|
657
|
-
if (prompt !== undefined || friction !== undefined)
|
|
623
|
+
if (prompt !== undefined || friction !== undefined) {
|
|
658
624
|
noteFeedbackAsked(currentDrivenBy() === undefined ? deps.attachId : undefined);
|
|
625
|
+
}
|
|
659
626
|
// Once per project, on a proved verdict, when the runs live only on this machine. Not on a result
|
|
660
627
|
// whose `reticleResult` already ends with the platform line: once per result, never twice.
|
|
661
628
|
const platform = isPlainObject(raw) && !(RESULT_FIELD in raw)
|
|
@@ -688,7 +655,6 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
688
655
|
tool: tool.name,
|
|
689
656
|
raw: answer,
|
|
690
657
|
isError: resultIsError(answer),
|
|
691
|
-
tab: session,
|
|
692
658
|
root: safeRoot(() => sessionRoot(deps, rawSessionId)),
|
|
693
659
|
harnessOn: () => impactSnapshot(artifactRoot)?.harnessConfig?.harnessEnabled,
|
|
694
660
|
})
|
|
@@ -738,8 +704,9 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
738
704
|
}
|
|
739
705
|
: {}),
|
|
740
706
|
};
|
|
741
|
-
if (!bound || !isPlainObject(result))
|
|
707
|
+
if (!bound || !isPlainObject(result)) {
|
|
742
708
|
return result;
|
|
709
|
+
}
|
|
743
710
|
// Reuse the session resolved above so the health envelope describes the SAME session the handler
|
|
744
711
|
// drove; only re-resolve if the up-front attempt failed but the handler somehow succeeded.
|
|
745
712
|
// A handler that answered with no tab to resolve (a Harness drive polled by runId after a daemon
|
|
@@ -767,9 +734,14 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
767
734
|
if (true === deps.pool?.stubInstalled?.(resolved.id)) {
|
|
768
735
|
envelope[EnvelopeKey.HOST_STUB] = HOST_STUB_NOTE;
|
|
769
736
|
}
|
|
737
|
+
const behind = sdkBehindNote(resolved);
|
|
738
|
+
if (behind !== undefined && 'verified' in result) {
|
|
739
|
+
envelope[EnvelopeKey.SDK_BEHIND] = behind;
|
|
740
|
+
}
|
|
770
741
|
// The health block is idempotent: add it only when the handler didn't already include a `session`.
|
|
771
|
-
if (!('session' in result))
|
|
742
|
+
if (!('session' in result)) {
|
|
772
743
|
Object.assign(envelope, healthEnvelope(resolved));
|
|
744
|
+
}
|
|
773
745
|
// Lease + age-warning are INDEPENDENT of the health block. Previously the `'session' in result`
|
|
774
746
|
// early-return skipped them whenever a handler returned its own health (which a throttled tab always
|
|
775
747
|
// does) — so a long-running backgrounded session, the case most likely to leak, never got the
|
|
@@ -780,11 +752,13 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
780
752
|
if (lease !== undefined && process.env['CI'] === undefined) {
|
|
781
753
|
envelope[EnvelopeKey.SESSION_LEASE] = lease;
|
|
782
754
|
}
|
|
783
|
-
if (opened !== undefined)
|
|
755
|
+
if (opened !== undefined) {
|
|
784
756
|
envelope[EnvelopeKey.ZERO_INSTALL] = opened.notice;
|
|
757
|
+
}
|
|
785
758
|
const warning = resolved.ageWarning();
|
|
786
|
-
if (warning !== undefined)
|
|
759
|
+
if (warning !== undefined) {
|
|
787
760
|
envelope[EnvelopeKey.SESSION_AGE_WARNING] = warning;
|
|
761
|
+
}
|
|
788
762
|
// Ask for a verdict when the agent has driven the page and not asked for one: a session that never
|
|
789
763
|
// calls a verdict-producing tool proves nothing, however many tools it used. One-shot per
|
|
790
764
|
// abandoned run, same discipline as the pool lease — a hint on every call is noise that gets tuned
|
|
@@ -806,11 +780,13 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
806
780
|
// that translation is where agents were already going wrong — `until` omitted, action arguments
|
|
807
781
|
// flat instead of nested under `args`. `ref` and `action` come from the act that actually
|
|
808
782
|
// dispatched, so the suggestion is about the element the agent touched. See verify-next-baton.
|
|
809
|
-
if (unverified !== undefined && !suppressBaton)
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
783
|
+
if (unverified !== undefined && !suppressBaton)
|
|
784
|
+
// `lastAct` read defensively: this envelope is built on EVERY tool call, so a session shape
|
|
785
|
+
// without it would turn a missing field into a crash on the whole surface rather than a missing
|
|
786
|
+
// suggestion. The baton degrades to prose, which is what it carried before.
|
|
787
|
+
{
|
|
813
788
|
envelope[EnvelopeKey.VERIFY_NEXT] = verifyNextBaton(unverified, resolved.lastAct?.effect() ?? {});
|
|
789
|
+
}
|
|
814
790
|
return Object.keys(envelope).length > 0 ? { ...result, ...envelope } : result;
|
|
815
791
|
}
|
|
816
792
|
/**
|
|
@@ -819,13 +795,16 @@ async function dispatchTool(tool, deps, args, call) {
|
|
|
819
795
|
* navigation can land the page under a new id, so the id the result reports wins.
|
|
820
796
|
*/
|
|
821
797
|
async function withStepShot(name, deps, args, raw, sessionId) {
|
|
822
|
-
if (!STEP_SHOT_TOOLS.has(name) || Array.isArray(args['steps']))
|
|
798
|
+
if (!STEP_SHOT_TOOLS.has(name) || Array.isArray(args['steps'])) {
|
|
823
799
|
return raw;
|
|
824
|
-
|
|
800
|
+
}
|
|
801
|
+
if (!isPlainObject(raw) || resultIsError(raw) || true === raw['paused']) {
|
|
825
802
|
return raw;
|
|
803
|
+
}
|
|
826
804
|
const tab = 'string' === typeof raw['sessionId'] ? raw['sessionId'] : sessionId;
|
|
827
|
-
if (tab === undefined)
|
|
805
|
+
if (tab === undefined) {
|
|
828
806
|
return raw;
|
|
807
|
+
}
|
|
829
808
|
// Paired with its check when the run is written: the n-th verdict picture is the n-th check.
|
|
830
809
|
const verdict = 'verified' in raw && (ReticleTool.ACT_AND_WAIT === name || ReticleTool.ASSERT === name);
|
|
831
810
|
return { ...raw, [EnvelopeKey.SCREENSHOT]: await takeStepShot(deps, tab, name, { verdict }) };
|
|
@@ -846,11 +825,18 @@ function safeRoot(get) {
|
|
|
846
825
|
function unmatchedRootOf(deps, sessionId) {
|
|
847
826
|
try {
|
|
848
827
|
const target = sessionTarget(deps, sessionId);
|
|
828
|
+
// A lease that claimed a root writes there. The page's unmatched bucket is not where this
|
|
829
|
+
// run goes, so naming it would send the agent to fix a folder the run never touches.
|
|
830
|
+
if (target.claimedRoot !== undefined) {
|
|
831
|
+
return undefined;
|
|
832
|
+
}
|
|
849
833
|
const resolved = deps.artifactRootFor?.(target.projectId, target.origin);
|
|
850
|
-
if (resolved === undefined || ArtifactRootReason.MATCHED_PROJECT === resolved.reason)
|
|
834
|
+
if (resolved === undefined || ArtifactRootReason.MATCHED_PROJECT === resolved.reason) {
|
|
851
835
|
return undefined;
|
|
852
|
-
|
|
836
|
+
}
|
|
837
|
+
if (resolved.root === deps.reticleRoot) {
|
|
853
838
|
return undefined;
|
|
839
|
+
}
|
|
854
840
|
return {
|
|
855
841
|
root: resolved.root,
|
|
856
842
|
contenders: resolved.candidates ?? [],
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* So: rank by what the daemon actually knows, and fall back to the differential only when it knows
|
|
18
18
|
* nothing. A cause we hold positive evidence against is not printed at all.
|
|
19
19
|
*/
|
|
20
|
+
import type { LeaseReaderFailure } from './lease-readiness.js';
|
|
20
21
|
/** What the daemon can say for certain at the moment a lease comes back unconnected. */
|
|
21
22
|
export interface LeaseEvidence {
|
|
22
23
|
/** A dial WAS made and turned away, with the reason. The only certain cause there is. */
|
|
@@ -56,3 +57,11 @@ export interface LeaseEvidence {
|
|
|
56
57
|
dialledUrl?: string;
|
|
57
58
|
}
|
|
58
59
|
export declare function leaseNotConnectedHint(url: string, port: number, evidence?: LeaseEvidence): string;
|
|
60
|
+
/**
|
|
61
|
+
* The leased page was still loading when the wait ran out, so nothing has failed yet: a slow first
|
|
62
|
+
* dev compile (Angular, a cold Vite) holds the document and its SDK dials in once it finishes.
|
|
63
|
+
* Saying "never dialled" here sent agents off debugging an install that works (#1555).
|
|
64
|
+
*/
|
|
65
|
+
export declare function leaseStillLoadingHint(url: string, waitedMs: number): string;
|
|
66
|
+
/** The hint for a lease whose zero-install reader did not run (#1701). The lease is already released. */
|
|
67
|
+
export declare function leaseReaderFailedHint(url: string, failure: LeaseReaderFailure): string;
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
* So: rank by what the daemon actually knows, and fall back to the differential only when it knows
|
|
18
18
|
* nothing. A cause we hold positive evidence against is not printed at all.
|
|
19
19
|
*/
|
|
20
|
-
import { isLoopbackHostname } from '@reticlehq/core';
|
|
20
|
+
import { isLoopbackHostname, LeaseNotReadyReason } from '@reticlehq/core';
|
|
21
|
+
import { INIT_COMMAND } from '../../portal/session/no-session-next-action.js';
|
|
21
22
|
const NUXT = 'nuxt';
|
|
22
23
|
const PORT_DIFFERENTIAL = "The usual cause is a PORT MISMATCH: the app's SDK connects to the port it was BUILT with, so a " +
|
|
23
24
|
"daemon on a different port never hears from it — check the app's reticle port (`.reticle.json`, " +
|
|
@@ -128,7 +129,7 @@ export function leaseNotConnectedHint(url, port, evidence = {}) {
|
|
|
128
129
|
const notThisApp = true === evidence.sdkMarker
|
|
129
130
|
? ''
|
|
130
131
|
: ' That may have been a DIFFERENT app, though: this one may carry no Reticle SDK at all, ' +
|
|
131
|
-
|
|
132
|
+
`in which case ask the user, then run \`${INIT_COMMAND}\` in ITS directory — every cause below assumes the ` +
|
|
132
133
|
'SDK is already installed.';
|
|
133
134
|
// Never beside a marker that WAS found: "it ships the SDK" and "the build stripped it" cannot
|
|
134
135
|
// both be the story.
|
|
@@ -150,7 +151,25 @@ export function leaseNotConnectedHint(url, port, evidence = {}) {
|
|
|
150
151
|
// was not seen; a production build is the other way to serve a page without it.
|
|
151
152
|
const noSdk = true === evidence.sdkMarker
|
|
152
153
|
? ''
|
|
153
|
-
:
|
|
154
|
+
: ` If the app carries no Reticle SDK at all, ask the user, then run \`${INIT_COMMAND}\` in it.` +
|
|
154
155
|
(false === evidence.sdkMarker || isRemoteUrl(url) ? PRODUCTION_STUB : '');
|
|
155
156
|
return `${opening}${nuxt}${marker} ${PORT_DIFFERENTIAL}${noSdk} ${REAL_CAUSES} ${RELEASE}`;
|
|
156
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* The leased page was still loading when the wait ran out, so nothing has failed yet: a slow first
|
|
160
|
+
* dev compile (Angular, a cold Vite) holds the document and its SDK dials in once it finishes.
|
|
161
|
+
* Saying "never dialled" here sent agents off debugging an install that works (#1555).
|
|
162
|
+
*/
|
|
163
|
+
export function leaseStillLoadingHint(url, waitedMs) {
|
|
164
|
+
const seconds = Math.round(waitedMs / 1000);
|
|
165
|
+
return (`${url} was still loading after ${seconds}s. Its SDK did not have time to connect. ` +
|
|
166
|
+
'Check reticle_session { action: "list" } again soon, or release and acquire again after the dev server compiles.');
|
|
167
|
+
}
|
|
168
|
+
/** The hint for a lease whose zero-install reader did not run (#1701). The lease is already released. */
|
|
169
|
+
export function leaseReaderFailedHint(url, failure) {
|
|
170
|
+
return failure.reason === LeaseNotReadyReason.NOT_HTML_DOCUMENT
|
|
171
|
+
? `${url} is not an HTML page, so no SDK can connect to it. The lease is released. ` +
|
|
172
|
+
'Acquire an HTML page of the app instead.'
|
|
173
|
+
: `The zero-install reader failed on ${url}: ${failure.cause}. The lease is released. ` +
|
|
174
|
+
'If the tab closed during setup, acquire again.';
|
|
175
|
+
}
|