@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
|
@@ -12,9 +12,13 @@
|
|
|
12
12
|
* question the fetch counters exist to answer and could not while nothing was reading.
|
|
13
13
|
*/
|
|
14
14
|
import { cloudFetch } from '../cloud/cloud-sync.js';
|
|
15
|
+
import { callingClientName } from '../../hooks/coding-agents.js';
|
|
15
16
|
import { resolveProjectCloud } from '../cloud/cloud-config.js';
|
|
16
|
-
import { isReadableMemoryScope, memoryReadUrl, scopedMemoryEntries, scopeOfMemoryResponse, } from '../cloud/memory-scope.js';
|
|
17
|
-
/**
|
|
17
|
+
import { isReadableMemoryScope, MemoryReadHeader, memoryReadUrl, scopedMemoryEntries, scopeOfMemoryResponse, } from '../cloud/memory-scope.js';
|
|
18
|
+
/**
|
|
19
|
+
* Named so a read from the tool surface is distinguishable from the CLI's and from replay's. The
|
|
20
|
+
* reader is the MCP client that made the call when one can be named; this only when none can.
|
|
21
|
+
*/
|
|
18
22
|
const MCP_AGENT_ID = 'reticle-mcp';
|
|
19
23
|
/** Why a lookup returned nothing. Each one is a different thing for the agent to do next. */
|
|
20
24
|
export const MemoryUnavailable = {
|
|
@@ -68,10 +72,34 @@ const asKnown = (raw) => {
|
|
|
68
72
|
* twice returns the same order — an unstable list reads as the corpus churning when it has not.
|
|
69
73
|
*/
|
|
70
74
|
const PROVED = 'proved';
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
const AGREED = 'agreed';
|
|
76
|
+
/** Set aside on the dashboard or by `reticle_memory {set-aside}`: nobody stands by it any more. */
|
|
77
|
+
const SET_ASIDE = 'stale';
|
|
78
|
+
/** Then agreed, then what a person wrote (no flow behind it), then flow intents. */
|
|
79
|
+
const RANKS = [
|
|
80
|
+
(t) => PROVED === t.status,
|
|
81
|
+
(t) => AGREED === t.status,
|
|
82
|
+
(t) => null === t.flowName,
|
|
83
|
+
() => true,
|
|
74
84
|
];
|
|
85
|
+
export const rankKnown = (things) => things
|
|
86
|
+
.map((thing, at) => ({ thing, at, rank: RANKS.findIndex((fits) => fits(thing)) }))
|
|
87
|
+
.sort((a, b) => a.rank - b.rank || a.at - b.at)
|
|
88
|
+
.map((r) => r.thing);
|
|
89
|
+
/**
|
|
90
|
+
* What a read can show: each statement once (a persona's intent saved on six pages pushed a
|
|
91
|
+
* person's own fact past the cap) and nothing set aside (it ranked second seconds after).
|
|
92
|
+
*/
|
|
93
|
+
const liveAndDistinct = (things) => {
|
|
94
|
+
const seen = new Set();
|
|
95
|
+
return rankKnown(things.filter((t) => SET_ASIDE !== t.status)).filter((t) => {
|
|
96
|
+
const key = t.statement.trim();
|
|
97
|
+
if (seen.has(key))
|
|
98
|
+
return false;
|
|
99
|
+
seen.add(key);
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
75
103
|
export async function readProjectMemory(fs, root, home, env, opts) {
|
|
76
104
|
const cloud = await resolveProjectCloud(fs, root, home, env);
|
|
77
105
|
if (null === cloud.config)
|
|
@@ -92,7 +120,7 @@ export async function readProjectMemory(fs, root, home, env, opts) {
|
|
|
92
120
|
authorization: `Bearer ${cloud.config.apiKey}`,
|
|
93
121
|
// What makes this read COUNT as an agent consulting the corpus rather than a human
|
|
94
122
|
// browsing — the distinction the dashboard's "times an agent consulted it" rests on.
|
|
95
|
-
|
|
123
|
+
[MemoryReadHeader.AGENT]: callingClientName() ?? MCP_AGENT_ID,
|
|
96
124
|
},
|
|
97
125
|
});
|
|
98
126
|
if (200 !== res.status)
|
|
@@ -118,14 +146,14 @@ export async function readProjectMemory(fs, root, home, env, opts) {
|
|
|
118
146
|
// The entry-level pass is redundant against the envelope check above and kept for a server that
|
|
119
147
|
// labels entries instead. `total` is counted AFTER it, so a truncated list still tells the truth
|
|
120
148
|
// about how many of THIS project's statements there were.
|
|
121
|
-
const known = entries.map(asKnown).filter((k) => k !== null);
|
|
149
|
+
const known = liveAndDistinct(entries.map(asKnown).filter((k) => k !== null));
|
|
122
150
|
return {
|
|
123
151
|
ok: true,
|
|
124
152
|
subject: opts.subject ?? null,
|
|
125
153
|
// Capped for the agent's context, but `total` always reports the truth so the cap is never
|
|
126
154
|
// silent — a truncated list that looks complete is how an agent concludes a project knows
|
|
127
155
|
// less than it does.
|
|
128
|
-
known:
|
|
156
|
+
known: known.slice(0, opts.limit),
|
|
129
157
|
total: known.length,
|
|
130
158
|
};
|
|
131
159
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as http from 'node:http';
|
|
2
2
|
import { Session } from '../session/session.js';
|
|
3
3
|
import { SessionManager } from '../session/session-manager.js';
|
|
4
|
+
import { type HarnessRequest } from './harness-request.js';
|
|
4
5
|
import { pairingTokenSource } from './pairing-token.js';
|
|
5
6
|
/** A human clicked ▶ on a saved flow in the panel — replay it with no agent. Wired by the daemon. */
|
|
6
7
|
type ReplayRequestHandler = (sessionId: string, flowName: string) => void;
|
|
@@ -107,12 +108,15 @@ export declare class Bridge {
|
|
|
107
108
|
*/
|
|
108
109
|
attachSyncRequest(handler: () => void): void;
|
|
109
110
|
/**
|
|
110
|
-
* Register a handler for the panel's
|
|
111
|
-
* bridge built without one ignores the request rather than refusing it.
|
|
111
|
+
* Register a handler for the panel's Harness controls (switch, Run, Stop). Optional for the same
|
|
112
|
+
* reason as the above: a bridge built without one ignores the request rather than refusing it.
|
|
112
113
|
*/
|
|
113
|
-
attachHarnessRequest(handler: (
|
|
114
|
-
/**
|
|
115
|
-
|
|
114
|
+
attachHarnessRequest(handler: (request: HarnessRequest, session: Session) => void): void;
|
|
115
|
+
/**
|
|
116
|
+
* Register a handler for the panel's Sign in, told which tab asked (its project is linked once the
|
|
117
|
+
* sign-in lands). Optional, like the above: without one it is ignored.
|
|
118
|
+
*/
|
|
119
|
+
attachSigninRequest(handler: (from: Session) => void): void;
|
|
116
120
|
/** Register a handler to run when a session connects. Additive — every handler runs. */
|
|
117
121
|
attachSessionCreate(handler: (session: Session) => void): void;
|
|
118
122
|
close(): Promise<void>;
|
|
@@ -8,11 +8,13 @@ import { EventType, HumanControlKind, RETICLE_WS_PATH, ReticleMessageSchema, LOO
|
|
|
8
8
|
import { Session } from '../session/session.js';
|
|
9
9
|
import { SessionManager } from '../session/session-manager.js';
|
|
10
10
|
import { tokensMatch } from './token-auth.js';
|
|
11
|
+
import { noteWrongPathUpgrades, wrongPathReason } from './wrong-path.js';
|
|
12
|
+
import { harnessRequest } from './harness-request.js';
|
|
11
13
|
import { pairingTokenSource } from './pairing-token.js';
|
|
12
14
|
import { log } from '../../log.js';
|
|
13
15
|
import { getSessionMetrics } from '../../telemetry/session-metrics.js';
|
|
14
16
|
import { SESSION_PARKED_REASON, sessionReplacedReason, } from '../session/facts/session-replaced.js';
|
|
15
|
-
import { describeSkew, sdkFix, SkewPair } from '../../command/version/version-skew.js';
|
|
17
|
+
import { describeSdkBehind, describeSkew, sdkFix, SDK_BEHIND_NARRATION, SkewPair, } from '../../command/version/version-skew.js';
|
|
16
18
|
import { noteVersionSkew } from '../../command/version/version-nudge.js';
|
|
17
19
|
import { protocolSkewReason } from './protocol-skew.js';
|
|
18
20
|
import { SERVER_VERSION } from '../../command/version/identity/server-version.js';
|
|
@@ -129,24 +131,6 @@ function replayRequest(event) {
|
|
|
129
131
|
const name = event.data['text'];
|
|
130
132
|
return 'string' === typeof name && name.length > 0 ? name : undefined;
|
|
131
133
|
}
|
|
132
|
-
/**
|
|
133
|
-
* The desired harness state if this event is the panel's switch, else undefined.
|
|
134
|
-
*
|
|
135
|
-
* Carries `on`/`off` rather than meaning "toggle": a double-click on a flaky connection sends two,
|
|
136
|
-
* and two toggles land back where they started while two `on`s are the same as one.
|
|
137
|
-
*/
|
|
138
|
-
function harnessRequest(event) {
|
|
139
|
-
if (event.type !== EventType.HUMAN_CONTROL)
|
|
140
|
-
return undefined;
|
|
141
|
-
if (event.data['kind'] !== HumanControlKind.HARNESS)
|
|
142
|
-
return undefined;
|
|
143
|
-
const want = event.data['text'];
|
|
144
|
-
if ('on' === want)
|
|
145
|
-
return true;
|
|
146
|
-
if ('off' === want)
|
|
147
|
-
return false;
|
|
148
|
-
return undefined;
|
|
149
|
-
}
|
|
150
134
|
/** True when this event is the panel's Sign in. Pure boundary narrowing, like the above. */
|
|
151
135
|
function isSigninRequest(event) {
|
|
152
136
|
return event.type === EventType.HUMAN_CONTROL && event.data['kind'] === HumanControlKind.SIGNIN;
|
|
@@ -401,6 +385,15 @@ export class Bridge {
|
|
|
401
385
|
this.#wss.on('error', (err) => {
|
|
402
386
|
log('bridge_ws_error', { error: err.message });
|
|
403
387
|
});
|
|
388
|
+
// A dial on any other path got a bare 400 from `ws` and left no trace for a diagnosis (#1242).
|
|
389
|
+
// Only a dial the origin check would have let in is the app's: a socket with no Origin is any
|
|
390
|
+
// local process, and recording it would tell the agent the app is running when it may not be.
|
|
391
|
+
noteWrongPathUpgrades(this.#wss, (path, origin) => {
|
|
392
|
+
log('bridge_wrong_path', { path, origin: origin ?? 'missing' });
|
|
393
|
+
if (origin !== undefined && this.#originAllowed(origin)) {
|
|
394
|
+
this.sessions.noteClosure(wrongPathReason(path, origin), this.#clock());
|
|
395
|
+
}
|
|
396
|
+
});
|
|
404
397
|
this.#wss.on('connection', (socket) => {
|
|
405
398
|
this.#onConnection(socket);
|
|
406
399
|
});
|
|
@@ -483,6 +476,22 @@ export class Bridge {
|
|
|
483
476
|
log('hello_invalid', { ...refused });
|
|
484
477
|
this.sessions.noteClosure(WS_CLOSE_REASON.INVALID_HELLO, this.#clock(), refused);
|
|
485
478
|
}
|
|
479
|
+
// On a LIVE session a frame that fails the schema is dropped, not answered with a close.
|
|
480
|
+
// The SDK reads every 1008 as permanent and stops reconnecting, so one event kind from a
|
|
481
|
+
// newer SDK ended the session for good, mid-drive, until a manual reload (#1413). What was
|
|
482
|
+
// thrown away is evidence, so it is recorded as a transport gap in this window: a verdict
|
|
483
|
+
// over it is downgraded rather than graded over an event nobody read. Only before hello is
|
|
484
|
+
// a bad frame still a terminal refusal.
|
|
485
|
+
if (undefined !== session) {
|
|
486
|
+
log('invalid_frame_dropped', { sessionId: session.id, ...peekFrameKind(text) });
|
|
487
|
+
session.pushEvent({
|
|
488
|
+
t: session.elapsed(),
|
|
489
|
+
type: EventType.TRANSPORT_OVERFLOW,
|
|
490
|
+
sessionId: session.id,
|
|
491
|
+
data: { dropped: 1 },
|
|
492
|
+
});
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
486
495
|
socket.close(...WS_CLOSE.INVALID_MESSAGE);
|
|
487
496
|
return;
|
|
488
497
|
}
|
|
@@ -664,6 +673,16 @@ export class Bridge {
|
|
|
664
673
|
session.versionSkew = skew;
|
|
665
674
|
noteVersionSkew(SkewPair.SDK, skew);
|
|
666
675
|
}
|
|
676
|
+
else {
|
|
677
|
+
// Wire-compatible but a minor or more behind: the agent hears it on its next tool call
|
|
678
|
+
// and the person on the overlay. Not `versionSkew`, which marks the pair as broken.
|
|
679
|
+
const behind = describeSdkBehind(parsed.sdkVersion, SERVER_VERSION, fixForThisProject);
|
|
680
|
+
if (behind !== undefined && parsed.sdkVersion !== undefined) {
|
|
681
|
+
log('sdk_behind', { sessionId: session.id, sdk: parsed.sdkVersion });
|
|
682
|
+
noteVersionSkew(SkewPair.SDK_BEHIND, behind);
|
|
683
|
+
session.pushNarration(SDK_BEHIND_NARRATION(parsed.sdkVersion, SERVER_VERSION), false);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
667
686
|
log('session_connected', { sessionId: session.id, url: session.url });
|
|
668
687
|
// The one fact that separates a broken install from an unused one. Best-effort and wrapped:
|
|
669
688
|
// a metric must never affect whether an app can connect. See SessionSummary.appConnects.
|
|
@@ -708,7 +727,7 @@ export class Bridge {
|
|
|
708
727
|
this.#onHarnessRequest?.(harness, session);
|
|
709
728
|
// Signing in writes `~/.reticle`, which only the daemon may do; the panel only asks.
|
|
710
729
|
else if (isSigninRequest(parsed.event))
|
|
711
|
-
this.#onSigninRequest?.();
|
|
730
|
+
this.#onSigninRequest?.(session);
|
|
712
731
|
// Pass the raw frame's byte length so the buffer doesn't re-serialize every event for accounting.
|
|
713
732
|
else
|
|
714
733
|
session.pushEvent(parsed.event, Buffer.byteLength(text, 'utf8'));
|
|
@@ -845,13 +864,16 @@ export class Bridge {
|
|
|
845
864
|
this.#onSyncRequest = handler;
|
|
846
865
|
}
|
|
847
866
|
/**
|
|
848
|
-
* Register a handler for the panel's
|
|
849
|
-
* bridge built without one ignores the request rather than refusing it.
|
|
867
|
+
* Register a handler for the panel's Harness controls (switch, Run, Stop). Optional for the same
|
|
868
|
+
* reason as the above: a bridge built without one ignores the request rather than refusing it.
|
|
850
869
|
*/
|
|
851
870
|
attachHarnessRequest(handler) {
|
|
852
871
|
this.#onHarnessRequest = handler;
|
|
853
872
|
}
|
|
854
|
-
/**
|
|
873
|
+
/**
|
|
874
|
+
* Register a handler for the panel's Sign in, told which tab asked (its project is linked once the
|
|
875
|
+
* sign-in lands). Optional, like the above: without one it is ignored.
|
|
876
|
+
*/
|
|
855
877
|
attachSigninRequest(handler) {
|
|
856
878
|
this.#onSigninRequest = handler;
|
|
857
879
|
}
|
|
@@ -869,3 +891,24 @@ export class Bridge {
|
|
|
869
891
|
});
|
|
870
892
|
}
|
|
871
893
|
}
|
|
894
|
+
/**
|
|
895
|
+
* The `kind` and event `type` of a frame that failed the schema, for the log: never its payload,
|
|
896
|
+
* which can carry anything the page sent. Each is a bounded string or absent.
|
|
897
|
+
*/
|
|
898
|
+
function peekFrameKind(text) {
|
|
899
|
+
const short = (v) => 'string' === typeof v ? v.slice(0, MAX_LOGGED_FRAME_FIELD) : undefined;
|
|
900
|
+
try {
|
|
901
|
+
const json = JSON.parse(text);
|
|
902
|
+
const kind = short(json?.kind);
|
|
903
|
+
const eventType = short(json?.event?.type);
|
|
904
|
+
return {
|
|
905
|
+
...(kind === undefined ? {} : { kind }),
|
|
906
|
+
...(eventType === undefined ? {} : { eventType }),
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
catch {
|
|
910
|
+
return {};
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
/** How much of a frame's `kind` or event `type` the drop log keeps. */
|
|
914
|
+
const MAX_LOGGED_FRAME_FIELD = 64;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the panel's Harness controls asked for, narrowed at the boundary: the autonomous switch,
|
|
3
|
+
* Run Harness (with an optional persona), or Stop. Keyed by the control's own wire kind.
|
|
4
|
+
*
|
|
5
|
+
* The switch carries `on`/`off` rather than meaning "toggle": a double-click on a flaky connection
|
|
6
|
+
* sends two, and two toggles land back where they started while two `on`s are the same as one.
|
|
7
|
+
*/
|
|
8
|
+
import { HumanControlKind } from '@reticlehq/core';
|
|
9
|
+
export type HarnessRequest = {
|
|
10
|
+
kind: typeof HumanControlKind.HARNESS;
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
} | {
|
|
13
|
+
kind: typeof HumanControlKind.HARNESS_RUN;
|
|
14
|
+
persona?: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: typeof HumanControlKind.HARNESS_STOP;
|
|
17
|
+
} | {
|
|
18
|
+
kind: typeof HumanControlKind.HARNESS_LINK;
|
|
19
|
+
};
|
|
20
|
+
export declare function harnessRequest(event: {
|
|
21
|
+
type: string;
|
|
22
|
+
data: Record<string, unknown>;
|
|
23
|
+
}): HarnessRequest | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the panel's Harness controls asked for, narrowed at the boundary: the autonomous switch,
|
|
3
|
+
* Run Harness (with an optional persona), or Stop. Keyed by the control's own wire kind.
|
|
4
|
+
*
|
|
5
|
+
* The switch carries `on`/`off` rather than meaning "toggle": a double-click on a flaky connection
|
|
6
|
+
* sends two, and two toggles land back where they started while two `on`s are the same as one.
|
|
7
|
+
*/
|
|
8
|
+
import { EventType, HumanControlKind } from '@reticlehq/core';
|
|
9
|
+
export function harnessRequest(event) {
|
|
10
|
+
if (event.type !== EventType.HUMAN_CONTROL)
|
|
11
|
+
return undefined;
|
|
12
|
+
const kind = event.data['kind'];
|
|
13
|
+
const text = event.data['text'];
|
|
14
|
+
if (HumanControlKind.HARNESS_STOP === kind || HumanControlKind.HARNESS_LINK === kind)
|
|
15
|
+
return { kind };
|
|
16
|
+
if (HumanControlKind.HARNESS_RUN === kind) {
|
|
17
|
+
const persona = 'string' === typeof text ? text.trim() : '';
|
|
18
|
+
return 0 < persona.length ? { kind, persona } : { kind };
|
|
19
|
+
}
|
|
20
|
+
if (HumanControlKind.HARNESS !== kind)
|
|
21
|
+
return undefined;
|
|
22
|
+
if ('on' === text)
|
|
23
|
+
return { kind, enabled: true };
|
|
24
|
+
if ('off' === text)
|
|
25
|
+
return { kind, enabled: false };
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { WebSocketServer } from 'ws';
|
|
2
|
+
/** The path an upgrade asked for: the pathname only, because a query can carry a pairing token. */
|
|
3
|
+
export declare function requestedPath(url: string | undefined): string;
|
|
4
|
+
/**
|
|
5
|
+
* What the no-session diagnosis says about it. The path is in it because the path is the fix. It
|
|
6
|
+
* says only what the record shows: a wrong-path upgrade is answered before any origin check, so
|
|
7
|
+
* the client could be anything, and a sentence promising the app is running would send the agent
|
|
8
|
+
* away from a dev server that really is stopped. The bridge records one only from an Origin its
|
|
9
|
+
* handshake would have accepted.
|
|
10
|
+
*/
|
|
11
|
+
export declare function wrongPathReason(path: string, origin: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Report each upgrade `ws` turns away for its path. Wraps `shouldHandle`, which `ws` documents as
|
|
14
|
+
* the method to override and calls for every upgrade before it answers 400, so the decision itself
|
|
15
|
+
* is left to `ws` and only observed here.
|
|
16
|
+
*/
|
|
17
|
+
export declare function noteWrongPathUpgrades(wss: WebSocketServer, note: (path: string, origin: string | undefined) => void): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RETICLE_WS_PATH } from '@reticlehq/core';
|
|
2
|
+
/** Long enough for any real path, short enough that a junk request cannot fill the log line. */
|
|
3
|
+
const MAX_PATH_SHOWN = 80;
|
|
4
|
+
/** The path an upgrade asked for: the pathname only, because a query can carry a pairing token. */
|
|
5
|
+
export function requestedPath(url) {
|
|
6
|
+
const path = (url ?? '').split('?', 1)[0] ?? '';
|
|
7
|
+
const shown = 0 === path.length ? '/' : path;
|
|
8
|
+
return shown.length > MAX_PATH_SHOWN ? `${shown.slice(0, MAX_PATH_SHOWN)}…` : shown;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* What the no-session diagnosis says about it. The path is in it because the path is the fix. It
|
|
12
|
+
* says only what the record shows: a wrong-path upgrade is answered before any origin check, so
|
|
13
|
+
* the client could be anything, and a sentence promising the app is running would send the agent
|
|
14
|
+
* away from a dev server that really is stopped. The bridge records one only from an Origin its
|
|
15
|
+
* handshake would have accepted.
|
|
16
|
+
*/
|
|
17
|
+
export function wrongPathReason(path, origin) {
|
|
18
|
+
return (`a WebSocket upgrade from ${origin} asked for ${path} and got a 400: the bridge listens on ` +
|
|
19
|
+
`${RETICLE_WS_PATH} only. If that was your app, point the URL given to connect({ url }) at ` +
|
|
20
|
+
`the bridge path, for example ws://localhost:<port>${RETICLE_WS_PATH}.`);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Report each upgrade `ws` turns away for its path. Wraps `shouldHandle`, which `ws` documents as
|
|
24
|
+
* the method to override and calls for every upgrade before it answers 400, so the decision itself
|
|
25
|
+
* is left to `ws` and only observed here.
|
|
26
|
+
*/
|
|
27
|
+
export function noteWrongPathUpgrades(wss, note) {
|
|
28
|
+
const handles = wss.shouldHandle.bind(wss);
|
|
29
|
+
wss.shouldHandle = (req) => {
|
|
30
|
+
const handled = handles(req);
|
|
31
|
+
if (false === handled)
|
|
32
|
+
note(requestedPath(req.url), req.headers.origin);
|
|
33
|
+
return handled;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -70,6 +70,15 @@ export function toRules(value) {
|
|
|
70
70
|
return rule;
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* The applied result, after telling the recorder. Steps driven while a mock is active are marked
|
|
75
|
+
* on the ambient tape, so a journey proved against mocked responses is not auto-saved as a flow
|
|
76
|
+
* that would replay against the real backend (#1459).
|
|
77
|
+
*/
|
|
78
|
+
function mocksApplied(deps, sessionId, count) {
|
|
79
|
+
deps.recordings.markMocked(sessionId, 0 < count);
|
|
80
|
+
return { applied: true, count };
|
|
81
|
+
}
|
|
73
82
|
export const NETWORK_MOCK_TOOLS = [
|
|
74
83
|
{
|
|
75
84
|
name: ReticleTool.NETWORK_MOCK,
|
|
@@ -104,14 +113,14 @@ export const NETWORK_MOCK_TOOLS = [
|
|
|
104
113
|
if (provider !== undefined) {
|
|
105
114
|
const applied = await provider.setMocks(session.url, rules);
|
|
106
115
|
if (applied)
|
|
107
|
-
return
|
|
116
|
+
return mocksApplied(deps, session.id, rules.length);
|
|
108
117
|
}
|
|
109
118
|
// A lease is a Playwright-owned page — CDP intercept was always there, this tool just had no
|
|
110
119
|
// route to it. Tried after the driven provider: when both exist, drive is the page the caller
|
|
111
120
|
// means, and a lease is the fallback rather than a competitor.
|
|
112
121
|
const leased = await deps.pool?.setMocksLease(session.id, rules);
|
|
113
122
|
if (true === leased)
|
|
114
|
-
return
|
|
123
|
+
return mocksApplied(deps, session.id, rules.length);
|
|
115
124
|
return {
|
|
116
125
|
applied: false,
|
|
117
126
|
count: 0,
|
|
@@ -87,6 +87,8 @@ export interface ScreenshotOpts {
|
|
|
87
87
|
* baseline tweaks (hiding the HUD, stopping animations) would make their window flicker each second.
|
|
88
88
|
*/
|
|
89
89
|
jpegQuality?: number;
|
|
90
|
+
/** One image pixel per CSS pixel, so a high-density display does not double a step screenshot. */
|
|
91
|
+
cssScale?: boolean;
|
|
90
92
|
}
|
|
91
93
|
/** The capability surface reticle_act depends on. A FAKE implementing this is injected in tests. */
|
|
92
94
|
export interface RealInputProvider {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { takeJsCoverage } from './js-coverage.js';
|
|
13
13
|
import { stampedDriveUrl } from './drive-url-stamp.js';
|
|
14
14
|
import { launchChromium } from '../../launch-chromium.js';
|
|
15
|
-
import {
|
|
15
|
+
import { chromiumLaunchHint, gotoOptions, SCREENSHOT_DETERMINISM, captureWithChromeHidden, } from '../pool/playwright-launcher.js';
|
|
16
16
|
import { BrowserLaunchKind } from '@reticlehq/core/telemetry';
|
|
17
17
|
import { getSessionMetrics } from '../../telemetry/session-metrics.js';
|
|
18
18
|
import { classifyConnectFailure } from '../../telemetry/connect-failure.js';
|
|
@@ -273,21 +273,24 @@ now = Date.now) {
|
|
|
273
273
|
}
|
|
274
274
|
return real(false);
|
|
275
275
|
}
|
|
276
|
-
/**
|
|
277
|
-
* Reticle paints its own dev overlay (presenter HUD + border glow) into the page. That chrome is
|
|
278
|
-
* time-varying — the activity log and border state change with every command — so capturing it
|
|
279
|
-
* makes a fresh screenshot of an unchanged page differ from its baseline. Hide it during capture
|
|
280
|
-
* (Playwright applies this stylesheet only for the shot, then reverts) so visual baselines reflect
|
|
281
|
-
* the app, not Reticle. Disabling animations settles any remaining transitions for determinism.
|
|
282
|
-
*/
|
|
283
|
-
const SCREENSHOT_DETERMINISM = { style: HIDE_RETICLE_CHROME_CSS, animations: 'disabled' };
|
|
284
276
|
/**
|
|
285
277
|
* Capture a PNG from a Playwright page. Shared by the CDP + launched providers so the
|
|
286
278
|
* screenshot path lives in one place (mirrors performGesture). Returns the raw PNG bytes.
|
|
287
279
|
*/
|
|
288
280
|
export async function capturePage(page, opts) {
|
|
281
|
+
// A step capture injects nothing into the page, so Reticle's own hosts are hidden another way.
|
|
282
|
+
if (true === opts.cssScale) {
|
|
283
|
+
return captureWithChromeHidden({ evaluate: (script) => page.evaluate(script) }, () => shoot(page, opts));
|
|
284
|
+
}
|
|
285
|
+
return shoot(page, opts);
|
|
286
|
+
}
|
|
287
|
+
async function shoot(page, opts) {
|
|
289
288
|
const buf = await page.screenshot(opts.jpegQuality !== undefined
|
|
290
|
-
? {
|
|
289
|
+
? {
|
|
290
|
+
type: 'jpeg',
|
|
291
|
+
quality: opts.jpegQuality,
|
|
292
|
+
...(true === opts.cssScale ? { scale: 'css' } : {}),
|
|
293
|
+
}
|
|
291
294
|
: opts.clip !== undefined
|
|
292
295
|
? { ...SCREENSHOT_DETERMINISM, clip: opts.clip }
|
|
293
296
|
: true === opts.fullPage
|
|
@@ -100,6 +100,12 @@ export declare class BrowserPool {
|
|
|
100
100
|
* that would have read a computed value.
|
|
101
101
|
*/
|
|
102
102
|
alias(registeredId: string, leaseId: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* Whether `sessionId` is a live lease that `owner` may let go of: one it took, or one taken by a
|
|
105
|
+
* caller with no id, which cannot be told apart from it. Another agent's lease is never this
|
|
106
|
+
* caller's to close (#1226).
|
|
107
|
+
*/
|
|
108
|
+
heldBy(sessionId: string, owner: string | undefined): boolean;
|
|
103
109
|
/** Mark a lease as still in use (called on agent activity) so the reaper doesn't reclaim it. */
|
|
104
110
|
touch(sessionId: string): void;
|
|
105
111
|
/**
|
|
@@ -117,6 +123,14 @@ export declare class BrowserPool {
|
|
|
117
123
|
* reaper take it out from under a diff.
|
|
118
124
|
*/
|
|
119
125
|
screenshotLease(sessionId: string, opts?: ScreenshotOptions): Promise<Uint8Array | undefined>;
|
|
126
|
+
/** The URL a lease was opened on — the one that carries its Reticle identity. */
|
|
127
|
+
leaseUrl(sessionId: string): string | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* Navigate a leased page through the browser. For a lease whose page has no SDK to take the
|
|
130
|
+
* command — a navigate to an image left the lease unreachable, and the next navigate answered "no
|
|
131
|
+
* connected session". False when this is not a lease or the page would not go.
|
|
132
|
+
*/
|
|
133
|
+
gotoLease(sessionId: string, url: string, timeoutMs?: number): Promise<boolean>;
|
|
120
134
|
/**
|
|
121
135
|
* Move the real pointer on a leased page, or false when this session is not a lease or cannot
|
|
122
136
|
* hover. Same optional-capability contract as screenshotLease: absence must read as "could not
|
|
@@ -144,6 +158,28 @@ export declare class BrowserPool {
|
|
|
144
158
|
height: number;
|
|
145
159
|
}): Promise<boolean>;
|
|
146
160
|
setMocksLease(sessionId: string, rules: readonly PooledMockRule[]): Promise<boolean>;
|
|
161
|
+
/** What a lease was granted when it opened, or undefined for a session that is not a lease. */
|
|
162
|
+
permissionsOf(sessionId: string): readonly string[] | undefined;
|
|
163
|
+
/**
|
|
164
|
+
* Whether this lease's page runs a caller-supplied init script — a stub of the bindings a desktop
|
|
165
|
+
* shell injects. Alias-resolved like every agent-facing lookup, and false for any session that is
|
|
166
|
+
* not a lease with a stub, so a verdict can say when it was measured against a fake shell.
|
|
167
|
+
*/
|
|
168
|
+
stubInstalled(sessionId: string): boolean;
|
|
169
|
+
/**
|
|
170
|
+
* The init script this lease installed, or undefined when it runs none. Alias-resolved like
|
|
171
|
+
* `stubInstalled`. The lease tool compares it to the script a caller asks for: the same text means
|
|
172
|
+
* the held tab already is what was asked for, so it is reused rather than released and remade.
|
|
173
|
+
*/
|
|
174
|
+
hostStubScript(sessionId: string): string | undefined;
|
|
175
|
+
/**
|
|
176
|
+
* What the leased page's `Notification.permission` says, or undefined when it cannot be asked.
|
|
177
|
+
*
|
|
178
|
+
* Read back rather than inferred from the grant, because the headless shell answers `denied`
|
|
179
|
+
* after a notifications grant — see context-permissions.ts. Bounded, so a page that never answers
|
|
180
|
+
* reads as "could not ask" instead of holding the caller.
|
|
181
|
+
*/
|
|
182
|
+
notificationPermission(sessionId: string): Promise<string | undefined>;
|
|
147
183
|
sweepExpired(): Promise<string[]>;
|
|
148
184
|
/**
|
|
149
185
|
* How many leases this pool has reclaimed for going stale.
|
|
@@ -178,6 +214,16 @@ export declare class BrowserPool {
|
|
|
178
214
|
owner?: string;
|
|
179
215
|
/** In a browser with a window the person can watch. */
|
|
180
216
|
headed?: boolean;
|
|
217
|
+
/**
|
|
218
|
+
* JavaScript installed before any page script runs, for this lease only. A view built for a
|
|
219
|
+
* desktop shell calls bindings the shell injects (`window.go`, `window.runtime`, a preload
|
|
220
|
+
* object) on mount; a stub here is what lets it reach its data path in a leased tab.
|
|
221
|
+
*/
|
|
222
|
+
initScript?: string;
|
|
223
|
+
/** Granted on the lease's origin before the first navigation, so the first render sees them. */
|
|
224
|
+
permissions?: readonly string[];
|
|
225
|
+
/** Accept a self-signed or local-CA dev certificate for this lease's context only (#1255). */
|
|
226
|
+
ignoreHTTPSErrors?: boolean;
|
|
181
227
|
}): Promise<Lease>;
|
|
182
228
|
/**
|
|
183
229
|
* The websocket address this lease's page reported it could not reach, if it reported one.
|
|
@@ -192,6 +238,8 @@ export declare class BrowserPool {
|
|
|
192
238
|
lastDialogMessage(sessionId: string): string | undefined;
|
|
193
239
|
/** Close every context and the browser. Pending waiters are rejected (the pool is terminal now). */
|
|
194
240
|
shutdown(): Promise<void>;
|
|
241
|
+
/** Whether this lease's context skips certificate checks. A context cannot change it later. */
|
|
242
|
+
ignoresHTTPSErrors(sessionId: string): boolean;
|
|
195
243
|
/** Whether this lease lives in the headed browser. */
|
|
196
244
|
isHeaded(sessionId: string): boolean;
|
|
197
245
|
}
|