@reticlehq/server 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +122 -123
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +18 -2
- package/dist/command/cli/adhoc-verdict.js +70 -6
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +28 -105
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +34 -4
- package/dist/command/cli/cli-verify.js +81 -12
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +145 -333
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +15 -1
- package/dist/command/cli/cloud-login.js +67 -13
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.js +1 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +29 -8
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -178
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +14 -0
- package/dist/command/cli.js +103 -83
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +9 -1
- package/dist/command/daemon/daemon-resolve.js +49 -10
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +10 -1
- package/dist/command/setup/init/init-port.js +22 -2
- package/dist/command/setup/init/init-runtime.d.ts +12 -2
- package/dist/command/setup/init/init-runtime.js +96 -37
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +36 -8
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +1 -1
- package/dist/command/setup/run-setup.d.ts +29 -9
- package/dist/command/setup/run-setup.js +34 -28
- package/dist/command/setup/setup-command.d.ts +23 -0
- package/dist/command/setup/setup-command.js +57 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +38 -2
- package/dist/features/crawl/crawl.js +14 -1
- package/dist/features/exhaust/ledger.d.ts +14 -14
- package/dist/features/harness/drive-report.d.ts +39 -5
- package/dist/features/harness/drive-report.js +271 -54
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/goals.d.ts +68 -7
- package/dist/features/harness/goals.js +289 -36
- package/dist/features/harness/harness.d.ts +30 -1
- package/dist/features/harness/harness.js +141 -7
- package/dist/features/harness/platform/local-apps.d.ts +36 -3
- package/dist/features/harness/platform/local-apps.js +81 -5
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +8 -2
- package/dist/features/harness/platform/remote-drive.js +22 -9
- package/dist/features/harness/platform/script.d.ts +57 -11
- package/dist/features/harness/platform/script.js +144 -12
- package/dist/features/harness/platform/server-driver.d.ts +17 -4
- package/dist/features/harness/platform/server-driver.js +29 -26
- package/dist/features/harness/platform-config.d.ts +38 -5
- package/dist/features/harness/platform-config.js +93 -8
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/script-run.d.ts +30 -1
- package/dist/features/harness/script/script-run.js +355 -48
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.js +22 -14
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +21 -2
- package/dist/hooks/driven-by.js +42 -2
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -183
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
- package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
- package/dist/judgement/runs/artifact/run-store.js +175 -8
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +53 -5
- package/dist/judgement/runs/drive-run.js +234 -20
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +5 -2
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +2 -0
- package/dist/judgement/runs/verification-sync.js +36 -15
- package/dist/language/flows/decision.js +2 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +7 -2
- package/dist/language/flows/flow-anchor.js +10 -3
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +37 -3
- package/dist/language/flows/flow-replay-run.js +16 -18
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +18 -1
- package/dist/language/flows/flow-replay.js +22 -7
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-step-runners.d.ts +2 -0
- package/dist/language/flows/flow-step-runners.js +12 -6
- package/dist/language/flows/flow-store-for-session.js +5 -1
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +61 -62
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +69 -10
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
- package/dist/language/flows/recording/tape/recordings.js +60 -10
- package/dist/language/flows/replay.js +29 -6
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +200 -193
- package/dist/memory/cloud/cloud-config.d.ts +10 -1
- package/dist/memory/cloud/cloud-config.js +19 -5
- package/dist/memory/cloud/cloud-sync.js +3 -3
- package/dist/memory/cloud/harness-config.d.ts +49 -0
- package/dist/memory/cloud/harness-config.js +16 -20
- package/dist/memory/cloud/memory-scope.d.ts +17 -0
- package/dist/memory/cloud/memory-scope.js +22 -0
- package/dist/memory/cloud/sync-cycle.d.ts +32 -4
- package/dist/memory/cloud/sync-cycle.js +113 -12
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +114 -4
- package/dist/memory/cloud/sync-disk.js +26 -2
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +16 -1
- package/dist/memory/impact/account-watch.js +26 -1
- package/dist/memory/impact/impact-store.d.ts +1 -4
- package/dist/memory/impact/impact-store.js +32 -42
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +12 -0
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +42 -2
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/journal-recorder.js +46 -3
- package/dist/memory/journal/on-disk/retention.d.ts +5 -0
- package/dist/memory/journal/on-disk/retention.js +27 -2
- package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +38 -7
- package/dist/memory/project/artifact-root-resolver.js +33 -5
- package/dist/memory/project/artifact-root.d.ts +4 -3
- package/dist/memory/project/artifact-root.js +2 -2
- package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
- package/dist/memory/project/dir/reticle-dir.js +23 -2
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +2 -0
- package/dist/memory/project/session-root.js +9 -1
- package/dist/memory/project/sync-status.d.ts +46 -0
- package/dist/memory/project/sync-status.js +135 -1
- package/dist/memory/recall/memory-tools.js +46 -3
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.js +36 -8
- package/dist/portal/bridge/bridge.d.ts +9 -5
- package/dist/portal/bridge/bridge.js +66 -23
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +2 -0
- package/dist/portal/input/real-input.js +13 -10
- package/dist/portal/pool/browser-pool.d.ts +48 -0
- package/dist/portal/pool/browser-pool.js +120 -2
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +27 -5
- package/dist/portal/pool/playwright-launcher.js +59 -14
- package/dist/portal/pool/pool-contract.d.ts +21 -1
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.js +6 -1
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
- package/dist/portal/session/dev-server/dev-command.js +27 -1
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/live-control-tools.js +82 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
- package/dist/portal/session/no-session-diagnosis.js +31 -9
- package/dist/portal/session/no-session-next-action.d.ts +20 -0
- package/dist/portal/session/no-session-next-action.js +134 -61
- package/dist/portal/session/no-session-watch.js +179 -22
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/session-health.d.ts +11 -0
- package/dist/portal/session/session-health.js +3 -1
- package/dist/portal/session/session-info.js +2 -1
- package/dist/portal/session/session-manager.d.ts +18 -0
- package/dist/portal/session/session-manager.js +54 -3
- package/dist/portal/session/session-successor.d.ts +8 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session.d.ts +15 -28
- package/dist/portal/session/session.js +60 -61
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +7 -1
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +13 -1
- package/dist/status-payload.js +13 -1
- package/dist/surface/http-server.js +7 -1
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
- package/dist/surface/mcp/mcp-proxy.js +29 -8
- package/dist/surface/mcp/mcp.d.ts +23 -0
- package/dist/surface/mcp/mcp.js +34 -4
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.js +22 -14
- package/dist/surface/mcp/shared-params.js +1 -1
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act-sequence-tool.js +136 -27
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +48 -34
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.js +25 -15
- package/dist/surface/tools/browser-tools.js +43 -1
- package/dist/surface/tools/chat-drives.d.ts +75 -0
- package/dist/surface/tools/chat-drives.js +265 -21
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +10 -0
- package/dist/surface/tools/empty-session-list.js +45 -5
- package/dist/surface/tools/error-recovery.d.ts +8 -0
- package/dist/surface/tools/error-recovery.js +69 -5
- package/dist/surface/tools/explore-tools.d.ts +23 -2
- package/dist/surface/tools/explore-tools.js +377 -74
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +4 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +52 -73
- package/dist/surface/tools/harness-explore.js +177 -146
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +5 -0
- package/dist/surface/tools/harness-plan.js +7 -0
- package/dist/surface/tools/harness-script.d.ts +22 -0
- package/dist/surface/tools/harness-script.js +256 -38
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +8 -0
- package/dist/surface/tools/harness-toolset.js +27 -4
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +220 -93
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +20 -0
- package/dist/surface/tools/lease-seed.js +45 -1
- package/dist/surface/tools/lease-tools.d.ts +10 -1
- package/dist/surface/tools/lease-tools.js +119 -69
- package/dist/surface/tools/live-call-text.js +2 -2
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +11 -1
- package/dist/surface/tools/next-step.js +73 -18
- package/dist/surface/tools/observe-tools.js +43 -5
- package/dist/surface/tools/platform-moment.d.ts +60 -0
- package/dist/surface/tools/platform-moment.js +132 -4
- package/dist/surface/tools/read-tools.js +65 -14
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +68 -2
- package/dist/surface/tools/tool-kit.js +73 -1
- package/dist/surface/tools/tools.js +25 -13
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +27 -6
- package/dist/telemetry/hud-metrics.js +99 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +26 -2
- package/dist/telemetry/telemetry.js +102 -21
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +12 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +16 -5
- package/docs/README.md +2 -2
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +24 -27
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +13 -12
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +8 -3
- package/docs/cli/drive.mdx +12 -12
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +32 -15
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +13 -4
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +3 -2
- package/docs/cli.mdx +110 -41
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +5 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +5 -2
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +66 -64
- package/docs/human-control.md +15 -14
- package/docs/index.mdx +15 -43
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +22 -12
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +8 -8
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +11 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +58 -29
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +22 -24
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +13 -4
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +51 -45
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +7 -5
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +6 -5
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -249
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { WebSocket } from 'ws';
|
|
2
2
|
import { type ChannelId, type ImpactSnapshot, type ProjectId } from '@reticlehq/core';
|
|
3
|
+
import { type NarrationBy } from './narration-args.js';
|
|
3
4
|
import type { HandshakeFacts } from './facts/handshake-facts.js';
|
|
4
5
|
import { LastAct } from './last-act.js';
|
|
5
6
|
import { GapLedger } from '@reticlehq/engine/evidence/gap-ledger.js';
|
|
6
|
-
import { CaptureLedger } from '../../surface/tools/feature-capture.js';
|
|
7
7
|
import { type PageRuntime } from './timing/command-timeout.js';
|
|
8
8
|
import { readHealthEvent, type SessionHealth } from './session-health.js';
|
|
9
9
|
export type { SessionHealth };
|
|
@@ -15,8 +15,8 @@ import { type InboxMessage } from './human/live-control.js';
|
|
|
15
15
|
export type { InboxMessage } from './human/live-control.js';
|
|
16
16
|
import { type ReviewMark } from './human/review-store.js';
|
|
17
17
|
import { type SessionLease } from './presence/session-lease.js';
|
|
18
|
-
import type { SessionInfo } from './session-info.js';
|
|
19
18
|
export type { SessionInfo } from './session-info.js';
|
|
19
|
+
import { type SessionInfo } from './session-info.js';
|
|
20
20
|
type Clock = () => number;
|
|
21
21
|
/**
|
|
22
22
|
* One connected browser tab. Owns its socket, a ring buffer of observations, and the
|
|
@@ -35,13 +35,8 @@ export declare class Session implements HandshakeFacts {
|
|
|
35
35
|
readonly projectId: ProjectId | undefined;
|
|
36
36
|
/**
|
|
37
37
|
* The `.reticle` directory this session's evidence belongs in — impact counters AND capsules.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* resolved per call: the answer cannot change while the tab is connected, and resolving it once
|
|
41
|
-
* means every counter that fires for this session agrees about where it goes.
|
|
42
|
-
*
|
|
43
|
-
* Undefined when nothing could name a project — the caller then falls back to the daemon's own
|
|
44
|
-
* root, which is what every counter did unconditionally before this existed.
|
|
38
|
+
* Stamped once, from the project it declared in HELLO, so every counter agrees where it goes.
|
|
39
|
+
* Undefined when nothing could name a project: callers fall back to the daemon's own root.
|
|
45
40
|
*/
|
|
46
41
|
artifactRoot: string | undefined;
|
|
47
42
|
/**
|
|
@@ -62,6 +57,8 @@ export declare class Session implements HandshakeFacts {
|
|
|
62
57
|
readonly redactKeys: readonly string[];
|
|
63
58
|
/** The desktop window this is and its document's HTTP status, merged from every PAGE_HEALTH. */
|
|
64
59
|
readonly page: ReturnType<typeof readHealthEvent>['page'];
|
|
60
|
+
/** The newest journal action: a verdict's screenshot names it, so the run pairs it with its check. */
|
|
61
|
+
lastActionId: string | undefined;
|
|
65
62
|
constructor(hello: HelloMessage, socket: WebSocket, clock: Clock);
|
|
66
63
|
/** Milliseconds since this session connected — the authoritative buffer clock. */
|
|
67
64
|
elapsed(): number;
|
|
@@ -107,7 +104,7 @@ export declare class Session implements HandshakeFacts {
|
|
|
107
104
|
preconditionFailure(): string | undefined;
|
|
108
105
|
/** What the rules that decide a verdict need from the daemon. See daemon-answers.ts. */
|
|
109
106
|
readonly note: typeof import("../../log.js").log;
|
|
110
|
-
readonly keepCallerContext:
|
|
107
|
+
readonly keepCallerContext: <A extends unknown[]>(fn: (...args: A) => void) => ((...args: A) => void);
|
|
111
108
|
/** Re-stamp an incoming event with server-relative time, buffer it, and fan out. */
|
|
112
109
|
pushEvent(event: ReticleEvent, byteSize?: number): void;
|
|
113
110
|
recordActedRef(ref: string): void;
|
|
@@ -124,7 +121,7 @@ export declare class Session implements HandshakeFacts {
|
|
|
124
121
|
provedLabels(): ReadonlySet<string>;
|
|
125
122
|
actedRefs(): ReadonlySet<string>;
|
|
126
123
|
noteRateLimited(dropped: number): void;
|
|
127
|
-
blindSpots(): Readonly<Record<string, number>>;
|
|
124
|
+
blindSpots(since?: number): Readonly<Record<string, number>>;
|
|
128
125
|
/** Learned ambient-churn counts (PredicateSession hook the settle oracle reads). */
|
|
129
126
|
ambientCounts(): AmbientCounts;
|
|
130
127
|
/** Only what THIS session observed — what teardown accumulates onto the persisted map. */
|
|
@@ -144,10 +141,7 @@ export declare class Session implements HandshakeFacts {
|
|
|
144
141
|
queryEvents(options: EventQueryOptions): Promise<ReticleEvent[]>;
|
|
145
142
|
/** What the durable ledger could not WRITE — see `readJournalWriteLoss` for the rule and why. */
|
|
146
143
|
journalWriteLoss(): Promise<JournalWriteLoss | undefined>;
|
|
147
|
-
/**
|
|
148
|
-
* Open an action-attribution window: events observed until finishAction attribute to the returned
|
|
149
|
-
* action id. Ids are minted independently of command correlation ids so the journal is self-contained.
|
|
150
|
-
*/
|
|
144
|
+
/** Open an attribution window: events until finishAction carry the returned (journal-own) id. */
|
|
151
145
|
beginAction(tool: string, args: Record<string, unknown>): string;
|
|
152
146
|
/**
|
|
153
147
|
* Record one action WITHOUT opening an attribution window — for a tool that returns a verdict but
|
|
@@ -189,11 +183,6 @@ export declare class Session implements HandshakeFacts {
|
|
|
189
183
|
* end of it.
|
|
190
184
|
*/
|
|
191
185
|
readonly gaps: GapLedger;
|
|
192
|
-
/**
|
|
193
|
-
* The read-only calls the journal does not keep, so "was `reticle_context` ever called" has
|
|
194
|
-
* something to fold. See surface/tools/feature-capture.ts — it is the only state that instrument adds.
|
|
195
|
-
*/
|
|
196
|
-
readonly capture: CaptureLedger;
|
|
197
186
|
/**
|
|
198
187
|
* Stamp the wall-clock of the latest AGENT command (called whenever a tool resolves this session).
|
|
199
188
|
* If the reaper had auto-ended the session, a fresh command means the agent is alive again, so the
|
|
@@ -245,9 +234,9 @@ export declare class Session implements HandshakeFacts {
|
|
|
245
234
|
* summary) so a transition never emits two PRESENTER commands.
|
|
246
235
|
*/
|
|
247
236
|
setState(next: SessionState, text?: string, tone?: PresenterTone): void;
|
|
248
|
-
/** Push a human note onto the inbox (see LiveControl). */
|
|
237
|
+
/** Push a human note onto the inbox (see LiveControl); the HUD shows it as sent. */
|
|
249
238
|
pushMessage(text: string): void;
|
|
250
|
-
/** Queued human notes, cleared as they are read (delivered-once). */
|
|
239
|
+
/** Queued human notes, cleared as they are read (delivered-once); the HUD shows them as seen. */
|
|
251
240
|
drainInbox(): InboxMessage[];
|
|
252
241
|
/** Diagnostic read of the inbox depth (does not clear). */
|
|
253
242
|
inboxSize(): number;
|
|
@@ -267,15 +256,13 @@ export declare class Session implements HandshakeFacts {
|
|
|
267
256
|
*/
|
|
268
257
|
applyHumanControl(data: HumanControlData): void;
|
|
269
258
|
/**
|
|
270
|
-
* Push the impact record to this tab's HUD.
|
|
271
|
-
*
|
|
272
|
-
* Debounced: the record changes on every tool call, and the panel does not need 200 frames to
|
|
273
|
-
* show a counter going up. The LAST state always lands, because the timer re-reads the store
|
|
274
|
-
* when it fires rather than capturing a snapshot when it was scheduled.
|
|
259
|
+
* Push the impact record to this tab's HUD. Debounced (a counter needs no 200 frames); the LAST
|
|
260
|
+
* state always lands, because the timer re-reads the store when it fires.
|
|
275
261
|
*/
|
|
276
262
|
pushImpact(read: () => ImpactSnapshot | undefined, immediate?: boolean): void;
|
|
277
263
|
pushPresenter(state: SessionState, text?: string, tone?: PresenterTone): void;
|
|
278
|
-
|
|
264
|
+
/** `mirror: false` for a notice about THIS page (its SDK is behind), which every tab says itself. */
|
|
265
|
+
pushNarration(text: string, mirror?: boolean, by?: NarrationBy): void;
|
|
279
266
|
/** A HUD replay's progress, or the Harness's drive plan: pictures the HUD redraws as they change. */
|
|
280
267
|
pushView(name: typeof ReticleCommand.FLOW_PROGRESS | typeof ReticleCommand.PLAN, args: object): void;
|
|
281
268
|
/** The one-time lease block on the first agent command, then undefined forever after. */
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { asProjectId } from '@reticlehq/core';
|
|
2
|
+
import { narrationArgs } from './narration-args.js';
|
|
2
3
|
import { refusedResult } from './page-commands/undeclared-command.js';
|
|
3
|
-
import { recordImpact } from '../../memory/impact/impact-recorder.js';
|
|
4
|
+
import { impactSnapshot, recordImpact } from '../../memory/impact/impact-recorder.js';
|
|
5
|
+
import { callingAgent } from '../../hooks/coding-agents.js';
|
|
4
6
|
import { recordNotes } from './human/notes-ledger.js';
|
|
5
7
|
import { commandPayload } from './command-payload.js';
|
|
6
8
|
import { LastAct } from './last-act.js';
|
|
7
9
|
import { GapLedger } from '@reticlehq/engine/evidence/gap-ledger.js';
|
|
8
|
-
import { CaptureLedger } from '../../surface/tools/feature-capture.js';
|
|
9
10
|
import { commandTimeoutMessage } from './timing/command-timeout.js';
|
|
10
11
|
import { readHealthEvent, healthNotices } from './session-health.js';
|
|
11
12
|
import { MIRRORED_COMMANDS, mirroredNarration } from './presence/session-mirror.js';
|
|
@@ -20,13 +21,15 @@ import { readJournalWriteLoss, readQueryEvents, windowLost, } from '../../memory
|
|
|
20
21
|
import {} from '@reticlehq/engine/window/ambient.js';
|
|
21
22
|
import { ObservedState, controlLabelsOf } from './facts/observed-state.js';
|
|
22
23
|
import { DepartureNote } from './facts/departure-note.js';
|
|
23
|
-
import { recordBrowserLatency,
|
|
24
|
+
import { recordBrowserLatency, recordSdkFailure } from '../../telemetry/session-metrics.js';
|
|
25
|
+
import { noteHudTabClosed, noteHudTabHidden, reportHudUse } from '../../telemetry/hud-events.js';
|
|
24
26
|
import { LiveControl } from './human/live-control.js';
|
|
25
27
|
import { ReviewStore } from './human/review-store.js';
|
|
26
28
|
import { buildSessionRecommendation } from './presence/session-recommendation.js';
|
|
27
29
|
import { buildPresenterArgs } from './human/presenter-args.js';
|
|
28
30
|
import { buildSessionLease } from './presence/session-lease.js';
|
|
29
31
|
import { buildSessionInfo } from './session-info.js';
|
|
32
|
+
import { notedAct, probeMarkers, withInstrumentation } from './recorded-gaps.js';
|
|
30
33
|
import { MAX_SUCCESSOR_HOPS, REBINDABLE_COMMANDS } from './rebind.js';
|
|
31
34
|
const DEFAULT_COMMAND_TIMEOUT_MS = 8000;
|
|
32
35
|
/** Prefix on correlated command ids (c1, c2, …) — distinguishes them from mark ids. */
|
|
@@ -57,13 +60,8 @@ export class Session {
|
|
|
57
60
|
projectId;
|
|
58
61
|
/**
|
|
59
62
|
* The `.reticle` directory this session's evidence belongs in — impact counters AND capsules.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* resolved per call: the answer cannot change while the tab is connected, and resolving it once
|
|
63
|
-
* means every counter that fires for this session agrees about where it goes.
|
|
64
|
-
*
|
|
65
|
-
* Undefined when nothing could name a project — the caller then falls back to the daemon's own
|
|
66
|
-
* root, which is what every counter did unconditionally before this existed.
|
|
63
|
+
* Stamped once, from the project it declared in HELLO, so every counter agrees where it goes.
|
|
64
|
+
* Undefined when nothing could name a project: callers fall back to the daemon's own root.
|
|
67
65
|
*/
|
|
68
66
|
artifactRoot;
|
|
69
67
|
/**
|
|
@@ -113,8 +111,9 @@ export class Session {
|
|
|
113
111
|
#live = new LiveControl();
|
|
114
112
|
/** Human review marks: mistakes the human pinned to elements, for the agent to drain and fix. */
|
|
115
113
|
#review = new ReviewStore((marks) => recordNotes(this.artifactRoot, marks));
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
#firstCommandDone = false; // whether the session_lease has been returned (fire-once)
|
|
115
|
+
/** The newest journal action: a verdict's screenshot names it, so the run pairs it with its check. */
|
|
116
|
+
lastActionId;
|
|
118
117
|
/** Durable causal-journal recorder; undefined when journaling is off (opt-out or not yet attached). */
|
|
119
118
|
#journal;
|
|
120
119
|
#activeActionId; // action window, held independently of the journal
|
|
@@ -284,7 +283,7 @@ export class Session {
|
|
|
284
283
|
if (event.type === EventType.HUD_USED) {
|
|
285
284
|
const use = HudUseDataSchema.safeParse(event.data);
|
|
286
285
|
if (use.success)
|
|
287
|
-
|
|
286
|
+
reportHudUse(use.data, this.id);
|
|
288
287
|
return;
|
|
289
288
|
}
|
|
290
289
|
if (event.documentId !== undefined)
|
|
@@ -294,6 +293,9 @@ export class Session {
|
|
|
294
293
|
if (event.type === EventType.PAGE_HEALTH) {
|
|
295
294
|
const r = readHealthEvent(event.data);
|
|
296
295
|
Object.assign(this.page, r.page);
|
|
296
|
+
// A hidden tab's HUD is not being looked at: its time stops until the tab is in front again.
|
|
297
|
+
if (r.hidden !== undefined)
|
|
298
|
+
noteHudTabHidden(this.id, r.hidden);
|
|
297
299
|
this.applyHealth(r.hidden ?? this.#hidden, r.focused ?? this.#focused, r.runtime, r.engine, r.brand);
|
|
298
300
|
}
|
|
299
301
|
// The in-page half of Reticle reporting its own failure — recorded like a tool error
|
|
@@ -382,10 +384,10 @@ export class Session {
|
|
|
382
384
|
return this.#observed.actedRefs();
|
|
383
385
|
}
|
|
384
386
|
noteRateLimited(dropped) {
|
|
385
|
-
this.#observed.noteRateLimited(dropped);
|
|
387
|
+
this.#observed.noteRateLimited(dropped, this.elapsed());
|
|
386
388
|
}
|
|
387
|
-
blindSpots() {
|
|
388
|
-
return this.#observed.blindSpots();
|
|
389
|
+
blindSpots(since) {
|
|
390
|
+
return this.#observed.blindSpots(since);
|
|
389
391
|
}
|
|
390
392
|
/** Learned ambient-churn counts (PredicateSession hook the settle oracle reads). */
|
|
391
393
|
ambientCounts() {
|
|
@@ -419,10 +421,7 @@ export class Session {
|
|
|
419
421
|
async journalWriteLoss() {
|
|
420
422
|
return readJournalWriteLoss(this.#journalReader, this.#buffer);
|
|
421
423
|
}
|
|
422
|
-
/**
|
|
423
|
-
* Open an action-attribution window: events observed until finishAction attribute to the returned
|
|
424
|
-
* action id. Ids are minted independently of command correlation ids so the journal is self-contained.
|
|
425
|
-
*/
|
|
424
|
+
/** Open an attribution window: events until finishAction carry the returned (journal-own) id. */
|
|
426
425
|
beginAction(tool, args) {
|
|
427
426
|
const actionId = this.#mintActionId();
|
|
428
427
|
// Held here, not only in the journal: with the journal off every event was unattributed, and
|
|
@@ -442,7 +441,8 @@ export class Session {
|
|
|
442
441
|
}
|
|
443
442
|
#mintActionId() {
|
|
444
443
|
this.#actionSeq += 1;
|
|
445
|
-
|
|
444
|
+
this.lastActionId = `${ACTION_ID_PREFIX}${String(this.#actionSeq)}`;
|
|
445
|
+
return this.lastActionId;
|
|
446
446
|
}
|
|
447
447
|
/**
|
|
448
448
|
* How many actions this session has dispatched.
|
|
@@ -490,11 +490,6 @@ export class Session {
|
|
|
490
490
|
* end of it.
|
|
491
491
|
*/
|
|
492
492
|
gaps = new GapLedger();
|
|
493
|
-
/**
|
|
494
|
-
* The read-only calls the journal does not keep, so "was `reticle_context` ever called" has
|
|
495
|
-
* something to fold. See surface/tools/feature-capture.ts — it is the only state that instrument adds.
|
|
496
|
-
*/
|
|
497
|
-
capture = new CaptureLedger();
|
|
498
493
|
// ── Server-authoritative liveness (immune to browser-tab throttling) ──────────────
|
|
499
494
|
/**
|
|
500
495
|
* Stamp the wall-clock of the latest AGENT command (called whenever a tool resolves this session).
|
|
@@ -601,7 +596,7 @@ export class Session {
|
|
|
601
596
|
// The label is only knowable from the REPLY — the request carries a ref, and a ref dies with
|
|
602
597
|
// the next re-render. Recorded here so coverage survives frameworks that replace nodes.
|
|
603
598
|
if (name === ReticleCommand.ACT)
|
|
604
|
-
this.recordActedLabelFrom(result);
|
|
599
|
+
this.recordActedLabelFrom(notedAct(this, result));
|
|
605
600
|
return result;
|
|
606
601
|
})
|
|
607
602
|
.finally(() => recordBrowserLatency(Date.now() - sentAt))
|
|
@@ -637,6 +632,7 @@ export class Session {
|
|
|
637
632
|
/** Reject everything still in flight — used on disconnect. */
|
|
638
633
|
rejectAll(reason, replaced = false) {
|
|
639
634
|
this.#pending.rejectAll(reason, replaced);
|
|
635
|
+
noteHudTabClosed(this.id);
|
|
640
636
|
for (const listener of this.#disconnectListeners)
|
|
641
637
|
listener();
|
|
642
638
|
this.#disconnectListeners.clear();
|
|
@@ -658,13 +654,9 @@ export class Session {
|
|
|
658
654
|
this.#successor = next;
|
|
659
655
|
}
|
|
660
656
|
/**
|
|
661
|
-
* The replacement, but only while it can actually answer.
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
* hour ago keeps handing commands to a socket that has since closed — and the caller pays the full
|
|
665
|
-
* timeout to learn it, turning an instant "session replaced" into a wait. The point of delegating
|
|
666
|
-
* was to save the caller a round trip; delegating to a dead socket costs them more than the error
|
|
667
|
-
* did.
|
|
657
|
+
* The replacement, but only while it can actually answer. A successor is never cleared, so without
|
|
658
|
+
* this a session replaced an hour ago hands commands to a closed socket and the caller pays the
|
|
659
|
+
* full timeout to learn it — more than the "session replaced" error it was meant to save.
|
|
668
660
|
*/
|
|
669
661
|
#liveSuccessor() {
|
|
670
662
|
// Walked, not just read one hop. Two replacements in quick succession — a page that reloads
|
|
@@ -714,13 +706,20 @@ export class Session {
|
|
|
714
706
|
this.#live.setState(next);
|
|
715
707
|
this.pushPresenter(next, text, tone);
|
|
716
708
|
}
|
|
717
|
-
/** Push a human note onto the inbox (see LiveControl). */
|
|
709
|
+
/** Push a human note onto the inbox (see LiveControl); the HUD shows it as sent. */
|
|
718
710
|
pushMessage(text) {
|
|
719
711
|
this.#live.push(text, this.elapsed());
|
|
712
|
+
this.#repaintNotes();
|
|
720
713
|
}
|
|
721
|
-
/** Queued human notes, cleared as they are read (delivered-once). */
|
|
714
|
+
/** Queued human notes, cleared as they are read (delivered-once); the HUD shows them as seen. */
|
|
722
715
|
drainInbox() {
|
|
723
|
-
|
|
716
|
+
const taken = this.#live.drain(callingAgent());
|
|
717
|
+
if (0 < taken.length)
|
|
718
|
+
this.#repaintNotes();
|
|
719
|
+
return taken;
|
|
720
|
+
}
|
|
721
|
+
#repaintNotes() {
|
|
722
|
+
this.pushImpact(() => impactSnapshot(this.artifactRoot), true);
|
|
724
723
|
}
|
|
725
724
|
/** Diagnostic read of the inbox depth (does not clear). */
|
|
726
725
|
inboxSize() {
|
|
@@ -760,28 +759,26 @@ export class Session {
|
|
|
760
759
|
}
|
|
761
760
|
}
|
|
762
761
|
/**
|
|
763
|
-
* Push the impact record to this tab's HUD.
|
|
764
|
-
*
|
|
765
|
-
* Debounced: the record changes on every tool call, and the panel does not need 200 frames to
|
|
766
|
-
* show a counter going up. The LAST state always lands, because the timer re-reads the store
|
|
767
|
-
* when it fires rather than capturing a snapshot when it was scheduled.
|
|
762
|
+
* Push the impact record to this tab's HUD. Debounced (a counter needs no 200 frames); the LAST
|
|
763
|
+
* state always lands, because the timer re-reads the store when it fires.
|
|
768
764
|
*/
|
|
769
765
|
pushImpact(read, immediate = false) {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
}
|
|
766
|
+
const send = () => {
|
|
767
|
+
const snapshot = read();
|
|
768
|
+
if (snapshot === undefined)
|
|
769
|
+
return; // each push carries this tab's own coverage
|
|
770
|
+
const post = () => this.#post(ReticleCommand.IMPACT, { snapshot: withInstrumentation(this, snapshot) });
|
|
771
|
+
post();
|
|
772
|
+
void probeMarkers([this]).then((learned) => learned && post()); // what the page carries
|
|
773
|
+
};
|
|
774
|
+
// A new tab's first record goes out at once: debounced, it reads "nothing recorded" over history.
|
|
775
|
+
if (immediate)
|
|
776
|
+
return send();
|
|
778
777
|
if (this.#impactTimer !== undefined)
|
|
779
778
|
return;
|
|
780
779
|
this.#impactTimer = setTimeout(() => {
|
|
781
780
|
this.#impactTimer = undefined;
|
|
782
|
-
|
|
783
|
-
if (snapshot !== undefined)
|
|
784
|
-
this.#post(ReticleCommand.IMPACT, { snapshot });
|
|
781
|
+
send();
|
|
785
782
|
}, IMPACT_PUSH_DEBOUNCE_MS);
|
|
786
783
|
this.#impactTimer.unref?.();
|
|
787
784
|
}
|
|
@@ -790,8 +787,13 @@ export class Session {
|
|
|
790
787
|
}
|
|
791
788
|
/** Fire-and-forget a narration row to the live panel (so a resolved mark shows "✓ fixed"). */
|
|
792
789
|
#impactTimer;
|
|
793
|
-
|
|
794
|
-
|
|
790
|
+
/** `mirror: false` for a notice about THIS page (its SDK is behind), which every tab says itself. */
|
|
791
|
+
pushNarration(text, mirror = true, by) {
|
|
792
|
+
const args = narrationArgs(text, by);
|
|
793
|
+
if (mirror)
|
|
794
|
+
this.#post(ReticleCommand.NARRATE, args);
|
|
795
|
+
else
|
|
796
|
+
this.#send(ReticleCommand.NARRATE, args);
|
|
795
797
|
}
|
|
796
798
|
/** A HUD replay's progress, or the Harness's drive plan: pictures the HUD redraws as they change. */
|
|
797
799
|
pushView(name, args) {
|
|
@@ -831,12 +833,9 @@ export class Session {
|
|
|
831
833
|
this.#viewers = read;
|
|
832
834
|
}
|
|
833
835
|
/**
|
|
834
|
-
* Fire-and-forget command send
|
|
835
|
-
*
|
|
836
|
-
*
|
|
837
|
-
* (narration, impact). PRESENTER is deliberately not among them: it is the glow and the lifecycle
|
|
838
|
-
* that say "the agent is driving THIS tab", and a viewer that showed it would be claiming
|
|
839
|
-
* something untrue about itself.
|
|
836
|
+
* Fire-and-forget command send, NOT registered in #pending. Mirrored to this project's other tabs
|
|
837
|
+
* for the commands that REPORT what happened. PRESENTER is not among them: it says "the agent is
|
|
838
|
+
* driving THIS tab", and a viewer that showed it would be claiming something untrue about itself.
|
|
840
839
|
*/
|
|
841
840
|
#post(name, args) {
|
|
842
841
|
this.#send(name, args);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { realmOf, AppRuntime, isOpaqueOrigin } from '@reticlehq/core';
|
|
1
|
+
import { realmOf, AppRuntime, isOpaqueOrigin, ReticleTool } from '@reticlehq/core';
|
|
2
2
|
/**
|
|
3
3
|
* Inbound silence beyond this means the page may genuinely be wedged; inside it, the SDK has spoken
|
|
4
4
|
* recently enough that "the page is hung" is provably the wrong story. A page that is streaming
|
|
@@ -17,6 +17,24 @@ const HIDDEN_ADVICE = 'The page last reported itself hidden, and this is a WKWeb
|
|
|
17
17
|
'observed on a hidden macOS WKWebView after a pause, even though capture still works; park it ' +
|
|
18
18
|
'off-screen rather than calling hide. If neither fits, the page is reachable but not executing, ' +
|
|
19
19
|
'which is worth reporting.';
|
|
20
|
+
/**
|
|
21
|
+
* A hidden page in an ordinary browser. Its frames and timers are throttled, so a command can time
|
|
22
|
+
* out while the SDK keeps reporting in, which is exactly the state ONE_WAY_ADVICE reads as a
|
|
23
|
+
* transport fault. Sending the agent to debug its own network there costs attempts and finds
|
|
24
|
+
* nothing (#1416): the way out is a tab nobody else is looking at, which a lease is.
|
|
25
|
+
*/
|
|
26
|
+
const HIDDEN_TAB_ADVICE = 'The page last reported itself hidden: it is a background tab, and the browser throttles a hidden ' +
|
|
27
|
+
"tab's frames and timers, so commands can time out while the page still reports in. This is not a " +
|
|
28
|
+
`network fault. Bring the tab to the front, or drive a tab Reticle owns: ${ReticleTool.LEASE} ` +
|
|
29
|
+
'{ action: "acquire", url: "%URL%" }.';
|
|
30
|
+
/**
|
|
31
|
+
* True only when the SDK REPORTED an ordinary browser tab. Not guessed from the URL: a Tauri or
|
|
32
|
+
* Electron dev server is http://localhost too, and an older SDK that omits the runtime would turn a
|
|
33
|
+
* hidden desktop window into "bring the tab forward", which addresses nothing there.
|
|
34
|
+
*/
|
|
35
|
+
function isWebTab(context) {
|
|
36
|
+
return AppRuntime.WEB === context.runtime;
|
|
37
|
+
}
|
|
20
38
|
/** True when this session is a WebKit desktop shell — the only runtime that suffers this. */
|
|
21
39
|
function isWebKitDesktop(context) {
|
|
22
40
|
if (realmOf(context.runtime).usesWebKit)
|
|
@@ -28,6 +46,12 @@ function isWebKitDesktop(context) {
|
|
|
28
46
|
}
|
|
29
47
|
export function commandTimeoutMessage(name, timeoutMs, context) {
|
|
30
48
|
const base = `command '${name}' timed out after ${String(timeoutMs)}ms`;
|
|
49
|
+
// A hidden WEB tab first, before the recently-heard branch: a background tab keeps reporting in
|
|
50
|
+
// while its throttled frames miss the command, so "heard recently" is expected there and says
|
|
51
|
+
// nothing about the transport. Desktop shells keep the order below unchanged.
|
|
52
|
+
if (context.hidden && isWebTab(context)) {
|
|
53
|
+
return `${base}. ${HIDDEN_TAB_ADVICE.replace('%URL%', context.url)}`;
|
|
54
|
+
}
|
|
31
55
|
// Checked FIRST, and it overrides the visibility story: a page that was heard from moments ago is
|
|
32
56
|
// executing JavaScript, so "hidden, hung or never presented" cannot be the explanation whatever
|
|
33
57
|
// `hidden` says. Deduced from the invariant, not from a measured incident — the Tauri case that
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The real clock, named once.
|
|
3
3
|
*
|
|
4
4
|
* The logic that needs a clock takes one as an argument so a test can drive it without waiting
|
|
5
|
-
* (
|
|
5
|
+
* (AGENTS.md rule 7). That leaves the production callers each constructing the same pair of
|
|
6
6
|
* closures, which is how two of them end up with different sleep implementations. One export, one
|
|
7
7
|
* place to look.
|
|
8
8
|
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The real clock, named once.
|
|
3
3
|
*
|
|
4
4
|
* The logic that needs a clock takes one as an argument so a test can drive it without waiting
|
|
5
|
-
* (
|
|
5
|
+
* (AGENTS.md rule 7). That leaves the production callers each constructing the same pair of
|
|
6
6
|
* closures, which is how two of them end up with different sleep implementations. One export, one
|
|
7
7
|
* place to look.
|
|
8
8
|
*/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type FirstRunWiring } from './first-run-wiring.js';
|
|
2
|
+
export interface FirstCallIo {
|
|
3
|
+
/** The unwired web app this call is about; undefined when wired, not a web app, or no project. */
|
|
4
|
+
project: () => string | undefined;
|
|
5
|
+
/** Which of these ports serve HTTP right now. */
|
|
6
|
+
serving: (ports: readonly number[]) => Promise<readonly number[]>;
|
|
7
|
+
/** The directory the process serving `url` runs in, when it can be observed. */
|
|
8
|
+
servingDirectory: (url: string) => string | undefined;
|
|
9
|
+
/** Open `url` in a lease — the path that supplies the SDK when the page never dials in. */
|
|
10
|
+
lease: (url: string) => Promise<unknown>;
|
|
11
|
+
/** Whether a session is connected now. */
|
|
12
|
+
connected: () => boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface FirstCallOpened {
|
|
15
|
+
url: string;
|
|
16
|
+
/** One line for the agent: what was opened, what it cannot see, and how to wire it for good. */
|
|
17
|
+
notice: string;
|
|
18
|
+
}
|
|
19
|
+
/** One lease per project for the daemon's life: a failure is reported once, never retried. */
|
|
20
|
+
export declare function firstCallOpener(io: FirstCallIo): () => Promise<FirstCallOpened | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* The daemon's two answers to an app nobody wired, built together because both ask the same
|
|
23
|
+
* question first — which unwired web app is this caller in. `firstRun` wires it when the agent
|
|
24
|
+
* lists sessions; `openUnwiredApp` opens it zero-install on a page-needing call.
|
|
25
|
+
*/
|
|
26
|
+
export declare function agentWiring(port: number, sessions: {
|
|
27
|
+
list(): readonly unknown[];
|
|
28
|
+
}, lease: (url: string) => Promise<unknown>): {
|
|
29
|
+
firstRun: FirstRunWiring;
|
|
30
|
+
openUnwiredApp: () => Promise<FirstCallOpened | undefined>;
|
|
31
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first call that needs a page, on an app nobody wired: open that app ourselves, zero-install.
|
|
3
|
+
*
|
|
4
|
+
* An install through the MCP server alone (a plugin, a hand-written `npx … mcp` config) never runs
|
|
5
|
+
* `init`, so the app carries no SDK and nothing ever connects. The agent's first page-needing call
|
|
6
|
+
* then answered with a diagnosis, and the agent stopped there. A lease supplies the SDK to a page
|
|
7
|
+
* that never dials in, so the daemon can answer that call with the app itself instead.
|
|
8
|
+
*
|
|
9
|
+
* Only for a call that already asked to drive or read a page, and only on evidence: exactly one dev
|
|
10
|
+
* server whose process runs inside this project's folder. The port scan is machine-wide, and a
|
|
11
|
+
* browser opened on another repo's app produces a confident verdict about code nobody touched. It
|
|
12
|
+
* changes nothing in the repo — wiring it for good stays the agent's call, named in the notice.
|
|
13
|
+
*
|
|
14
|
+
* Where the serving process cannot be observed (no `lsof`, so Windows) nothing is opened and the
|
|
15
|
+
* no-session answer names the lease and the init command instead.
|
|
16
|
+
*/
|
|
17
|
+
import { realpathSync } from 'node:fs';
|
|
18
|
+
import { resolve, sep } from 'node:path';
|
|
19
|
+
import { DEV_SERVER_PORTS } from '../../command/cli/ports/resolve/cli-port.js';
|
|
20
|
+
import { callingClientDirectory } from '../../hooks/client-directory.js';
|
|
21
|
+
import { detectDevCommandInProject, initCommandIn } from './dev-server/dev-command.js';
|
|
22
|
+
import { probeDevServerStates } from './dev-server/dev-server-probe.js';
|
|
23
|
+
import { firstRunWiring } from './first-run-wiring.js';
|
|
24
|
+
import { servingDirectoryOf } from './serving-directory.js';
|
|
25
|
+
const LOCALHOST = 'http://localhost';
|
|
26
|
+
/** The path with symlinks resolved when it exists (lsof reports `/private/tmp`, callers `/tmp`). */
|
|
27
|
+
function real(path) {
|
|
28
|
+
try {
|
|
29
|
+
return realpathSync(path);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return resolve(path);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const inside = (c, p) => c === p || c.startsWith(`${p}${sep}`);
|
|
36
|
+
/** Compared both as written and with links resolved: either spelling may be the one lsof used. */
|
|
37
|
+
function within(child, parent) {
|
|
38
|
+
if (child === undefined)
|
|
39
|
+
return false;
|
|
40
|
+
return inside(resolve(child), resolve(parent)) || inside(real(child), real(parent));
|
|
41
|
+
}
|
|
42
|
+
function openedNotice(url, init) {
|
|
43
|
+
return (`This app is not wired for Reticle, so Reticle opened ${url} in its own browser and supplied ` +
|
|
44
|
+
'the SDK (zero-install: DOM, network, console and routes; no component state and no source ' +
|
|
45
|
+
`file:line). To wire it for good, run \`${init}\`, then ` +
|
|
46
|
+
'restart the dev server and reload the page.');
|
|
47
|
+
}
|
|
48
|
+
/** One lease per project for the daemon's life: a failure is reported once, never retried. */
|
|
49
|
+
export function firstCallOpener(io) {
|
|
50
|
+
const tried = new Set();
|
|
51
|
+
return async () => {
|
|
52
|
+
const dir = io.project();
|
|
53
|
+
if (dir === undefined || tried.has(dir))
|
|
54
|
+
return undefined;
|
|
55
|
+
const pinned = detectDevCommandInProject(dir)?.port;
|
|
56
|
+
const candidates = new Set(DEV_SERVER_PORTS);
|
|
57
|
+
if (pinned !== undefined)
|
|
58
|
+
candidates.add(pinned);
|
|
59
|
+
const own = (await io.serving([...candidates]))
|
|
60
|
+
.map((port) => `${LOCALHOST}:${String(port)}`)
|
|
61
|
+
.filter((url) => within(io.servingDirectory(url), dir));
|
|
62
|
+
const [url] = own;
|
|
63
|
+
// ponytail: nothing serving yet is not an attempt, so a later call looks again.
|
|
64
|
+
if (url === undefined || 1 !== own.length)
|
|
65
|
+
return undefined;
|
|
66
|
+
tried.add(dir);
|
|
67
|
+
await io.lease(url).catch(() => undefined);
|
|
68
|
+
if (!io.connected())
|
|
69
|
+
return undefined;
|
|
70
|
+
return { url, notice: openedNotice(url, initCommandIn(dir)) };
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The daemon's two answers to an app nobody wired, built together because both ask the same
|
|
75
|
+
* question first — which unwired web app is this caller in. `firstRun` wires it when the agent
|
|
76
|
+
* lists sessions; `openUnwiredApp` opens it zero-install on a page-needing call.
|
|
77
|
+
*/
|
|
78
|
+
export function agentWiring(port, sessions, lease) {
|
|
79
|
+
const firstRun = firstRunWiring({ port, cliPath: process.argv[1] ?? '' });
|
|
80
|
+
const openUnwiredApp = firstCallOpener({
|
|
81
|
+
project: () => firstRun.projectDirectory(callingClientDirectory() ?? process.cwd()),
|
|
82
|
+
serving: async (ports) => (await probeDevServerStates(ports)).serving,
|
|
83
|
+
servingDirectory: (url) => servingDirectoryOf(url),
|
|
84
|
+
lease,
|
|
85
|
+
connected: () => 0 < sessions.list().length,
|
|
86
|
+
});
|
|
87
|
+
return { firstRun, openUnwiredApp };
|
|
88
|
+
}
|
package/dist/start-options.d.ts
CHANGED
|
@@ -12,7 +12,13 @@ export interface StartOptions {
|
|
|
12
12
|
* answers the handler the bridge runs on each press. An embedder of the library leaves it out, and
|
|
13
13
|
* its panel falls back to copying `reticle login`.
|
|
14
14
|
*/
|
|
15
|
-
hudSignIn?: (repaint: () => void
|
|
15
|
+
hudSignIn?: (repaint: () => void,
|
|
16
|
+
/** Links the asking tab's project once the sign-in lands (`hudLink`). */
|
|
17
|
+
link?: (root: string) => Promise<number>) => (from?: {
|
|
18
|
+
artifactRoot?: string | undefined;
|
|
19
|
+
}) => void;
|
|
20
|
+
/** The Harness page's Link this project: link the project in this folder, as `reticle connect` does. */
|
|
21
|
+
hudLink?: (root: string) => Promise<number>;
|
|
16
22
|
port?: number;
|
|
17
23
|
/** Bind address. Non-loopback hosts require a token. Defaults to RETICLE_HOST or localhost. */
|
|
18
24
|
host?: string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { NetworkDetail } from './portal/input/network-detail.js';
|
|
2
|
+
import type { StartOptions } from './start-options.js';
|
|
3
|
+
import type { Bridge } from './portal/bridge/bridge.js';
|
|
4
|
+
import type { RealInputProvider } from './portal/input/real-input.js';
|
|
5
|
+
import { BrowserPool } from './portal/pool/browser-pool.js';
|
|
6
|
+
import { type InjectedConnect } from './portal/pool/zero-install.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build the shared browser pool (one headless Chromium, N capped isolated leased contexts). Lazy —
|
|
9
|
+
* no Chromium launches until the first lease — so creating it is free even when never used.
|
|
10
|
+
*/
|
|
11
|
+
/** Where the zero-install reader connects: this daemon's own bridge, with its pairing token. */
|
|
12
|
+
export declare function readerConnect(port: number, token: string | undefined): InjectedConnect;
|
|
13
|
+
export declare function createBrowserPool(headless: boolean, reader: InjectedConnect): BrowserPool;
|
|
14
|
+
/**
|
|
15
|
+
* Route CDP-authoritative network detail onto the driven session's journal.
|
|
16
|
+
*
|
|
17
|
+
* The page and the SDK session share an origin, so a NET_DETAIL is pushed to the matching connected
|
|
18
|
+
* session. Shared by both entry points: `startDaemon` previously omitted it entirely, so on the path
|
|
19
|
+
* users actually take, CDP network detail was collected and then dropped on the floor.
|
|
20
|
+
*/
|
|
21
|
+
export declare function makeNetworkDetailRouter(bridge: Bridge, driveUrl: string | undefined): (detail: NetworkDetail) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the drive/real-input provider from options — shared by start and startDaemon so the
|
|
24
|
+
* precedence (driveUrl launch+own → CDP attach → none) and the storageState/injectConnect plumbing
|
|
25
|
+
* live in ONE place. `onNavigateError` is the entrypoint's own cleanup (close the bridge/shared server)
|
|
26
|
+
* so a failed launch never leaks a WS port. A past divergence between the two paths let daemon mode
|
|
27
|
+
* run with a different setup — this removes that risk.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveRealInput(options: StartOptions, onNavigateError: () => Promise<void>, onNetworkDetail?: (detail: NetworkDetail) => void): Promise<{
|
|
30
|
+
realInput?: RealInputProvider;
|
|
31
|
+
owned?: {
|
|
32
|
+
dispose: () => Promise<void>;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* The SDK-upgrade sentence for the package.json of the project the page announced, evaluated at
|
|
37
|
+
* each HELLO so a just-edited manifest is what we name. The daemon's cwd only when that project's
|
|
38
|
+
* directory is unknown, and the framework-neutral sensor when that is not an app either (#1135).
|
|
39
|
+
*/
|
|
40
|
+
export declare function sdkFixForProject(projectId?: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a session's artifact root, from everything this machine knows about where projects live.
|
|
43
|
+
*
|
|
44
|
+
* Built once per daemon and closed over by every tool call. The two sources are read lazily and
|
|
45
|
+
* cheaply on each call rather than snapshotted at startup: `init` can run in another terminal while
|
|
46
|
+
* this daemon is up, and a resolution that used a startup snapshot would keep answering with a map
|
|
47
|
+
* from before the project the agent is now driving existed.
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Every `.reticle` root on this machine that sync should consider, from the same two sources the
|
|
51
|
+
* artifact resolver uses.
|
|
52
|
+
*
|
|
53
|
+
* Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
|
|
54
|
+
* another terminal while this daemon is up, and a startup snapshot would keep that repo silent
|
|
55
|
+
* until somebody restarted a process they have no reason to suspect.
|
|
56
|
+
*
|
|
57
|
+
* Returns directories that MIGHT be linked; the caller resolves each and skips the ones that are
|
|
58
|
+
* not. Deciding that here would mean reading every cloud.json on every tick.
|
|
59
|
+
*/
|
|
60
|
+
export declare function knownProjectRoots(): string[];
|
|
61
|
+
/** This project's platform credential (stored, else the env key), as the env the platform readers take. */
|
|
62
|
+
export declare const platformEnvFor: (root: string | undefined) => () => Promise<NodeJS.ProcessEnv>;
|
|
63
|
+
export declare const loadHarnessConfig: (root: string) => Promise<import("./features/harness/platform-config.js").PlatformModelConfig | undefined>;
|