@reticlehq/server 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +122 -123
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +18 -2
- package/dist/command/cli/adhoc-verdict.js +70 -6
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +28 -105
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +34 -4
- package/dist/command/cli/cli-verify.js +81 -12
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +145 -333
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +15 -1
- package/dist/command/cli/cloud-login.js +67 -13
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.js +1 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +29 -8
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -178
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +14 -0
- package/dist/command/cli.js +103 -83
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +9 -1
- package/dist/command/daemon/daemon-resolve.js +49 -10
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +10 -1
- package/dist/command/setup/init/init-port.js +22 -2
- package/dist/command/setup/init/init-runtime.d.ts +12 -2
- package/dist/command/setup/init/init-runtime.js +96 -37
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +36 -8
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +1 -1
- package/dist/command/setup/run-setup.d.ts +29 -9
- package/dist/command/setup/run-setup.js +34 -28
- package/dist/command/setup/setup-command.d.ts +23 -0
- package/dist/command/setup/setup-command.js +57 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +38 -2
- package/dist/features/crawl/crawl.js +14 -1
- package/dist/features/exhaust/ledger.d.ts +14 -14
- package/dist/features/harness/drive-report.d.ts +39 -5
- package/dist/features/harness/drive-report.js +271 -54
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/goals.d.ts +68 -7
- package/dist/features/harness/goals.js +289 -36
- package/dist/features/harness/harness.d.ts +30 -1
- package/dist/features/harness/harness.js +141 -7
- package/dist/features/harness/platform/local-apps.d.ts +36 -3
- package/dist/features/harness/platform/local-apps.js +81 -5
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +8 -2
- package/dist/features/harness/platform/remote-drive.js +22 -9
- package/dist/features/harness/platform/script.d.ts +57 -11
- package/dist/features/harness/platform/script.js +144 -12
- package/dist/features/harness/platform/server-driver.d.ts +17 -4
- package/dist/features/harness/platform/server-driver.js +29 -26
- package/dist/features/harness/platform-config.d.ts +38 -5
- package/dist/features/harness/platform-config.js +93 -8
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/script-run.d.ts +30 -1
- package/dist/features/harness/script/script-run.js +355 -48
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.js +22 -14
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +21 -2
- package/dist/hooks/driven-by.js +42 -2
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -183
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
- package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
- package/dist/judgement/runs/artifact/run-store.js +175 -8
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +53 -5
- package/dist/judgement/runs/drive-run.js +234 -20
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +5 -2
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +2 -0
- package/dist/judgement/runs/verification-sync.js +36 -15
- package/dist/language/flows/decision.js +2 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +7 -2
- package/dist/language/flows/flow-anchor.js +10 -3
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +37 -3
- package/dist/language/flows/flow-replay-run.js +16 -18
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +18 -1
- package/dist/language/flows/flow-replay.js +22 -7
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-step-runners.d.ts +2 -0
- package/dist/language/flows/flow-step-runners.js +12 -6
- package/dist/language/flows/flow-store-for-session.js +5 -1
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +61 -62
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +69 -10
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
- package/dist/language/flows/recording/tape/recordings.js +60 -10
- package/dist/language/flows/replay.js +29 -6
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +200 -193
- package/dist/memory/cloud/cloud-config.d.ts +10 -1
- package/dist/memory/cloud/cloud-config.js +19 -5
- package/dist/memory/cloud/cloud-sync.js +3 -3
- package/dist/memory/cloud/harness-config.d.ts +49 -0
- package/dist/memory/cloud/harness-config.js +16 -20
- package/dist/memory/cloud/memory-scope.d.ts +17 -0
- package/dist/memory/cloud/memory-scope.js +22 -0
- package/dist/memory/cloud/sync-cycle.d.ts +32 -4
- package/dist/memory/cloud/sync-cycle.js +113 -12
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +114 -4
- package/dist/memory/cloud/sync-disk.js +26 -2
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +16 -1
- package/dist/memory/impact/account-watch.js +26 -1
- package/dist/memory/impact/impact-store.d.ts +1 -4
- package/dist/memory/impact/impact-store.js +32 -42
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +12 -0
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +42 -2
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/journal-recorder.js +46 -3
- package/dist/memory/journal/on-disk/retention.d.ts +5 -0
- package/dist/memory/journal/on-disk/retention.js +27 -2
- package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +38 -7
- package/dist/memory/project/artifact-root-resolver.js +33 -5
- package/dist/memory/project/artifact-root.d.ts +4 -3
- package/dist/memory/project/artifact-root.js +2 -2
- package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
- package/dist/memory/project/dir/reticle-dir.js +23 -2
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +2 -0
- package/dist/memory/project/session-root.js +9 -1
- package/dist/memory/project/sync-status.d.ts +46 -0
- package/dist/memory/project/sync-status.js +135 -1
- package/dist/memory/recall/memory-tools.js +46 -3
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.js +36 -8
- package/dist/portal/bridge/bridge.d.ts +9 -5
- package/dist/portal/bridge/bridge.js +66 -23
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +2 -0
- package/dist/portal/input/real-input.js +13 -10
- package/dist/portal/pool/browser-pool.d.ts +48 -0
- package/dist/portal/pool/browser-pool.js +120 -2
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +27 -5
- package/dist/portal/pool/playwright-launcher.js +59 -14
- package/dist/portal/pool/pool-contract.d.ts +21 -1
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.js +6 -1
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
- package/dist/portal/session/dev-server/dev-command.js +27 -1
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/live-control-tools.js +82 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
- package/dist/portal/session/no-session-diagnosis.js +31 -9
- package/dist/portal/session/no-session-next-action.d.ts +20 -0
- package/dist/portal/session/no-session-next-action.js +134 -61
- package/dist/portal/session/no-session-watch.js +179 -22
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/session-health.d.ts +11 -0
- package/dist/portal/session/session-health.js +3 -1
- package/dist/portal/session/session-info.js +2 -1
- package/dist/portal/session/session-manager.d.ts +18 -0
- package/dist/portal/session/session-manager.js +54 -3
- package/dist/portal/session/session-successor.d.ts +8 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session.d.ts +15 -28
- package/dist/portal/session/session.js +60 -61
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +7 -1
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +13 -1
- package/dist/status-payload.js +13 -1
- package/dist/surface/http-server.js +7 -1
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
- package/dist/surface/mcp/mcp-proxy.js +29 -8
- package/dist/surface/mcp/mcp.d.ts +23 -0
- package/dist/surface/mcp/mcp.js +34 -4
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.js +22 -14
- package/dist/surface/mcp/shared-params.js +1 -1
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act-sequence-tool.js +136 -27
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +48 -34
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.js +25 -15
- package/dist/surface/tools/browser-tools.js +43 -1
- package/dist/surface/tools/chat-drives.d.ts +75 -0
- package/dist/surface/tools/chat-drives.js +265 -21
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +10 -0
- package/dist/surface/tools/empty-session-list.js +45 -5
- package/dist/surface/tools/error-recovery.d.ts +8 -0
- package/dist/surface/tools/error-recovery.js +69 -5
- package/dist/surface/tools/explore-tools.d.ts +23 -2
- package/dist/surface/tools/explore-tools.js +377 -74
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +4 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +52 -73
- package/dist/surface/tools/harness-explore.js +177 -146
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +5 -0
- package/dist/surface/tools/harness-plan.js +7 -0
- package/dist/surface/tools/harness-script.d.ts +22 -0
- package/dist/surface/tools/harness-script.js +256 -38
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +8 -0
- package/dist/surface/tools/harness-toolset.js +27 -4
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +220 -93
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +20 -0
- package/dist/surface/tools/lease-seed.js +45 -1
- package/dist/surface/tools/lease-tools.d.ts +10 -1
- package/dist/surface/tools/lease-tools.js +119 -69
- package/dist/surface/tools/live-call-text.js +2 -2
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +11 -1
- package/dist/surface/tools/next-step.js +73 -18
- package/dist/surface/tools/observe-tools.js +43 -5
- package/dist/surface/tools/platform-moment.d.ts +60 -0
- package/dist/surface/tools/platform-moment.js +132 -4
- package/dist/surface/tools/read-tools.js +65 -14
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +68 -2
- package/dist/surface/tools/tool-kit.js +73 -1
- package/dist/surface/tools/tools.js +25 -13
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +27 -6
- package/dist/telemetry/hud-metrics.js +99 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +26 -2
- package/dist/telemetry/telemetry.js +102 -21
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +12 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +16 -5
- package/docs/README.md +2 -2
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +24 -27
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +13 -12
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +8 -3
- package/docs/cli/drive.mdx +12 -12
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +32 -15
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +13 -4
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +3 -2
- package/docs/cli.mdx +110 -41
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +5 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +5 -2
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +66 -64
- package/docs/human-control.md +15 -14
- package/docs/index.mdx +15 -43
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +22 -12
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +8 -8
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +11 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +58 -29
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +22 -24
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +13 -4
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +51 -45
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +7 -5
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +6 -5
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -249
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import { takeCallSecrets, withCallSecrets } from './tool-kit.js';
|
|
1
2
|
import { healthEnvelope } from '../../portal/session/session-health.js';
|
|
2
3
|
import { logToolCall, toolLogPath } from '../../hooks/tool-log.js';
|
|
3
4
|
import { nextStep } from './next-step.js';
|
|
4
5
|
import { currentDrivenBy } from '../../hooks/driven-by.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
6
|
+
import { runAsAgent } from '../../hooks/coding-agents.js';
|
|
7
|
+
import { takeHumanNotes } from './human-notes.js';
|
|
8
|
+
import { takeDriveNotes } from '../../features/harness/drive-runs.js';
|
|
9
|
+
import { harnessDriving, msgHarnessHasTheTab } from './harness-tab-guard.js';
|
|
10
|
+
import { sessionRoot, sessionTarget } from '../../memory/project/session-root.js';
|
|
11
|
+
import { ArtifactRootReason } from '../../memory/project/artifact-root.js';
|
|
12
|
+
import { agentNudge, takePlatformMoment } from './platform-moment.js';
|
|
13
|
+
import { RESULT_FIELD, trackVerdict } from './reticle-result.js';
|
|
14
|
+
import { forTheAgent } from './agent/for-the-agent.js';
|
|
15
|
+
import { feedbackAlreadyAsked, noteFeedbackAsked } from './agent/notices.js';
|
|
16
|
+
import { SKEW_SHORT_WARNING, SKEW_VERDICT_WARNING } from '../../portal/session/session-health.js';
|
|
7
17
|
import { verifyNextBaton, SUPPRESS_VERIFY_NEXT_ENV } from './verify-next-baton.js';
|
|
8
|
-
import { TelemetryActor, TelemetryEventKind, TRANSPORT_LIMITS, fingerprintFinding, } from '@reticlehq/core';
|
|
18
|
+
import { TelemetryActor, TelemetryEventKind, THROTTLED_WARNING, TRANSPORT_LIMITS, fingerprintFinding, } from '@reticlehq/core';
|
|
9
19
|
import { getSessionMetrics } from '../../telemetry/session-metrics.js';
|
|
10
20
|
import { getTelemetry } from '../../telemetry/telemetry.js';
|
|
11
21
|
import { takeUpdateNudge } from '../../command/update/update-nudge.js';
|
|
@@ -18,21 +28,19 @@ import { buildErrorPayload, refusalReasonFor } from './error-recovery.js';
|
|
|
18
28
|
import { resultIsError } from '../mcp/faults/mcp-is-error.js';
|
|
19
29
|
import { verificationOf } from '../../telemetry/verification-of.js';
|
|
20
30
|
import { emitBugFoundHook, emitVerdictHook } from '../../hooks/hook-emit.js';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { withHarnessDrive } from '../../telemetry/harness-drive.js';
|
|
24
|
-
import { OnboardingPhase, OnboardingStepStatus } from '@reticlehq/core/telemetry';
|
|
25
|
-
import { DiscoveryInvite, asString } from '@reticlehq/core';
|
|
31
|
+
import { noteActed, noteFirstVerdict, noteOnboardingFirst, noteVerdictProduced, } from '../../telemetry/onboarding-firsts.js';
|
|
32
|
+
import { DiscoveryInvite } from '@reticlehq/core';
|
|
26
33
|
import { SESSION_ID_ARG, sessionIdFromArgs, spentRefFromArgs } from './tools-helpers.js';
|
|
27
|
-
import { EnvelopeKey } from './tool-kit.js';
|
|
34
|
+
import { EnvelopeKey, HOST_STUB_NOTE, STEP_SHOT_TOOLS } from './tool-kit.js';
|
|
28
35
|
import { ReticleTool } from '@reticlehq/core';
|
|
29
36
|
import { takeFeedbackPrompt } from './feedback-tools.js';
|
|
30
37
|
import { takeFeedbackUndelivered } from '../../telemetry/feedback-delivery.js';
|
|
31
38
|
import { noteRefsMinted, wrongTabRefusal } from '../../portal/session/facts/ref-provenance.js';
|
|
32
|
-
import { CAPTURED_TOOLS, noteCapturedCall, noteToolDispatched, } from './feature-capture.js';
|
|
33
39
|
import { span } from '../../trace.js';
|
|
40
|
+
import { takeStepShot } from '../../features/visual/step-shots.js';
|
|
34
41
|
import { defectForToolResult, deltaForToolResult, impactSnapshot, initImpact, recordImpact, } from '../../memory/impact/impact-recorder.js';
|
|
35
|
-
import { frictionOf, inviteFor } from './feedback-invite.js';
|
|
42
|
+
import { FrictionKind, frictionOf, inviteFor } from './feedback-invite.js';
|
|
43
|
+
import { VACUOUS_BECAUSE } from '@reticlehq/engine/evidence/verified.js';
|
|
36
44
|
/**
|
|
37
45
|
* The live-session tools whose result MUST carry the
|
|
38
46
|
* session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
|
|
@@ -158,17 +166,6 @@ export const SESSION_EXEMPT_TOOLS = new Set([
|
|
|
158
166
|
// when NO session exists — "nothing ever connected" is feedback we especially want.
|
|
159
167
|
ReticleTool.FEEDBACK,
|
|
160
168
|
]);
|
|
161
|
-
/**
|
|
162
|
-
* The merged action that hands the drive to a model inside the daemon.
|
|
163
|
-
*
|
|
164
|
-
* Derived from the member tool's own name rather than spelled again: the merge dispatches on
|
|
165
|
-
* `action`, and `reticle_verify` plus `explore` IS `reticle_verify_explore`. A literal here would be
|
|
166
|
-
* a third spelling of one name, and the one that silently stops matching when the action is renamed.
|
|
167
|
-
*/
|
|
168
|
-
const HARNESS_DRIVE_ACTION = ReticleTool.VERIFY_EXPLORE.slice(`${ReticleTool.VERIFY}_`.length);
|
|
169
|
-
function isHarnessDrive(toolName, args) {
|
|
170
|
-
return ReticleTool.VERIFY === toolName && HARNESS_DRIVE_ACTION === args['action'];
|
|
171
|
-
}
|
|
172
169
|
function isPlainObject(value) {
|
|
173
170
|
return 'object' === typeof value && value !== null && !Array.isArray(value);
|
|
174
171
|
}
|
|
@@ -183,7 +180,7 @@ function isPlainObject(value) {
|
|
|
183
180
|
* The RULE itself lives in verification-of.ts, because getting it wrong fails silently.
|
|
184
181
|
*/
|
|
185
182
|
function recordVerification(toolName, result, durationMs, brand, sessionId) {
|
|
186
|
-
const verification = verificationOf(toolName, result, durationMs, brand);
|
|
183
|
+
const verification = verificationOf(toolName, result, durationMs, brand, currentDrivenBy() !== undefined);
|
|
187
184
|
if (verification === undefined)
|
|
188
185
|
return;
|
|
189
186
|
getSessionMetrics().recordVerification();
|
|
@@ -202,12 +199,8 @@ function recordVerification(toolName, result, durationMs, brand, sessionId) {
|
|
|
202
199
|
emitVerdictHook(toolName, result, verification.verified, sessionId);
|
|
203
200
|
// The ONBOARD half of the same moment: the first verdict of this run, once.
|
|
204
201
|
noteFirstVerdict();
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
step: 'verdict_produced',
|
|
208
|
-
status: OnboardingStepStatus.COMPLETED,
|
|
209
|
-
elapsedMs: Math.max(0, Math.round(durationMs)),
|
|
210
|
-
});
|
|
202
|
+
// The FIRST_RUN rung: once per machine + project, not once per verdict.
|
|
203
|
+
noteVerdictProduced(durationMs);
|
|
211
204
|
}
|
|
212
205
|
/**
|
|
213
206
|
* Emit one `bug_found` per defect in a tool result, and count it into the session.
|
|
@@ -231,9 +224,15 @@ function reportBugsFound(toolName, result, sessionId) {
|
|
|
231
224
|
? { kind: bug.kind, source: bug.source, route }
|
|
232
225
|
: { kind: bug.kind, source: bug.source };
|
|
233
226
|
const fingerprint = fingerprintFinding(identity);
|
|
227
|
+
const occurrence = metrics.recordBugOccurrence(fingerprint);
|
|
234
228
|
void getTelemetry().emit(TelemetryEventKind.BUG_FOUND, {
|
|
235
229
|
actor: TelemetryActor.AGENT,
|
|
236
|
-
bug: {
|
|
230
|
+
bug: {
|
|
231
|
+
...bug,
|
|
232
|
+
repeat: !first,
|
|
233
|
+
fingerprint,
|
|
234
|
+
...(occurrence === undefined ? {} : { occurrence }),
|
|
235
|
+
},
|
|
237
236
|
});
|
|
238
237
|
// The same defect, said out loud to whoever is building on Reticle. Inside the loop rather than
|
|
239
238
|
// after it because the event is PER DEFECT — one event carrying a list would make a consumer
|
|
@@ -278,7 +277,9 @@ function frictionInviteFor(toolName, raw) {
|
|
|
278
277
|
return undefined;
|
|
279
278
|
const friction = frictionOf({
|
|
280
279
|
unknownTool: false,
|
|
281
|
-
|
|
280
|
+
// A vacuous unknown is the caller's: it asserted nothing real (a bare `settled` wait, which the
|
|
281
|
+
// instructions recommend). Inviting a bug report there told agents Reticle had failed them.
|
|
282
|
+
verifiedUnknown: 'unknown' === raw['verified'] && VACUOUS_BECAUSE !== raw['because'],
|
|
282
283
|
repeatRun: getSessionMetrics().currentRun,
|
|
283
284
|
errored: resultIsError(raw),
|
|
284
285
|
// A verdict is progress. Without this, three successful act_and_wait calls in a row — the exact
|
|
@@ -344,13 +345,52 @@ function pinnedArgs(args, explicitSessionId, session) {
|
|
|
344
345
|
return args;
|
|
345
346
|
return { ...args, [SESSION_ID_ARG]: session.id };
|
|
346
347
|
}
|
|
347
|
-
export async function runTool(tool, deps,
|
|
348
|
+
export async function runTool(tool, deps, given, call) {
|
|
349
|
+
// A replay's secrets leave the arguments here, before the tool log, the journal or telemetry can
|
|
350
|
+
// see them, and are supplied to this call alone.
|
|
351
|
+
const { secrets, rest: args } = takeCallSecrets(given);
|
|
352
|
+
// A verdict still being decided is waited for by a session end (`trackVerdict`); the result is
|
|
353
|
+
// compacted for the agent last, after telemetry and the tool log have read the full result.
|
|
354
|
+
return trackVerdict(tool.name, withCallSecrets(secrets, async () => {
|
|
355
|
+
const result = await loggedTool(tool, deps, args, call);
|
|
356
|
+
const attach = currentDrivenBy() === undefined ? deps.attachId : undefined;
|
|
357
|
+
const root = attach === undefined
|
|
358
|
+
? undefined
|
|
359
|
+
: safeRoot(() => sessionRoot(deps, sessionIdFromArgs(args)));
|
|
360
|
+
return forTheAgent({ name: tool.name, args, result, attach, root, fold: NOTICE_FOLD });
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
363
|
+
/** Advisories that become once-per-session notice lines. See agent/notices.ts. */
|
|
364
|
+
export const NOTICE_FOLD = {
|
|
365
|
+
advisories: [
|
|
366
|
+
EnvelopeKey.FEEDBACK_PROMPT,
|
|
367
|
+
EnvelopeKey.FEEDBACK_INVITE,
|
|
368
|
+
EnvelopeKey.TALK_TO_US,
|
|
369
|
+
EnvelopeKey.UPDATE_AVAILABLE,
|
|
370
|
+
// NOT `version_skew`: it is decisive — it explains every result after it and names the command to
|
|
371
|
+
// run — so it rides out as its own key, untouched (one-shot at its source already).
|
|
372
|
+
EnvelopeKey.PLATFORM,
|
|
373
|
+
EnvelopeKey.SESSION_LEASE,
|
|
374
|
+
EnvelopeKey.SESSION_AGE_WARNING,
|
|
375
|
+
EnvelopeKey.FEEDBACK_UNDELIVERED,
|
|
376
|
+
EnvelopeKey.ZERO_INSTALL,
|
|
377
|
+
],
|
|
378
|
+
notices: EnvelopeKey.NOTICES,
|
|
379
|
+
next: EnvelopeKey.NEXT,
|
|
380
|
+
warning: EnvelopeKey.WARNING,
|
|
381
|
+
onceWarnings: new Map([
|
|
382
|
+
// `session.throttled` still rides on every result: only the paragraph explaining it goes.
|
|
383
|
+
[THROTTLED_WARNING, undefined],
|
|
384
|
+
[SKEW_VERDICT_WARNING, SKEW_SHORT_WARNING],
|
|
385
|
+
]),
|
|
386
|
+
};
|
|
387
|
+
async function loggedTool(tool, deps, args, call) {
|
|
348
388
|
const logPath = toolLogPath();
|
|
349
389
|
if (logPath === undefined)
|
|
350
|
-
return dispatchTool(tool, deps, args);
|
|
390
|
+
return dispatchTool(tool, deps, args, call);
|
|
351
391
|
const at = deps.now();
|
|
352
392
|
try {
|
|
353
|
-
const result = await dispatchTool(tool, deps, args);
|
|
393
|
+
const result = await dispatchTool(tool, deps, args, call);
|
|
354
394
|
logToolCall(logPath, { tool: tool.name, args, at, ms: deps.now() - at, result });
|
|
355
395
|
return result;
|
|
356
396
|
}
|
|
@@ -360,7 +400,7 @@ export async function runTool(tool, deps, args) {
|
|
|
360
400
|
throw error;
|
|
361
401
|
}
|
|
362
402
|
}
|
|
363
|
-
async function dispatchTool(tool, deps, args) {
|
|
403
|
+
async function dispatchTool(tool, deps, args, call) {
|
|
364
404
|
// Both dispatch paths (MCP + programmatic) pass through here — the one place "which tool is mostly
|
|
365
405
|
// used" can be counted. This used to EMIT an event per call; it now increments an in-process counter
|
|
366
406
|
// that leaves once, with the session summary. A verification loop is 50–200 calls, and PostHog bills
|
|
@@ -399,6 +439,14 @@ async function dispatchTool(tool, deps, args) {
|
|
|
399
439
|
reportRefusal(tool.name, error);
|
|
400
440
|
return { error };
|
|
401
441
|
}
|
|
442
|
+
// One driver per tab. The Harness clicking through a page while the agent clicks too is two hands
|
|
443
|
+
// on one mouse: neither result means anything. The agent's own action waits; its reads still run.
|
|
444
|
+
const busy = ACTION_TOOLS.has(tool.name) ? harnessDriving(deps, args) : undefined;
|
|
445
|
+
if (busy !== undefined) {
|
|
446
|
+
const error = msgHarnessHasTheTab(busy);
|
|
447
|
+
reportRefusal(tool.name, error);
|
|
448
|
+
return { error };
|
|
449
|
+
}
|
|
402
450
|
// An ACTION is what gets abandoned. Counted here, against verifications, so "the agent drove the
|
|
403
451
|
// page and then wandered off" becomes a number instead of an impression.
|
|
404
452
|
if (ACTION_TOOLS.has(tool.name)) {
|
|
@@ -423,6 +471,24 @@ async function dispatchTool(tool, deps, args) {
|
|
|
423
471
|
session = undefined;
|
|
424
472
|
}
|
|
425
473
|
}
|
|
474
|
+
// Nothing connected, and the app was never wired: a call that needs a page opens it zero-install
|
|
475
|
+
// rather than answering with a diagnosis the agent stops at. See zero-install-first-call.ts.
|
|
476
|
+
const openUnwired = deps.openUnwiredApp;
|
|
477
|
+
const opened = openUnwired !== undefined &&
|
|
478
|
+
session === undefined &&
|
|
479
|
+
bound &&
|
|
480
|
+
rawSessionId === undefined &&
|
|
481
|
+
0 === deps.sessions.list().length
|
|
482
|
+
? await openUnwired()
|
|
483
|
+
: undefined;
|
|
484
|
+
if (opened !== undefined) {
|
|
485
|
+
try {
|
|
486
|
+
session = deps.sessions.resolve(rawSessionId);
|
|
487
|
+
}
|
|
488
|
+
catch {
|
|
489
|
+
session = undefined;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
426
492
|
// CDP tools against a skewed session: refuse with the sentence reticle_sessions already knows,
|
|
427
493
|
// before Playwright invents a closed page. ready:true leases still hit this path.
|
|
428
494
|
if (session?.versionSkew !== undefined && CDP_TOOLS.has(tool.name)) {
|
|
@@ -430,43 +496,6 @@ async function dispatchTool(tool, deps, args) {
|
|
|
430
496
|
reportRefusal(tool.name, message);
|
|
431
497
|
throw new Error(message);
|
|
432
498
|
}
|
|
433
|
-
// The read-only calls the journal never keeps, recorded HERE because this is the one dispatch
|
|
434
|
-
// point every call routes through — a second recording site is a second thing to forget, and this
|
|
435
|
-
// instrument exists precisely because nothing was recorded before. Recorded before the handler
|
|
436
|
-
// runs: a read dispatches no action, so the counter reads the same either side.
|
|
437
|
-
//
|
|
438
|
-
// `reticle_context` is session-EXEMPT, so `session` above is undefined for it and it needs its own
|
|
439
|
-
// lenient resolve. Failing that resolve is silent by design: a call made with nothing connected
|
|
440
|
-
// has no per-session ledger to land in, and an instrument must never be why a tool call fails.
|
|
441
|
-
//
|
|
442
|
-
// EVERY tool is counted here, not just the read set: which of the 70-odd names in the table an
|
|
443
|
-
// agent actually reaches for is the question a decision about cutting or consolidating the surface
|
|
444
|
-
// turns on, and it had no answer. `reticle_run` is the one exclusion, for the same reason
|
|
445
|
-
// `reportRefusal` and `bugsInResult` exclude it — its handler calls `runTool` on the real tool, so
|
|
446
|
-
// the inner call is already counted under the name that RAN, and counting the wrapper too would
|
|
447
|
-
// both double the total and hide the run-only tier behind a single wrapper name. That tier is
|
|
448
|
-
// precisely the one the decision hinges on. See surface/tools/tool-hit-rate.ts.
|
|
449
|
-
if (ReticleTool.RUN !== tool.name) {
|
|
450
|
-
let target = session;
|
|
451
|
-
if (target === undefined) {
|
|
452
|
-
try {
|
|
453
|
-
target = deps.sessions.resolve(rawSessionId);
|
|
454
|
-
}
|
|
455
|
-
catch {
|
|
456
|
-
target = undefined;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
if (target !== undefined) {
|
|
460
|
-
noteToolDispatched(target, tool.name);
|
|
461
|
-
if (CAPTURED_TOOLS.has(tool.name)) {
|
|
462
|
-
const subject = asString(args['ref']) ?? asString(args['target']);
|
|
463
|
-
noteCapturedCall(target, {
|
|
464
|
-
tool: tool.name,
|
|
465
|
-
...(subject === undefined ? {} : { subject }),
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
499
|
// A ref that was handed out by a DIFFERENT tab, on a call that named no session. Refused here, at
|
|
471
500
|
// the one point that knows both the ref and the tab resolution picked — the handler only learns
|
|
472
501
|
// that the ref missed, and answers that with "the DOM re-rendered", which is a confident diagnosis
|
|
@@ -500,16 +529,11 @@ async function dispatchTool(tool, deps, args) {
|
|
|
500
529
|
// `dispatchArgs`, not `args`: an inferred session is pinned into the arguments before the
|
|
501
530
|
// handler sees them, so a tool that resolves the session a second time cannot land on a
|
|
502
531
|
// different one than the dispatcher chose.
|
|
503
|
-
const
|
|
504
|
-
//
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
|
|
508
|
-
// it drives and records, it adjudicates nothing, and its result carries no verified/pass field
|
|
509
|
-
// to read. Deriving one from how far the drive got would be inventing a verdict nobody reached.
|
|
510
|
-
// What was missing was never an event here — it was that a session driven BY US read exactly
|
|
511
|
-
// like one the agent earned, which is what the span fixes.
|
|
512
|
-
raw = await (isHarnessDrive(tool.name, args) ? withHarnessDrive(call) : call());
|
|
532
|
+
const invokeHandler = () => span('tool.handler', { tool: tool.name, session: session?.id }, () => tool.handler(deps, dispatchArgs, call));
|
|
533
|
+
// The Harness's own inner calls carry their drive in an async context (`runDrivenBy`), which is
|
|
534
|
+
// what attributes their verdicts; the outer explore call adjudicates nothing of its own.
|
|
535
|
+
// As the agent on this connection, so a note it reads is marked seen by that agent.
|
|
536
|
+
raw = await runAsAgent(deps.attachId, invokeHandler);
|
|
513
537
|
}
|
|
514
538
|
catch (error) {
|
|
515
539
|
// The commonest refusal shape by far, and the one nothing could see: the message is built, handed
|
|
@@ -547,6 +571,7 @@ async function dispatchTool(tool, deps, args) {
|
|
|
547
571
|
// concurrency slot and peakConcurrentTools would climb forever on an unhealthy session.
|
|
548
572
|
settleTiming(Date.now() - startedAt);
|
|
549
573
|
}
|
|
574
|
+
raw = await withStepShot(tool.name, deps, args, raw, session?.id ?? rawSessionId);
|
|
550
575
|
// Milestones describe work that ran. Refusals and paused calls must not consume the firsts.
|
|
551
576
|
// Record action before verdict: act_and_wait can complete both in this same call.
|
|
552
577
|
if (isPlainObject(raw) && !resultIsError(raw) && raw['paused'] !== true && raw['ok'] !== false) {
|
|
@@ -600,7 +625,10 @@ async function dispatchTool(tool, deps, args) {
|
|
|
600
625
|
if (session !== undefined && REF_MINTING_TOOLS.has(tool.name))
|
|
601
626
|
noteRefsMinted(session.id);
|
|
602
627
|
}
|
|
603
|
-
|
|
628
|
+
// The feedback family is asked at most once per agent session (agent/notices.ts): gated here, at
|
|
629
|
+
// the take, so a suppressed ask is never counted as one that was made.
|
|
630
|
+
const asked = feedbackAlreadyAsked(currentDrivenBy() === undefined ? deps.attachId : undefined);
|
|
631
|
+
const prompt = isPlainObject(raw) && !asked ? takeFeedbackPrompt(tool.name) : undefined;
|
|
604
632
|
// Same one-shot channel as the feedback ask: the agent is mid-task, so anything it would have to go
|
|
605
633
|
// and ASK for is something it will never ask for. Spliced on ANY tool result, not just a
|
|
606
634
|
// verification, because an out-of-date install is worth mentioning whatever the agent is doing.
|
|
@@ -625,9 +653,12 @@ async function dispatchTool(tool, deps, args) {
|
|
|
625
653
|
// `refused` friction the line is written for. `errored` could only ever see the handlers that
|
|
626
654
|
// RETURN an error. So the denominator was counting a small, unrepresentative slice of the
|
|
627
655
|
// invitations and reading near-empty, which looks identical to a nudge that never fires.
|
|
628
|
-
const friction = frictionInviteFor(tool.name, raw);
|
|
629
|
-
|
|
630
|
-
|
|
656
|
+
const friction = asked || prompt !== undefined ? undefined : frictionInviteFor(tool.name, raw);
|
|
657
|
+
if (prompt !== undefined || friction !== undefined)
|
|
658
|
+
noteFeedbackAsked(currentDrivenBy() === undefined ? deps.attachId : undefined);
|
|
659
|
+
// Once per project, on a proved verdict, when the runs live only on this machine. Not on a result
|
|
660
|
+
// whose `reticleResult` already ends with the platform line: once per result, never twice.
|
|
661
|
+
const platform = isPlainObject(raw) && !(RESULT_FIELD in raw)
|
|
631
662
|
? await takePlatformMoment(deps, raw, () => sessionRoot(deps, rawSessionId))
|
|
632
663
|
: undefined;
|
|
633
664
|
// What the agent should do next, on every client that reads results. Not for the Harness, whose
|
|
@@ -636,18 +667,48 @@ async function dispatchTool(tool, deps, args) {
|
|
|
636
667
|
const next = isPlainObject(raw) && ReticleTool.RUN !== tool.name && currentDrivenBy() === undefined
|
|
637
668
|
? nextStep({
|
|
638
669
|
tool: tool.name,
|
|
670
|
+
unmatched: unmatchedRootOf(deps, rawSessionId),
|
|
639
671
|
verdict: 'verified' in raw,
|
|
640
672
|
root: safeRoot(() => sessionRoot(deps, rawSessionId)),
|
|
641
673
|
// A partial deps (tests, the demo) may carry no clock; the line is advice, never a reason to fail.
|
|
642
674
|
now: 'function' === typeof deps.now ? deps.now() : Date.now(),
|
|
643
675
|
})
|
|
644
676
|
: undefined;
|
|
645
|
-
|
|
677
|
+
// Only an agent's own call (an MCP connection, not the Harness, not the HUD's or the chat's calls
|
|
678
|
+
// into the same tools) takes what is waiting for the agent: those calls answer nobody who reads.
|
|
679
|
+
const answer = isPlainObject(raw) ? raw : undefined;
|
|
680
|
+
const agentCall = answer !== undefined && deps.attachId !== undefined && currentDrivenBy() === undefined;
|
|
681
|
+
// A Harness drive started or finished, from the HUD, the platform's chat or this agent: one line,
|
|
682
|
+
// once. Not about the run this very result already reports.
|
|
683
|
+
// One-time advisories toward the platform and the Harness (`platform-moment.ts`), only on the agent's
|
|
684
|
+
// own calls, riding the same platform line as the moments above.
|
|
685
|
+
const nudge = agentCall && answer !== undefined
|
|
686
|
+
? await agentNudge({
|
|
687
|
+
deps,
|
|
688
|
+
tool: tool.name,
|
|
689
|
+
raw: answer,
|
|
690
|
+
isError: resultIsError(answer),
|
|
691
|
+
tab: session,
|
|
692
|
+
root: safeRoot(() => sessionRoot(deps, rawSessionId)),
|
|
693
|
+
harnessOn: () => impactSnapshot(artifactRoot)?.harnessConfig?.harnessEnabled,
|
|
694
|
+
})
|
|
695
|
+
: undefined;
|
|
696
|
+
const platformLine = platform === undefined ? nudge : nudge === undefined ? platform : `${platform}\n${nudge}`;
|
|
697
|
+
const drives = agentCall
|
|
698
|
+
? takeDriveNotes('string' === typeof answer?.['runId'] ? answer['runId'] : undefined)
|
|
699
|
+
: [];
|
|
700
|
+
// The person's notes from the HUD, on ANY tool. Act tools splice their own `control` first.
|
|
701
|
+
const notes = agentCall && answer !== undefined && !(EnvelopeKey.CONTROL in answer)
|
|
702
|
+
? await runAsAgent(deps.attachId, () => Promise.resolve(takeHumanNotes(deps.sessions, rawSessionId, session)))
|
|
703
|
+
: undefined;
|
|
704
|
+
const result = 0 === drives.length &&
|
|
705
|
+
notes === undefined &&
|
|
706
|
+
prompt === undefined &&
|
|
646
707
|
update === undefined &&
|
|
647
708
|
skew === undefined &&
|
|
648
709
|
undelivered === undefined &&
|
|
649
710
|
friction === undefined &&
|
|
650
|
-
|
|
711
|
+
platformLine === undefined &&
|
|
651
712
|
next === undefined
|
|
652
713
|
? raw
|
|
653
714
|
: {
|
|
@@ -657,14 +718,20 @@ async function dispatchTool(tool, deps, args) {
|
|
|
657
718
|
...(friction !== undefined
|
|
658
719
|
? {
|
|
659
720
|
[EnvelopeKey.FEEDBACK_INVITE]: inviteFor(friction),
|
|
660
|
-
// The
|
|
661
|
-
|
|
721
|
+
// The founder's calendar only for an agent genuinely STUCK (the same call, again,
|
|
722
|
+
// with no progress). An ordinary refusal carried it too, and read as a sales pitch
|
|
723
|
+
// stapled to an error message.
|
|
724
|
+
...(FrictionKind.REPEATING === friction
|
|
725
|
+
? { [EnvelopeKey.TALK_TO_US]: DiscoveryInvite.AGENT }
|
|
726
|
+
: {}),
|
|
662
727
|
}
|
|
663
728
|
: {}),
|
|
664
729
|
...(prompt !== undefined ? { [EnvelopeKey.FEEDBACK_PROMPT]: prompt } : {}),
|
|
665
730
|
...(update !== undefined ? { [EnvelopeKey.UPDATE_AVAILABLE]: update } : {}),
|
|
666
731
|
...(skew !== undefined ? { [EnvelopeKey.VERSION_SKEW]: skew } : {}),
|
|
667
|
-
...(
|
|
732
|
+
...(platformLine !== undefined ? { [EnvelopeKey.PLATFORM]: platformLine } : {}),
|
|
733
|
+
...(0 === drives.length ? {} : { [EnvelopeKey.HARNESS]: drives.join('\n') }),
|
|
734
|
+
...(notes === undefined ? {} : { [EnvelopeKey.CONTROL]: notes }),
|
|
668
735
|
...(undelivered !== undefined
|
|
669
736
|
? {
|
|
670
737
|
[EnvelopeKey.FEEDBACK_UNDELIVERED]: `your earlier report did NOT send: ${undelivered}. Tell the human what you found so it is not lost.`,
|
|
@@ -675,7 +742,15 @@ async function dispatchTool(tool, deps, args) {
|
|
|
675
742
|
return result;
|
|
676
743
|
// Reuse the session resolved above so the health envelope describes the SAME session the handler
|
|
677
744
|
// drove; only re-resolve if the up-front attempt failed but the handler somehow succeeded.
|
|
678
|
-
|
|
745
|
+
// A handler that answered with no tab to resolve (a Harness drive polled by runId after a daemon
|
|
746
|
+
// restart reads its record from disk) keeps its answer: there is no session health to describe.
|
|
747
|
+
let driven = session;
|
|
748
|
+
try {
|
|
749
|
+
driven ??= deps.sessions.resolve(rawSessionId);
|
|
750
|
+
}
|
|
751
|
+
catch {
|
|
752
|
+
return result;
|
|
753
|
+
}
|
|
679
754
|
// ...unless the call replaced that document. A full navigation or reload registers a NEW Session
|
|
680
755
|
// under the same id (or under the id the result reports it arrived at), and the object resolved
|
|
681
756
|
// before the call is the page that unloaded: it reported itself hidden on the way out, so every
|
|
@@ -684,6 +759,14 @@ async function dispatchTool(tool, deps, args) {
|
|
|
684
759
|
const arrivedId = 'string' === typeof result['sessionId'] ? result['sessionId'] : driven.id;
|
|
685
760
|
const resolved = deps.sessions.get?.(arrivedId) ?? driven;
|
|
686
761
|
const envelope = {};
|
|
762
|
+
// A leased tab opened with `initScript` runs a STUB of the bindings a desktop shell injects. Said
|
|
763
|
+
// on every session-bound result, not only on verdicts, for the same reason health is: a green from
|
|
764
|
+
// that tab proves the app's view logic, and nothing else in the result would say so.
|
|
765
|
+
// Optional-called: a partial pool in a test double has no lookup, and absence must read as "no
|
|
766
|
+
// stub", never as a crash on the whole tool surface.
|
|
767
|
+
if (true === deps.pool?.stubInstalled?.(resolved.id)) {
|
|
768
|
+
envelope[EnvelopeKey.HOST_STUB] = HOST_STUB_NOTE;
|
|
769
|
+
}
|
|
687
770
|
// The health block is idempotent: add it only when the handler didn't already include a `session`.
|
|
688
771
|
if (!('session' in result))
|
|
689
772
|
Object.assign(envelope, healthEnvelope(resolved));
|
|
@@ -692,8 +775,13 @@ async function dispatchTool(tool, deps, args) {
|
|
|
692
775
|
// does) — so a long-running backgrounded session, the case most likely to leak, never got the
|
|
693
776
|
// one-time pool-lease reminder or the age cleanup nudge. Splice them regardless.
|
|
694
777
|
const lease = resolved.takeSessionLease();
|
|
695
|
-
|
|
778
|
+
// In CI there is no panel and no human to hand it back to: the reminder was noise in every
|
|
779
|
+
// pipeline log. Still taken, so the once-per-session cadence is unchanged.
|
|
780
|
+
if (lease !== undefined && process.env['CI'] === undefined) {
|
|
696
781
|
envelope[EnvelopeKey.SESSION_LEASE] = lease;
|
|
782
|
+
}
|
|
783
|
+
if (opened !== undefined)
|
|
784
|
+
envelope[EnvelopeKey.ZERO_INSTALL] = opened.notice;
|
|
697
785
|
const warning = resolved.ageWarning();
|
|
698
786
|
if (warning !== undefined)
|
|
699
787
|
envelope[EnvelopeKey.SESSION_AGE_WARNING] = warning;
|
|
@@ -725,6 +813,23 @@ async function dispatchTool(tool, deps, args) {
|
|
|
725
813
|
envelope[EnvelopeKey.VERIFY_NEXT] = verifyNextBaton(unverified, resolved.lastAct?.effect() ?? {});
|
|
726
814
|
return Object.keys(envelope).length > 0 ? { ...result, ...envelope } : result;
|
|
727
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* A picture of the page the moment this call's outcome was decided, named on the result. Only on
|
|
818
|
+
* an answer that touched the page: a refusal or a paused call drove nothing worth a picture. A
|
|
819
|
+
* navigation can land the page under a new id, so the id the result reports wins.
|
|
820
|
+
*/
|
|
821
|
+
async function withStepShot(name, deps, args, raw, sessionId) {
|
|
822
|
+
if (!STEP_SHOT_TOOLS.has(name) || Array.isArray(args['steps']))
|
|
823
|
+
return raw;
|
|
824
|
+
if (!isPlainObject(raw) || resultIsError(raw) || true === raw['paused'])
|
|
825
|
+
return raw;
|
|
826
|
+
const tab = 'string' === typeof raw['sessionId'] ? raw['sessionId'] : sessionId;
|
|
827
|
+
if (tab === undefined)
|
|
828
|
+
return raw;
|
|
829
|
+
// Paired with its check when the run is written: the n-th verdict picture is the n-th check.
|
|
830
|
+
const verdict = 'verified' in raw && (ReticleTool.ACT_AND_WAIT === name || ReticleTool.ASSERT === name);
|
|
831
|
+
return { ...raw, [EnvelopeKey.SCREENSHOT]: await takeStepShot(deps, tab, name, { verdict }) };
|
|
832
|
+
}
|
|
728
833
|
/** A root, or undefined when none can be resolved: a missing root is never a reason to throw. */
|
|
729
834
|
function safeRoot(get) {
|
|
730
835
|
try {
|
|
@@ -734,3 +839,25 @@ function safeRoot(get) {
|
|
|
734
839
|
return undefined;
|
|
735
840
|
}
|
|
736
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* Where this session's evidence goes when no project claims it (`~/.reticle/unmatched/<id>`), with
|
|
844
|
+
* the folders that compete for its id; undefined when it lands in a project. Never throws.
|
|
845
|
+
*/
|
|
846
|
+
function unmatchedRootOf(deps, sessionId) {
|
|
847
|
+
try {
|
|
848
|
+
const target = sessionTarget(deps, sessionId);
|
|
849
|
+
const resolved = deps.artifactRootFor?.(target.projectId, target.origin);
|
|
850
|
+
if (resolved === undefined || ArtifactRootReason.MATCHED_PROJECT === resolved.reason)
|
|
851
|
+
return undefined;
|
|
852
|
+
if (resolved.root === deps.reticleRoot)
|
|
853
|
+
return undefined;
|
|
854
|
+
return {
|
|
855
|
+
root: resolved.root,
|
|
856
|
+
contenders: resolved.candidates ?? [],
|
|
857
|
+
...(resolved.serving === undefined ? {} : { serving: resolved.serving }),
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
catch {
|
|
861
|
+
return undefined;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
@@ -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 { isLoopbackHostname } from '@reticlehq/core';
|
|
20
21
|
const NUXT = 'nuxt';
|
|
21
22
|
const PORT_DIFFERENTIAL = "The usual cause is a PORT MISMATCH: the app's SDK connects to the port it was BUILT with, so a " +
|
|
22
23
|
"daemon on a different port never hears from it — check the app's reticle port (`.reticle.json`, " +
|
|
@@ -36,6 +37,17 @@ const NUXT_FIRST = 'This project is Nuxt: the most likely cause by a distance is
|
|
|
36
37
|
'Reticle plugin, because Nuxt does NOT register a newly added plugin on HMR. Restart `nuxt dev` ' +
|
|
37
38
|
'and re-acquire before investigating anything else.';
|
|
38
39
|
const RELEASE = 'The tab stays leased either way — release it with reticle_lease{action:"release"}.';
|
|
40
|
+
const PRODUCTION_STUB = ' If this is a production build (`vite build`, `next build`, `next start`, or a deployed site), it strips ' +
|
|
41
|
+
'Reticle or replaces it with an inert stub by design; point the lease at the dev server instead.';
|
|
42
|
+
function isRemoteUrl(url) {
|
|
43
|
+
try {
|
|
44
|
+
const hostname = new URL(url).hostname.toLowerCase();
|
|
45
|
+
return !isLoopbackHostname(hostname);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
39
51
|
function markerClause(sdkMarker) {
|
|
40
52
|
if (sdkMarker === undefined)
|
|
41
53
|
return '';
|
|
@@ -82,8 +94,8 @@ export function leaseNotConnectedHint(url, port, evidence = {}) {
|
|
|
82
94
|
`this daemon is on ${String(port)}, so the dial never reached it. Nothing about the app's ` +
|
|
83
95
|
`wiring is in question. Either start the daemon on ${String(dialled)}, or point the app at ` +
|
|
84
96
|
`${String(port)} — the app's port comes from its build config (\`.reticle.json\`, ` +
|
|
85
|
-
`RETICLE_PORT, or the build plugin's \`port\`), and \`
|
|
86
|
-
`outright.${marker} ${RELEASE}`);
|
|
97
|
+
`RETICLE_PORT, or the build plugin's \`port\`), and \`reticle.connect({ url })\` ` +
|
|
98
|
+
`overrides it outright.${marker} ${RELEASE}`);
|
|
87
99
|
}
|
|
88
100
|
// 0b. The page's own policy forbids the connection. Read off the document it served, so it is
|
|
89
101
|
// proof about the page in hand, and it holds whether or not the app ships an SDK: neither
|
|
@@ -118,18 +130,27 @@ export function leaseNotConnectedHint(url, port, evidence = {}) {
|
|
|
118
130
|
: ' That may have been a DIFFERENT app, though: this one may carry no Reticle SDK at all, ' +
|
|
119
131
|
'in which case run `reticle init` in ITS directory first — every cause below assumes the ' +
|
|
120
132
|
'SDK is already installed.';
|
|
133
|
+
// Never beside a marker that WAS found: "it ships the SDK" and "the build stripped it" cannot
|
|
134
|
+
// both be the story.
|
|
135
|
+
const production = true !== evidence.sdkMarker && (false === evidence.sdkMarker || isRemoteUrl(url))
|
|
136
|
+
? PRODUCTION_STUB
|
|
137
|
+
: '';
|
|
121
138
|
return (`${opening} An app for this project HAS connected on this port before, so the port is ` +
|
|
122
|
-
`proven.${notThisApp}${nuxt}${marker} ${REAL_CAUSES} ${RELEASE}`);
|
|
139
|
+
`proven.${notThisApp}${nuxt}${marker}${production} ${REAL_CAUSES} ${RELEASE}`);
|
|
123
140
|
}
|
|
124
141
|
// 4. Wired, but never seen connect. Rank the real causes; keep the port differential last, where
|
|
125
142
|
// the evidence for it actually sits.
|
|
126
143
|
if (true === evidence.initialized) {
|
|
127
|
-
|
|
144
|
+
const production = false === evidence.sdkMarker ? PRODUCTION_STUB : '';
|
|
145
|
+
return `${opening}${nuxt}${marker}${production} ${REAL_CAUSES} If none of those, it may be dialling a different daemon than this one: check the app's reticle port matches ${String(port)}. ${RELEASE}`;
|
|
128
146
|
}
|
|
129
147
|
// 5. Nothing known. The differential, plus the possibility this app carries no SDK at all —
|
|
130
148
|
// except when the marker check already ruled that out, which is the whole reason for the bit.
|
|
149
|
+
// Nothing says the project was ever wired, so `reticle init` stays the advice whenever the SDK
|
|
150
|
+
// was not seen; a production build is the other way to serve a page without it.
|
|
131
151
|
const noSdk = true === evidence.sdkMarker
|
|
132
152
|
? ''
|
|
133
|
-
: ' If the app carries no Reticle SDK at all, run `reticle init` in it first.'
|
|
153
|
+
: ' If the app carries no Reticle SDK at all, run `reticle init` in it first.' +
|
|
154
|
+
(false === evidence.sdkMarker || isRemoteUrl(url) ? PRODUCTION_STUB : '');
|
|
134
155
|
return `${opening}${nuxt}${marker} ${PORT_DIFFERENTIAL}${noSdk} ${REAL_CAUSES} ${RELEASE}`;
|
|
135
156
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `permissions` argument of `reticle_lease { action: "acquire" }` (#1370).
|
|
3
|
+
*
|
|
4
|
+
* Granted before the first navigation of a fresh lease. On an origin that already has a live lease,
|
|
5
|
+
* acquire hands back THAT lease rather than opening a second tab, and it may be another agent's tab
|
|
6
|
+
* mid-flow — nothing at this layer knows whose it is. So its grants never change there: the same list
|
|
7
|
+
* is a plain reuse, a different one is refused with the way out (release, then acquire again).
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import type { BrowserPool } from '../../portal/pool/browser-pool.js';
|
|
11
|
+
export declare const LEASE_PERMISSIONS_ARG: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
12
|
+
type PermissionPool = Pick<BrowserPool, 'notificationPermission'>;
|
|
13
|
+
/** The validated list, undefined when the caller passed none, or a refusal naming the right shape. */
|
|
14
|
+
export declare function parseLeasePermissions(raw: unknown): readonly string[] | undefined;
|
|
15
|
+
/** A permission failure, reworded for the agent; undefined for every other error. */
|
|
16
|
+
export declare function permissionRefusal(err: unknown): Error | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* What to tell the agent when the page cannot see a notifications grant, else undefined.
|
|
19
|
+
*
|
|
20
|
+
* Undefined too when the page could not be asked: the grant was made, and a reading nobody took is
|
|
21
|
+
* not evidence that it failed.
|
|
22
|
+
*/
|
|
23
|
+
export declare function notificationReadBack(pool: PermissionPool, sessionId: string, permissions: readonly string[] | undefined): Promise<string | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Refuse to reuse a held lease under a different set of grants. Nothing to refuse when the caller
|
|
26
|
+
* named no list, or the same one in any order.
|
|
27
|
+
*/
|
|
28
|
+
export declare function refuseRegrant(pool: Pick<BrowserPool, 'permissionsOf'>, sessionId: string, permissions: readonly string[] | undefined): void;
|
|
29
|
+
/** `{ hint }` joining whichever parts are present, or nothing at all. */
|
|
30
|
+
export declare function hintOf(...parts: (string | undefined)[]): {
|
|
31
|
+
hint?: string;
|
|
32
|
+
};
|
|
33
|
+
export {};
|