@reticlehq/server 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/SKILL.md +123 -116
- package/dist/chromium-launch-options.d.ts +3 -1
- package/dist/chromium-launch-options.js +2 -1
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +19 -2
- package/dist/command/cli/adhoc-verdict.js +76 -9
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/answers/open-note.d.ts +2 -0
- package/dist/command/cli/answers/open-note.js +22 -0
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +31 -112
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +35 -5
- package/dist/command/cli/cli-verify.js +114 -35
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +192 -341
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +22 -0
- package/dist/command/cli/cloud-login.js +96 -8
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/drive/drive-attach.d.ts +27 -2
- package/dist/command/cli/drive/drive-attach.js +71 -4
- package/dist/command/cli/drive/drive-command.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +13 -7
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.d.ts +10 -0
- package/dist/command/cli/ports/port-holder.js +25 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +35 -12
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -181
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +20 -0
- package/dist/command/cli.js +130 -104
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +23 -1
- package/dist/command/daemon/daemon-resolve.js +79 -9
- package/dist/command/setup/agent-writer.d.ts +1 -1
- package/dist/command/setup/agent-writer.js +3 -2
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
- package/dist/command/setup/bringup/connect-lease.js +1 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
- package/dist/command/setup/bringup/dev-server-wait.js +19 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +14 -1
- package/dist/command/setup/init/init-port.js +32 -2
- package/dist/command/setup/init/init-runtime.d.ts +22 -2
- package/dist/command/setup/init/init-runtime.js +114 -38
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +38 -9
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +2 -1
- package/dist/command/setup/run-setup.d.ts +34 -9
- package/dist/command/setup/run-setup.js +65 -51
- package/dist/command/setup/setup-command.d.ts +25 -1
- package/dist/command/setup/setup-command.js +59 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +49 -4
- package/dist/features/crawl/crawl-tools.js +4 -0
- package/dist/features/crawl/crawl.d.ts +6 -0
- package/dist/features/crawl/crawl.js +23 -2
- package/dist/features/exhaust/ledger.d.ts +21 -14
- package/dist/features/exhaust/ledger.js +35 -9
- package/dist/features/harness/app-findings.d.ts +2 -0
- package/dist/features/harness/app-findings.js +52 -0
- package/dist/features/harness/drive-report.d.ts +61 -1
- package/dist/features/harness/drive-report.js +394 -26
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +10 -14
- package/dist/features/harness/drivers.js +10 -14
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/fill-values.d.ts +3 -73
- package/dist/features/harness/fill-values.js +3 -169
- package/dist/features/harness/goals.d.ts +82 -0
- package/dist/features/harness/goals.js +330 -0
- package/dist/features/harness/harness.d.ts +51 -1
- package/dist/features/harness/harness.js +207 -6
- package/dist/features/harness/platform/drive-target.d.ts +30 -0
- package/dist/features/harness/platform/drive-target.js +81 -0
- package/dist/features/harness/platform/local-apps.d.ts +127 -0
- package/dist/features/harness/platform/local-apps.js +280 -0
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +186 -0
- package/dist/features/harness/platform/remote-drive.js +378 -0
- package/dist/features/harness/platform/script.d.ts +94 -0
- package/dist/features/harness/platform/script.js +260 -0
- package/dist/features/harness/platform/server-driver.d.ts +54 -0
- package/dist/features/harness/platform/server-driver.js +182 -0
- package/dist/features/harness/platform-config.d.ts +41 -1
- package/dist/features/harness/platform-config.js +106 -9
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/app-controls.d.ts +5 -0
- package/dist/features/harness/script/app-controls.js +40 -0
- package/dist/features/harness/script/lane-ids.d.ts +14 -0
- package/dist/features/harness/script/lane-ids.js +16 -0
- package/dist/features/harness/script/script-run.d.ts +70 -0
- package/dist/features/harness/script/script-run.js +606 -0
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.d.ts +10 -1
- package/dist/features/visual/visual-tools.js +62 -17
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +23 -0
- package/dist/hooks/driven-by.js +56 -0
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/hooks/hook-commands.js +15 -4
- package/dist/hooks/tool-log.d.ts +9 -0
- package/dist/hooks/tool-log.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +80 -243
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
- package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
- package/dist/judgement/runs/artifact/run-store.js +195 -3
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +71 -1
- package/dist/judgement/runs/drive-run.js +317 -5
- package/dist/judgement/runs/repair-prompt.js +1 -1
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +13 -3
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +5 -2
- package/dist/judgement/runs/verification-sync.js +40 -18
- package/dist/language/flows/change/gate.d.ts +10 -0
- package/dist/language/flows/change/gate.js +22 -0
- package/dist/language/flows/decision.js +36 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +61 -10
- package/dist/language/flows/flow-anchor.js +98 -6
- package/dist/language/flows/flow-cross-step.d.ts +15 -0
- package/dist/language/flows/flow-cross-step.js +21 -0
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +45 -14
- package/dist/language/flows/flow-mutate-tools.js +5 -3
- package/dist/language/flows/flow-replay-run.d.ts +23 -9
- package/dist/language/flows/flow-replay-run.js +115 -110
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +40 -1
- package/dist/language/flows/flow-replay.js +110 -22
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-scope.js +5 -1
- package/dist/language/flows/flow-step-runners.d.ts +22 -2
- package/dist/language/flows/flow-step-runners.js +247 -47
- package/dist/language/flows/flow-store-for-session.d.ts +2 -2
- package/dist/language/flows/flow-store-for-session.js +7 -3
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +112 -89
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +74 -12
- package/dist/language/flows/heal-run.js +6 -4
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/flake.d.ts +2 -2
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
- package/dist/language/flows/recording/tape/recordings.js +95 -13
- package/dist/language/flows/replay-from-hud.d.ts +20 -0
- package/dist/language/flows/replay-from-hud.js +51 -0
- package/dist/language/flows/replay.d.ts +9 -5
- package/dist/language/flows/replay.js +56 -15
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/suite/suite-flakes.js +2 -0
- package/dist/language/flows/suite-selection.d.ts +2 -15
- package/dist/language/flows/suite-selection.js +4 -3
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +202 -191
- package/dist/launch-chromium.d.ts +27 -5
- package/dist/launch-chromium.js +38 -8
- package/dist/memory/cloud/cloud-config.d.ts +22 -1
- package/dist/memory/cloud/cloud-config.js +34 -5
- package/dist/memory/cloud/cloud-sync.d.ts +17 -14
- package/dist/memory/cloud/cloud-sync.js +15 -4
- package/dist/memory/cloud/harness-config.d.ts +75 -1
- package/dist/memory/cloud/harness-config.js +115 -24
- package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
- package/dist/memory/cloud/hud-notices-source.js +128 -0
- package/dist/memory/cloud/memory-scope.d.ts +161 -0
- package/dist/memory/cloud/memory-scope.js +227 -0
- package/dist/memory/cloud/sync-cycle.d.ts +44 -7
- package/dist/memory/cloud/sync-cycle.js +129 -15
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +121 -9
- package/dist/memory/cloud/sync-disk.d.ts +1 -1
- package/dist/memory/cloud/sync-disk.js +31 -10
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +34 -0
- package/dist/memory/impact/account-watch.js +59 -0
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +12 -2
- package/dist/memory/impact/impact-store.d.ts +17 -4
- package/dist/memory/impact/impact-store.js +169 -63
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +14 -2
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +122 -4
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/envelope.d.ts +8 -8
- package/dist/memory/journal/journal-recorder.js +52 -3
- package/dist/memory/journal/on-disk/retention.d.ts +8 -0
- package/dist/memory/journal/on-disk/retention.js +32 -2
- package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
- package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +42 -9
- package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
- package/dist/memory/project/artifact-root-resolver.js +125 -16
- package/dist/memory/project/artifact-root.d.ts +46 -8
- package/dist/memory/project/artifact-root.js +89 -10
- package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
- package/dist/memory/project/dir/reticle-dir.js +26 -3
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/project-tools.js +22 -3
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +26 -1
- package/dist/memory/project/session-root.js +49 -5
- package/dist/memory/project/sync-status.d.ts +85 -0
- package/dist/memory/project/sync-status.js +224 -0
- package/dist/memory/recall/memory-tools.js +47 -2
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.d.ts +19 -0
- package/dist/memory/recall/project-memory.js +80 -13
- package/dist/portal/bridge/bridge.d.ts +9 -3
- package/dist/portal/bridge/bridge.js +82 -22
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/pairing-token.d.ts +9 -0
- package/dist/portal/bridge/pairing-token.js +17 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +83 -10
- package/dist/portal/input/real-input.js +218 -30
- package/dist/portal/input/viewport-tools.js +3 -3
- package/dist/portal/pool/browser-pool.d.ts +70 -9
- package/dist/portal/pool/browser-pool.js +190 -37
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +35 -0
- package/dist/portal/pool/playwright-launcher.js +64 -3
- package/dist/portal/pool/pool-contract.d.ts +28 -5
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.d.ts +8 -0
- package/dist/portal/session/command-payload.js +24 -0
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
- package/dist/portal/session/dev-server/dev-command.js +87 -12
- package/dist/portal/session/facts/departure-note.d.ts +22 -0
- package/dist/portal/session/facts/departure-note.js +47 -0
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/facts/session-replaced.d.ts +5 -0
- package/dist/portal/session/facts/session-replaced.js +5 -0
- package/dist/portal/session/first-run-wiring.d.ts +42 -0
- package/dist/portal/session/first-run-wiring.js +132 -0
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/human/notes-ledger.d.ts +20 -0
- package/dist/portal/session/human/notes-ledger.js +55 -0
- package/dist/portal/session/human/review-store.d.ts +12 -0
- package/dist/portal/session/human/review-store.js +18 -10
- package/dist/portal/session/live-control-tools.d.ts +0 -13
- package/dist/portal/session/live-control-tools.js +107 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
- package/dist/portal/session/no-session-diagnosis.js +46 -9
- package/dist/portal/session/no-session-next-action.d.ts +31 -0
- package/dist/portal/session/no-session-next-action.js +159 -60
- package/dist/portal/session/no-session-watch.d.ts +14 -1
- package/dist/portal/session/no-session-watch.js +227 -17
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/presence/session-mirror.js +3 -0
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/serving-directory.d.ts +27 -0
- package/dist/portal/session/serving-directory.js +45 -0
- package/dist/portal/session/session-health.d.ts +18 -0
- package/dist/portal/session/session-health.js +9 -1
- package/dist/portal/session/session-info.d.ts +8 -1
- package/dist/portal/session/session-info.js +8 -1
- package/dist/portal/session/session-manager.d.ts +39 -0
- package/dist/portal/session/session-manager.js +98 -11
- package/dist/portal/session/session-reaper.js +4 -1
- package/dist/portal/session/session-successor.d.ts +13 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session-tools.js +26 -3
- package/dist/portal/session/session.d.ts +22 -30
- package/dist/portal/session/session.js +81 -79
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +12 -0
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +23 -1
- package/dist/status-payload.js +36 -1
- package/dist/surface/http-server.js +18 -2
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
- package/dist/surface/mcp/mcp-proxy.js +65 -13
- package/dist/surface/mcp/mcp.d.ts +34 -6
- package/dist/surface/mcp/mcp.js +61 -17
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.d.ts +4 -2
- package/dist/surface/mcp/server-instructions.js +32 -14
- package/dist/surface/mcp/shared-params.js +2 -2
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act/settle-in-flight.js +25 -3
- package/dist/surface/tools/act-sequence-tool.js +138 -29
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +71 -41
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +42 -17
- package/dist/surface/tools/browser-tools.js +51 -2
- package/dist/surface/tools/chat-drives.d.ts +101 -0
- package/dist/surface/tools/chat-drives.js +409 -0
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +51 -0
- package/dist/surface/tools/empty-session-list.js +120 -0
- package/dist/surface/tools/error-recovery.d.ts +14 -0
- package/dist/surface/tools/error-recovery.js +105 -8
- package/dist/surface/tools/explore-tools.d.ts +31 -1
- package/dist/surface/tools/explore-tools.js +438 -66
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +18 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +118 -57
- package/dist/surface/tools/harness-explore.js +344 -292
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +17 -0
- package/dist/surface/tools/harness-plan.js +38 -0
- package/dist/surface/tools/harness-script.d.ts +30 -0
- package/dist/surface/tools/harness-script.js +560 -0
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +22 -1
- package/dist/surface/tools/harness-toolset.js +101 -7
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +263 -85
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +49 -0
- package/dist/surface/tools/lease-seed.js +167 -0
- package/dist/surface/tools/lease-tools.d.ts +13 -24
- package/dist/surface/tools/lease-tools.js +146 -197
- package/dist/surface/tools/live-call-text.js +4 -4
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +29 -0
- package/dist/surface/tools/next-step.js +214 -0
- package/dist/surface/tools/observe-tools.js +45 -9
- package/dist/surface/tools/platform-moment.d.ts +72 -0
- package/dist/surface/tools/platform-moment.js +296 -0
- package/dist/surface/tools/query-hint-schema.d.ts +7 -0
- package/dist/surface/tools/query-hint-schema.js +10 -0
- package/dist/surface/tools/read-tools.js +71 -14
- package/dist/surface/tools/real-input-attempt.js +96 -13
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +83 -3
- package/dist/surface/tools/tool-kit.js +77 -7
- package/dist/surface/tools/tools.js +43 -59
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +29 -6
- package/dist/telemetry/hud-metrics.js +116 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +38 -2
- package/dist/telemetry/telemetry.js +144 -34
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +13 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +20 -6
- package/docs/README.md +3 -3
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +25 -28
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +33 -28
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +14 -3
- package/docs/cli/drive.mdx +20 -14
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +43 -28
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +18 -5
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +5 -4
- package/docs/cli.mdx +111 -42
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +9 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +7 -8
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +65 -61
- package/docs/human-control.md +16 -16
- package/docs/index.mdx +15 -42
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +23 -13
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +9 -9
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +32 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +69 -30
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +23 -25
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +22 -13
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +55 -46
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +17 -5
- package/docs/what-is-reticle.mdx +5 -3
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -241
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/features/harness/driver.d.ts +0 -50
- package/dist/features/harness/driver.js +0 -236
- package/dist/features/harness/jev-driver.d.ts +0 -188
- package/dist/features/harness/jev-driver.js +0 -678
- package/dist/features/harness/openai-driver.d.ts +0 -58
- package/dist/features/harness/openai-driver.js +0 -206
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
- package/dist/memory/project/dir/fill-value-store.js +0 -88
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
- package/docs/local-registry.md +0 -143
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wiring `start` and `startDaemon` share, built in one place so the two entry points cannot drift.
|
|
3
|
+
*
|
|
4
|
+
* Split from `index.ts`: that file is the package's front door and the two entry points; these are
|
|
5
|
+
* the pieces both of them assemble — the browser pool, the drive/real-input provider, the CDP network
|
|
6
|
+
* router, and the per-project lookups the daemon closes over. `daemon-parity.test.ts` checks both
|
|
7
|
+
* entry points still call them.
|
|
8
|
+
*/
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { cpus, homedir } from 'node:os';
|
|
11
|
+
import { bridgeWsUrl, EventType, ReticleDir, ReticleEnv } from '@reticlehq/core';
|
|
12
|
+
import { fetchPlatformConfig } from './features/harness/platform-config.js';
|
|
13
|
+
import { platformEnvPort } from './memory/cloud/cloud-config.js';
|
|
14
|
+
import { knownProjectCandidates, projectDirectoryFor, } from './memory/project/artifact-root-resolver.js';
|
|
15
|
+
import { createNodeFileSystem } from './memory/project/fs/fs-port.js';
|
|
16
|
+
import { originOf } from './portal/session/session-manager.js';
|
|
17
|
+
import { setBrowserMode, BrowserMode } from './telemetry/browser-mode.js';
|
|
18
|
+
import { sdkFixForDirectory } from './command/version/sdk-fix.js';
|
|
19
|
+
import { SERVER_VERSION } from './command/version/identity/server-version.js';
|
|
20
|
+
import { CdpRealInputProvider, LaunchedRealInputProvider } from './portal/input/real-input.js';
|
|
21
|
+
import { BrowserPool } from './portal/pool/browser-pool.js';
|
|
22
|
+
import { playwrightLauncher, resolveMaxContexts } from './portal/pool/playwright-launcher.js';
|
|
23
|
+
import { readReaderBundle, zeroInstallScript as zeroInstallScriptFor, } from './portal/pool/zero-install.js';
|
|
24
|
+
/**
|
|
25
|
+
* Build the shared browser pool (one headless Chromium, N capped isolated leased contexts). Lazy —
|
|
26
|
+
* no Chromium launches until the first lease — so creating it is free even when never used.
|
|
27
|
+
*/
|
|
28
|
+
/** Where the zero-install reader connects: this daemon's own bridge, with its pairing token. */
|
|
29
|
+
export function readerConnect(port, token) {
|
|
30
|
+
return { url: bridgeWsUrl(port), ...(token === undefined ? {} : { token }) };
|
|
31
|
+
}
|
|
32
|
+
export function createBrowserPool(headless, reader) {
|
|
33
|
+
const maxContexts = resolveMaxContexts(process.env[ReticleEnv.MAX_CONTEXTS], cpus().length);
|
|
34
|
+
const genSessionId = () => `lease-${'function' === typeof globalThis.crypto?.randomUUID
|
|
35
|
+
? globalThis.crypto.randomUUID()
|
|
36
|
+
: String(Date.now())}`;
|
|
37
|
+
// Built on first use and kept: the page that needs it is one whose app never connected.
|
|
38
|
+
let script;
|
|
39
|
+
const zeroInstallScript = () => {
|
|
40
|
+
if (script === undefined) {
|
|
41
|
+
const bundle = readReaderBundle();
|
|
42
|
+
script = bundle === undefined ? null : zeroInstallScriptFor(bundle, reader);
|
|
43
|
+
}
|
|
44
|
+
return script ?? undefined;
|
|
45
|
+
};
|
|
46
|
+
return new BrowserPool(playwrightLauncher({ headless }), {
|
|
47
|
+
maxContexts,
|
|
48
|
+
genSessionId,
|
|
49
|
+
zeroInstallScript,
|
|
50
|
+
launchHeaded: playwrightLauncher({ headless: false }),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Route CDP-authoritative network detail onto the driven session's journal.
|
|
55
|
+
*
|
|
56
|
+
* The page and the SDK session share an origin, so a NET_DETAIL is pushed to the matching connected
|
|
57
|
+
* session. Shared by both entry points: `startDaemon` previously omitted it entirely, so on the path
|
|
58
|
+
* users actually take, CDP network detail was collected and then dropped on the floor.
|
|
59
|
+
*/
|
|
60
|
+
export function makeNetworkDetailRouter(bridge, driveUrl) {
|
|
61
|
+
const driveOrigin = originOf(driveUrl ?? '');
|
|
62
|
+
return (detail) => {
|
|
63
|
+
// Route by the DOCUMENT that issued the request, not by the request's own origin.
|
|
64
|
+
//
|
|
65
|
+
// Matching the request's origin only works for same-origin calls. An app on one origin calling an
|
|
66
|
+
// API on another — most API calls — produced a detail matching no session, and it was dropped
|
|
67
|
+
// without a trace. The drive-URL fallback papered over it on the launched path and did nothing on
|
|
68
|
+
// the CDP-attach path, where driveUrl is undefined and the fallback compares against ''.
|
|
69
|
+
const pageOrigin = originOf(detail.pageUrl ?? '');
|
|
70
|
+
const requestOrigin = originOf(detail.url);
|
|
71
|
+
for (const session of bridge.sessions.all()) {
|
|
72
|
+
const origin = originOf(session.url);
|
|
73
|
+
// originOf returns `string | undefined`, NEVER '' — so the old `!== ''` guards were dead, and a
|
|
74
|
+
// bare `origin === requestOrigin` matched `undefined === undefined` when BOTH the session URL and
|
|
75
|
+
// the detail URL were unparseable. That routed a NET_DETAIL (with its response headers, incl.
|
|
76
|
+
// set-cookie) onto an unrelated session. Require a DEFINED origin; undefined operands then simply
|
|
77
|
+
// fail to match any of the three candidates.
|
|
78
|
+
const matches = origin !== undefined &&
|
|
79
|
+
(origin === pageOrigin || origin === requestOrigin || origin === driveOrigin);
|
|
80
|
+
if (matches) {
|
|
81
|
+
session.pushEvent({
|
|
82
|
+
t: 0,
|
|
83
|
+
type: EventType.NET_DETAIL,
|
|
84
|
+
sessionId: session.id,
|
|
85
|
+
data: { ...detail },
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolve the drive/real-input provider from options — shared by start and startDaemon so the
|
|
93
|
+
* precedence (driveUrl launch+own → CDP attach → none) and the storageState/injectConnect plumbing
|
|
94
|
+
* live in ONE place. `onNavigateError` is the entrypoint's own cleanup (close the bridge/shared server)
|
|
95
|
+
* so a failed launch never leaks a WS port. A past divergence between the two paths let daemon mode
|
|
96
|
+
* run with a different setup — this removes that risk.
|
|
97
|
+
*/
|
|
98
|
+
export async function resolveRealInput(options, onNavigateError, onNetworkDetail) {
|
|
99
|
+
const driveUrl = options.driveUrl;
|
|
100
|
+
if (driveUrl !== undefined && driveUrl.length > 0) {
|
|
101
|
+
const headless = options.headless ?? true;
|
|
102
|
+
// The one place that knows. Everything downstream reads it rather than re-deriving it, and a
|
|
103
|
+
// daemon that launches nothing keeps the default (ATTACHED) rather than guessing.
|
|
104
|
+
setBrowserMode(headless ? BrowserMode.HEADLESS : BrowserMode.HEADED);
|
|
105
|
+
const injectConnect = options.injectConnect;
|
|
106
|
+
const storageState = options.storageState;
|
|
107
|
+
const factory = options.realInputFactory ??
|
|
108
|
+
((opts) => new LaunchedRealInputProvider({
|
|
109
|
+
driveUrl: opts.driveUrl,
|
|
110
|
+
headless: opts.headless,
|
|
111
|
+
...(injectConnect !== undefined ? { injectConnect } : {}),
|
|
112
|
+
...(storageState !== undefined ? { storageState } : {}),
|
|
113
|
+
...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
|
|
114
|
+
}));
|
|
115
|
+
const launched = factory({ driveUrl, headless });
|
|
116
|
+
try {
|
|
117
|
+
await launched.navigate();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
await onNavigateError(); // no leaked WS port on a failed start
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
return { realInput: launched, owned: launched };
|
|
124
|
+
}
|
|
125
|
+
const cdpUrl = options.cdpUrl ?? process.env[ReticleEnv.CDP_URL];
|
|
126
|
+
if (cdpUrl !== undefined && cdpUrl.length > 0) {
|
|
127
|
+
// Same network sink as the launched path. Whether Reticle opened the browser or attached to one
|
|
128
|
+
// someone else opened has no bearing on whether it can read that browser's network.
|
|
129
|
+
const cdp = new CdpRealInputProvider({
|
|
130
|
+
cdpUrl,
|
|
131
|
+
...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
|
|
132
|
+
});
|
|
133
|
+
return { realInput: cdp, owned: cdp };
|
|
134
|
+
}
|
|
135
|
+
return {};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The SDK-upgrade sentence for the package.json of the project the page announced, evaluated at
|
|
139
|
+
* each HELLO so a just-edited manifest is what we name. The daemon's cwd only when that project's
|
|
140
|
+
* directory is unknown, and the framework-neutral sensor when that is not an app either (#1135).
|
|
141
|
+
*/
|
|
142
|
+
export function sdkFixForProject(projectId) {
|
|
143
|
+
return sdkFixForDirectory(SERVER_VERSION, projectDirectoryFor(projectId) ?? process.cwd());
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolve a session's artifact root, from everything this machine knows about where projects live.
|
|
147
|
+
*
|
|
148
|
+
* Built once per daemon and closed over by every tool call. The two sources are read lazily and
|
|
149
|
+
* cheaply on each call rather than snapshotted at startup: `init` can run in another terminal while
|
|
150
|
+
* this daemon is up, and a resolution that used a startup snapshot would keep answering with a map
|
|
151
|
+
* from before the project the agent is now driving existed.
|
|
152
|
+
*/
|
|
153
|
+
/**
|
|
154
|
+
* Every `.reticle` root on this machine that sync should consider, from the same two sources the
|
|
155
|
+
* artifact resolver uses.
|
|
156
|
+
*
|
|
157
|
+
* Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
|
|
158
|
+
* another terminal while this daemon is up, and a startup snapshot would keep that repo silent
|
|
159
|
+
* until somebody restarted a process they have no reason to suspect.
|
|
160
|
+
*
|
|
161
|
+
* Returns directories that MIGHT be linked; the caller resolves each and skips the ones that are
|
|
162
|
+
* not. Deciding that here would mean reading every cloud.json on every tick.
|
|
163
|
+
*/
|
|
164
|
+
export function knownProjectRoots() {
|
|
165
|
+
return [...new Set(knownProjectCandidates().map((c) => join(c.directory, ReticleDir.ROOT)))];
|
|
166
|
+
}
|
|
167
|
+
/** This project's platform credential (stored, else the env key), as the env the platform readers take. */
|
|
168
|
+
export const platformEnvFor = (root) => platformEnvPort(createNodeFileSystem(), root ?? join(process.cwd(), ReticleDir.ROOT), homedir(), process.env);
|
|
169
|
+
export const loadHarnessConfig = async (root) => fetchPlatformConfig(await platformEnvFor(root)());
|
package/dist/status-payload.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* answering requests. See takeVersionSkewOnto in command/version/version-nudge.ts.
|
|
8
8
|
*/
|
|
9
9
|
import type { SessionInfo } from './portal/session/session-info.js';
|
|
10
|
+
import { instrumentationOf, type InstrumentedTab } from './portal/session/recorded-gaps.js';
|
|
10
11
|
interface StatusPayload {
|
|
11
12
|
running: true;
|
|
12
13
|
version: string;
|
|
@@ -30,12 +31,23 @@ interface StatusPayload {
|
|
|
30
31
|
whyLead?: string;
|
|
31
32
|
/** Port of the verify HTTP endpoint this daemon serves — present only when started with `--http`. */
|
|
32
33
|
verifyPort?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Each connected tab's instrumentation coverage and, once a verdict recorded a gap, the prompt for
|
|
36
|
+
* a coding agent — what `reticle doctor` prints as its coverage line.
|
|
37
|
+
*/
|
|
38
|
+
coverage?: TabCoverage[];
|
|
33
39
|
}
|
|
40
|
+
type TabCoverage = {
|
|
41
|
+
sessionId: string;
|
|
42
|
+
url?: string;
|
|
43
|
+
} & ReturnType<typeof instrumentationOf>;
|
|
34
44
|
export declare function statusPayload(sessionCount: number, sessions: SessionInfo[],
|
|
35
45
|
/** The no-session diagnosis, injected so this stays pure and the port probe stays off this path. */
|
|
36
46
|
why?: string, verifyPort?: number,
|
|
37
47
|
/** The short rendering of the same diagnosis. Absent on a daemon that has no provider wired. */
|
|
38
|
-
whyLead?: string
|
|
48
|
+
whyLead?: string,
|
|
49
|
+
/** The live tabs, for their coverage. */
|
|
50
|
+
tabs?: readonly InstrumentedTab[]): StatusPayload;
|
|
39
51
|
/**
|
|
40
52
|
* Why `serve --http` cannot claim success against an already-running daemon — or undefined when
|
|
41
53
|
* that daemon already serves the verify HTTP endpoint on the wanted port.
|
|
@@ -47,4 +59,14 @@ whyLead?: string): StatusPayload;
|
|
|
47
59
|
* which errs loud rather than green.
|
|
48
60
|
*/
|
|
49
61
|
export declare function verifyEndpointMismatch(status: unknown, wantedPort: number): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* What a restart is about to do to the agents attached to the daemon whose `/status` this is, or
|
|
64
|
+
* undefined when nothing.
|
|
65
|
+
*
|
|
66
|
+
* A restart puts this CLI's version on the daemon. An agent whose own MCP server is older stays
|
|
67
|
+
* attached to a daemon it no longer matches, and a running agent cannot restart its own MCP server,
|
|
68
|
+
* so the restart that was meant to converge the versions strands it instead (#812). Said before the
|
|
69
|
+
* kill, with the way to restart at the version the attached agents run.
|
|
70
|
+
*/
|
|
71
|
+
export declare function strandedClientsNote(status: unknown, next?: string): string | undefined;
|
|
50
72
|
export {};
|
package/dist/status-payload.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { CONTRACT_FINGERPRINT } from '@reticlehq/core';
|
|
2
2
|
import { SERVER_VERSION } from './command/version/identity/server-version.js';
|
|
3
|
+
import { instrumentationOf } from './portal/session/recorded-gaps.js';
|
|
3
4
|
export function statusPayload(sessionCount, sessions,
|
|
4
5
|
/** The no-session diagnosis, injected so this stays pure and the port probe stays off this path. */
|
|
5
6
|
why, verifyPort,
|
|
6
7
|
/** The short rendering of the same diagnosis. Absent on a daemon that has no provider wired. */
|
|
7
|
-
whyLead
|
|
8
|
+
whyLead,
|
|
9
|
+
/** The live tabs, for their coverage. */
|
|
10
|
+
tabs = []) {
|
|
8
11
|
return {
|
|
9
12
|
running: true,
|
|
10
13
|
version: SERVER_VERSION,
|
|
@@ -16,6 +19,15 @@ whyLead) {
|
|
|
16
19
|
...(0 === sessionCount && why !== undefined ? { why } : {}),
|
|
17
20
|
...(0 === sessionCount && whyLead !== undefined ? { whyLead } : {}),
|
|
18
21
|
...(verifyPort === undefined ? {} : { verifyPort }),
|
|
22
|
+
...(0 === tabs.length
|
|
23
|
+
? {}
|
|
24
|
+
: {
|
|
25
|
+
coverage: tabs.map((tab) => ({
|
|
26
|
+
sessionId: tab.id,
|
|
27
|
+
...(tab.url === undefined ? {} : { url: tab.url }),
|
|
28
|
+
...instrumentationOf(tab),
|
|
29
|
+
})),
|
|
30
|
+
}),
|
|
19
31
|
};
|
|
20
32
|
}
|
|
21
33
|
/**
|
|
@@ -39,3 +51,26 @@ export function verifyEndpointMismatch(status, wantedPort) {
|
|
|
39
51
|
? `the daemon already running serves the verify HTTP endpoint on :${String(served)}, not :${String(wantedPort)} — ${fix}`
|
|
40
52
|
: `a daemon is already running without the verify HTTP endpoint — \`--http\` cannot be applied to it; ${fix}`;
|
|
41
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* What a restart is about to do to the agents attached to the daemon whose `/status` this is, or
|
|
56
|
+
* undefined when nothing.
|
|
57
|
+
*
|
|
58
|
+
* A restart puts this CLI's version on the daemon. An agent whose own MCP server is older stays
|
|
59
|
+
* attached to a daemon it no longer matches, and a running agent cannot restart its own MCP server,
|
|
60
|
+
* so the restart that was meant to converge the versions strands it instead (#812). Said before the
|
|
61
|
+
* kill, with the way to restart at the version the attached agents run.
|
|
62
|
+
*/
|
|
63
|
+
export function strandedClientsNote(status, next = SERVER_VERSION) {
|
|
64
|
+
const raw = 'object' === typeof status && null !== status
|
|
65
|
+
? status.mcpPeers
|
|
66
|
+
: undefined;
|
|
67
|
+
const peers = Array.isArray(raw) ? raw.filter((v) => 'string' === typeof v) : [];
|
|
68
|
+
const behind = [...new Set(peers.filter((v) => v !== next))];
|
|
69
|
+
const pin = behind[0];
|
|
70
|
+
if (pin === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
return (`warning: ${String(peers.length)} agent MCP server(s) are attached at ${behind.join(', ')}, ` +
|
|
73
|
+
`and this restart runs the daemon at ${next}. They stay attached to a daemon they no longer ` +
|
|
74
|
+
'match until their editor restarts its MCP server. To keep them working, restart at their ' +
|
|
75
|
+
`version instead: npx @reticlehq/server@${pin} restart`);
|
|
76
|
+
}
|
|
@@ -5,6 +5,7 @@ import { getSessionMetrics } from '../telemetry/session-metrics.js';
|
|
|
5
5
|
import { agentPeerSkew, PEER_VERSION_PARAM, PEER_CONTRACT_PARAM, } from '../command/version/peer-announce.js';
|
|
6
6
|
import { log } from '../log.js';
|
|
7
7
|
import { isLoopbackHost, isLocalWebOrigin, isLoopbackPeer, requestToken, tokensMatch, } from '../portal/bridge/token-auth.js';
|
|
8
|
+
import { clientDirectoryFromPeer, runWithClientDirectory } from '../hooks/client-directory.js';
|
|
8
9
|
import { LOOPBACK_IDLE_MS } from './loopback-agent.js';
|
|
9
10
|
/**
|
|
10
11
|
* Creates a shared HTTP server that handles both the WebSocket bridge (browser SDK) and the
|
|
@@ -27,6 +28,8 @@ export function createSharedServer(options = {}) {
|
|
|
27
28
|
* and this message is addressed to the proxy rather than to the client behind it.
|
|
28
29
|
*/
|
|
29
30
|
const sseStreams = new Map();
|
|
31
|
+
/** The version each attached agent's MCP server announced, by SSE session. */
|
|
32
|
+
const peerVersions = new Map();
|
|
30
33
|
const token = options.token;
|
|
31
34
|
// The agent control plane (MCP transport) and /status carry the same trust as the browser WS: a
|
|
32
35
|
// loopback peer is trusted (the local stdio proxy and `reticle status` always dial 127.0.0.1), but any
|
|
@@ -78,7 +81,11 @@ export function createSharedServer(options = {}) {
|
|
|
78
81
|
if ('GET' === req.method && path === STATUS_PATH) {
|
|
79
82
|
// A setup run waiting on this daemon says so on its polls; see daemon-usefulness.
|
|
80
83
|
const held = url.searchParams.has(STATUS_HOLD_QUERY);
|
|
81
|
-
const
|
|
84
|
+
const status = statusProvider?.(held) ?? { running: true };
|
|
85
|
+
// The attached agents' MCP versions, so `restart` can say whom it is about to strand (#812).
|
|
86
|
+
const body = JSON.stringify('object' === typeof status && null !== status && 0 < peerVersions.size
|
|
87
|
+
? { ...status, mcpPeers: [...peerVersions.values()] }
|
|
88
|
+
: status);
|
|
82
89
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
83
90
|
res.end(body);
|
|
84
91
|
return;
|
|
@@ -156,11 +163,15 @@ export function createSharedServer(options = {}) {
|
|
|
156
163
|
const sid = transport.sessionId;
|
|
157
164
|
transports.set(sid, transport);
|
|
158
165
|
sseStreams.set(sid, res);
|
|
166
|
+
const peerVersion = url.searchParams.get(PEER_VERSION_PARAM);
|
|
167
|
+
if (null !== peerVersion && 0 < peerVersion.length)
|
|
168
|
+
peerVersions.set(sid, peerVersion);
|
|
159
169
|
if (1 === transports.size)
|
|
160
170
|
agentPresence?.(true); // first agent attached
|
|
161
171
|
res.on('close', () => {
|
|
162
172
|
transports.delete(sid);
|
|
163
173
|
sseStreams.delete(sid);
|
|
174
|
+
peerVersions.delete(sid);
|
|
164
175
|
transport.close().catch(() => undefined);
|
|
165
176
|
mcpServer.close().catch(() => undefined);
|
|
166
177
|
log('mcp_client_disconnected', { sessionId: sid });
|
|
@@ -202,7 +213,12 @@ export function createSharedServer(options = {}) {
|
|
|
202
213
|
res.end('session not found');
|
|
203
214
|
return;
|
|
204
215
|
}
|
|
205
|
-
|
|
216
|
+
const clientDirectory = clientDirectoryFromPeer(isLoopbackPeer(req.socket.remoteAddress), req.headers);
|
|
217
|
+
const deliver = () => transport.handlePostMessage(req, res);
|
|
218
|
+
const posted = clientDirectory === undefined
|
|
219
|
+
? deliver()
|
|
220
|
+
: runWithClientDirectory(clientDirectory, deliver);
|
|
221
|
+
posted.catch((err) => {
|
|
206
222
|
const message = err instanceof Error ? err.message : String(err);
|
|
207
223
|
log('mcp_message_error', { error: message });
|
|
208
224
|
});
|
|
@@ -71,6 +71,7 @@ export declare function describeAttachState(state: AttachState): string | undefi
|
|
|
71
71
|
/** What `reticle status` reports about the client side of the install. */
|
|
72
72
|
interface AttachStatusFields {
|
|
73
73
|
mcpClient: AttachState;
|
|
74
|
+
mcpClientSaid: string;
|
|
74
75
|
mcpClientAction?: string;
|
|
75
76
|
}
|
|
76
77
|
/**
|
|
@@ -169,6 +169,13 @@ export function describeAttachState(state) {
|
|
|
169
169
|
return NEVER_CALLED_ACTION;
|
|
170
170
|
return undefined;
|
|
171
171
|
}
|
|
172
|
+
/** Each state in words, for a person: the state names are the record's, never the reader's. */
|
|
173
|
+
const ATTACH_STATE_SAID = {
|
|
174
|
+
[AttachState.ENUMERATED]: "✓ your agent has read and used Reticle's tools",
|
|
175
|
+
[AttachState.NEVER_CALLED]: "your agent read Reticle's tools and has not called one yet",
|
|
176
|
+
[AttachState.NEVER_ENUMERATED]: '✗ your agent started Reticle and never read its tools',
|
|
177
|
+
[AttachState.NEVER_ATTACHED]: 'no agent has started Reticle on this port yet',
|
|
178
|
+
};
|
|
172
179
|
/**
|
|
173
180
|
* The client-side fields for one `status` run.
|
|
174
181
|
*
|
|
@@ -181,5 +188,9 @@ export function attachStatusFields(stateDir, port) {
|
|
|
181
188
|
const action = describeAttachState(state);
|
|
182
189
|
// OMITTED rather than undefined: `exactOptionalPropertyTypes` is on, and an absent key is also
|
|
183
190
|
// what keeps the healthy line to one fact.
|
|
184
|
-
return {
|
|
191
|
+
return {
|
|
192
|
+
mcpClient: state,
|
|
193
|
+
mcpClientSaid: ATTACH_STATE_SAID[state],
|
|
194
|
+
...(action === undefined ? {} : { mcpClientAction: action }),
|
|
195
|
+
};
|
|
185
196
|
}
|
|
@@ -25,6 +25,8 @@ export declare const RECONNECT_INITIALIZE_ID = "__reticle_proxy_reinit";
|
|
|
25
25
|
export declare class PendingRequests {
|
|
26
26
|
#private;
|
|
27
27
|
observeOutbound(line: string): void;
|
|
28
|
+
/** Whether this unanswered request asked for a Harness drive. */
|
|
29
|
+
isDrive(id: unknown): boolean;
|
|
28
30
|
observeInbound(line: string): void;
|
|
29
31
|
get unanswered(): string[];
|
|
30
32
|
/**
|
|
@@ -34,6 +36,8 @@ export declare class PendingRequests {
|
|
|
34
36
|
take(id: unknown): boolean;
|
|
35
37
|
/** Take every unanswered id and forget them, so the same request is failed at most once. */
|
|
36
38
|
drain(): string[];
|
|
39
|
+
/** Forget which requests were drives, once their replies are written. */
|
|
40
|
+
clearDrives(): void;
|
|
37
41
|
}
|
|
38
42
|
/**
|
|
39
43
|
* JSON-RPC errors for every request that was in flight when the stream died.
|
|
@@ -99,6 +103,11 @@ export declare class HandshakeReplay {
|
|
|
99
103
|
* to reconnect and how to answer what it cannot send.
|
|
100
104
|
*/
|
|
101
105
|
export declare function buildSessionUrl(rawData: string, port: number): string | null;
|
|
106
|
+
/** The briefing's facts about this directory; a live session outweighs stale memory (#1138). */
|
|
107
|
+
export declare function instructionStateAt(port: number, liveSessions?: number): {
|
|
108
|
+
previouslyConnected: boolean;
|
|
109
|
+
appHere: boolean;
|
|
110
|
+
};
|
|
102
111
|
export declare function startMcpProxy(port: number,
|
|
103
112
|
/**
|
|
104
113
|
* Bring a daemon back before reconnecting. Without it the proxy retried a DEAD port until the
|
|
@@ -9,7 +9,7 @@ export { SseFrameParser } from './sse-frame-parser.js';
|
|
|
9
9
|
export { probeDaemon, waitForDaemon, waitForDaemonBind } from './proxy/proxy-daemon-probe.js';
|
|
10
10
|
import { probeDaemon } from './proxy/proxy-daemon-probe.js';
|
|
11
11
|
import { SERVER_VERSION } from '../../command/version/identity/server-version.js';
|
|
12
|
-
import { buildServerInstructions } from './server-instructions.js';
|
|
12
|
+
import { buildServerInstructions, localizeInstructions } from './server-instructions.js';
|
|
13
13
|
import { hasAnyProjectConnectedBefore } from '../../memory/recall/prior/connection-memory.js';
|
|
14
14
|
import { reticleStateHome } from '../../command/daemon/daemon.js';
|
|
15
15
|
import { projectIdsAt } from '../../command/cli/ports/resolve/cli-port.js';
|
|
@@ -17,6 +17,7 @@ import { PEER_VERSION_PARAM, PEER_CONTRACT_PARAM } from '../../command/version/p
|
|
|
17
17
|
import { onStreamDrop, onClientRequest, onReconnectBudgetSpent, onQueueExpired, OnDrop, OnRequest, } from './proxy/proxy-lifecycle.js';
|
|
18
18
|
import { describePresence, probePresence } from '../../command/daemon/binding/port-presence.js';
|
|
19
19
|
import { flushProxySessionMetrics } from '../../telemetry/proxy-telemetry.js';
|
|
20
|
+
import { detectStack } from '../../telemetry/feedback-context.js';
|
|
20
21
|
/**
|
|
21
22
|
* The same `/status` probe `doctor`, `status` and `kill` ask with. Reused rather than re-written:
|
|
22
23
|
* the whole defect this import closes was the proxy answering a DIFFERENT question from every other
|
|
@@ -31,6 +32,7 @@ export { accountProxyLogWrite, proxyLog, proxyLogPath, PROXY_LOG_CHECK_BYTES, re
|
|
|
31
32
|
import { proxyLog } from './proxy/proxy-log.js';
|
|
32
33
|
import { OutageReason, OutageStage, reportMcpOutage } from './faults/mcp-outage.js';
|
|
33
34
|
import { postToSession } from './proxy/mcp-post-transport.js';
|
|
35
|
+
import { MSG_DRIVE_MAY_BE_RUNNING, isHarnessDriveCall } from './proxy/drive-calls.js';
|
|
34
36
|
import { reconnectDelayMs } from './proxy/proxy-backoff.js';
|
|
35
37
|
import { PROXY_IDLE_EXIT_EVENT, ProxyIdleExit, resolveProxyIdleExitMs } from './proxy-idle-exit.js';
|
|
36
38
|
export { reconnectDelayMs } from './proxy/proxy-backoff.js';
|
|
@@ -83,11 +85,20 @@ const INITIALIZED_METHOD = 'notifications/initialized';
|
|
|
83
85
|
*/
|
|
84
86
|
export class PendingRequests {
|
|
85
87
|
#ids = new Set();
|
|
88
|
+
/** The pending requests that start or poll a Harness drive, which outlives a lost connection. */
|
|
89
|
+
#drives = new Set();
|
|
86
90
|
observeOutbound(line) {
|
|
87
91
|
const msg = parseJsonRpc(line);
|
|
88
92
|
if (null === msg || msg.id === undefined || msg.method === undefined)
|
|
89
93
|
return;
|
|
90
|
-
|
|
94
|
+
const id = JSON.stringify(msg.id);
|
|
95
|
+
this.#ids.add(id);
|
|
96
|
+
if (isHarnessDriveCall(msg))
|
|
97
|
+
this.#drives.add(id);
|
|
98
|
+
}
|
|
99
|
+
/** Whether this unanswered request asked for a Harness drive. */
|
|
100
|
+
isDrive(id) {
|
|
101
|
+
return this.#drives.has(JSON.stringify(id));
|
|
91
102
|
}
|
|
92
103
|
observeInbound(line) {
|
|
93
104
|
const msg = parseJsonRpc(line);
|
|
@@ -103,6 +114,7 @@ export class PendingRequests {
|
|
|
103
114
|
* a duplicate response to one id is a protocol violation, not a belt-and-braces retry.
|
|
104
115
|
*/
|
|
105
116
|
take(id) {
|
|
117
|
+
this.#drives.delete(JSON.stringify(id));
|
|
106
118
|
return this.#ids.delete(JSON.stringify(id));
|
|
107
119
|
}
|
|
108
120
|
/** Take every unanswered id and forget them, so the same request is failed at most once. */
|
|
@@ -111,6 +123,10 @@ export class PendingRequests {
|
|
|
111
123
|
this.#ids.clear();
|
|
112
124
|
return ids;
|
|
113
125
|
}
|
|
126
|
+
/** Forget which requests were drives, once their replies are written. */
|
|
127
|
+
clearDrives() {
|
|
128
|
+
this.#drives.clear();
|
|
129
|
+
}
|
|
114
130
|
}
|
|
115
131
|
/**
|
|
116
132
|
* JSON-RPC errors for every request that was in flight when the stream died.
|
|
@@ -125,9 +141,12 @@ export class PendingRequests {
|
|
|
125
141
|
* with the MCP server still perfectly alive. An agent cannot tell that apart from "still working".
|
|
126
142
|
*/
|
|
127
143
|
export function streamLossReplies(pending, reason, nextStep) {
|
|
128
|
-
|
|
129
|
-
.
|
|
130
|
-
|
|
144
|
+
const replies = pending.drain().map((id) => {
|
|
145
|
+
const parsed = JSON.parse(id);
|
|
146
|
+
return transportLossReply(parsed, reason, nextStep, pending.isDrive(parsed));
|
|
147
|
+
});
|
|
148
|
+
pending.clearDrives();
|
|
149
|
+
return replies;
|
|
131
150
|
}
|
|
132
151
|
/**
|
|
133
152
|
* -32001: a server-defined error. Not -32603 (internal): nothing went wrong INSIDE the call, the
|
|
@@ -141,14 +160,16 @@ const TRANSPORT_LOSS_CODE = -32001;
|
|
|
141
160
|
* `nextStep` is appended when the caller knows one. Without it this reply describes a condition and
|
|
142
161
|
* stops there, which is all a first-run user got out of their first ever tool call.
|
|
143
162
|
*/
|
|
144
|
-
function transportLossReply(id, reason, nextStep) {
|
|
163
|
+
function transportLossReply(id, reason, nextStep, drive = false) {
|
|
145
164
|
return JSON.stringify({
|
|
146
165
|
jsonrpc: '2.0',
|
|
147
166
|
id,
|
|
148
167
|
error: {
|
|
149
168
|
code: TRANSPORT_LOSS_CODE,
|
|
150
|
-
message:
|
|
151
|
-
|
|
169
|
+
message: (drive
|
|
170
|
+
? `the daemon connection dropped (${reason}) before this call was answered. ${MSG_DRIVE_MAY_BE_RUNNING}`
|
|
171
|
+
: `the daemon connection dropped (${reason}) before this call was answered — it did NOT ` +
|
|
172
|
+
'complete. Reticle is recovering the connection; retry if the action is safe to repeat.') +
|
|
152
173
|
(nextStep === undefined ? '' : ` ${nextStep}`),
|
|
153
174
|
},
|
|
154
175
|
});
|
|
@@ -288,14 +309,43 @@ export function buildSessionUrl(rawData, port) {
|
|
|
288
309
|
*/
|
|
289
310
|
function proxyInstructions(port) {
|
|
290
311
|
try {
|
|
291
|
-
return buildServerInstructions(
|
|
292
|
-
previouslyConnected: hasAnyProjectConnectedBefore(reticleStateHome(), port, projectIdsAt(process.cwd())),
|
|
293
|
-
});
|
|
312
|
+
return buildServerInstructions(instructionStateAt(port));
|
|
294
313
|
}
|
|
295
314
|
catch {
|
|
296
315
|
return buildServerInstructions({ previouslyConnected: false });
|
|
297
316
|
}
|
|
298
317
|
}
|
|
318
|
+
/** The briefing's facts about this directory; a live session outweighs stale memory (#1138). */
|
|
319
|
+
export function instructionStateAt(port, liveSessions = 0) {
|
|
320
|
+
const cwd = process.cwd();
|
|
321
|
+
return {
|
|
322
|
+
previouslyConnected: liveSessions > 0 || hasAnyProjectConnectedBefore(reticleStateHome(), port, projectIdsAt(cwd)),
|
|
323
|
+
appHere: detectStack(cwd).stack !== undefined,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
/** An `initialize` reply re-briefed for the AGENT's directory; see localizeInstructions. */
|
|
327
|
+
function withLocalBriefing(line, appHere) {
|
|
328
|
+
if (!line.includes('"instructions"'))
|
|
329
|
+
return line;
|
|
330
|
+
try {
|
|
331
|
+
const msg = JSON.parse(line);
|
|
332
|
+
if (null === msg || 'object' !== typeof msg || !('result' in msg))
|
|
333
|
+
return line;
|
|
334
|
+
const result = msg.result;
|
|
335
|
+
if (null === result || 'object' !== typeof result || !('instructions' in result))
|
|
336
|
+
return line;
|
|
337
|
+
const { instructions } = result;
|
|
338
|
+
if ('string' !== typeof instructions)
|
|
339
|
+
return line;
|
|
340
|
+
const localized = localizeInstructions(instructions, appHere);
|
|
341
|
+
if (localized === instructions)
|
|
342
|
+
return line;
|
|
343
|
+
return JSON.stringify({ ...msg, result: { ...result, instructions: localized } });
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return line;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
299
349
|
export function startMcpProxy(port,
|
|
300
350
|
/**
|
|
301
351
|
* Bring a daemon back before reconnecting. Without it the proxy retried a DEAD port until the
|
|
@@ -395,6 +445,7 @@ onUsableSession = () => undefined) {
|
|
|
395
445
|
queueTimer.unref();
|
|
396
446
|
};
|
|
397
447
|
const replay = new HandshakeReplay();
|
|
448
|
+
const appHere = detectStack(process.cwd()).stack !== undefined;
|
|
398
449
|
const pending = new PendingRequests();
|
|
399
450
|
const quit = (code) => {
|
|
400
451
|
if (stopped)
|
|
@@ -421,7 +472,7 @@ onUsableSession = () => undefined) {
|
|
|
421
472
|
const emit = (line) => {
|
|
422
473
|
idleExit.noteTraffic();
|
|
423
474
|
pending.observeInbound(line);
|
|
424
|
-
process.stdout.write(`${line}\n`);
|
|
475
|
+
process.stdout.write(`${withLocalBriefing(line, appHere)}\n`);
|
|
425
476
|
};
|
|
426
477
|
let attempts = 0;
|
|
427
478
|
/** The daemon announced a planned shutdown; the next drop is that, not a fault. */
|
|
@@ -459,6 +510,7 @@ onUsableSession = () => undefined) {
|
|
|
459
510
|
if (null === failure)
|
|
460
511
|
return;
|
|
461
512
|
const msg = parseJsonRpc(line);
|
|
513
|
+
const drive = null !== msg && pending.isDrive(msg.id);
|
|
462
514
|
if (null === msg || msg.id === undefined || !pending.take(msg.id))
|
|
463
515
|
return;
|
|
464
516
|
// No outage is reported here, deliberately. A POST leg that died while the SSE stream is
|
|
@@ -472,7 +524,7 @@ onUsableSession = () => undefined) {
|
|
|
472
524
|
reason: failure.reason,
|
|
473
525
|
note: 'the stream is still up, so nothing else would ever have answered this call',
|
|
474
526
|
});
|
|
475
|
-
emit(transportLossReply(msg.id, failure.reason));
|
|
527
|
+
emit(transportLossReply(msg.id, failure.reason, undefined, drive));
|
|
476
528
|
});
|
|
477
529
|
};
|
|
478
530
|
function onSseEvent(event, data, p) {
|
|
@@ -3,15 +3,21 @@ import { z } from 'zod';
|
|
|
3
3
|
import { type ToolDeps } from '../tools/tools.js';
|
|
4
4
|
import type { ToolDef } from '../tools/tools.js';
|
|
5
5
|
import { type ToolSurface } from '../tools/tool-surface.js';
|
|
6
|
+
import { type ToolCall } from '../tools/tool-kit.js';
|
|
7
|
+
import { type InstructionState } from './server-instructions.js';
|
|
6
8
|
/** The JSON-RPC method the SDK registers its tool dispatcher under. */
|
|
7
9
|
export declare const CALL_TOOL_METHOD = "tools/call";
|
|
8
10
|
/**
|
|
9
|
-
* Merge the runtime-spliced envelope
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Merge the runtime-spliced envelope into a tool's declared outputSchema so structuredContent
|
|
12
|
+
* validation keeps those fields instead of rejecting the call. The tool's own keys win over the
|
|
13
|
+
* permissive envelope defaults (e.g. ACT keeps its typed `session` shape).
|
|
14
|
+
*
|
|
15
|
+
* EVERY tool with an output schema, not only the session-bound ones: `runTool` adds `next`,
|
|
16
|
+
* `update_available`, `version_skew` and the feedback keys to any tool's result, and a session-exempt
|
|
17
|
+
* tool with a strict schema (`reticle_context`) failed the whole call on a validating client the
|
|
18
|
+
* first time one of them rode on it.
|
|
13
19
|
*/
|
|
14
|
-
export declare function withSessionEnvelope(
|
|
20
|
+
export declare function withSessionEnvelope(_name: string, outputSchema: z.ZodRawShape | undefined): z.ZodRawShape | undefined;
|
|
15
21
|
/**
|
|
16
22
|
* Abbreviations whose internal period is NOT a sentence end.
|
|
17
23
|
*
|
|
@@ -31,6 +37,28 @@ export { firstSentence } from '../tools/first-sentence.js';
|
|
|
31
37
|
* form with `RETICLE_ENCODING=pretty`; `RETICLE_ENCODING=toon` is the even-denser tabular encoding.
|
|
32
38
|
*/
|
|
33
39
|
export declare function encodeResult(result: unknown, encoding: string): string;
|
|
40
|
+
/** The slice of the SDK's per-request `extra` a tool call reads: cancellation and progress. */
|
|
41
|
+
interface McpRequestExtra {
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
_meta?: {
|
|
44
|
+
progressToken?: string | number;
|
|
45
|
+
};
|
|
46
|
+
sendNotification?: (notification: {
|
|
47
|
+
method: typeof PROGRESS_NOTIFICATION;
|
|
48
|
+
params: {
|
|
49
|
+
progressToken: string | number;
|
|
50
|
+
progress: number;
|
|
51
|
+
message: string;
|
|
52
|
+
};
|
|
53
|
+
}) => Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
declare const PROGRESS_NOTIFICATION = "notifications/progress";
|
|
56
|
+
/**
|
|
57
|
+
* The request's cancellation and, when the client sent a progress token, a progress reporter. A
|
|
58
|
+
* long call (a Harness drive's wait) reports each step, so a client that resets its timeout on
|
|
59
|
+
* progress keeps waiting instead of abandoning a call that is working.
|
|
60
|
+
*/
|
|
61
|
+
export declare function toolCallOf(extra: McpRequestExtra | undefined): ToolCall;
|
|
34
62
|
/**
|
|
35
63
|
* The tools a profile advertises directly.
|
|
36
64
|
*
|
|
@@ -77,7 +105,7 @@ export declare function createMcpServer(rawDeps: ToolDeps, profile?: ToolSurface
|
|
|
77
105
|
* told to instrument a project that is already wired loses a paragraph, while an agent not told
|
|
78
106
|
* loses the entire install — and the second is what the field overwhelmingly shows.
|
|
79
107
|
*/
|
|
80
|
-
previouslyConnected?: boolean,
|
|
108
|
+
previouslyConnected?: boolean | Omit<InstructionState, 'advertised'>,
|
|
81
109
|
/**
|
|
82
110
|
* The full tool table this server serves. Defaults to what this package ships.
|
|
83
111
|
*
|