@reticlehq/server 3.7.0 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +59 -68
- package/bin/reticle.js +9 -2
- package/dist/command/cli/adhoc-suite.js +1 -1
- package/dist/command/cli/adhoc-verdict.d.ts +12 -0
- package/dist/command/cli/adhoc-verdict.js +62 -4
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +5 -1
- package/dist/command/cli/auth/cloud-session.d.ts +11 -19
- package/dist/command/cli/auth/cloud-session.js +23 -0
- package/dist/command/cli/auth/device-flow.d.ts +3 -37
- package/dist/command/cli/cli-doctor.js +66 -21
- package/dist/command/cli/cli-flow-commands.js +53 -11
- package/dist/command/cli/cli-kill.d.ts +8 -0
- package/dist/command/cli/cli-kill.js +43 -3
- package/dist/command/cli/cli-parse-feedback.d.ts +4 -0
- package/dist/command/cli/cli-parse-feedback.js +13 -1
- package/dist/command/cli/cli-parse-grammar.d.ts +1 -2
- package/dist/command/cli/cli-parse-grammar.js +1 -6
- package/dist/command/cli/cli-parse-serve.d.ts +24 -0
- package/dist/command/cli/cli-parse-serve.js +124 -0
- package/dist/command/cli/cli-parse.d.ts +12 -11
- package/dist/command/cli/cli-parse.js +100 -123
- package/dist/command/cli/cli-usage.d.ts +0 -11
- package/dist/command/cli/cli-usage.js +43 -16
- package/dist/command/cli/cli-verify.d.ts +1 -1
- package/dist/command/cli/cli-verify.js +29 -14
- package/dist/command/cli/cloud-cli.js +27 -9
- package/dist/command/cli/cloud-kit.js +3 -3
- package/dist/command/cli/cloud-link.d.ts +1 -20
- package/dist/command/cli/cloud-link.js +2 -0
- package/dist/command/cli/cloud-login.d.ts +6 -2
- package/dist/command/cli/cloud-login.js +13 -41
- package/dist/command/cli/config/checkout.d.ts +10 -0
- package/dist/command/cli/config/checkout.js +78 -0
- package/dist/command/cli/doctor/doctor-agent-link.d.ts +23 -0
- package/dist/command/cli/doctor/doctor-agent-link.js +28 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +1 -7
- package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
- package/dist/command/cli/doctor/doctor-rows.js +4 -0
- package/dist/command/cli/drive/drive-attach.d.ts +5 -0
- package/dist/command/cli/drive/drive-attach.js +21 -1
- package/dist/command/cli/hook/codex-transcript.d.ts +20 -0
- package/dist/command/cli/hook/codex-transcript.js +224 -0
- package/dist/command/cli/hook/episode-structure.d.ts +24 -0
- package/dist/command/cli/hook/episode-structure.js +138 -0
- package/dist/command/cli/hook/hook-command.d.ts +9 -0
- package/dist/command/cli/hook/hook-command.js +211 -0
- package/dist/command/cli/hook/hook-fast.d.ts +31 -0
- package/dist/command/cli/hook/hook-fast.js +136 -0
- package/dist/command/cli/hook/prompt-hook.d.ts +30 -0
- package/dist/command/cli/hook/prompt-hook.js +199 -0
- package/dist/command/cli/hook/tool-hook.d.ts +21 -0
- package/dist/command/cli/hook/tool-hook.js +259 -0
- package/dist/command/cli/launch/cli-launch.d.ts +2 -0
- package/dist/command/cli/launch/cli-launch.js +22 -2
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +28 -2
- package/dist/command/cli/mcp-command.d.ts +9 -0
- package/dist/command/cli/mcp-command.js +127 -41
- package/dist/command/cli/open-navigate.d.ts +43 -0
- package/dist/command/cli/open-navigate.js +85 -0
- package/dist/command/cli/ports/port-holder.d.ts +16 -4
- package/dist/command/cli/ports/port-holder.js +58 -12
- package/dist/command/cli/ports/resolve/cli-port.js +18 -2
- package/dist/command/cli/project-name.d.ts +1 -7
- package/dist/command/cli/project-name.js +1 -0
- package/dist/command/cli/report-command.d.ts +8 -2
- package/dist/command/cli/report-command.js +95 -18
- package/dist/command/cli/status-fields.d.ts +9 -2
- package/dist/command/cli/status-fields.js +148 -4
- package/dist/command/cli/try-command.d.ts +3 -4
- package/dist/command/cli/try-command.js +6 -11
- package/dist/command/cli/verify-results.d.ts +4 -1
- package/dist/command/cli/verify-results.js +3 -1
- package/dist/command/cli.d.ts +1 -7
- package/dist/command/cli.js +79 -160
- package/dist/command/daemon/daemon-resilience.d.ts +6 -1
- package/dist/command/daemon/daemon-resilience.js +31 -18
- package/dist/command/daemon/daemon.d.ts +11 -0
- package/dist/command/daemon/daemon.js +70 -2
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +2 -0
- package/dist/command/daemon/lifetime/daemon-usefulness.js +13 -2
- package/dist/command/daemon/wake-decision.js +4 -2
- package/dist/command/daemon/win32-escape.d.ts +32 -0
- package/dist/command/daemon/win32-escape.js +119 -0
- package/dist/command/setup/agent-configs.d.ts +9 -0
- package/dist/command/setup/agent-configs.js +9 -0
- package/dist/command/setup/auto-approve.d.ts +10 -3
- package/dist/command/setup/auto-approve.js +51 -3
- package/dist/command/setup/bringup/dev-server-files.d.ts +1 -9
- package/dist/command/setup/bringup/dev-server-wait.js +5 -1
- package/dist/command/setup/bringup/ensure-daemon.js +4 -7
- package/dist/command/setup/init/init-host.js +6 -0
- package/dist/command/setup/init/init-port.js +5 -4
- package/dist/command/setup/init/init-runtime.js +7 -1
- package/dist/command/setup/node-effects.d.ts +8 -0
- package/dist/command/setup/node-effects.js +36 -4
- package/dist/command/setup/probe/dev-port.d.ts +26 -0
- package/dist/command/setup/probe/dev-port.js +117 -0
- package/dist/command/setup/probe/page-probe.d.ts +1 -1
- package/dist/command/setup/probe/page-probe.js +11 -3
- package/dist/command/setup/remaining-steps.d.ts +0 -7
- package/dist/command/setup/remaining-steps.js +3 -2
- package/dist/command/setup/run-setup.d.ts +11 -0
- package/dist/command/setup/run-setup.js +33 -5
- package/dist/command/setup/setup-command.d.ts +2 -0
- package/dist/command/setup/setup-command.js +22 -4
- package/dist/command/update/updater.d.ts +1 -6
- package/dist/command/update/updater.js +4 -5
- package/dist/command/update/version-seen.d.ts +24 -0
- package/dist/command/update/version-seen.js +65 -0
- package/dist/command/version/peer-announce.d.ts +9 -1
- package/dist/command/version/peer-announce.js +25 -2
- package/dist/command/version/sdk-fix.d.ts +5 -6
- package/dist/command/version/sdk-fix.js +17 -32
- package/dist/command/version/version-skew.d.ts +16 -1
- package/dist/command/version/version-skew.js +84 -10
- package/dist/features/crawl/crawl-tools.js +2 -2
- package/dist/features/crawl/crawl.js +2 -0
- package/dist/features/exhaust/ledger.d.ts +15 -96
- package/dist/features/exhaust/ledger.js +3 -3
- package/dist/features/harness/drive-runs.d.ts +28 -4
- package/dist/features/harness/drive-runs.js +99 -7
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/harness.d.ts +5 -0
- package/dist/features/harness/harness.js +24 -12
- package/dist/features/harness/platform/platform-drives.d.ts +7 -1
- package/dist/features/harness/platform/platform-drives.js +12 -7
- package/dist/features/harness/platform/refusal.d.ts +1 -1
- package/dist/features/harness/platform/refusal.js +4 -4
- package/dist/features/harness/platform/remote-drive.js +70 -28
- package/dist/features/harness/platform/server-driver.js +22 -1
- package/dist/features/harness/platform-config.d.ts +1 -10
- package/dist/features/harness/platform-config.js +0 -20
- package/dist/features/license/license.d.ts +2 -14
- package/dist/features/visual/step-shots.d.ts +33 -1
- package/dist/features/visual/step-shots.js +155 -1
- package/dist/features/visual/visual-tools.js +12 -4
- package/dist/hooks/coding-agents.d.ts +6 -0
- package/dist/hooks/coding-agents.js +24 -3
- package/dist/hooks/episode-stamp.d.ts +32 -0
- package/dist/hooks/episode-stamp.js +61 -0
- package/dist/hooks/hook-commands.js +19 -9
- package/dist/index.d.ts +5 -1
- package/dist/index.js +66 -24
- package/dist/judgement/app-graph/journal-steps.d.ts +8 -0
- package/dist/judgement/app-graph/journal-steps.js +92 -0
- package/dist/judgement/capsule/capsule-store.d.ts +2 -39
- package/dist/judgement/domain/domain-model.js +1 -10
- package/dist/judgement/domain/domain-tools.js +4 -2
- package/dist/judgement/runs/artifact/run-store.d.ts +28 -8
- package/dist/judgement/runs/artifact/run-store.js +153 -28
- package/dist/judgement/runs/default-run-id.d.ts +3 -1
- package/dist/judgement/runs/default-run-id.js +15 -3
- package/dist/judgement/runs/drive-run.d.ts +3 -3
- package/dist/judgement/runs/drive-run.js +11 -7
- package/dist/judgement/runs/run-ledger.d.ts +21 -0
- package/dist/judgement/runs/run-ledger.js +143 -0
- package/dist/judgement/runs/runner-port.d.ts +1 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +4 -3
- package/dist/judgement/runs/verification-sync.js +27 -5
- package/dist/language/flows/affected-tools.js +2 -1
- package/dist/language/flows/annotate-notes/annotate.js +8 -3
- package/dist/language/flows/annotate-tools.js +1 -1
- package/dist/language/flows/change/affected.d.ts +8 -0
- package/dist/language/flows/change/affected.js +20 -7
- package/dist/language/flows/decision.js +19 -4
- package/dist/language/flows/fields/flow-secret-field.d.ts +9 -0
- package/dist/language/flows/fields/flow-secret-field.js +67 -5
- package/dist/language/flows/flow-anchor.d.ts +5 -0
- package/dist/language/flows/flow-anchor.js +4 -0
- package/dist/language/flows/flow-cross-step.d.ts +7 -1
- package/dist/language/flows/flow-cross-step.js +9 -0
- package/dist/language/flows/flow-expect-grammar.js +15 -10
- package/dist/language/flows/flow-intent.js +6 -1
- package/dist/language/flows/flow-journey.d.ts +8 -0
- package/dist/language/flows/flow-journey.js +13 -0
- package/dist/language/flows/flow-lease.d.ts +27 -0
- package/dist/language/flows/flow-lease.js +59 -0
- package/dist/language/flows/flow-replay-run.d.ts +1 -87
- package/dist/language/flows/flow-replay-run.js +111 -310
- package/dist/language/flows/flow-replay.js +21 -19
- package/dist/language/flows/flow-replayable.d.ts +38 -0
- package/dist/language/flows/flow-replayable.js +179 -0
- package/dist/language/flows/flow-start-path.d.ts +108 -0
- package/dist/language/flows/flow-start-path.js +313 -0
- package/dist/language/flows/flow-step-runners.d.ts +23 -2
- package/dist/language/flows/flow-step-runners.js +191 -32
- package/dist/language/flows/flow-store-for-session.d.ts +8 -1
- package/dist/language/flows/flow-store-for-session.js +6 -0
- package/dist/language/flows/flow-tools.d.ts +2 -23
- package/dist/language/flows/flow-tools.js +63 -113
- package/dist/language/flows/flows.d.ts +4 -6
- package/dist/language/flows/flows.js +90 -15
- package/dist/language/flows/heal-run.d.ts +10 -4
- package/dist/language/flows/heal-run.js +26 -9
- package/dist/language/flows/recording/flake.d.ts +3 -27
- package/dist/language/flows/recording/flake.js +1 -1
- package/dist/language/flows/recording/recording-backtrack.js +1 -4
- package/dist/language/flows/recording/tape/recordings.d.ts +11 -1
- package/dist/language/flows/recording/tape/recordings.js +9 -3
- package/dist/language/flows/replay.d.ts +25 -5
- package/dist/language/flows/replay.js +83 -16
- package/dist/language/flows/stores/assertion-tiers-store.js +1 -1
- package/dist/language/flows/suite/coverage.d.ts +9 -0
- package/dist/language/flows/suite/coverage.js +12 -1
- package/dist/language/flows/suite-selection.d.ts +25 -0
- package/dist/language/flows/suite-selection.js +41 -9
- package/dist/machine/git-tracks.d.ts +6 -0
- package/dist/machine/git-tracks.js +36 -0
- package/dist/memory/cloud/background-sync.d.ts +25 -0
- package/dist/memory/cloud/background-sync.js +79 -0
- package/dist/memory/cloud/cloud-config.d.ts +12 -1
- package/dist/memory/cloud/cloud-config.js +39 -13
- package/dist/memory/cloud/cloud-sync.d.ts +3 -24
- package/dist/memory/cloud/cloud-sync.js +5 -2
- package/dist/memory/cloud/harness-config.d.ts +0 -7
- package/dist/memory/cloud/memory-scope.d.ts +19 -0
- package/dist/memory/cloud/memory-scope.js +48 -0
- package/dist/memory/cloud/sync-answer.d.ts +43 -0
- package/dist/memory/cloud/sync-answer.js +42 -0
- package/dist/memory/cloud/sync-cycle.d.ts +40 -10
- package/dist/memory/cloud/sync-cycle.js +97 -144
- package/dist/memory/cloud/sync-daemon.d.ts +50 -3
- package/dist/memory/cloud/sync-daemon.js +473 -83
- package/dist/memory/cloud/sync-describe.d.ts +28 -0
- package/dist/memory/cloud/sync-describe.js +92 -0
- package/dist/memory/cloud/sync-disk.d.ts +9 -1
- package/dist/memory/cloud/sync-disk.js +137 -33
- package/dist/memory/cloud/sync-flow-versions.d.ts +26 -0
- package/dist/memory/cloud/sync-flow-versions.js +42 -0
- package/dist/memory/impact/impact-store.js +32 -15
- package/dist/memory/intent/intent-shard.d.ts +41 -266
- package/dist/memory/intent/intent-tools.js +20 -61
- package/dist/memory/intent/record-request.d.ts +27 -0
- package/dist/memory/intent/record-request.js +88 -0
- package/dist/memory/intent/settled-words.js +9 -1
- package/dist/memory/journal/drive-flow.d.ts +3 -0
- package/dist/memory/journal/drive-flow.js +11 -41
- package/dist/memory/journal/envelope-store.js +1 -1
- package/dist/memory/journal/envelope.d.ts +6 -154
- package/dist/memory/journal/episode-log.d.ts +107 -0
- package/dist/memory/journal/episode-log.js +302 -0
- package/dist/memory/journal/journal-recorder.d.ts +7 -0
- package/dist/memory/journal/journal-recorder.js +22 -9
- package/dist/memory/journal/on-disk/ambient-file.d.ts +1 -7
- package/dist/memory/journal/on-disk/ambient-file.js +1 -1
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +24 -3
- package/dist/memory/journal/on-disk/workspace-gitignore.js +38 -7
- package/dist/memory/journal/on-disk/workspace-tiers.js +7 -0
- package/dist/memory/journal/self-observation.js +3 -1
- package/dist/memory/journal/session-end.js +23 -9
- package/dist/memory/journal/session-journal.js +39 -20
- package/dist/memory/project/artifact-root-resolver.d.ts +14 -1
- package/dist/memory/project/artifact-root-resolver.js +68 -23
- package/dist/memory/project/artifact-root.d.ts +17 -3
- package/dist/memory/project/artifact-root.js +47 -9
- package/dist/memory/project/fs/fs-port.d.ts +5 -0
- package/dist/memory/project/fs/fs-port.js +13 -0
- package/dist/memory/project/learned-routes.d.ts +3 -4
- package/dist/memory/project/learned-routes.js +3 -11
- package/dist/memory/project/link-directory.js +5 -2
- package/dist/memory/project/root-claims.d.ts +3 -1
- package/dist/memory/project/root-claims.js +41 -7
- package/dist/memory/project/session-root.d.ts +1 -1
- package/dist/memory/project/session-root.js +1 -15
- package/dist/memory/project/sync-status.js +5 -6
- package/dist/memory/recall/memory-tools.js +2 -2
- package/dist/memory/recall/platform-memory.d.ts +3 -1
- package/dist/memory/recall/platform-memory.js +9 -1
- package/dist/memory/recall/project-memory.js +15 -19
- package/dist/portal/bridge/auth-failure-reason.d.ts +13 -0
- package/dist/portal/bridge/auth-failure-reason.js +19 -0
- package/dist/portal/bridge/bridge.d.ts +19 -4
- package/dist/portal/bridge/bridge.js +150 -177
- package/dist/portal/bridge/harness-request.d.ts +15 -0
- package/dist/portal/bridge/harness-request.js +19 -0
- package/dist/portal/bridge/origin/origin-follow.d.ts +46 -0
- package/dist/portal/bridge/origin/origin-follow.js +110 -0
- package/dist/portal/bridge/pairing-token.d.ts +6 -0
- package/dist/portal/bridge/pairing-token.js +47 -16
- package/dist/portal/bridge/protocol-skew.d.ts +27 -2
- package/dist/portal/bridge/protocol-skew.js +66 -2
- package/dist/portal/bridge/session-nonces.d.ts +46 -0
- package/dist/portal/bridge/session-nonces.js +72 -0
- package/dist/portal/input/viewport-tools.d.ts +31 -0
- package/dist/portal/input/viewport-tools.js +106 -15
- package/dist/portal/pool/bounded-close.d.ts +23 -0
- package/dist/portal/pool/bounded-close.js +38 -0
- package/dist/portal/pool/browser-pool.d.ts +44 -39
- package/dist/portal/pool/browser-pool.js +247 -95
- package/dist/portal/pool/context-permissions.d.ts +9 -1
- package/dist/portal/pool/context-permissions.js +26 -0
- package/dist/portal/pool/lease-emulation.d.ts +37 -0
- package/dist/portal/pool/lease-emulation.js +29 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +74 -7
- package/dist/portal/pool/pool-contract.d.ts +23 -1
- package/dist/portal/pool/pool-lease.d.ts +128 -0
- package/dist/portal/pool/pool-lease.js +49 -0
- package/dist/portal/pool/zero-install.d.ts +8 -1
- package/dist/portal/pool/zero-install.js +24 -2
- package/dist/portal/production/production-activation.d.ts +136 -0
- package/dist/portal/production/production-activation.js +173 -0
- package/dist/portal/production/production-drive.d.ts +52 -0
- package/dist/portal/production/production-drive.js +301 -0
- package/dist/portal/production/production-hello.d.ts +23 -0
- package/dist/portal/production/production-hello.js +23 -0
- package/dist/portal/realm/web-realm.js +42 -15
- package/dist/portal/session/control-envelope.d.ts +1 -1
- package/dist/portal/session/dev-server/served-document.d.ts +0 -5
- package/dist/portal/session/dev-server/served-document.js +6 -8
- package/dist/portal/session/facts/handshake-facts.d.ts +8 -1
- package/dist/portal/session/first-run-wiring.d.ts +3 -36
- package/dist/portal/session/first-run-wiring.js +10 -103
- package/dist/portal/session/live-control-tools.js +61 -19
- package/dist/portal/session/no-session-next-action.d.ts +11 -0
- package/dist/portal/session/no-session-next-action.js +40 -15
- package/dist/portal/session/no-session-watch.d.ts +7 -0
- package/dist/portal/session/no-session-watch.js +67 -23
- package/dist/portal/session/output-budget.d.ts +10 -0
- package/dist/portal/session/output-budget.js +16 -0
- package/dist/portal/session/presence/session-lease.d.ts +2 -0
- package/dist/portal/session/presence/session-lease.js +8 -0
- package/dist/portal/session/recorded-gaps.d.ts +15 -11
- package/dist/portal/session/recorded-gaps.js +39 -18
- package/dist/portal/session/serving-directory.d.ts +24 -2
- package/dist/portal/session/serving-directory.js +93 -5
- package/dist/portal/session/session-info.d.ts +26 -0
- package/dist/portal/session/session-info.js +20 -0
- package/dist/portal/session/session-manager.d.ts +35 -3
- package/dist/portal/session/session-manager.js +69 -14
- package/dist/portal/session/session-successor.js +1 -9
- package/dist/portal/session/session-tools.js +22 -4
- package/dist/portal/session/session.d.ts +10 -10
- package/dist/portal/session/session.js +37 -29
- package/dist/portal/session/zero-install-first-call.d.ts +7 -2
- package/dist/portal/session/zero-install-first-call.js +43 -20
- package/dist/start-wiring.d.ts +2 -2
- package/dist/start-wiring.js +17 -3
- package/dist/status-payload.d.ts +11 -1
- package/dist/status-payload.js +7 -1
- package/dist/surface/agent-presence-grace.d.ts +11 -0
- package/dist/surface/agent-presence-grace.js +34 -0
- package/dist/surface/http-server.d.ts +12 -1
- package/dist/surface/http-server.js +64 -15
- package/dist/surface/mcp/faults/mcp-outage.d.ts +12 -2
- package/dist/surface/mcp/faults/mcp-outage.js +19 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +17 -74
- package/dist/surface/mcp/mcp-proxy.js +194 -267
- package/dist/surface/mcp/mcp.d.ts +20 -3
- package/dist/surface/mcp/mcp.js +88 -25
- package/dist/surface/mcp/proxy/drive-calls.d.ts +44 -0
- package/dist/surface/mcp/proxy/drive-calls.js +114 -5
- package/dist/surface/mcp/proxy/proxy-boot.d.ts +11 -0
- package/dist/surface/mcp/proxy/proxy-boot.js +1 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +6 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +14 -1
- package/dist/surface/mcp/proxy/proxy-handshake.d.ts +34 -2
- package/dist/surface/mcp/proxy/proxy-handshake.js +76 -8
- package/dist/surface/mcp/server-instructions.js +35 -16
- package/dist/surface/mcp/shared-params.d.ts +8 -0
- package/dist/surface/mcp/shared-params.js +15 -1
- package/dist/surface/mcp/sse-frame-parser.d.ts +11 -0
- package/dist/surface/mcp/sse-frame-parser.js +18 -0
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +13 -0
- package/dist/surface/mcp/tool-catalog-cache.d.ts +2 -0
- package/dist/surface/mcp/tool-catalog-cache.js +14 -4
- package/dist/surface/tools/account-tool.d.ts +4 -3
- package/dist/surface/tools/account-tool.js +20 -31
- package/dist/surface/tools/act/act-danger.d.ts +2 -0
- package/dist/surface/tools/act/act-danger.js +41 -14
- package/dist/surface/tools/act/act-observation.d.ts +11 -0
- package/dist/surface/tools/act/act-observation.js +33 -0
- package/dist/surface/tools/act/act-preflight.js +10 -3
- package/dist/surface/tools/act/act-sequence-retry.js +2 -1
- package/dist/surface/tools/act/act-target.js +19 -5
- package/dist/surface/tools/act/durable.js +1 -1
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +9 -7
- package/dist/surface/tools/act/navigation/navigate-arrival.js +11 -14
- package/dist/surface/tools/act/unsettled-find.d.ts +36 -0
- package/dist/surface/tools/act/unsettled-find.js +71 -0
- package/dist/surface/tools/act-sequence-tool.js +53 -24
- package/dist/surface/tools/act-tools.d.ts +2 -3
- package/dist/surface/tools/act-tools.js +49 -47
- package/dist/surface/tools/agent/compact-envelope.d.ts +2 -2
- package/dist/surface/tools/agent/for-the-agent.js +41 -3
- package/dist/surface/tools/assert/assert-grade.js +8 -3
- package/dist/surface/tools/assert/assert-verdict.js +4 -2
- package/dist/surface/tools/browser-tools.js +7 -4
- package/dist/surface/tools/chat-drives.js +50 -25
- package/dist/surface/tools/coverage-tools.js +1 -1
- package/dist/surface/tools/dynamic-tools.d.ts +8 -0
- package/dist/surface/tools/dynamic-tools.js +89 -34
- package/dist/surface/tools/empty-session-list.d.ts +18 -25
- package/dist/surface/tools/empty-session-list.js +67 -38
- package/dist/surface/tools/error-recovery.d.ts +17 -7
- package/dist/surface/tools/error-recovery.js +53 -20
- package/dist/surface/tools/explore-tools.d.ts +10 -0
- package/dist/surface/tools/explore-tools.js +72 -19
- package/dist/surface/tools/feedback-tools.js +23 -2
- package/dist/surface/tools/gap-novelty.d.ts +6 -0
- package/dist/surface/tools/gap-novelty.js +9 -0
- package/dist/surface/tools/gaps/capability-absences.js +4 -3
- package/dist/surface/tools/harness-explore.d.ts +1 -1
- package/dist/surface/tools/harness-explore.js +6 -4
- package/dist/surface/tools/harness-gate.d.ts +43 -21
- package/dist/surface/tools/harness-gate.js +55 -81
- package/dist/surface/tools/harness-script.d.ts +2 -0
- package/dist/surface/tools/harness-script.js +11 -6
- package/dist/surface/tools/harness-toolset.js +3 -4
- package/dist/surface/tools/invoke-tool.d.ts +0 -8
- package/dist/surface/tools/invoke-tool.js +164 -178
- package/dist/surface/tools/lease-hint.d.ts +9 -0
- package/dist/surface/tools/lease-hint.js +22 -3
- package/dist/surface/tools/lease-permissions.d.ts +1 -1
- package/dist/surface/tools/lease-readiness.d.ts +55 -0
- package/dist/surface/tools/lease-readiness.js +150 -2
- package/dist/surface/tools/lease-tools.d.ts +3 -75
- package/dist/surface/tools/lease-tools.js +124 -188
- package/dist/surface/tools/map-tools.d.ts +20 -0
- package/dist/surface/tools/map-tools.js +145 -0
- package/dist/surface/tools/merge-tools.js +11 -7
- package/dist/surface/tools/next-step.js +6 -3
- package/dist/surface/tools/observe-tools.js +46 -35
- package/dist/surface/tools/platform-moment.d.ts +3 -12
- package/dist/surface/tools/platform-moment.js +12 -24
- package/dist/surface/tools/read/complete-snapshot.d.ts +7 -1
- package/dist/surface/tools/read/complete-snapshot.js +13 -2
- package/dist/surface/tools/read/query-paginate.js +6 -0
- package/dist/surface/tools/read/query-shape.d.ts +9 -0
- package/dist/surface/tools/read/query-shape.js +15 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.d.ts +1 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.js +73 -0
- package/dist/surface/tools/read-tools.js +5 -5
- package/dist/surface/tools/real-input-attempt.d.ts +11 -0
- package/dist/surface/tools/real-input-attempt.js +206 -38
- package/dist/surface/tools/reconcile-tools.js +21 -8
- package/dist/surface/tools/reticle-result.d.ts +3 -0
- package/dist/surface/tools/reticle-result.js +8 -1
- package/dist/surface/tools/run-report.d.ts +22 -0
- package/dist/surface/tools/run-report.js +141 -0
- package/dist/surface/tools/session-ports.d.ts +57 -0
- package/dist/surface/tools/session-ports.js +102 -0
- package/dist/surface/tools/tool-kit.d.ts +58 -4
- package/dist/surface/tools/tool-kit.js +140 -6
- package/dist/surface/tools/tool-surface.d.ts +2 -0
- package/dist/surface/tools/tool-surface.js +45 -0
- package/dist/surface/tools/tools.js +49 -87
- package/dist/telemetry/automation-hint.d.ts +5 -0
- package/dist/telemetry/automation-hint.js +7 -0
- package/dist/telemetry/cli-telemetry.d.ts +22 -0
- package/dist/telemetry/cli-telemetry.js +80 -11
- package/dist/telemetry/daemon-telemetry.d.ts +3 -1
- package/dist/telemetry/daemon-telemetry.js +9 -2
- package/dist/telemetry/feedback-cli.d.ts +1 -1
- package/dist/telemetry/feedback-cli.js +8 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/feedback.js +51 -4
- package/dist/telemetry/harness-run.d.ts +3 -3
- package/dist/telemetry/harness-run.js +18 -7
- package/dist/telemetry/hud-events.d.ts +1 -1
- package/dist/telemetry/hud-metrics.d.ts +6 -3
- package/dist/telemetry/hud-metrics.js +20 -8
- package/dist/telemetry/install-source.js +1 -1
- package/dist/telemetry/mcp-connection.d.ts +1 -1
- package/dist/telemetry/mcp-connection.js +21 -2
- package/dist/telemetry/onboarding-firsts.d.ts +6 -1
- package/dist/telemetry/onboarding-firsts.js +41 -1
- package/dist/telemetry/proxy-telemetry.d.ts +42 -0
- package/dist/telemetry/proxy-telemetry.js +70 -1
- package/dist/telemetry/session-metrics.d.ts +1 -3
- package/dist/telemetry/session-metrics.js +16 -12
- package/dist/telemetry/telemetry.d.ts +9 -1
- package/dist/telemetry/telemetry.js +16 -1
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +7 -1
- package/dist/wire-journal.js +12 -2
- package/docs/README.md +4 -2
- package/docs/actions.mdx +7 -6
- package/docs/adapters.md +2 -1
- package/docs/agent-cheatsheet.md +19 -5
- package/docs/architecture.md +13 -10
- package/docs/autodrive.md +6 -5
- package/docs/benchmarks.md +2 -2
- package/docs/capabilities.mdx +1 -1
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +6 -6
- package/docs/cli/doctor.mdx +3 -1
- package/docs/cli/feedback.mdx +11 -7
- package/docs/cli/gate.mdx +1 -1
- package/docs/cli/help.mdx +1 -1
- package/docs/cli/init.mdx +20 -16
- package/docs/cli/mcp.mdx +5 -2
- package/docs/cli/open.mdx +5 -2
- package/docs/cli/report.mdx +1 -1
- package/docs/cli/restart.mdx +1 -1
- package/docs/cli/rollback.mdx +4 -4
- package/docs/cli/serve.mdx +7 -5
- package/docs/cli/setup.mdx +1 -1
- package/docs/cli/status.mdx +6 -2
- package/docs/cli/stop.mdx +3 -3
- package/docs/cli/telemetry.mdx +5 -1
- package/docs/cli/try.mdx +8 -8
- package/docs/cli/update.mdx +8 -5
- package/docs/cli/verify.mdx +12 -5
- package/docs/cli/version.mdx +1 -1
- package/docs/cli.mdx +10 -6
- package/docs/debugging.md +1 -1
- package/docs/deploy-checks.md +8 -6
- package/docs/desktop.mdx +14 -18
- package/docs/enterprise.md +6 -6
- package/docs/environment.mdx +5 -3
- package/docs/faq.mdx +9 -6
- package/docs/first-drive.md +19 -9
- package/docs/flows.md +3 -4
- package/docs/for-agents.md +1 -1
- package/docs/frameworks.mdx +34 -11
- package/docs/getting-started.md +46 -29
- package/docs/http-transport.md +2 -2
- package/docs/human-control.md +8 -8
- package/docs/index.mdx +2 -2
- package/docs/install-agentic.mdx +18 -19
- package/docs/install-manual.mdx +8 -4
- package/docs/integration-patterns.md +5 -5
- package/docs/multi-agent-testing.md +7 -5
- package/docs/packages/browser.mdx +34 -2
- package/docs/packages/core.mdx +2 -1
- package/docs/packages/electron.mdx +15 -3
- package/docs/packages/eslint-plugin.mdx +1 -1
- package/docs/packages/next.mdx +17 -5
- package/docs/packages/react.mdx +8 -1
- package/docs/packages/server.mdx +3 -3
- package/docs/packages/tauri.mdx +3 -3
- package/docs/packages/vite-plugin.mdx +1 -1
- package/docs/packages.mdx +19 -6
- package/docs/platform-integration.md +12 -4
- package/docs/predicates.mdx +18 -7
- package/docs/production-mode.md +108 -0
- package/docs/prompt-capture.md +99 -0
- package/docs/quickstart.mdx +14 -12
- package/docs/recipes.mdx +9 -8
- package/docs/required-checks.md +3 -2
- package/docs/skill-file.mdx +4 -3
- package/docs/skill-setup.md +2 -2
- package/docs/skill.md +62 -70
- package/docs/state-files.md +1 -0
- package/docs/state-management.mdx +11 -9
- package/docs/system-map.md +14 -13
- package/docs/telemetry.md +32 -24
- package/docs/testing.md +9 -5
- package/docs/tools/act-and-wait.mdx +17 -13
- package/docs/tools/act-sequence.mdx +40 -66
- package/docs/tools/act.mdx +7 -5
- package/docs/tools/assert.mdx +1 -1
- package/docs/tools/look.mdx +1 -1
- package/docs/tools/navigate.mdx +1 -1
- package/docs/tools/network.mdx +13 -11
- package/docs/tools/overview.mdx +3 -3
- package/docs/tools/query.mdx +3 -3
- package/docs/tools/session-and-feedback.mdx +9 -6
- package/docs/tools/sessions.mdx +7 -0
- package/docs/tools/snapshot.mdx +9 -7
- package/docs/tools/tools-and-run.mdx +11 -10
- package/docs/tools/verify.mdx +1 -1
- package/docs/troubleshooting.mdx +21 -9
- package/docs/usage.md +58 -43
- package/docs/use-cases.mdx +2 -2
- package/docs/vs-chrome-devtools-mcp.mdx +5 -5
- package/docs/vs-playwright-mcp.mdx +5 -4
- package/docs/what-is-recorded.md +12 -7
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/dev/stale-issue-guard.d.ts +0 -34
- package/dist/command/dev/stale-issue-guard.js +0 -69
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { noteOwnReload, notePageLoaded } from '../../features/harness/drive-runs.js';
|
|
1
2
|
import { asProjectId } from '@reticlehq/core';
|
|
2
3
|
import { narrationArgs } from './narration-args.js';
|
|
3
4
|
import { refusedResult } from './page-commands/undeclared-command.js';
|
|
@@ -15,7 +16,7 @@ const IMPACT_PUSH_DEBOUNCE_MS = 700;
|
|
|
15
16
|
import { PendingCommands, CommandTimeoutError } from './page-commands/pending-commands.js';
|
|
16
17
|
import { span } from '../../trace.js';
|
|
17
18
|
import { keepCallerContextInDaemon, noteToDaemonLog } from './daemon-answers.js';
|
|
18
|
-
import { isKnownRealm, EventType, HumanControlDataSchema, HumanControlKind, HumanMarkDataSchema, HudUseDataSchema, ReticleCommand, parseEventPayload, PresenterTone, SESSION_HEALTH,
|
|
19
|
+
import { isKnownRealm, EventType, HumanControlDataSchema, HumanControlKind, HumanMarkDataSchema, HudUseDataSchema, ReticleCommand, parseEventPayload, PresenterTone, SESSION_HEALTH, SESSION_LIFECYCLE, SessionState, } from '@reticlehq/core';
|
|
19
20
|
import { RingBuffer } from '@reticlehq/engine/window/ring-buffer.js';
|
|
20
21
|
import { readJournalWriteLoss, readQueryEvents, windowLost, } from '../../memory/journal/journal-query.js';
|
|
21
22
|
import {} from '@reticlehq/engine/window/ambient.js';
|
|
@@ -28,6 +29,7 @@ import { ReviewStore } from './human/review-store.js';
|
|
|
28
29
|
import { buildSessionRecommendation } from './presence/session-recommendation.js';
|
|
29
30
|
import { buildPresenterArgs } from './human/presenter-args.js';
|
|
30
31
|
import { buildSessionLease } from './presence/session-lease.js';
|
|
32
|
+
import { sessionAgeWarning } from './presence/session-lease.js';
|
|
31
33
|
import { buildSessionInfo } from './session-info.js';
|
|
32
34
|
import { notedAct, probeMarkers, withInstrumentation } from './recorded-gaps.js';
|
|
33
35
|
import { MAX_SUCCESSOR_HOPS, REBINDABLE_COMMANDS } from './rebind.js';
|
|
@@ -56,31 +58,36 @@ export class Session {
|
|
|
56
58
|
* MINTED HERE. This is one of the two places a projectId enters the daemon with its provenance
|
|
57
59
|
* intact: the field is `projectId` on a zod-parsed HELLO, so the page said what it is. Every
|
|
58
60
|
* downstream reader takes the brand from this property rather than re-blessing a string.
|
|
61
|
+
* Set once more, by `adoptProject`, when a page that said nothing names its project later.
|
|
59
62
|
*/
|
|
60
63
|
projectId;
|
|
64
|
+
/** Take a later HELLO's project id when the first carried none. A set project is kept. */
|
|
65
|
+
adoptProject(projectId) {
|
|
66
|
+
if (this.projectId !== undefined)
|
|
67
|
+
return false;
|
|
68
|
+
this.projectId = asProjectId(projectId);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
61
71
|
/**
|
|
62
72
|
* The `.reticle` directory this session's evidence belongs in — impact counters AND capsules.
|
|
63
73
|
* Stamped once, from the project it declared in HELLO, so every counter agrees where it goes.
|
|
64
74
|
* Undefined when nothing could name a project: callers fall back to the daemon's own root.
|
|
65
75
|
*/
|
|
66
76
|
artifactRoot;
|
|
67
|
-
/**
|
|
68
|
-
* Same-origin endpoints this session's project declared as background (`.reticle.json`
|
|
69
|
-
* `background`). Stamped with `artifactRoot`, from the same project. Empty excludes nothing.
|
|
70
|
-
*/
|
|
77
|
+
/** Same-origin `background` endpoints of this session's project, stamped with `artifactRoot`. */
|
|
71
78
|
background = [];
|
|
72
79
|
url;
|
|
73
80
|
title;
|
|
74
81
|
adapters;
|
|
75
82
|
hasCapabilities;
|
|
76
|
-
// What the page said
|
|
77
|
-
// the rule that `undefined` means "too old to say" and never "no".
|
|
83
|
+
// What the page said at HELLO. `HandshakeFacts` holds the reasoning (`undefined` is never "no").
|
|
78
84
|
versionSkew;
|
|
79
85
|
sdkVersion;
|
|
80
86
|
captureBodies;
|
|
81
87
|
channels;
|
|
82
88
|
commands;
|
|
83
89
|
sourceMapping;
|
|
90
|
+
instrumentation;
|
|
84
91
|
redactKeys;
|
|
85
92
|
#socket;
|
|
86
93
|
#clock;
|
|
@@ -134,6 +141,8 @@ export class Session {
|
|
|
134
141
|
*/
|
|
135
142
|
#editEpoch;
|
|
136
143
|
#departureNote = new DepartureNote();
|
|
144
|
+
/** Set when a production nonce opened this session: every act then passes the production policy. */
|
|
145
|
+
production;
|
|
137
146
|
constructor(hello, socket, clock) {
|
|
138
147
|
this.id = hello.sessionId;
|
|
139
148
|
this.projectId = hello.projectId === undefined ? undefined : asProjectId(hello.projectId);
|
|
@@ -142,6 +151,7 @@ export class Session {
|
|
|
142
151
|
this.adapters = hello.adapters;
|
|
143
152
|
this.hasCapabilities = hello.hasCapabilities ?? false;
|
|
144
153
|
this.sourceMapping = hello.sourceMapping;
|
|
154
|
+
this.instrumentation = hello.instrumentation;
|
|
145
155
|
this.redactKeys = hello.redactKeys ?? [];
|
|
146
156
|
this.#socket = socket;
|
|
147
157
|
this.#clock = clock;
|
|
@@ -233,6 +243,7 @@ export class Session {
|
|
|
233
243
|
hasCapabilities: this.hasCapabilities,
|
|
234
244
|
runtime: this.#runtime,
|
|
235
245
|
versionSkew: this.versionSkew,
|
|
246
|
+
sdkVersion: this.sdkVersion,
|
|
236
247
|
hidden: this.#hidden,
|
|
237
248
|
page: this.page,
|
|
238
249
|
health: () => this.health(),
|
|
@@ -288,6 +299,7 @@ export class Session {
|
|
|
288
299
|
}
|
|
289
300
|
if (event.documentId !== undefined)
|
|
290
301
|
this.#documentId = event.documentId;
|
|
302
|
+
notePageLoaded(this.id, event, this.#clock());
|
|
291
303
|
if (event.editEpoch !== undefined)
|
|
292
304
|
this.#editEpoch = event.editEpoch;
|
|
293
305
|
if (event.type === EventType.PAGE_HEALTH) {
|
|
@@ -555,15 +567,19 @@ export class Session {
|
|
|
555
567
|
}
|
|
556
568
|
/** Send a command to the browser and await its reply (or time out). */
|
|
557
569
|
command(name, args = {}, timeoutMs = DEFAULT_COMMAND_TIMEOUT_MS) {
|
|
558
|
-
//
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
570
|
+
// The production policy decides here, where every driven action passes, and never in the page.
|
|
571
|
+
if (this.production === undefined)
|
|
572
|
+
return this.#dispatch(name, args, timeoutMs);
|
|
573
|
+
return this.production.gate(name, args, (n, a) => this.#dispatch(n, a, timeoutMs));
|
|
574
|
+
}
|
|
575
|
+
#dispatch(name, args, ms) {
|
|
576
|
+
// Recorded here, where every driven action passes (act_sequence and flow replay too). A reload
|
|
577
|
+
// sent from here is ours, so the page coming back is not a person reloading mid-drive.
|
|
578
|
+
const ref = args['ref'];
|
|
579
|
+
if (name === ReticleCommand.ACT && 'string' === typeof ref)
|
|
580
|
+
this.recordActedRef(ref);
|
|
581
|
+
if (name === ReticleCommand.REFRESH)
|
|
582
|
+
noteOwnReload(this.id, this.#clock());
|
|
567
583
|
// Refused before it is sent, when the page said it does not serve this. The rule, and why
|
|
568
584
|
// an absent declaration is not an empty list, live in `undeclared-command.ts`.
|
|
569
585
|
const refused = refusedResult(name, this.commands, `${COMMAND_ID_PREFIX}refused`);
|
|
@@ -574,12 +590,12 @@ export class Session {
|
|
|
574
590
|
// have made itself after a `reticle_sessions` round trip, minus the round trip.
|
|
575
591
|
const successor = this.#liveSuccessor();
|
|
576
592
|
if (successor !== undefined)
|
|
577
|
-
return successor.command(name, args,
|
|
593
|
+
return successor.command(name, args, ms);
|
|
578
594
|
const id = this.#pending.nextId(COMMAND_ID_PREFIX);
|
|
579
595
|
const payload = commandPayload(id, this.id, name, args);
|
|
580
596
|
// The timeout message is built LAZILY: health can change while a command is in flight, and the
|
|
581
597
|
// diagnosis should describe the page as it was when the command actually gave up.
|
|
582
|
-
const awaited = this.#pending.track(id,
|
|
598
|
+
const awaited = this.#pending.track(id, ms, () => commandTimeoutMessage(name, ms, {
|
|
583
599
|
url: this.url,
|
|
584
600
|
hidden: this.#hidden,
|
|
585
601
|
lastSeenMs: this.lastSeenMs(),
|
|
@@ -617,7 +633,7 @@ export class Session {
|
|
|
617
633
|
// timeout means a caller who granted 8s can wait 16, and across a chain of replacements the
|
|
618
634
|
// total is unbounded — a wait nobody asked for, on the path that exists to save a round trip.
|
|
619
635
|
// A budget already spent means there is nothing left to retry into, so the error stands.
|
|
620
|
-
const remaining =
|
|
636
|
+
const remaining = ms - (Date.now() - sentAt);
|
|
621
637
|
if (remaining <= 0)
|
|
622
638
|
throw error;
|
|
623
639
|
return next.command(name, args, remaining);
|
|
@@ -806,17 +822,9 @@ export class Session {
|
|
|
806
822
|
this.#firstCommandDone = true;
|
|
807
823
|
return buildSessionLease(this.id, this.#startedAt);
|
|
808
824
|
}
|
|
809
|
-
/**
|
|
810
|
-
* Returns a human-readable age warning after SESSION_LEASE.WARN_AFTER_MS (10 min), else undefined.
|
|
811
|
-
* Spliced onto every session-bound tool result so the agent is passively reminded to clean up
|
|
812
|
-
* without needing an explicit polling loop.
|
|
813
|
-
*/
|
|
825
|
+
/** The age reminder spliced onto session-bound results, so the agent cleans up without polling. */
|
|
814
826
|
ageWarning() {
|
|
815
|
-
|
|
816
|
-
if (ageMs < SESSION_LEASE.WARN_AFTER_MS)
|
|
817
|
-
return undefined;
|
|
818
|
-
const minutes = Math.floor(ageMs / 60_000);
|
|
819
|
-
return `Session ${this.id} has been open for ${String(minutes)} minutes. If your task is complete, call reticle_session{action:"end"} now.`;
|
|
827
|
+
return sessionAgeWarning(this.id, this.#clock() - this.#startedAt);
|
|
820
828
|
}
|
|
821
829
|
/**
|
|
822
830
|
* The tabs that should SEE what this session is told, supplied by the SessionManager.
|
|
@@ -16,16 +16,21 @@ export interface FirstCallOpened {
|
|
|
16
16
|
/** One line for the agent: what was opened, what it cannot see, and how to wire it for good. */
|
|
17
17
|
notice: string;
|
|
18
18
|
}
|
|
19
|
+
/** Compared both as written and with links resolved: either spelling may be the one lsof used. */
|
|
20
|
+
export declare function within(child: string | undefined, parent: string): boolean;
|
|
21
|
+
/** The caller's running app, for a lease that names no url. */
|
|
22
|
+
export declare function projectAppUrlFinder(io: Pick<FirstCallIo, 'project' | 'serving' | 'servingDirectory'>): () => Promise<string | undefined>;
|
|
19
23
|
/** One lease per project for the daemon's life: a failure is reported once, never retried. */
|
|
20
24
|
export declare function firstCallOpener(io: FirstCallIo): () => Promise<FirstCallOpened | undefined>;
|
|
21
25
|
/**
|
|
22
26
|
* 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`
|
|
27
|
+
* question first — which unwired web app is this caller in. `firstRun` names it when the agent
|
|
24
28
|
* lists sessions; `openUnwiredApp` opens it zero-install on a page-needing call.
|
|
25
29
|
*/
|
|
26
|
-
export declare function agentWiring(
|
|
30
|
+
export declare function agentWiring(sessions: {
|
|
27
31
|
list(): readonly unknown[];
|
|
28
32
|
}, lease: (url: string) => Promise<unknown>): {
|
|
29
33
|
firstRun: FirstRunWiring;
|
|
30
34
|
openUnwiredApp: () => Promise<FirstCallOpened | undefined>;
|
|
35
|
+
projectAppUrl: () => Promise<string | undefined>;
|
|
31
36
|
};
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* browser opened on another repo's app produces a confident verdict about code nobody touched. It
|
|
12
12
|
* changes nothing in the repo — wiring it for good stays the agent's call, named in the notice.
|
|
13
13
|
*
|
|
14
|
-
* Where the serving process cannot be observed
|
|
15
|
-
*
|
|
14
|
+
* Where the serving process cannot be observed nothing is opened, and the no-session answer names
|
|
15
|
+
* the lease and the init command instead. On Windows the lookup reads the listener's command line
|
|
16
|
+
* (see `findListenerCwd`), so a dev server run from the project's `node_modules` counts.
|
|
16
17
|
*/
|
|
17
18
|
import { realpathSync } from 'node:fs';
|
|
18
19
|
import { resolve, sep } from 'node:path';
|
|
@@ -21,6 +22,7 @@ import { callingClientDirectory } from '../../hooks/client-directory.js';
|
|
|
21
22
|
import { detectDevCommandInProject, initCommandIn } from './dev-server/dev-command.js';
|
|
22
23
|
import { probeDevServerStates } from './dev-server/dev-server-probe.js';
|
|
23
24
|
import { firstRunWiring } from './first-run-wiring.js';
|
|
25
|
+
import { wiringConsent } from './no-session-next-action.js';
|
|
24
26
|
import { servingDirectoryOf } from './serving-directory.js';
|
|
25
27
|
const LOCALHOST = 'http://localhost';
|
|
26
28
|
/** The path with symlinks resolved when it exists (lsof reports `/private/tmp`, callers `/tmp`). */
|
|
@@ -34,7 +36,7 @@ function real(path) {
|
|
|
34
36
|
}
|
|
35
37
|
const inside = (c, p) => c === p || c.startsWith(`${p}${sep}`);
|
|
36
38
|
/** Compared both as written and with links resolved: either spelling may be the one lsof used. */
|
|
37
|
-
function within(child, parent) {
|
|
39
|
+
export function within(child, parent) {
|
|
38
40
|
if (child === undefined)
|
|
39
41
|
return false;
|
|
40
42
|
return inside(resolve(child), resolve(parent)) || inside(real(child), real(parent));
|
|
@@ -42,8 +44,30 @@ function within(child, parent) {
|
|
|
42
44
|
function openedNotice(url, init) {
|
|
43
45
|
return (`This app is not wired for Reticle, so Reticle opened ${url} in its own browser and supplied ` +
|
|
44
46
|
'the SDK (zero-install: DOM, network, console and routes; no component state and no source ' +
|
|
45
|
-
`file:line). To wire it for good
|
|
46
|
-
'
|
|
47
|
+
`file:line). To wire it for good: ${wiringConsent(init)} Then restart the dev server and ` +
|
|
48
|
+
'reload the page.');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The one dev server that runs in this project's folder, or undefined when there is none or more
|
|
52
|
+
* than one. Two servers in one project is a choice the caller makes, not one Reticle guesses.
|
|
53
|
+
*/
|
|
54
|
+
async function projectAppUrlIn(io, dir) {
|
|
55
|
+
const pinned = detectDevCommandInProject(dir)?.port;
|
|
56
|
+
const candidates = new Set(DEV_SERVER_PORTS);
|
|
57
|
+
if (pinned !== undefined) {
|
|
58
|
+
candidates.add(pinned);
|
|
59
|
+
}
|
|
60
|
+
const own = (await io.serving([...candidates]))
|
|
61
|
+
.map((port) => `${LOCALHOST}:${String(port)}`)
|
|
62
|
+
.filter((url) => within(io.servingDirectory(url), dir));
|
|
63
|
+
return 1 === own.length ? own[0] : undefined;
|
|
64
|
+
}
|
|
65
|
+
/** The caller's running app, for a lease that names no url. */
|
|
66
|
+
export function projectAppUrlFinder(io) {
|
|
67
|
+
return async () => {
|
|
68
|
+
const dir = io.project();
|
|
69
|
+
return dir === undefined ? undefined : projectAppUrlIn(io, dir);
|
|
70
|
+
};
|
|
47
71
|
}
|
|
48
72
|
/** One lease per project for the daemon's life: a failure is reported once, never retried. */
|
|
49
73
|
export function firstCallOpener(io) {
|
|
@@ -52,16 +76,9 @@ export function firstCallOpener(io) {
|
|
|
52
76
|
const dir = io.project();
|
|
53
77
|
if (dir === undefined || tried.has(dir))
|
|
54
78
|
return undefined;
|
|
55
|
-
const
|
|
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;
|
|
79
|
+
const url = await projectAppUrlIn(io, dir);
|
|
63
80
|
// ponytail: nothing serving yet is not an attempt, so a later call looks again.
|
|
64
|
-
if (url === undefined
|
|
81
|
+
if (url === undefined)
|
|
65
82
|
return undefined;
|
|
66
83
|
tried.add(dir);
|
|
67
84
|
await io.lease(url).catch(() => undefined);
|
|
@@ -72,17 +89,23 @@ export function firstCallOpener(io) {
|
|
|
72
89
|
}
|
|
73
90
|
/**
|
|
74
91
|
* 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`
|
|
92
|
+
* question first — which unwired web app is this caller in. `firstRun` names it when the agent
|
|
76
93
|
* lists sessions; `openUnwiredApp` opens it zero-install on a page-needing call.
|
|
77
94
|
*/
|
|
78
|
-
export function agentWiring(
|
|
79
|
-
const firstRun = firstRunWiring(
|
|
80
|
-
const
|
|
95
|
+
export function agentWiring(sessions, lease) {
|
|
96
|
+
const firstRun = firstRunWiring();
|
|
97
|
+
const io = {
|
|
81
98
|
project: () => firstRun.projectDirectory(callingClientDirectory() ?? process.cwd()),
|
|
82
99
|
serving: async (ports) => (await probeDevServerStates(ports)).serving,
|
|
83
100
|
servingDirectory: (url) => servingDirectoryOf(url),
|
|
84
101
|
lease,
|
|
85
102
|
connected: () => 0 < sessions.list().length,
|
|
86
|
-
}
|
|
87
|
-
|
|
103
|
+
};
|
|
104
|
+
// Wired or not: a lease that names no url wants the app this caller works in either way.
|
|
105
|
+
const callerFolder = () => callingClientDirectory() ?? process.cwd();
|
|
106
|
+
return {
|
|
107
|
+
firstRun,
|
|
108
|
+
openUnwiredApp: firstCallOpener(io),
|
|
109
|
+
projectAppUrl: projectAppUrlFinder({ ...io, project: callerFolder }),
|
|
110
|
+
};
|
|
88
111
|
}
|
package/dist/start-wiring.d.ts
CHANGED
|
@@ -47,8 +47,8 @@ export declare function sdkFixForProject(projectId?: string): string;
|
|
|
47
47
|
* from before the project the agent is now driving existed.
|
|
48
48
|
*/
|
|
49
49
|
/**
|
|
50
|
-
* Every `.reticle` root on this machine that sync should consider
|
|
51
|
-
*
|
|
50
|
+
* Every `.reticle` root on this machine that sync should consider: the sources the artifact resolver
|
|
51
|
+
* uses, plus every root a lease claimed in this process.
|
|
52
52
|
*
|
|
53
53
|
* Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
|
|
54
54
|
* another terminal while this daemon is up, and a startup snapshot would keep that repo silent
|
package/dist/start-wiring.js
CHANGED
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
* router, and the per-project lookups the daemon closes over. `daemon-parity.test.ts` checks both
|
|
7
7
|
* entry points still call them.
|
|
8
8
|
*/
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
9
10
|
import { join } from 'node:path';
|
|
11
|
+
import { worktreeTwins } from './command/cli/config/checkout.js';
|
|
10
12
|
import { cpus, homedir } from 'node:os';
|
|
11
13
|
import { bridgeWsUrl, EventType, ReticleDir, ReticleEnv } from '@reticlehq/core';
|
|
12
14
|
import { fetchPlatformConfig } from './features/harness/platform-config.js';
|
|
13
15
|
import { platformEnvPort } from './memory/cloud/cloud-config.js';
|
|
14
16
|
import { knownProjectCandidates, projectDirectoryFor, } from './memory/project/artifact-root-resolver.js';
|
|
15
17
|
import { createNodeFileSystem } from './memory/project/fs/fs-port.js';
|
|
18
|
+
import { claimedArtifactRoots } from './memory/project/root-claims.js';
|
|
16
19
|
import { originOf } from './portal/session/session-manager.js';
|
|
17
20
|
import { setBrowserMode, BrowserMode } from './telemetry/browser-mode.js';
|
|
18
21
|
import { sdkFixForDirectory } from './command/version/sdk-fix.js';
|
|
@@ -151,8 +154,8 @@ export function sdkFixForProject(projectId) {
|
|
|
151
154
|
* from before the project the agent is now driving existed.
|
|
152
155
|
*/
|
|
153
156
|
/**
|
|
154
|
-
* Every `.reticle` root on this machine that sync should consider
|
|
155
|
-
*
|
|
157
|
+
* Every `.reticle` root on this machine that sync should consider: the sources the artifact resolver
|
|
158
|
+
* uses, plus every root a lease claimed in this process.
|
|
156
159
|
*
|
|
157
160
|
* Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
|
|
158
161
|
* another terminal while this daemon is up, and a startup snapshot would keep that repo silent
|
|
@@ -162,7 +165,18 @@ export function sdkFixForProject(projectId) {
|
|
|
162
165
|
* not. Deciding that here would mean reading every cloud.json on every tick.
|
|
163
166
|
*/
|
|
164
167
|
export function knownProjectRoots() {
|
|
165
|
-
|
|
168
|
+
const directories = knownProjectCandidates().map((c) => c.directory);
|
|
169
|
+
// A page served from a git worktree writes its runs into that worktree's copy of the project.
|
|
170
|
+
const twins = directories
|
|
171
|
+
.flatMap(worktreeTwins)
|
|
172
|
+
.filter((d) => existsSync(join(d, ReticleDir.ROOT)));
|
|
173
|
+
return [
|
|
174
|
+
...new Set([
|
|
175
|
+
...[...directories, ...twins].map((d) => join(d, ReticleDir.ROOT)),
|
|
176
|
+
// A lease opened with `root` writes there; without this, that work is never sent.
|
|
177
|
+
...claimedArtifactRoots(),
|
|
178
|
+
]),
|
|
179
|
+
];
|
|
166
180
|
}
|
|
167
181
|
/** This project's platform credential (stored, else the env key), as the env the platform readers take. */
|
|
168
182
|
export const platformEnvFor = (root) => platformEnvPort(createNodeFileSystem(), root ?? join(process.cwd(), ReticleDir.ROOT), homedir(), process.env);
|
package/dist/status-payload.d.ts
CHANGED
|
@@ -36,6 +36,11 @@ interface StatusPayload {
|
|
|
36
36
|
* a coding agent — what `reticle doctor` prints as its coverage line.
|
|
37
37
|
*/
|
|
38
38
|
coverage?: TabCoverage[];
|
|
39
|
+
/**
|
|
40
|
+
* SDK version of each connected page, same order as the live tabs.
|
|
41
|
+
* `null` means the page did not report a version. Absent when nothing is connected.
|
|
42
|
+
*/
|
|
43
|
+
pageSdkVersions?: readonly (string | null)[];
|
|
39
44
|
}
|
|
40
45
|
type TabCoverage = {
|
|
41
46
|
sessionId: string;
|
|
@@ -47,7 +52,12 @@ why?: string, verifyPort?: number,
|
|
|
47
52
|
/** The short rendering of the same diagnosis. Absent on a daemon that has no provider wired. */
|
|
48
53
|
whyLead?: string,
|
|
49
54
|
/** The live tabs, for their coverage. */
|
|
50
|
-
tabs?: readonly InstrumentedTab[]
|
|
55
|
+
tabs?: readonly InstrumentedTab[],
|
|
56
|
+
/**
|
|
57
|
+
* SDK version of each connected page. `null` is a page that did not report one.
|
|
58
|
+
* Absent when nothing is connected. A newer CLI reads this to choose skew advice (#1709).
|
|
59
|
+
*/
|
|
60
|
+
pageSdkVersions?: readonly (string | null)[]): StatusPayload;
|
|
51
61
|
/**
|
|
52
62
|
* Why `serve --http` cannot claim success against an already-running daemon — or undefined when
|
|
53
63
|
* that daemon already serves the verify HTTP endpoint on the wanted port.
|
package/dist/status-payload.js
CHANGED
|
@@ -7,7 +7,12 @@ why, verifyPort,
|
|
|
7
7
|
/** The short rendering of the same diagnosis. Absent on a daemon that has no provider wired. */
|
|
8
8
|
whyLead,
|
|
9
9
|
/** The live tabs, for their coverage. */
|
|
10
|
-
tabs = []
|
|
10
|
+
tabs = [],
|
|
11
|
+
/**
|
|
12
|
+
* SDK version of each connected page. `null` is a page that did not report one.
|
|
13
|
+
* Absent when nothing is connected. A newer CLI reads this to choose skew advice (#1709).
|
|
14
|
+
*/
|
|
15
|
+
pageSdkVersions = []) {
|
|
11
16
|
return {
|
|
12
17
|
running: true,
|
|
13
18
|
version: SERVER_VERSION,
|
|
@@ -28,6 +33,7 @@ tabs = []) {
|
|
|
28
33
|
...instrumentationOf(tab),
|
|
29
34
|
})),
|
|
30
35
|
}),
|
|
36
|
+
...(0 === pageSdkVersions.length ? {} : { pageSdkVersions }),
|
|
31
37
|
};
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hold back "the last agent detached" for a short grace.
|
|
3
|
+
*
|
|
4
|
+
* The daemon ends every browser session when the last agent detaches. A proxy that reconnects
|
|
5
|
+
* closes its stream and opens a new one, so a single drop of the link ended the user's session, and
|
|
6
|
+
* the agent's next call found "no connected session". With the grace, an agent that comes back
|
|
7
|
+
* inside it never detached, as far as the sessions can tell.
|
|
8
|
+
*/
|
|
9
|
+
/** Run `fn` after `ms`; the return value cancels it. Injected so a test needs no clock. */
|
|
10
|
+
export type Schedule = (fn: () => void, ms: number) => () => void;
|
|
11
|
+
export declare function withDetachGrace(onPresence: (connected: boolean) => void, graceMs: number, schedule?: Schedule): (connected: boolean) => void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hold back "the last agent detached" for a short grace.
|
|
3
|
+
*
|
|
4
|
+
* The daemon ends every browser session when the last agent detaches. A proxy that reconnects
|
|
5
|
+
* closes its stream and opens a new one, so a single drop of the link ended the user's session, and
|
|
6
|
+
* the agent's next call found "no connected session". With the grace, an agent that comes back
|
|
7
|
+
* inside it never detached, as far as the sessions can tell.
|
|
8
|
+
*/
|
|
9
|
+
const realSchedule = (fn, ms) => {
|
|
10
|
+
const timer = setTimeout(fn, ms);
|
|
11
|
+
// The grace must never keep a daemon alive that is shutting down.
|
|
12
|
+
timer.unref();
|
|
13
|
+
return () => clearTimeout(timer);
|
|
14
|
+
};
|
|
15
|
+
export function withDetachGrace(onPresence, graceMs, schedule = realSchedule) {
|
|
16
|
+
let cancelDetach;
|
|
17
|
+
return (connected) => {
|
|
18
|
+
if (!connected) {
|
|
19
|
+
cancelDetach?.();
|
|
20
|
+
cancelDetach = schedule(() => {
|
|
21
|
+
cancelDetach = undefined;
|
|
22
|
+
onPresence(false);
|
|
23
|
+
}, graceMs);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (cancelDetach !== undefined) {
|
|
27
|
+
// Back inside the grace: the detach was never reported, so there is no attach to report.
|
|
28
|
+
cancelDetach();
|
|
29
|
+
cancelDetach = undefined;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
onPresence(true);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -8,7 +8,12 @@ export interface SharedServer {
|
|
|
8
8
|
* so each concurrent Claude Code client needs its own McpServer.
|
|
9
9
|
* Must be called before listen.
|
|
10
10
|
*/
|
|
11
|
-
attachMcp(factory: (peerSkew?: string) => McpServer): void;
|
|
11
|
+
attachMcp(factory: (peerSkew?: string, proxyId?: string, agentSession?: string) => McpServer): void;
|
|
12
|
+
/**
|
|
13
|
+
* SDK version of each page connected when an agent attaches.
|
|
14
|
+
* The daemon skew advice reads this so it does not tell the agent to restart over matching pages.
|
|
15
|
+
*/
|
|
16
|
+
attachPageSdkVersions(provider: () => readonly (string | undefined)[]): void;
|
|
12
17
|
/** Register the JSON the daemon returns from GET /status (live sessions + health for `reticle status`). */
|
|
13
18
|
/** `held`: the request carried STATUS_HOLD_QUERY — a setup run is waiting on this daemon. */
|
|
14
19
|
attachStatus(provider: (held: boolean) => unknown): void;
|
|
@@ -21,6 +26,12 @@ export interface SharedServer {
|
|
|
21
26
|
* unattached, the route 404s, which is exactly what a newer CLI needs to hear from an older daemon.
|
|
22
27
|
*/
|
|
23
28
|
attachDrive(provider: (url: string) => Promise<unknown>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Register the handler behind POST /shutdown: the daemon's normal shutdown path. Only a loopback
|
|
31
|
+
* caller with the pairing token reaches it. Left unattached, the route 404s, and the caller falls
|
|
32
|
+
* back to a signal.
|
|
33
|
+
*/
|
|
34
|
+
attachShutdown(handler: () => void): void;
|
|
24
35
|
/**
|
|
25
36
|
* Register a callback fired when the AGENT presence changes — true when the first MCP client (any
|
|
26
37
|
* agent: Codex/OpenCode/Claude/Hermes) connects, false when the last one disconnects. Agent-
|