@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
|
@@ -58,22 +58,25 @@ const PAGE_CAPABILITIES = [
|
|
|
58
58
|
];
|
|
59
59
|
/** Why an action's settle wait ended, when the page said. */
|
|
60
60
|
function readSettleReason(result) {
|
|
61
|
-
if ('object' !== typeof result || null === result)
|
|
61
|
+
if ('object' !== typeof result || null === result) {
|
|
62
62
|
return undefined;
|
|
63
|
+
}
|
|
63
64
|
const reason = result.settleReason;
|
|
64
65
|
return 'string' === typeof reason ? reason : undefined;
|
|
65
66
|
}
|
|
66
67
|
/** A network event's correlation id, if it carries one. Events are `unknown` at this boundary. */
|
|
67
68
|
function readRequestId(data) {
|
|
68
|
-
if ('object' !== typeof data || null === data)
|
|
69
|
+
if ('object' !== typeof data || null === data) {
|
|
69
70
|
return undefined;
|
|
71
|
+
}
|
|
70
72
|
const id = data.id;
|
|
71
73
|
return 'string' === typeof id ? id : undefined;
|
|
72
74
|
}
|
|
73
75
|
/** What the request was pointed at, for a blind spot a person has to read. */
|
|
74
76
|
function readUrl(data) {
|
|
75
|
-
if ('object' !== typeof data || null === data)
|
|
77
|
+
if ('object' !== typeof data || null === data) {
|
|
76
78
|
return undefined;
|
|
79
|
+
}
|
|
77
80
|
const url = data.url;
|
|
78
81
|
return 'string' === typeof url ? url : undefined;
|
|
79
82
|
}
|
|
@@ -158,6 +161,11 @@ export const NOT_EVIDENCE = {
|
|
|
158
161
|
*/
|
|
159
162
|
export const NO_PROTOCOL_CHANNEL = {
|
|
160
163
|
download: 'a file the application produced; the protocol has no channel for an emitted artifact',
|
|
164
|
+
// Recorded for the episode, not yet read by a verdict. Both are screen facts and belong on `ui`,
|
|
165
|
+
// but putting them there changes what an assertion sees (a canvas animating every frame is a
|
|
166
|
+
// screen that never settles), and that ships only after the fixture bench measures it.
|
|
167
|
+
media: 'media playback state; kept as evidence, not yet adjudicated on `ui`',
|
|
168
|
+
canvas: 'a digest of canvas pixels; kept as evidence, not yet adjudicated on `ui`',
|
|
161
169
|
};
|
|
162
170
|
/**
|
|
163
171
|
* The capabilities that change the world, and therefore need an attribution window.
|
|
@@ -193,6 +201,7 @@ const REPORTED_AS_COVERAGE = new Set([
|
|
|
193
201
|
*/
|
|
194
202
|
const PROTOCOL_ANOMALY = {
|
|
195
203
|
[ContradictionKind.UI_ADVANCED_REQUEST_FAILED]: AnomalyKind.ADVANCED_OVER_FAILURE,
|
|
204
|
+
[ContradictionKind.UI_ADVANCED_UNSIGNALLED]: AnomalyKind.ADVANCED_OVER_FAILURE,
|
|
196
205
|
[ContradictionKind.SIGNAL_CONTRADICTED]: AnomalyKind.CLAIMED_OVER_FAILURE,
|
|
197
206
|
[ContradictionKind.RESPONSE_IGNORED]: AnomalyKind.EFFECT_DISCARDED,
|
|
198
207
|
[ContradictionKind.SIGNAL_WITHOUT_CONSEQUENCE]: AnomalyKind.CLAIM_UNCORROBORATED,
|
|
@@ -260,8 +269,9 @@ export class WebRealm extends Realm {
|
|
|
260
269
|
super();
|
|
261
270
|
this.#deps = deps;
|
|
262
271
|
const breaker = deps.mutations;
|
|
263
|
-
if (breaker !== undefined)
|
|
272
|
+
if (breaker !== undefined) {
|
|
264
273
|
this.mutate = (mutation) => breaker.mutate(mutation);
|
|
274
|
+
}
|
|
265
275
|
const port = deps.fixtures;
|
|
266
276
|
if (port !== undefined) {
|
|
267
277
|
this.captureFixture = async () => ({
|
|
@@ -348,8 +358,9 @@ export class WebRealm extends Realm {
|
|
|
348
358
|
// rule `HandshakeFacts` states for every field it carries. Such a page gets the full list,
|
|
349
359
|
// which is the behaviour it had before anyone could ask.
|
|
350
360
|
const served = this.#deps.session.commands;
|
|
351
|
-
if (served === undefined)
|
|
361
|
+
if (served === undefined) {
|
|
352
362
|
return PAGE_CAPABILITIES;
|
|
363
|
+
}
|
|
353
364
|
const offered = new Set(served);
|
|
354
365
|
return PAGE_CAPABILITIES.filter((c) => offered.has(c.name));
|
|
355
366
|
}
|
|
@@ -426,8 +437,9 @@ export class WebRealm extends Realm {
|
|
|
426
437
|
const channel = CHANNEL_OF_PREFIX[String(event.type).split('.')[0] ?? ''];
|
|
427
438
|
// Unrecognised prefix: reported on no channel rather than guessed onto one. An observation
|
|
428
439
|
// attributed to a source that did not produce it is worse than an observation nobody has.
|
|
429
|
-
if (channel === undefined)
|
|
440
|
+
if (channel === undefined) {
|
|
430
441
|
continue;
|
|
442
|
+
}
|
|
431
443
|
out.push({
|
|
432
444
|
id: `${window.id}-${String(index)}`,
|
|
433
445
|
window: window.id,
|
|
@@ -528,7 +540,11 @@ export class WebRealm extends Realm {
|
|
|
528
540
|
*/
|
|
529
541
|
#effectElsewhere(window) {
|
|
530
542
|
const events = this.#deps.session.eventsSince(window.openedAt);
|
|
531
|
-
return findContradictions(events, {
|
|
543
|
+
return findContradictions(events, {
|
|
544
|
+
actionSince: window.openedAt,
|
|
545
|
+
appOrigin: this.#deps.session.url,
|
|
546
|
+
background: this.#deps.session.background,
|
|
547
|
+
})
|
|
532
548
|
.filter((c) => ContradictionKind.CONSEQUENCE_ELSEWHERE === c.kind)
|
|
533
549
|
.map((c) => ({
|
|
534
550
|
kind: BlindSpotKind.EFFECT_ELSEWHERE,
|
|
@@ -549,12 +565,15 @@ export class WebRealm extends Realm {
|
|
|
549
565
|
const opened = new Map();
|
|
550
566
|
for (const event of this.#deps.session.eventsSince(window.openedAt)) {
|
|
551
567
|
const id = readRequestId(event.data);
|
|
552
|
-
if (id === undefined)
|
|
568
|
+
if (id === undefined) {
|
|
553
569
|
continue;
|
|
554
|
-
|
|
570
|
+
}
|
|
571
|
+
if (event.type === EventType.NET_PENDING) {
|
|
555
572
|
opened.set(id, readUrl(event.data) ?? id);
|
|
556
|
-
|
|
573
|
+
}
|
|
574
|
+
else if (event.type === EventType.NET_REQUEST) {
|
|
557
575
|
opened.delete(id);
|
|
576
|
+
}
|
|
558
577
|
}
|
|
559
578
|
return [...opened.values()].map((where) => ({
|
|
560
579
|
kind: BlindSpotKind.STILL_IN_FLIGHT,
|
|
@@ -589,7 +608,11 @@ export class WebRealm extends Realm {
|
|
|
589
608
|
// finding relative to ONE action. Passing `{}` left that rule switched off, and a planted
|
|
590
609
|
// double submit came back proved. In this protocol the window IS the action's extent, so
|
|
591
610
|
// its opening moment is exactly the boundary those rules are asking for.
|
|
592
|
-
const found = findContradictions(events, {
|
|
611
|
+
const found = findContradictions(events, {
|
|
612
|
+
actionSince: window.openedAt,
|
|
613
|
+
appOrigin: this.#deps.session.url,
|
|
614
|
+
background: this.#deps.session.background,
|
|
615
|
+
}).filter((c) => !REPORTED_AS_COVERAGE.has(c.kind));
|
|
593
616
|
// Synchronous underneath: the rules read a buffer that is already in memory. The interface
|
|
594
617
|
// is async for a realm that has to go and ask.
|
|
595
618
|
return Promise.resolve(found.map((contradiction) => {
|
|
@@ -622,18 +645,22 @@ export class WebRealm extends Realm {
|
|
|
622
645
|
async locate(query) {
|
|
623
646
|
const args = 'object' === typeof query && null !== query ? { ...query } : {};
|
|
624
647
|
const result = await this.#deps.session.command(ReticleCommand.QUERY, args);
|
|
625
|
-
if (true !== result.ok)
|
|
648
|
+
if (true !== result.ok) {
|
|
626
649
|
return [];
|
|
650
|
+
}
|
|
627
651
|
const elements = result.result?.elements;
|
|
628
|
-
if (!Array.isArray(elements))
|
|
652
|
+
if (!Array.isArray(elements)) {
|
|
629
653
|
return [];
|
|
654
|
+
}
|
|
630
655
|
const found = [];
|
|
631
656
|
for (const element of elements) {
|
|
632
|
-
if ('object' !== typeof element || null === element)
|
|
657
|
+
if ('object' !== typeof element || null === element) {
|
|
633
658
|
continue;
|
|
659
|
+
}
|
|
634
660
|
const ref = element.ref;
|
|
635
|
-
if ('string' !== typeof ref)
|
|
661
|
+
if ('string' !== typeof ref) {
|
|
636
662
|
continue;
|
|
663
|
+
}
|
|
637
664
|
const name = element.name;
|
|
638
665
|
const text = element.text;
|
|
639
666
|
found.push({
|
|
@@ -30,7 +30,7 @@ interface PausedResult {
|
|
|
30
30
|
* human's message entirely (not merely hides it). Declared here beside PausedResult so the schema and
|
|
31
31
|
* the runtime shape are the same source; spread into each act tool's outputSchema.
|
|
32
32
|
*/
|
|
33
|
-
export declare const pausedOutputShape: z.
|
|
33
|
+
export declare const pausedOutputShape: Record<string, z.ZodType>;
|
|
34
34
|
/** The optional `control` key `withControl` may add — keeps callers' return types honest. */
|
|
35
35
|
type ControlSpread = {
|
|
36
36
|
control?: ControlEnvelope;
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The document a local dev server actually serves: its CSP header and HTML, read once and failing
|
|
3
|
-
* soft. Shared by `doctor` (is a policy blocking the bridge?) and a lease that never dialled (was
|
|
4
|
-
* it the page's own policy?), which is why it lives beside the dev-server probe and not in either.
|
|
5
|
-
*/
|
|
6
1
|
/** What a served page said about its policy. The same shape `diagnoseObservedWebCsp` reads. */
|
|
7
2
|
export interface ObservedWebDocument {
|
|
8
3
|
url: string;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The document a local dev server actually serves: its CSP header and HTML, read once and failing
|
|
3
|
+
* soft. Shared by `doctor` (is a policy blocking the bridge?) and a lease that never dialled (was
|
|
4
|
+
* it the page's own policy?), which is why it lives beside the dev-server probe and not in either.
|
|
5
|
+
*/
|
|
6
|
+
import { originOf } from '@reticlehq/core';
|
|
1
7
|
const CSP_HEADER = 'content-security-policy';
|
|
2
8
|
const DOCUMENT_TIMEOUT_MS = 1_000;
|
|
3
9
|
const LOOPBACK_HOSTS = ['localhost', '127.0.0.1', '[::1]'];
|
|
@@ -13,14 +19,6 @@ function loopbackDocumentUrl(raw) {
|
|
|
13
19
|
return undefined;
|
|
14
20
|
}
|
|
15
21
|
}
|
|
16
|
-
function originOf(raw) {
|
|
17
|
-
try {
|
|
18
|
-
return new URL(raw).origin;
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
22
|
/** A connected tab for this project, or on its observed origin, disproves a CSP diagnosis. */
|
|
25
23
|
export function hasConnectedDocument(sessions, documentUrls, projectId) {
|
|
26
24
|
if (projectId !== undefined && sessions.some((session) => session.projectId === projectId)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelId } from '@reticlehq/core';
|
|
1
|
+
import type { ChannelId, HelloInstrumentation } from '@reticlehq/core';
|
|
2
2
|
/**
|
|
3
3
|
* What the page told us about itself when it connected.
|
|
4
4
|
*
|
|
@@ -46,6 +46,13 @@ export interface HandshakeFacts {
|
|
|
46
46
|
* `false` separates "the project turned it off" from "nothing provides one".
|
|
47
47
|
*/
|
|
48
48
|
sourceMapping?: boolean | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Who put the SDK in this page, when it said: `injected` by a hosted verifier, or `installed` by
|
|
51
|
+
* the app. Undefined means installed, as every SDK before the field was.
|
|
52
|
+
*
|
|
53
|
+
* Read by the session listing, so a URL-only check never looks like an app with the SDK installed.
|
|
54
|
+
*/
|
|
55
|
+
instrumentation?: HelloInstrumentation | undefined;
|
|
49
56
|
/**
|
|
50
57
|
* Extra key names this app declared sensitive via `connect({ redact: { keys } })`.
|
|
51
58
|
*
|
|
@@ -1,42 +1,9 @@
|
|
|
1
|
-
export interface WiredStep {
|
|
2
|
-
mark: string;
|
|
3
|
-
title: string;
|
|
4
|
-
target: string;
|
|
5
|
-
}
|
|
6
|
-
export interface WireOutcome {
|
|
7
|
-
ok: boolean;
|
|
8
|
-
/** Where init ran. */
|
|
9
|
-
directory: string;
|
|
10
|
-
/** Every step of init's plan, applied or not, as it printed them. */
|
|
11
|
-
steps: WiredStep[];
|
|
12
|
-
/** The app's url, when init got as far as the dev server. */
|
|
13
|
-
url?: string;
|
|
14
|
-
/** Why it stopped, in init's words or ours. */
|
|
15
|
-
error?: string;
|
|
16
|
-
}
|
|
17
|
-
export interface RunResult {
|
|
18
|
-
code: number;
|
|
19
|
-
stdout: string;
|
|
20
|
-
stderr: string;
|
|
21
|
-
}
|
|
22
|
-
export type RunCli = (args: readonly string[], cwd: string) => Promise<RunResult>;
|
|
23
1
|
export interface FirstRunWiring {
|
|
24
2
|
/**
|
|
25
|
-
* The
|
|
26
|
-
*
|
|
3
|
+
* The unwired web app at `cwd`, or undefined when it cannot be told without guessing: a daemon
|
|
4
|
+
* started in the home directory or at a filesystem root has no project of its own.
|
|
27
5
|
*/
|
|
28
6
|
projectDirectory(cwd: string): string | undefined;
|
|
29
|
-
wire(directory: string): Promise<WireOutcome>;
|
|
30
7
|
}
|
|
31
8
|
export declare function projectDirectoryOf(cwd: string, home?: string, wired?: (dir: string) => boolean): string | undefined;
|
|
32
|
-
|
|
33
|
-
export declare function readInitOutput(stdout: string): {
|
|
34
|
-
steps: WiredStep[];
|
|
35
|
-
result: unknown;
|
|
36
|
-
};
|
|
37
|
-
export declare function firstRunWiring(options: {
|
|
38
|
-
/** This daemon's port, so init wires the app to it rather than choosing another. */
|
|
39
|
-
port: number;
|
|
40
|
-
cliPath: string;
|
|
41
|
-
run?: RunCli;
|
|
42
|
-
}): FirstRunWiring;
|
|
9
|
+
export declare function firstRunWiring(): FirstRunWiring;
|
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Which unwired web app a caller is in.
|
|
3
3
|
*
|
|
4
|
-
* Installing Reticle puts a CLI and an MCP server on the machine and touches no project. The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* A child process rather than an import: the daemon never imports `@reticlehq/init`
|
|
10
|
-
* (library-path-boundary.test.ts), and running the CLI keeps that line where it is.
|
|
11
|
-
*
|
|
12
|
-
* Once per directory for the life of the daemon. A second call returns the first answer, so an agent
|
|
13
|
-
* that asks again after a failure is told the same thing rather than re-running a codemod on files
|
|
14
|
-
* the first run already changed.
|
|
4
|
+
* Installing Reticle puts a CLI and an MCP server on the machine and touches no project. The
|
|
5
|
+
* daemon never wires a project by itself: `init` changes the user's files, so it runs only when
|
|
6
|
+
* the user agrees (the agent runs the command, or the user does). The daemon only finds the
|
|
7
|
+
* unwired app, so that the first session call can offer the zero-install lease and the consent
|
|
8
|
+
* question for it.
|
|
15
9
|
*/
|
|
16
|
-
import { spawn } from 'node:child_process';
|
|
17
10
|
import { existsSync, readFileSync } from 'node:fs';
|
|
18
11
|
import { homedir } from 'node:os';
|
|
19
12
|
import { join, resolve } from 'node:path';
|
|
20
13
|
import { isWebApp } from '@reticlehq/init';
|
|
21
14
|
import { readProjectId } from '../../command/cli/ports/resolve/cli-port.js';
|
|
22
|
-
/** init has a dev server to start and a page to wait for; past this it is not coming. */
|
|
23
|
-
const WIRE_TIMEOUT_MS = 120_000;
|
|
24
|
-
/** A plan line as init prints it: `[✓] Vite plugin → vite.config.ts`. */
|
|
25
|
-
const PLAN_LINE = /^\s*\[(.)\]\s+(.+?)\s+→\s+(.+)$/;
|
|
26
15
|
export function projectDirectoryOf(cwd, home = homedir(), wired = (dir) => readProjectId(dir) !== undefined) {
|
|
27
16
|
const dir = resolve(cwd);
|
|
28
17
|
if (dir === resolve(home) || dir === resolve('/'))
|
|
29
18
|
return undefined;
|
|
30
|
-
// Already wired:
|
|
19
|
+
// Already wired: there is no step to offer.
|
|
31
20
|
if (wired(dir))
|
|
32
21
|
return undefined;
|
|
33
|
-
// Only an app with a page: a
|
|
22
|
+
// Only an app with a page: a library or an API package has nothing to lease or to wire.
|
|
34
23
|
return isWebApp('.', {
|
|
35
24
|
exists: (p) => existsSync(join(dir, p)),
|
|
36
25
|
readFile: (p) => {
|
|
@@ -45,88 +34,6 @@ export function projectDirectoryOf(cwd, home = homedir(), wired = (dir) => readP
|
|
|
45
34
|
? dir
|
|
46
35
|
: undefined;
|
|
47
36
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const steps = stdout
|
|
51
|
-
.split('\n')
|
|
52
|
-
.map((line) => PLAN_LINE.exec(line))
|
|
53
|
-
.flatMap((m) => null === m
|
|
54
|
-
? []
|
|
55
|
-
: [{ mark: m[1] ?? '', title: (m[2] ?? '').trim(), target: (m[3] ?? '').trim() }]);
|
|
56
|
-
const at = stdout.lastIndexOf('\n{\n') + 1;
|
|
57
|
-
let result;
|
|
58
|
-
try {
|
|
59
|
-
result = JSON.parse(stdout.slice(at));
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
result = undefined;
|
|
63
|
-
}
|
|
64
|
-
return { steps, result };
|
|
65
|
-
}
|
|
66
|
-
function nodeRun(cliPath) {
|
|
67
|
-
return (args, cwd) => new Promise((done) => {
|
|
68
|
-
const child = spawn(process.execPath, [cliPath, ...args], {
|
|
69
|
-
cwd,
|
|
70
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
71
|
-
env: process.env,
|
|
72
|
-
});
|
|
73
|
-
let stdout = '';
|
|
74
|
-
let stderr = '';
|
|
75
|
-
child.stdout.on('data', (chunk) => (stdout += chunk.toString('utf8')));
|
|
76
|
-
child.stderr.on('data', (chunk) => (stderr += chunk.toString('utf8')));
|
|
77
|
-
const timer = setTimeout(() => child.kill(), WIRE_TIMEOUT_MS);
|
|
78
|
-
child.on('error', (error) => {
|
|
79
|
-
clearTimeout(timer);
|
|
80
|
-
done({ code: 1, stdout, stderr: `${stderr}${error.message}` });
|
|
81
|
-
});
|
|
82
|
-
child.on('close', (code) => {
|
|
83
|
-
clearTimeout(timer);
|
|
84
|
-
done({ code: code ?? 1, stdout, stderr });
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
export function firstRunWiring(options) {
|
|
89
|
-
const run = options.run ?? nodeRun(options.cliPath);
|
|
90
|
-
const done = new Map();
|
|
91
|
-
return {
|
|
92
|
-
projectDirectory: (cwd) => projectDirectoryOf(cwd),
|
|
93
|
-
wire(directory) {
|
|
94
|
-
const held = done.get(directory);
|
|
95
|
-
if (held !== undefined)
|
|
96
|
-
return held;
|
|
97
|
-
const outcome = run(['init', '--no-mcp', '--json', '--port', String(options.port)], directory)
|
|
98
|
-
.then(({ code, stdout, stderr }) => {
|
|
99
|
-
// Under --json the plan lines may go to stderr, keeping stdout for the one object.
|
|
100
|
-
const { result } = readInitOutput(stdout);
|
|
101
|
-
const { steps } = readInitOutput(`${stdout}\n${stderr}`);
|
|
102
|
-
const record = 'object' === typeof result && null !== result
|
|
103
|
-
? result
|
|
104
|
-
: {};
|
|
105
|
-
const url = 'string' === typeof record['url'] ? record['url'] : undefined;
|
|
106
|
-
const ok = 0 === code && true === record['ok'];
|
|
107
|
-
const lastError = stderr.trim().split('\n').at(-1);
|
|
108
|
-
return {
|
|
109
|
-
ok,
|
|
110
|
-
directory,
|
|
111
|
-
steps,
|
|
112
|
-
...(url === undefined ? {} : { url }),
|
|
113
|
-
...(ok
|
|
114
|
-
? {}
|
|
115
|
-
: {
|
|
116
|
-
error: lastError !== undefined && 0 < lastError.length
|
|
117
|
-
? lastError
|
|
118
|
-
: `init exited ${String(code)}`,
|
|
119
|
-
}),
|
|
120
|
-
};
|
|
121
|
-
})
|
|
122
|
-
.catch((error) => ({
|
|
123
|
-
ok: false,
|
|
124
|
-
directory,
|
|
125
|
-
steps: [],
|
|
126
|
-
error: error instanceof Error ? error.message : String(error),
|
|
127
|
-
}));
|
|
128
|
-
done.set(directory, outcome);
|
|
129
|
-
return outcome;
|
|
130
|
-
},
|
|
131
|
-
};
|
|
37
|
+
export function firstRunWiring() {
|
|
38
|
+
return { projectDirectory: (cwd) => projectDirectoryOf(cwd) };
|
|
132
39
|
}
|
|
@@ -14,6 +14,20 @@ async function settledJournal(session) {
|
|
|
14
14
|
await session.flushJournal?.();
|
|
15
15
|
return session.readJournalActions();
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Did the caller name a session that has DEPARTED?
|
|
19
|
+
*
|
|
20
|
+
* `resolve` answers a departed id with its live SUCCESSOR. That is right for everything that
|
|
21
|
+
* observes -- a tab reloads, its id survives in sessionStorage, and an `assert` should keep
|
|
22
|
+
* working -- and wrong for a call that changes a session's state: it acts on a tab the caller never
|
|
23
|
+
* named (#983, #1774). An id the daemon has never seen is not departed; it falls through to
|
|
24
|
+
* `resolve`, which refuses it with the live ids named.
|
|
25
|
+
*/
|
|
26
|
+
function namedSessionDeparted(sessions, requested) {
|
|
27
|
+
return (requested !== undefined &&
|
|
28
|
+
sessions.get(requested) === undefined &&
|
|
29
|
+
sessions.departed(requested) !== undefined);
|
|
30
|
+
}
|
|
17
31
|
/**
|
|
18
32
|
* The session an id-less yield hands back.
|
|
19
33
|
*
|
|
@@ -70,6 +84,20 @@ function endingTurnWithNothingAttached(deps, id) {
|
|
|
70
84
|
const DISCONNECT_NEEDS_SESSION_ID = '`disconnect: true` needs the `sessionId` of the page to detach — list them with ' +
|
|
71
85
|
'reticle_session{action:"list"}; it is never picked for you, because detaching the wrong window ' +
|
|
72
86
|
'cuts you off from the app.';
|
|
87
|
+
/** A resume on a named session that has departed: there is no pause left to clear (#1774). */
|
|
88
|
+
function resumeDepartedNote(requested) {
|
|
89
|
+
return (`session '${requested}' had already disconnected, so there was no pause to clear. ` +
|
|
90
|
+
'Nothing else was resumed: a named session is matched exactly, never substituted.');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A review on a named session that has departed. Marks belong to one tab, so a listing from another
|
|
94
|
+
* tab answers a question the caller did not ask.
|
|
95
|
+
*/
|
|
96
|
+
function reviewDepartedError(requested) {
|
|
97
|
+
return (`session '${requested}' had already disconnected, so its marks are gone. ` +
|
|
98
|
+
'No other session was read: a named session is matched exactly, never substituted. ' +
|
|
99
|
+
'List the live sessions with reticle_session{action:"list"}.');
|
|
100
|
+
}
|
|
73
101
|
/** The agent's claim, when it is one of the words a run verdict uses. */
|
|
74
102
|
function claimOf(value) {
|
|
75
103
|
const claims = [
|
|
@@ -89,7 +117,7 @@ export const LIVE_CONTROL_TOOLS = [
|
|
|
89
117
|
'until the daemon restarts — for a stray window (a hidden desktop webview, a 404 page) that keeps coming back. ' +
|
|
90
118
|
'Ending a tab you leased also releases that lease (`leaseReleased: true`).',
|
|
91
119
|
inputSchema: {
|
|
92
|
-
summary: z.string().optional(),
|
|
120
|
+
summary: z.string().optional().describe('One sentence: what this session proved.'),
|
|
93
121
|
claim: z
|
|
94
122
|
.enum([VerdictStatus.PASS, VerdictStatus.FAIL, VerdictStatus.PARTIAL])
|
|
95
123
|
.optional()
|
|
@@ -133,23 +161,14 @@ export const LIVE_CONTROL_TOOLS = [
|
|
|
133
161
|
return Promise.resolve({ ended: true, note: YIELD_WITHOUT_SESSION_NOTE });
|
|
134
162
|
}
|
|
135
163
|
// A NAMED session that has DEPARTED is already ended, and nothing else may be ended in its
|
|
136
|
-
// place.
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
// keep working -- and wrong here, because ending a session is destructive and cannot be
|
|
141
|
-
// taken back. Reported from the field: `sessionId: "sac14d46c…"` returned `ended: true` for
|
|
142
|
-
// `"s08e37e5c…"`, once where the requested session's browser had just closed, so the
|
|
143
|
-
// behaviour was "target missing => end something else" rather than "target missing => say
|
|
144
|
-
// so" (#983).
|
|
164
|
+
// place. Ending a session is destructive and cannot be taken back. Reported from the field:
|
|
165
|
+
// `sessionId: "sac14d46c…"` returned `ended: true` for `"s08e37e5c…"`, once where the
|
|
166
|
+
// requested session's browser had just closed, so the behaviour was "target missing => end
|
|
167
|
+
// something else" rather than "target missing => say so" (#983).
|
|
145
168
|
//
|
|
146
169
|
// Not an error, either: this tool is documented as idempotent, and "the session you named is
|
|
147
|
-
// already gone" is precisely the idempotent answer.
|
|
148
|
-
|
|
149
|
-
// ids named.
|
|
150
|
-
if (requested !== undefined &&
|
|
151
|
-
deps.sessions.get(requested) === undefined &&
|
|
152
|
-
deps.sessions.departed(requested) !== undefined) {
|
|
170
|
+
// already gone" is precisely the idempotent answer.
|
|
171
|
+
if (namedSessionDeparted(deps.sessions, requested)) {
|
|
153
172
|
return Promise.resolve({
|
|
154
173
|
ended: true,
|
|
155
174
|
sessionId: requested,
|
|
@@ -231,6 +250,17 @@ export const LIVE_CONTROL_TOOLS = [
|
|
|
231
250
|
note: YIELD_WITHOUT_SESSION_NOTE,
|
|
232
251
|
});
|
|
233
252
|
}
|
|
253
|
+
// A NAMED session that has DEPARTED has nothing to hand back, and no other tab may be marked
|
|
254
|
+
// as waiting in its place (#1774). The same idempotent answer `end` gives.
|
|
255
|
+
if (namedSessionDeparted(deps.sessions, requested)) {
|
|
256
|
+
return Promise.resolve({
|
|
257
|
+
yielded: true,
|
|
258
|
+
mode: ask ? PresenterTone.ASK : PresenterTone.WAITING,
|
|
259
|
+
sessionId: requested,
|
|
260
|
+
note: `session '${String(requested)}' had already disconnected, so there was nothing to yield. ` +
|
|
261
|
+
'Nothing else was yielded: a named session is matched exactly, never substituted.',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
234
264
|
const session = resolveYieldTarget(deps.sessions, requested);
|
|
235
265
|
const note = asString(args['note']);
|
|
236
266
|
const tone = ask ? PresenterTone.ASK : PresenterTone.WAITING;
|
|
@@ -253,9 +283,15 @@ export const LIVE_CONTROL_TOOLS = [
|
|
|
253
283
|
description: 'Clear a human pause and resume driving the page. Sets state "active" and syncs the panel ' +
|
|
254
284
|
'(PRESENTER). Call after you have addressed the human guidance returned by a paused reticle_act.',
|
|
255
285
|
inputSchema: { ...sessionIdShape },
|
|
256
|
-
outputSchema: { ok: z.boolean() },
|
|
286
|
+
outputSchema: { ok: z.boolean(), note: z.string().optional() },
|
|
257
287
|
handler: (deps, args) => {
|
|
258
|
-
const
|
|
288
|
+
const requested = asString(args['sessionId']);
|
|
289
|
+
// A NAMED session that has DEPARTED has no pause to clear. Resuming its successor would clear a
|
|
290
|
+
// pause the human set by hand on a tab the agent never named (#1774). Idempotent, as `end` is.
|
|
291
|
+
if (namedSessionDeparted(deps.sessions, requested)) {
|
|
292
|
+
return Promise.resolve({ ok: true, note: resumeDepartedNote(String(requested)) });
|
|
293
|
+
}
|
|
294
|
+
const session = deps.sessions.resolve(requested);
|
|
259
295
|
// setState echoes ACTIVE to the panel in a single PRESENTER push.
|
|
260
296
|
session.setState(SessionState.ACTIVE);
|
|
261
297
|
return Promise.resolve({ ok: true });
|
|
@@ -334,7 +370,13 @@ export const LIVE_CONTROL_TOOLS = [
|
|
|
334
370
|
.describe('The note on the mark that was actually retired. CHECK IT against the mark you meant to resolve: a bare `resolved:true` cannot tell you it closed the right one, and ids are only meaningful while the session that issued them lives.'),
|
|
335
371
|
},
|
|
336
372
|
handler: (deps, args) => {
|
|
337
|
-
const
|
|
373
|
+
const requested = asString(args['sessionId']);
|
|
374
|
+
// A NAMED session that has DEPARTED is refused, not substituted: a listing or a `resolve` on its
|
|
375
|
+
// successor reads or retires marks on a tab the caller never named (#1774).
|
|
376
|
+
if (namedSessionDeparted(deps.sessions, requested)) {
|
|
377
|
+
throw new Error(reviewDepartedError(String(requested)));
|
|
378
|
+
}
|
|
379
|
+
const session = deps.sessions.resolve(requested);
|
|
338
380
|
const resolveId = asString(args['resolve']);
|
|
339
381
|
let resolved;
|
|
340
382
|
let resolvedNote;
|
|
@@ -28,6 +28,8 @@ interface NextActionFacts {
|
|
|
28
28
|
everConnected: boolean;
|
|
29
29
|
initialized: boolean;
|
|
30
30
|
listening: readonly number[];
|
|
31
|
+
/** Scanned ports that serve a page from a process that cannot be tied to this project. */
|
|
32
|
+
otherListeners?: readonly number[];
|
|
31
33
|
dev: DevCommand | undefined;
|
|
32
34
|
/**
|
|
33
35
|
* File-existence predicate for the project root, pure for testing.
|
|
@@ -114,6 +116,15 @@ export declare function departedPortGone(facts: {
|
|
|
114
116
|
listening: readonly number[];
|
|
115
117
|
slowListeners?: readonly number[];
|
|
116
118
|
}): boolean;
|
|
119
|
+
export declare const INIT_COMMAND = "npx @reticlehq/server init";
|
|
120
|
+
/**
|
|
121
|
+
* The consent question for wiring, in one wording for every place that offers `init`: the
|
|
122
|
+
* handshake, the first session call, every next action and the plugin hook. `init` changes the user's files, so the
|
|
123
|
+
* agent asks first. The lease changes nothing, so it needs no question.
|
|
124
|
+
*/
|
|
125
|
+
export declare function wiringConsent(init?: string): string;
|
|
126
|
+
/** The zero-install call, with the URL only when it can be named without guessing. */
|
|
127
|
+
export declare function zeroInstallLease(url: string | undefined): string;
|
|
117
128
|
export declare function nextActionFor(facts: NextActionFacts): NoSessionNextAction;
|
|
118
129
|
/** The same action as one sentence, for the prose message the human reads. */
|
|
119
130
|
export declare function renderNextAction(next: NoSessionNextAction): string;
|