@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
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The end-of-run report: the run ledger as the agent shows it to the user.
|
|
3
|
+
*
|
|
4
|
+
* Added to the answer of the call that ends an agent's run: a session end, a yield, or a released
|
|
5
|
+
* tab. A run that ended by releasing its tab got no word about the run before this, and its agent
|
|
6
|
+
* wrote its own summary. The report is a schema'd object, the markdown built from it, and one
|
|
7
|
+
* instruction. The cloud line is said only when the project is not linked, and it says what it is.
|
|
8
|
+
*/
|
|
9
|
+
import { CLOUD_VALUE_LINE, ReticleTool, RUN_REPORT_FIELD, RUN_REPORT_INSTRUCTION, UPGRADE_HINT_SILENCE_ENV, Verified, asString, } from '@reticlehq/core';
|
|
10
|
+
import { ResultWord, linkedToPlatform, seconds } from './reticle-result.js';
|
|
11
|
+
const HEAD = '**Reticle run report: ';
|
|
12
|
+
const SEP = ' · ';
|
|
13
|
+
/** Claims listed before the rest are counted: enough to read, not enough to flood a reply. */
|
|
14
|
+
const CLAIMS_SHOWN = 20;
|
|
15
|
+
const Said = {
|
|
16
|
+
NOTHING_CHECKED: 'nothing was checked',
|
|
17
|
+
CAUGHT: 'Caught, expected to hold and did not',
|
|
18
|
+
FLOWS_SAVED: 'Flows saved',
|
|
19
|
+
FLOWS_REPLAYED: 'Flows replayed',
|
|
20
|
+
NO_FLOWS: 'Flows: none saved, none replayed',
|
|
21
|
+
MEMORY: 'Memory',
|
|
22
|
+
TIME: 'Time',
|
|
23
|
+
FIRST_VERDICT: 'first verdict after',
|
|
24
|
+
};
|
|
25
|
+
const WORD = {
|
|
26
|
+
[Verified.YES]: ResultWord.PROVED,
|
|
27
|
+
[Verified.NO]: ResultWord.FAILED,
|
|
28
|
+
[Verified.UNKNOWN]: ResultWord.NOT_PROVED,
|
|
29
|
+
[Verified.NO_FAULT]: ResultWord.NOT_PROVED,
|
|
30
|
+
};
|
|
31
|
+
const plural = (n, word) => `${String(n)} ${word}${1 === n ? '' : 's'}`;
|
|
32
|
+
function headline(report) {
|
|
33
|
+
const all = [...report.claims, ...report.flows.replayed].map((c) => c.verified);
|
|
34
|
+
const count = (v) => all.filter((each) => v === each).length;
|
|
35
|
+
const total = all.length;
|
|
36
|
+
const word = `${HEAD}${WORD[report.verified]}**${SEP}`;
|
|
37
|
+
if (0 === total)
|
|
38
|
+
return `${word}${Said.NOTHING_CHECKED}`;
|
|
39
|
+
if (Verified.NO === report.verified)
|
|
40
|
+
return `${word}${String(count(Verified.NO))} of ${plural(total, 'check')} did not hold`;
|
|
41
|
+
if (Verified.YES === report.verified)
|
|
42
|
+
return `${word}${String(total)} of ${plural(total, 'check')} held`;
|
|
43
|
+
return `${word}${String(total - count(Verified.YES) - count(Verified.NO))} of ${plural(total, 'check')} undecided`;
|
|
44
|
+
}
|
|
45
|
+
/** The report as markdown: the verdict, each claim with its evidence, then what the run left. */
|
|
46
|
+
export function renderRunReport(report) {
|
|
47
|
+
const claims = report.claims
|
|
48
|
+
.slice(0, CLAIMS_SHOWN)
|
|
49
|
+
.map((c) => `- ${c.verified}: ${c.claim}${c.evidence === undefined ? '' : ` (${c.evidence})`}`);
|
|
50
|
+
const more = report.claims.length - CLAIMS_SHOWN;
|
|
51
|
+
const { saved, replayed } = report.flows;
|
|
52
|
+
const flows = 0 === saved.length && 0 === replayed.length
|
|
53
|
+
? [`- ${Said.NO_FLOWS}`]
|
|
54
|
+
: [
|
|
55
|
+
...(0 === saved.length ? [] : [`- ${Said.FLOWS_SAVED}: ${saved.join(', ')}`]),
|
|
56
|
+
...(0 === replayed.length
|
|
57
|
+
? []
|
|
58
|
+
: [
|
|
59
|
+
`- ${Said.FLOWS_REPLAYED}: ${replayed.map((r) => `${r.name} (${r.verified})`).join(', ')}`,
|
|
60
|
+
]),
|
|
61
|
+
];
|
|
62
|
+
const time = report.firstVerdictMs === undefined
|
|
63
|
+
? seconds(report.wallMs)
|
|
64
|
+
: `${seconds(report.wallMs)}, ${Said.FIRST_VERDICT} ${seconds(report.firstVerdictMs)}`;
|
|
65
|
+
return [
|
|
66
|
+
headline(report),
|
|
67
|
+
...claims,
|
|
68
|
+
...(0 < more ? [`- (+${String(more)} more claims)`] : []),
|
|
69
|
+
...(0 === report.caught.length ? [] : [`- ${Said.CAUGHT}: ${report.caught.join('; ')}`]),
|
|
70
|
+
...flows,
|
|
71
|
+
`- ${Said.MEMORY}: ${plural(report.memory.written, 'note')} written, ${String(report.memory.read)} read`,
|
|
72
|
+
`- ${Said.TIME}: ${time}`,
|
|
73
|
+
...(report.cloud === undefined ? [] : [`- ${report.cloud}`]),
|
|
74
|
+
].join('\n');
|
|
75
|
+
}
|
|
76
|
+
/** The calls that end an agent's run, by their own name or as an action of a merged tool. */
|
|
77
|
+
export function endsRun(tool, args) {
|
|
78
|
+
const action = asString(args['action']);
|
|
79
|
+
switch (tool) {
|
|
80
|
+
case ReticleTool.END_SESSION:
|
|
81
|
+
case ReticleTool.YIELD:
|
|
82
|
+
case ReticleTool.LEASE_RELEASE:
|
|
83
|
+
return true;
|
|
84
|
+
case ReticleTool.SESSION:
|
|
85
|
+
return 'end' === action || 'yield' === action;
|
|
86
|
+
case ReticleTool.LEASE:
|
|
87
|
+
return 'release' === action;
|
|
88
|
+
default:
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** `reticle_intent` actions that write a statement, and the ones that read them back. */
|
|
93
|
+
const IntentWrite = { RECORD: 'record', DECLARE: 'declare' };
|
|
94
|
+
const INTENT_READS = new Set(['list', 'index', 'subject', 'get']);
|
|
95
|
+
const isRecord = (value) => null !== value && 'object' === typeof value && !Array.isArray(value);
|
|
96
|
+
/** What an answer says the run saved or read. An answer that refused counts for nothing. */
|
|
97
|
+
export function noteToolResult(ledger, tool, args, result) {
|
|
98
|
+
if (!isRecord(result) || result['error'] !== undefined)
|
|
99
|
+
return;
|
|
100
|
+
if (ReticleTool.FLOW_SAVE === tool || ReticleTool.FLOW_SAVE_RECORDED === tool) {
|
|
101
|
+
const name = result['name'];
|
|
102
|
+
if ('string' === typeof name)
|
|
103
|
+
ledger.flowSaved(name);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const action = asString(args['action']);
|
|
107
|
+
if (ReticleTool.INTENT === tool) {
|
|
108
|
+
// The intent ledger in `.reticle/intent/` is the memory an unlinked project has.
|
|
109
|
+
if (IntentWrite.RECORD === action)
|
|
110
|
+
ledger.memoryWritten();
|
|
111
|
+
const declared = args['intents'];
|
|
112
|
+
if (IntentWrite.DECLARE === action && Array.isArray(declared))
|
|
113
|
+
ledger.memoryWritten(declared.length);
|
|
114
|
+
if (action !== undefined && INTENT_READS.has(action))
|
|
115
|
+
ledger.memoryRead([JSON.stringify(result)]);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (ReticleTool.MEMORY !== tool)
|
|
119
|
+
return;
|
|
120
|
+
if ('add' === action && result['added'] !== undefined)
|
|
121
|
+
ledger.memoryWritten();
|
|
122
|
+
const known = result['known'];
|
|
123
|
+
if (Array.isArray(known))
|
|
124
|
+
ledger.memoryRead(known.map((entry) => JSON.stringify(entry)));
|
|
125
|
+
}
|
|
126
|
+
/** The report as an answer field, or no field when the ledger holds no run. Empties the ledger. */
|
|
127
|
+
export function runReportField(ledger, root, env, now) {
|
|
128
|
+
if (ledger.isEmpty())
|
|
129
|
+
return {};
|
|
130
|
+
const taken = ledger.take(now);
|
|
131
|
+
const silenced = env[UPGRADE_HINT_SILENCE_ENV] !== undefined;
|
|
132
|
+
const linked = root === undefined || linkedToPlatform(root, env);
|
|
133
|
+
const report = silenced || linked ? taken : { ...taken, cloud: CLOUD_VALUE_LINE };
|
|
134
|
+
return {
|
|
135
|
+
[RUN_REPORT_FIELD]: {
|
|
136
|
+
report,
|
|
137
|
+
markdown: renderRunReport(report),
|
|
138
|
+
instruction: RUN_REPORT_INSTRUCTION,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider capabilities handed to features as ports: a suite fixture to seed from, save/restore,
|
|
3
|
+
* slowing the page and breaking it. Each is `undefined` when the provider cannot do it. They sit on
|
|
4
|
+
* the tool side because a feature reaching into the input layer directly would depend on a driver.
|
|
5
|
+
*/
|
|
6
|
+
import type { RealInputProvider } from '../../portal/input/real-input.js';
|
|
7
|
+
import { type StorageFixturePort } from '../../portal/input/storage-fixture.js';
|
|
8
|
+
import { type NetworkMutationPort } from '../../portal/input/network-mutation.js';
|
|
9
|
+
import type { Perturbation, SeedStorage } from '@reticlehq/core';
|
|
10
|
+
/**
|
|
11
|
+
* The state a suite should boot its flows from: whatever the agent is already sitting in.
|
|
12
|
+
*
|
|
13
|
+
* This is the join the fixture work was building toward. A suite's flows each start from cold, so
|
|
14
|
+
* fifty of them prove the login works fifty times — and the flow that LOGS OUT leaves every flow
|
|
15
|
+
* after it signed out, which no navigation repairs, because the problem is not where the subject is
|
|
16
|
+
* but what it holds. A seed is applied to an isolated context BEFORE the first navigation, which is
|
|
17
|
+
* exactly and only when a fixture can work.
|
|
18
|
+
*
|
|
19
|
+
* Best-effort, deliberately. A fixture is an OPTIMISATION over running from cold, and running from
|
|
20
|
+
* cold is correct: a suite that refused to start because a cookie jar could not be read would have
|
|
21
|
+
* traded a slow answer for no answer. Every "no" here — no provider, no storage support, nothing
|
|
22
|
+
* driven, a browser that threw, nothing worth seeding — produces the same honest `undefined`, and
|
|
23
|
+
* the suite runs exactly as it did before any of this existed.
|
|
24
|
+
*/
|
|
25
|
+
export declare function suiteFixtureSeed(realInput: RealInputProvider | undefined, appUrl: string): Promise<SeedStorage | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* A way to make this session's page SLOW on purpose, or nothing.
|
|
28
|
+
*
|
|
29
|
+
* The third of these seams, for the same reason as the other two: a feature reaching into the input
|
|
30
|
+
* layer directly is a feature depending on a driver, and the boundary guard asks about it.
|
|
31
|
+
*
|
|
32
|
+
* Installs delays and NOTHING else. A rule that carried a status or a body would substitute a
|
|
33
|
+
* response the server never sent, and an app raced against invented data produces invented races —
|
|
34
|
+
* a fabricated defect handed to somebody at 3am, which is worse than finding nothing.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sessionPerturbationPort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<{
|
|
37
|
+
slow(rules: readonly Perturbation[]): Promise<void>;
|
|
38
|
+
clear(): Promise<void>;
|
|
39
|
+
} | undefined>;
|
|
40
|
+
/**
|
|
41
|
+
* Save/restore for this session's page, or nothing.
|
|
42
|
+
*
|
|
43
|
+
* The same job as `suiteFixtureSeed` next door, stopping one step earlier: that one captures and
|
|
44
|
+
* converts, this hands back the PORT so a caller can re-apply what it captured later. It lives here
|
|
45
|
+
* for the reason written above — a feature reaching into the input layer directly is a feature
|
|
46
|
+
* depending on a driver, and the boundary guard asks about it. It asked.
|
|
47
|
+
*/
|
|
48
|
+
export declare function suiteFixturePort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<StorageFixturePort | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* A way to break this session's page, or nothing.
|
|
51
|
+
*
|
|
52
|
+
* Sits beside `suiteFixtureSeed` because it is the same shape of job: turning a provider capability
|
|
53
|
+
* into something a feature can use, on the one side of the graph that is allowed to know about both.
|
|
54
|
+
* A flow tool reaching into the input layer directly would be a feature depending on a driver, which
|
|
55
|
+
* is the reach the boundary guard exists to ask about.
|
|
56
|
+
*/
|
|
57
|
+
export declare function sessionMutationPort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<NetworkMutationPort | undefined>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { fixturePortFor, seedFromStorageState, } from '../../portal/input/storage-fixture.js';
|
|
2
|
+
import { mutationPortFor } from '../../portal/input/network-mutation.js';
|
|
3
|
+
/**
|
|
4
|
+
* The state a suite should boot its flows from: whatever the agent is already sitting in.
|
|
5
|
+
*
|
|
6
|
+
* This is the join the fixture work was building toward. A suite's flows each start from cold, so
|
|
7
|
+
* fifty of them prove the login works fifty times — and the flow that LOGS OUT leaves every flow
|
|
8
|
+
* after it signed out, which no navigation repairs, because the problem is not where the subject is
|
|
9
|
+
* but what it holds. A seed is applied to an isolated context BEFORE the first navigation, which is
|
|
10
|
+
* exactly and only when a fixture can work.
|
|
11
|
+
*
|
|
12
|
+
* Best-effort, deliberately. A fixture is an OPTIMISATION over running from cold, and running from
|
|
13
|
+
* cold is correct: a suite that refused to start because a cookie jar could not be read would have
|
|
14
|
+
* traded a slow answer for no answer. Every "no" here — no provider, no storage support, nothing
|
|
15
|
+
* driven, a browser that threw, nothing worth seeding — produces the same honest `undefined`, and
|
|
16
|
+
* the suite runs exactly as it did before any of this existed.
|
|
17
|
+
*/
|
|
18
|
+
export async function suiteFixtureSeed(realInput, appUrl) {
|
|
19
|
+
if (realInput === undefined) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const port = await fixturePortFor(realInput, appUrl);
|
|
24
|
+
if (port === undefined) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return seedFromStorageState(await port.capture(), appUrl);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A way to make this session's page SLOW on purpose, or nothing.
|
|
35
|
+
*
|
|
36
|
+
* The third of these seams, for the same reason as the other two: a feature reaching into the input
|
|
37
|
+
* layer directly is a feature depending on a driver, and the boundary guard asks about it.
|
|
38
|
+
*
|
|
39
|
+
* Installs delays and NOTHING else. A rule that carried a status or a body would substitute a
|
|
40
|
+
* response the server never sent, and an app raced against invented data produces invented races —
|
|
41
|
+
* a fabricated defect handed to somebody at 3am, which is worse than finding nothing.
|
|
42
|
+
*/
|
|
43
|
+
export async function sessionPerturbationPort(realInput, appUrl) {
|
|
44
|
+
if (realInput === undefined || appUrl === undefined) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const setMocks = realInput.setMocks?.bind(realInput);
|
|
48
|
+
if (setMocks === undefined) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
if (!(await realInput.isAvailableFor(appUrl))) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
slow: async (rules) => {
|
|
56
|
+
await setMocks(appUrl, [...rules]);
|
|
57
|
+
},
|
|
58
|
+
/** Clearing is the undo. A page left slowed is damage the next run inherits. */
|
|
59
|
+
clear: async () => {
|
|
60
|
+
await setMocks(appUrl, []);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Save/restore for this session's page, or nothing.
|
|
66
|
+
*
|
|
67
|
+
* The same job as `suiteFixtureSeed` next door, stopping one step earlier: that one captures and
|
|
68
|
+
* converts, this hands back the PORT so a caller can re-apply what it captured later. It lives here
|
|
69
|
+
* for the reason written above — a feature reaching into the input layer directly is a feature
|
|
70
|
+
* depending on a driver, and the boundary guard asks about it. It asked.
|
|
71
|
+
*/
|
|
72
|
+
export async function suiteFixturePort(realInput, appUrl) {
|
|
73
|
+
if (realInput === undefined || appUrl === undefined) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
return await fixturePortFor(realInput, appUrl);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A way to break this session's page, or nothing.
|
|
85
|
+
*
|
|
86
|
+
* Sits beside `suiteFixtureSeed` because it is the same shape of job: turning a provider capability
|
|
87
|
+
* into something a feature can use, on the one side of the graph that is allowed to know about both.
|
|
88
|
+
* A flow tool reaching into the input layer directly would be a feature depending on a driver, which
|
|
89
|
+
* is the reach the boundary guard exists to ask about.
|
|
90
|
+
*/
|
|
91
|
+
export async function sessionMutationPort(realInput, appUrl) {
|
|
92
|
+
if (realInput === undefined || appUrl === undefined) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
return await mutationPortFor(realInput, appUrl);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// A provider that cannot answer is the same answer as a provider that cannot break anything.
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -13,6 +13,7 @@ import type { BaselineStore } from '../../memory/project/baselines.js';
|
|
|
13
13
|
import type { RecordingStore } from '../../language/flows/recording/tape/recordings.js';
|
|
14
14
|
import type { FileSystemPort } from '../../memory/project/fs/fs-port.js';
|
|
15
15
|
import type { ArtifactRoot } from '../../memory/project/artifact-root.js';
|
|
16
|
+
import type { NonceMinter } from '../../portal/production/production-activation.js';
|
|
16
17
|
import type { FlowStore } from '../../language/flows/flows.js';
|
|
17
18
|
import type { ProjectStore } from '../../memory/project/project-store.js';
|
|
18
19
|
import type { AnnotationStore } from '../../language/flows/stores/annotation-store.js';
|
|
@@ -76,6 +77,11 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
76
77
|
* it, so two agents on one origin never share a tab (#1226). Absent ⇒ every acquire gets its own.
|
|
77
78
|
*/
|
|
78
79
|
attachId?: string;
|
|
80
|
+
/**
|
|
81
|
+
* The coding agent's own session id, as its MCP server announced it on connect. Joins this
|
|
82
|
+
* connection's episode to the agent hooks' records. Absent: the agent announced none.
|
|
83
|
+
*/
|
|
84
|
+
agentSession?: string;
|
|
79
85
|
/** Run one sync cycle with the platform now, for `reticle_project { push }`. Absent: not linked here. */
|
|
80
86
|
syncNow?: () => Promise<unknown>;
|
|
81
87
|
/** Wires the app on the agent's first use, instead of at installation. Absent: tell, do not wire. */
|
|
@@ -88,6 +94,8 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
88
94
|
url: string;
|
|
89
95
|
notice: string;
|
|
90
96
|
} | undefined>;
|
|
97
|
+
/** The one dev server running in the caller's project folder, for a lease that names no url. */
|
|
98
|
+
projectAppUrl?: () => Promise<string | undefined>;
|
|
91
99
|
/** cross-run outcome memory (.reticle/project.json). */
|
|
92
100
|
project: ProjectStore;
|
|
93
101
|
/** optional native-input provider. undefined ⇒ everything stays synthetic. */
|
|
@@ -140,6 +148,11 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
140
148
|
* ToolDeps keeps working; absent falls back to the default port.
|
|
141
149
|
*/
|
|
142
150
|
bridgePort?: number;
|
|
151
|
+
/**
|
|
152
|
+
* The bridge's session-nonce registry. Local callers only: a production lease mints its nonce
|
|
153
|
+
* here. Absent where no bridge runs in this process, and a production lease then refuses.
|
|
154
|
+
*/
|
|
155
|
+
nonces?: NonceMinter;
|
|
143
156
|
/**
|
|
144
157
|
* A consumer's OWN dependencies, carried through untouched.
|
|
145
158
|
*
|
|
@@ -159,13 +172,13 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
159
172
|
export interface ToolDef<Ext = unknown> {
|
|
160
173
|
name: string;
|
|
161
174
|
description: string;
|
|
162
|
-
inputSchema: z.
|
|
175
|
+
inputSchema: Record<string, z.ZodType>;
|
|
163
176
|
/**
|
|
164
177
|
* JSON Schema-compatible output schema for this tool. When present, the MCP server advertises it
|
|
165
178
|
* in the tools/list response so schema-aware clients (like @reticlehq/cli) can validate outputs and
|
|
166
179
|
* compose tool calls safely. Also drives TOON encoding for snapshot/query results.
|
|
167
180
|
*/
|
|
168
|
-
outputSchema?: z.
|
|
181
|
+
outputSchema?: Record<string, z.ZodType>;
|
|
169
182
|
/**
|
|
170
183
|
* One concrete, valid call — the shape, not the prose.
|
|
171
184
|
*
|
|
@@ -268,6 +281,8 @@ export declare const EnvelopeKey: {
|
|
|
268
281
|
readonly TALK_TO_US: "talk_to_us";
|
|
269
282
|
/** SDK/daemon version skew — often the one fact that explains everything else in the session. */
|
|
270
283
|
readonly VERSION_SKEW: "version_skew";
|
|
284
|
+
/** On each verdict from a page whose SDK is behind the daemon. See session-info.ts. */
|
|
285
|
+
readonly SDK_BEHIND: "sdk_behind";
|
|
271
286
|
/** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
|
|
272
287
|
readonly FEEDBACK_UNDELIVERED: "feedback_undelivered";
|
|
273
288
|
/** Once per project: verified runs exist only on this machine. See platform-moment.ts. */
|
|
@@ -290,6 +305,8 @@ export declare const EnvelopeKey: {
|
|
|
290
305
|
readonly ZERO_INSTALL: "zero_install";
|
|
291
306
|
/** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
|
|
292
307
|
readonly NOTICES: "notices";
|
|
308
|
+
/** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
|
|
309
|
+
readonly RUN_REPORT: "runReport";
|
|
293
310
|
};
|
|
294
311
|
export type EnvelopeKey = (typeof EnvelopeKey)[keyof typeof EnvelopeKey];
|
|
295
312
|
/**
|
|
@@ -305,10 +322,47 @@ export declare const HOST_STUB_NOTE: string;
|
|
|
305
322
|
* `steps`) takes one per step, inside the sequence, rather than one for the whole call.
|
|
306
323
|
*/
|
|
307
324
|
export declare const STEP_SHOT_TOOLS: ReadonlySet<string>;
|
|
325
|
+
/**
|
|
326
|
+
* Tools that DRIVE the page. An action with no verdict after it is the signature of the loop
|
|
327
|
+
* breaking mid-task — see `abandonedActions`. `act_and_wait` is one of these AND a verification, so
|
|
328
|
+
* it settles its own action, which is exactly right: it is the tool that does both.
|
|
329
|
+
*/
|
|
330
|
+
export declare const ACTION_TOOLS: ReadonlySet<string>;
|
|
331
|
+
/**
|
|
332
|
+
* Tools that go through Playwright CDP rather than the page SDK.
|
|
333
|
+
*
|
|
334
|
+
* Under version skew these fail with "Target page, context or browser has been closed" while every
|
|
335
|
+
* DOM tool against the same tab still works (#688). They are session-EXEMPT (own result contracts),
|
|
336
|
+
* so the bound-tool resolve in `runTool` never runs for them — resolve again there so we can refuse with
|
|
337
|
+
* the skew sentence before Playwright lies about a closed page.
|
|
338
|
+
*/
|
|
339
|
+
export declare const CDP_TOOLS: ReadonlySet<string>;
|
|
340
|
+
/**
|
|
341
|
+
* Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
|
|
342
|
+
* that spends one cannot be routed to a different tab without saying so — see ref-provenance.ts.
|
|
343
|
+
*
|
|
344
|
+
* Over-inclusion is the safe direction here and under-inclusion is not dangerous either: both ends
|
|
345
|
+
* produce a REFUSAL naming the two tabs, never a silent drive against the wrong one.
|
|
346
|
+
*/
|
|
347
|
+
export declare const REF_MINTING_TOOLS: ReadonlySet<string>;
|
|
348
|
+
/**
|
|
349
|
+
* The live-session tools whose result MUST carry the
|
|
350
|
+
* session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
|
|
351
|
+
* can never return a healthy-looking result from any of these. `runTool` is the single choke point
|
|
352
|
+
* (mcp.ts + tool-invoker.ts) that splices health on (`invoke-tool.ts`); the guard test asserts the set is exhaustive.
|
|
353
|
+
*/
|
|
354
|
+
export declare const SESSION_BOUND_TOOLS: ReadonlySet<string>;
|
|
355
|
+
/**
|
|
356
|
+
* Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
|
|
357
|
+
* disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
|
|
358
|
+
* exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
|
|
359
|
+
* `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
|
|
360
|
+
*/
|
|
361
|
+
export declare const SESSION_EXEMPT_TOOLS: ReadonlySet<string>;
|
|
308
362
|
/** A step-screenshot tool, with the one sentence about its screenshot on the end of its description. */
|
|
309
363
|
export declare function withScreenshotDoc(tool: ToolDef): ToolDef;
|
|
310
364
|
/** The one sentence every tool that takes a step screenshot says about it. */
|
|
311
|
-
export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice.";
|
|
365
|
+
export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice. When `pending: true`, the file may still be in write; wait before you read it.";
|
|
312
366
|
/**
|
|
313
367
|
* Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime.
|
|
314
368
|
* Merged into each session-bound tool's outputSchema so a schema-strict client (structuredContent
|
|
@@ -317,7 +371,7 @@ export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the pa
|
|
|
317
371
|
* Derived from `EnvelopeKey` rather than re-listed: this shape and the splice sites disagreed for a
|
|
318
372
|
* whole release, and every key that went missing was a channel nobody could see was missing.
|
|
319
373
|
*/
|
|
320
|
-
export declare const sessionEnvelopeShape: z.
|
|
374
|
+
export declare const sessionEnvelopeShape: Record<string, z.ZodType>;
|
|
321
375
|
/** Unwrap a browser command result or throw its error so the agent sees a clean failure. */
|
|
322
376
|
export declare function commandOrThrow(deps: ToolDeps, sessionId: string | undefined, name: ReticleCommand, args: Record<string, unknown>): Promise<unknown>;
|
|
323
377
|
/** Full DOM snapshot → normalized tree lines + route, for tools that diff or scan the page. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
|
-
import { asRecord, asString, ReticleCommand, ReticleTool, SnapshotMode, } from '@reticlehq/core';
|
|
3
|
+
import { asRecord, asString, ReticleCommand, ReticleTool, SnapshotMode, RUN_REPORT_FIELD, } from '@reticlehq/core';
|
|
4
4
|
import { normalizeLines } from '../../memory/project/baselines.js';
|
|
5
5
|
import { SnapshotCache } from './read/snapshot-delta.js';
|
|
6
6
|
/**
|
|
@@ -77,6 +77,8 @@ export const EnvelopeKey = {
|
|
|
77
77
|
TALK_TO_US: 'talk_to_us',
|
|
78
78
|
/** SDK/daemon version skew — often the one fact that explains everything else in the session. */
|
|
79
79
|
VERSION_SKEW: 'version_skew',
|
|
80
|
+
/** On each verdict from a page whose SDK is behind the daemon. See session-info.ts. */
|
|
81
|
+
SDK_BEHIND: 'sdk_behind',
|
|
80
82
|
/** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
|
|
81
83
|
FEEDBACK_UNDELIVERED: 'feedback_undelivered',
|
|
82
84
|
/** Once per project: verified runs exist only on this machine. See platform-moment.ts. */
|
|
@@ -99,6 +101,8 @@ export const EnvelopeKey = {
|
|
|
99
101
|
ZERO_INSTALL: 'zero_install',
|
|
100
102
|
/** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
|
|
101
103
|
NOTICES: 'notices',
|
|
104
|
+
/** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
|
|
105
|
+
RUN_REPORT: RUN_REPORT_FIELD,
|
|
102
106
|
};
|
|
103
107
|
/**
|
|
104
108
|
* The sentence every session-bound result carries while its leased tab runs on a stubbed shell.
|
|
@@ -119,6 +123,132 @@ export const STEP_SHOT_TOOLS = new Set([
|
|
|
119
123
|
ReticleTool.NAVIGATE,
|
|
120
124
|
ReticleTool.ASSERT,
|
|
121
125
|
]);
|
|
126
|
+
/**
|
|
127
|
+
* Tools that DRIVE the page. An action with no verdict after it is the signature of the loop
|
|
128
|
+
* breaking mid-task — see `abandonedActions`. `act_and_wait` is one of these AND a verification, so
|
|
129
|
+
* it settles its own action, which is exactly right: it is the tool that does both.
|
|
130
|
+
*/
|
|
131
|
+
export const ACTION_TOOLS = new Set([
|
|
132
|
+
ReticleTool.ACT,
|
|
133
|
+
ReticleTool.ACT_SEQUENCE,
|
|
134
|
+
ReticleTool.ACT_AND_WAIT,
|
|
135
|
+
]);
|
|
136
|
+
/**
|
|
137
|
+
* Tools that go through Playwright CDP rather than the page SDK.
|
|
138
|
+
*
|
|
139
|
+
* Under version skew these fail with "Target page, context or browser has been closed" while every
|
|
140
|
+
* DOM tool against the same tab still works (#688). They are session-EXEMPT (own result contracts),
|
|
141
|
+
* so the bound-tool resolve in `runTool` never runs for them — resolve again there so we can refuse with
|
|
142
|
+
* the skew sentence before Playwright lies about a closed page.
|
|
143
|
+
*/
|
|
144
|
+
export const CDP_TOOLS = new Set([
|
|
145
|
+
ReticleTool.SCREENSHOT,
|
|
146
|
+
ReticleTool.VISUAL_DIFF,
|
|
147
|
+
ReticleTool.NETWORK_MOCK,
|
|
148
|
+
ReticleTool.VIEWPORT,
|
|
149
|
+
// Breaks a request through the same Playwright route `reticle_network_mock` uses, so it fails the
|
|
150
|
+
// same way under version skew and must be refused with the same sentence.
|
|
151
|
+
ReticleTool.FLOW_MUTATE,
|
|
152
|
+
]);
|
|
153
|
+
/**
|
|
154
|
+
* Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
|
|
155
|
+
* that spends one cannot be routed to a different tab without saying so — see ref-provenance.ts.
|
|
156
|
+
*
|
|
157
|
+
* Over-inclusion is the safe direction here and under-inclusion is not dangerous either: both ends
|
|
158
|
+
* produce a REFUSAL naming the two tabs, never a silent drive against the wrong one.
|
|
159
|
+
*/
|
|
160
|
+
export const REF_MINTING_TOOLS = new Set([
|
|
161
|
+
ReticleTool.SNAPSHOT,
|
|
162
|
+
ReticleTool.QUERY,
|
|
163
|
+
ReticleTool.INSPECT,
|
|
164
|
+
// The same three merged, on the `merged` surface. Its `state` action mints nothing, and
|
|
165
|
+
// over-inclusion is the safe direction here: the worst case is a refusal naming two tabs.
|
|
166
|
+
ReticleTool.LOOK,
|
|
167
|
+
ReticleTool.EXPLORE,
|
|
168
|
+
// `crawl` mints refs for the controls it drives and `coverage` for the ones it reports untouched.
|
|
169
|
+
// Both are actions on the merged verify tool now.
|
|
170
|
+
ReticleTool.VERIFY,
|
|
171
|
+
]);
|
|
172
|
+
/**
|
|
173
|
+
* The live-session tools whose result MUST carry the
|
|
174
|
+
* session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
|
|
175
|
+
* can never return a healthy-looking result from any of these. `runTool` is the single choke point
|
|
176
|
+
* (mcp.ts + tool-invoker.ts) that splices health on (`invoke-tool.ts`); the guard test asserts the set is exhaustive.
|
|
177
|
+
*/
|
|
178
|
+
export const SESSION_BOUND_TOOLS = new Set([
|
|
179
|
+
// Resolves a session and reads its event window (`session.eventsSince`), exactly as OBSERVE and
|
|
180
|
+
// NETWORK do. Without this it runs with no session and answers from nothing.
|
|
181
|
+
ReticleTool.SNAPSHOT,
|
|
182
|
+
ReticleTool.QUERY,
|
|
183
|
+
ReticleTool.INSPECT,
|
|
184
|
+
// All four merged. Every member here is session-bound, so unlike `verify` there is no split to
|
|
185
|
+
// adjudicate — the merged tool inherits the only answer its members ever gave.
|
|
186
|
+
ReticleTool.LOOK,
|
|
187
|
+
// Merged change/flows/affected/coverage/crawl. Its members were SPLIT across bound and exempt —
|
|
188
|
+
// coverage/change/crawl bound, flow_verify exempt because it returns its own suite contract — and
|
|
189
|
+
// a merged tool has to be one or the other. Bound is the right side: `crawl` drives the app
|
|
190
|
+
// itself, so a throttled or event-dropping tab is exactly the condition its verdict depends on,
|
|
191
|
+
// and dropping the health disclosure there to protect a sibling's output shape would trade an
|
|
192
|
+
// honesty signal for a formatting preference.
|
|
193
|
+
ReticleTool.VERIFY,
|
|
194
|
+
ReticleTool.ACT,
|
|
195
|
+
ReticleTool.ACT_SEQUENCE,
|
|
196
|
+
ReticleTool.ACT_AND_WAIT,
|
|
197
|
+
ReticleTool.OBSERVE,
|
|
198
|
+
ReticleTool.WAIT_FOR,
|
|
199
|
+
ReticleTool.ASSERT,
|
|
200
|
+
// Reads the live page as well as the event window, so a throttled tab can make it compare a stale
|
|
201
|
+
// render against fresh data — exactly the case the health envelope exists to disclose.
|
|
202
|
+
ReticleTool.RECONCILE,
|
|
203
|
+
ReticleTool.NETWORK,
|
|
204
|
+
ReticleTool.CONSOLE,
|
|
205
|
+
ReticleTool.ANIMATIONS,
|
|
206
|
+
ReticleTool.BASELINE, // merged save/list/diff — save+diff are live reads
|
|
207
|
+
ReticleTool.RECORD, // merged start/stop — both live
|
|
208
|
+
ReticleTool.REPLAY,
|
|
209
|
+
ReticleTool.CLOCK,
|
|
210
|
+
ReticleTool.STATE,
|
|
211
|
+
ReticleTool.STORAGE,
|
|
212
|
+
ReticleTool.EXPLORE,
|
|
213
|
+
ReticleTool.SCROLL_TO,
|
|
214
|
+
ReticleTool.NAVIGATE,
|
|
215
|
+
]);
|
|
216
|
+
/**
|
|
217
|
+
* Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
|
|
218
|
+
* disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
|
|
219
|
+
* exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
|
|
220
|
+
* `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
|
|
221
|
+
*/
|
|
222
|
+
export const SESSION_EXEMPT_TOOLS = new Set([
|
|
223
|
+
ReticleTool.CAPABILITIES, // has a fromDisk mode with no live session
|
|
224
|
+
ReticleTool.CONTRACT_SAVE, // persists the registry to disk
|
|
225
|
+
ReticleTool.FLOW_SAVE, // sessionId only scopes the write to the app's flow subdir; disk-side
|
|
226
|
+
ReticleTool.FLOW, // merged list/load/delete — sessionId only scopes the project; all disk-side
|
|
227
|
+
ReticleTool.FLOW_REPLAY, // returns its own FlowReplayResult contract (+ auto-records a run)
|
|
228
|
+
ReticleTool.FLOW_SAVE_RECORDED, // reads the recording buffer, writes disk
|
|
229
|
+
// FLOW_HEAL is no longer a name runTool ever sees: it became `reticle_verify {action:"heal"}`,
|
|
230
|
+
// and VERIFY is already listed here, so the exemption is inherited from the parent. Left as a
|
|
231
|
+
// dangling name it would be a lie this file's own test 6 is written to catch.
|
|
232
|
+
ReticleTool.INTENT, // reads/writes .reticle/intent/; sessionId only picks the project
|
|
233
|
+
ReticleTool.CONTEXT, // folds the journal + intent ledger; must still answer when nothing is connected
|
|
234
|
+
ReticleTool.MAP, // folds the journals on disk into the App Graph; answers with no tab connected
|
|
235
|
+
ReticleTool.PROJECT, // reads .reticle/project.json
|
|
236
|
+
// Reads the team's shared memory over HTTP; sessionId only resolves WHICH project's link file to
|
|
237
|
+
// use. It must answer with no tab connected — "what does this project know?" is a question an
|
|
238
|
+
// agent asks before it has opened anything.
|
|
239
|
+
ReticleTool.MEMORY,
|
|
240
|
+
ReticleTool.RUN_EXPORT, // reads .reticle/runs/<id>.json (verification-run artifact)
|
|
241
|
+
ReticleTool.SESSION, // merged lifecycle/human-channel family (tune/yield/end/resume/messages/review/narrate)
|
|
242
|
+
ReticleTool.SCREENSHOT, // own contract; provider-driven, not a live-DOM-health read
|
|
243
|
+
ReticleTool.VISUAL_DIFF, // own contract (matched/ratio/region)
|
|
244
|
+
ReticleTool.NETWORK_MOCK, // own contract (applied/count); provider-driven, not a live-DOM read
|
|
245
|
+
ReticleTool.VIEWPORT, // own contract (applied/width/height); provider-driven, not a live-DOM read
|
|
246
|
+
ReticleTool.ANNOTATE, // annotates a recording's steps; pure disk-side metadata, no live DOM read
|
|
247
|
+
ReticleTool.LEASE, // merged acquire/release — its sessionId is a pool lease id, not a live session
|
|
248
|
+
// Its sessionId only enriches the report with the tab's runtime/engine, and it must stay callable
|
|
249
|
+
// when NO session exists — "nothing ever connected" is feedback we especially want.
|
|
250
|
+
ReticleTool.FEEDBACK,
|
|
251
|
+
]);
|
|
122
252
|
/** A step-screenshot tool, with the one sentence about its screenshot on the end of its description. */
|
|
123
253
|
export function withScreenshotDoc(tool) {
|
|
124
254
|
return STEP_SHOT_TOOLS.has(tool.name)
|
|
@@ -126,7 +256,7 @@ export function withScreenshotDoc(tool) {
|
|
|
126
256
|
: tool;
|
|
127
257
|
}
|
|
128
258
|
/** The one sentence every tool that takes a step screenshot says about it. */
|
|
129
|
-
export const SCREENSHOT_DOC = ' `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice.';
|
|
259
|
+
export const SCREENSHOT_DOC = ' `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice. When `pending: true`, the file may still be in write; wait before you read it.';
|
|
130
260
|
/**
|
|
131
261
|
* Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime.
|
|
132
262
|
* Merged into each session-bound tool's outputSchema so a schema-strict client (structuredContent
|
|
@@ -147,16 +277,18 @@ export async function commandOrThrow(deps, sessionId,
|
|
|
147
277
|
name, args) {
|
|
148
278
|
const session = deps.sessions.resolve(sessionId);
|
|
149
279
|
const result = await session.command(name, args);
|
|
150
|
-
if (!result.ok)
|
|
280
|
+
if (!result.ok) {
|
|
151
281
|
throw new Error(result.error ?? `command '${name}' failed`);
|
|
282
|
+
}
|
|
152
283
|
return result.result;
|
|
153
284
|
}
|
|
154
285
|
/** Full DOM snapshot → normalized tree lines + route, for tools that diff or scan the page. */
|
|
155
286
|
export async function snapshotTree(deps, sessionId) {
|
|
156
287
|
const session = deps.sessions.resolve(sessionId);
|
|
157
288
|
const result = await session.command(ReticleCommand.SNAPSHOT, { mode: SnapshotMode.FULL });
|
|
158
|
-
if (!result.ok)
|
|
289
|
+
if (!result.ok) {
|
|
159
290
|
throw new Error(result.error ?? 'snapshot failed');
|
|
291
|
+
}
|
|
160
292
|
const snap = (result.result ?? {});
|
|
161
293
|
return { lines: normalizeLines(snap.tree ?? ''), route: snap.status?.route ?? '' };
|
|
162
294
|
}
|
|
@@ -181,14 +313,16 @@ export function callSecrets() {
|
|
|
181
313
|
* telemetry — ever sees them.
|
|
182
314
|
*/
|
|
183
315
|
export function takeCallSecrets(args) {
|
|
184
|
-
if (!(CALL_SECRETS_ARG in args))
|
|
316
|
+
if (!(CALL_SECRETS_ARG in args)) {
|
|
185
317
|
return { secrets: undefined, rest: args };
|
|
318
|
+
}
|
|
186
319
|
const { [CALL_SECRETS_ARG]: raw, ...rest } = args;
|
|
187
320
|
const secrets = {};
|
|
188
321
|
for (const [key, value] of Object.entries(asRecord(raw))) {
|
|
189
322
|
const text = asString(value);
|
|
190
|
-
if (text !== undefined && 0 < text.length)
|
|
323
|
+
if (text !== undefined && 0 < text.length) {
|
|
191
324
|
secrets[key] = text;
|
|
325
|
+
}
|
|
192
326
|
}
|
|
193
327
|
return { secrets, rest };
|
|
194
328
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
|
|
1
2
|
import type { ToolDef } from './tool-kit.js';
|
|
2
3
|
/**
|
|
3
4
|
* There is ONE tool surface. This is not a menu.
|
|
@@ -193,3 +194,4 @@ export declare function describeToolSurface(active: ToolSurface, requested?: str
|
|
|
193
194
|
*/
|
|
194
195
|
export declare function defaultAdvertisedNames(): readonly string[];
|
|
195
196
|
export declare function filterTools(tools: ToolDef[], surface: ToolSurface): ToolDef[];
|
|
197
|
+
export declare function toolAnnotations(name: string): ToolAnnotations;
|