@reticlehq/server 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +122 -123
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +18 -2
- package/dist/command/cli/adhoc-verdict.js +70 -6
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +28 -105
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +34 -4
- package/dist/command/cli/cli-verify.js +81 -12
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +145 -333
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +15 -1
- package/dist/command/cli/cloud-login.js +67 -13
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.js +1 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +29 -8
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -178
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +14 -0
- package/dist/command/cli.js +103 -83
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +9 -1
- package/dist/command/daemon/daemon-resolve.js +49 -10
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +10 -1
- package/dist/command/setup/init/init-port.js +22 -2
- package/dist/command/setup/init/init-runtime.d.ts +12 -2
- package/dist/command/setup/init/init-runtime.js +96 -37
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +36 -8
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +1 -1
- package/dist/command/setup/run-setup.d.ts +29 -9
- package/dist/command/setup/run-setup.js +34 -28
- package/dist/command/setup/setup-command.d.ts +23 -0
- package/dist/command/setup/setup-command.js +57 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +38 -2
- package/dist/features/crawl/crawl.js +14 -1
- package/dist/features/exhaust/ledger.d.ts +14 -14
- package/dist/features/harness/drive-report.d.ts +39 -5
- package/dist/features/harness/drive-report.js +271 -54
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/goals.d.ts +68 -7
- package/dist/features/harness/goals.js +289 -36
- package/dist/features/harness/harness.d.ts +30 -1
- package/dist/features/harness/harness.js +141 -7
- package/dist/features/harness/platform/local-apps.d.ts +36 -3
- package/dist/features/harness/platform/local-apps.js +81 -5
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +8 -2
- package/dist/features/harness/platform/remote-drive.js +22 -9
- package/dist/features/harness/platform/script.d.ts +57 -11
- package/dist/features/harness/platform/script.js +144 -12
- package/dist/features/harness/platform/server-driver.d.ts +17 -4
- package/dist/features/harness/platform/server-driver.js +29 -26
- package/dist/features/harness/platform-config.d.ts +38 -5
- package/dist/features/harness/platform-config.js +93 -8
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/script-run.d.ts +30 -1
- package/dist/features/harness/script/script-run.js +355 -48
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.js +22 -14
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +21 -2
- package/dist/hooks/driven-by.js +42 -2
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -183
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
- package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
- package/dist/judgement/runs/artifact/run-store.js +175 -8
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +53 -5
- package/dist/judgement/runs/drive-run.js +234 -20
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +5 -2
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +2 -0
- package/dist/judgement/runs/verification-sync.js +36 -15
- package/dist/language/flows/decision.js +2 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +7 -2
- package/dist/language/flows/flow-anchor.js +10 -3
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +37 -3
- package/dist/language/flows/flow-replay-run.js +16 -18
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +18 -1
- package/dist/language/flows/flow-replay.js +22 -7
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-step-runners.d.ts +2 -0
- package/dist/language/flows/flow-step-runners.js +12 -6
- package/dist/language/flows/flow-store-for-session.js +5 -1
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +61 -62
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +69 -10
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
- package/dist/language/flows/recording/tape/recordings.js +60 -10
- package/dist/language/flows/replay.js +29 -6
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +200 -193
- package/dist/memory/cloud/cloud-config.d.ts +10 -1
- package/dist/memory/cloud/cloud-config.js +19 -5
- package/dist/memory/cloud/cloud-sync.js +3 -3
- package/dist/memory/cloud/harness-config.d.ts +49 -0
- package/dist/memory/cloud/harness-config.js +16 -20
- package/dist/memory/cloud/memory-scope.d.ts +17 -0
- package/dist/memory/cloud/memory-scope.js +22 -0
- package/dist/memory/cloud/sync-cycle.d.ts +32 -4
- package/dist/memory/cloud/sync-cycle.js +113 -12
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +114 -4
- package/dist/memory/cloud/sync-disk.js +26 -2
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +16 -1
- package/dist/memory/impact/account-watch.js +26 -1
- package/dist/memory/impact/impact-store.d.ts +1 -4
- package/dist/memory/impact/impact-store.js +32 -42
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +12 -0
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +42 -2
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/journal-recorder.js +46 -3
- package/dist/memory/journal/on-disk/retention.d.ts +5 -0
- package/dist/memory/journal/on-disk/retention.js +27 -2
- package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +38 -7
- package/dist/memory/project/artifact-root-resolver.js +33 -5
- package/dist/memory/project/artifact-root.d.ts +4 -3
- package/dist/memory/project/artifact-root.js +2 -2
- package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
- package/dist/memory/project/dir/reticle-dir.js +23 -2
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +2 -0
- package/dist/memory/project/session-root.js +9 -1
- package/dist/memory/project/sync-status.d.ts +46 -0
- package/dist/memory/project/sync-status.js +135 -1
- package/dist/memory/recall/memory-tools.js +46 -3
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.js +36 -8
- package/dist/portal/bridge/bridge.d.ts +9 -5
- package/dist/portal/bridge/bridge.js +66 -23
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +2 -0
- package/dist/portal/input/real-input.js +13 -10
- package/dist/portal/pool/browser-pool.d.ts +48 -0
- package/dist/portal/pool/browser-pool.js +120 -2
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +27 -5
- package/dist/portal/pool/playwright-launcher.js +59 -14
- package/dist/portal/pool/pool-contract.d.ts +21 -1
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.js +6 -1
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
- package/dist/portal/session/dev-server/dev-command.js +27 -1
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/live-control-tools.js +82 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
- package/dist/portal/session/no-session-diagnosis.js +31 -9
- package/dist/portal/session/no-session-next-action.d.ts +20 -0
- package/dist/portal/session/no-session-next-action.js +134 -61
- package/dist/portal/session/no-session-watch.js +179 -22
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/session-health.d.ts +11 -0
- package/dist/portal/session/session-health.js +3 -1
- package/dist/portal/session/session-info.js +2 -1
- package/dist/portal/session/session-manager.d.ts +18 -0
- package/dist/portal/session/session-manager.js +54 -3
- package/dist/portal/session/session-successor.d.ts +8 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session.d.ts +15 -28
- package/dist/portal/session/session.js +60 -61
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +7 -1
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +13 -1
- package/dist/status-payload.js +13 -1
- package/dist/surface/http-server.js +7 -1
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
- package/dist/surface/mcp/mcp-proxy.js +29 -8
- package/dist/surface/mcp/mcp.d.ts +23 -0
- package/dist/surface/mcp/mcp.js +34 -4
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.js +22 -14
- package/dist/surface/mcp/shared-params.js +1 -1
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act-sequence-tool.js +136 -27
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +48 -34
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.js +25 -15
- package/dist/surface/tools/browser-tools.js +43 -1
- package/dist/surface/tools/chat-drives.d.ts +75 -0
- package/dist/surface/tools/chat-drives.js +265 -21
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +10 -0
- package/dist/surface/tools/empty-session-list.js +45 -5
- package/dist/surface/tools/error-recovery.d.ts +8 -0
- package/dist/surface/tools/error-recovery.js +69 -5
- package/dist/surface/tools/explore-tools.d.ts +23 -2
- package/dist/surface/tools/explore-tools.js +377 -74
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +4 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +52 -73
- package/dist/surface/tools/harness-explore.js +177 -146
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +5 -0
- package/dist/surface/tools/harness-plan.js +7 -0
- package/dist/surface/tools/harness-script.d.ts +22 -0
- package/dist/surface/tools/harness-script.js +256 -38
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +8 -0
- package/dist/surface/tools/harness-toolset.js +27 -4
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +220 -93
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +20 -0
- package/dist/surface/tools/lease-seed.js +45 -1
- package/dist/surface/tools/lease-tools.d.ts +10 -1
- package/dist/surface/tools/lease-tools.js +119 -69
- package/dist/surface/tools/live-call-text.js +2 -2
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +11 -1
- package/dist/surface/tools/next-step.js +73 -18
- package/dist/surface/tools/observe-tools.js +43 -5
- package/dist/surface/tools/platform-moment.d.ts +60 -0
- package/dist/surface/tools/platform-moment.js +132 -4
- package/dist/surface/tools/read-tools.js +65 -14
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +68 -2
- package/dist/surface/tools/tool-kit.js +73 -1
- package/dist/surface/tools/tools.js +25 -13
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +27 -6
- package/dist/telemetry/hud-metrics.js +99 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +26 -2
- package/dist/telemetry/telemetry.js +102 -21
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +12 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +16 -5
- package/docs/README.md +2 -2
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +24 -27
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +13 -12
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +8 -3
- package/docs/cli/drive.mdx +12 -12
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +32 -15
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +13 -4
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +3 -2
- package/docs/cli.mdx +110 -41
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +5 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +5 -2
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +66 -64
- package/docs/human-control.md +15 -14
- package/docs/index.mdx +15 -43
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +22 -12
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +8 -8
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +11 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +58 -29
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +22 -24
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +13 -4
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +51 -45
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +7 -5
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +6 -5
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -249
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,7 @@ export interface RunningServer {
|
|
|
75
75
|
close: () => Promise<void>;
|
|
76
76
|
}
|
|
77
77
|
export { resolveBridgeSecurity } from './portal/bridge/bridge-security.js';
|
|
78
|
+
/** Start the Reticle bridge (browser WS endpoint) and, by default, the MCP stdio server. */
|
|
78
79
|
export declare function start(options?: StartOptions): Promise<RunningServer>;
|
|
79
80
|
/**
|
|
80
81
|
* Start the Reticle bridge in daemon mode: a single HTTP server handles both the WebSocket
|
package/dist/index.js
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
import { applyHarnessSwitch, harnessConfigsByRoot } from './memory/cloud/harness-config.js';
|
|
2
2
|
import { coveragePercents } from './features/exhaust/ledger.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { watchAccountFiles } from './memory/impact/account-watch.js';
|
|
3
|
+
import { agentWiring } from './portal/session/zero-install-first-call.js';
|
|
4
|
+
import { pushIfMoved, watchAccountFiles } from './memory/impact/account-watch.js';
|
|
6
5
|
import { SESSION_FILE } from './command/cli/cloud-kit.js';
|
|
7
6
|
import { join } from 'node:path';
|
|
8
7
|
import { homedir } from 'node:os';
|
|
9
|
-
import { linkedCloudPort,
|
|
8
|
+
import { linkedCloudPort, sessionCloudPort } from './memory/cloud/cloud-config.js';
|
|
10
9
|
import { sessionRoot } from './memory/project/session-root.js';
|
|
11
10
|
import { attachCloudSync } from './memory/cloud/sync-daemon.js';
|
|
12
11
|
import { wireHooks } from './hooks/hook-commands.js';
|
|
13
12
|
import { currentDrivenBy } from './hooks/driven-by.js';
|
|
14
|
-
import { artifactRootResolver
|
|
13
|
+
import { artifactRootResolver } from './memory/project/artifact-root-resolver.js';
|
|
15
14
|
import { servingDirectoryOf } from './portal/session/serving-directory.js';
|
|
16
15
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
17
|
-
import { AGENT_STOPPED_NOTICE, RETICLE_DEFAULT_PORT,
|
|
18
|
-
import { originOf } from './portal/session/session-manager.js';
|
|
19
|
-
import { setBrowserMode, BrowserMode } from './telemetry/browser-mode.js';
|
|
16
|
+
import { AGENT_STOPPED_NOTICE, RETICLE_DEFAULT_PORT, ReticleCommand, ReticleDir, ReticleEnv, LOOPBACK_HOST, } from '@reticlehq/core';
|
|
20
17
|
import { replayFromHud } from './language/flows/replay-from-hud.js';
|
|
21
18
|
import { createSharedServer } from './surface/http-server.js';
|
|
22
19
|
import { openLoopbackAlias } from './command/daemon/binding/loopback-alias.js';
|
|
23
20
|
import { reportAppInstrumented } from './telemetry/app-instrumented.js';
|
|
24
21
|
import { resolveBridgeSecurityWithAutoToken } from './portal/bridge/bridge-security.js';
|
|
25
22
|
import { Bridge } from './portal/bridge/bridge.js';
|
|
26
|
-
import { sdkFixForDirectory } from './command/version/sdk-fix.js';
|
|
27
23
|
import { connectionSkew } from './command/version/version-nudge.js';
|
|
28
24
|
import { SERVER_VERSION } from './command/version/identity/server-version.js';
|
|
29
25
|
import { BaselineStore } from './memory/project/baselines.js';
|
|
@@ -45,27 +41,22 @@ import { startVerifyServer } from './judgement/runs/verify-server.js';
|
|
|
45
41
|
import { createMcpServer } from './surface/mcp/mcp.js';
|
|
46
42
|
import { instructionStateAt } from './surface/mcp/mcp-proxy.js';
|
|
47
43
|
import { LEASE_ACQUIRE_TOOL } from './surface/tools/lease-tools.js';
|
|
48
|
-
import { startChatDrives } from './surface/tools/chat-drives.js';
|
|
44
|
+
import { attachHudHarness, projectLinkOnly, startChatDrives } from './surface/tools/chat-drives.js';
|
|
49
45
|
import { runTool } from './surface/tools/invoke-tool.js';
|
|
50
46
|
import { SessionReaper, endAllSessions, MCP_DISCONNECT_SUMMARY, } from './portal/session/session-reaper.js';
|
|
51
47
|
import { wireSessionScope } from './portal/session/no-session-watch.js';
|
|
52
48
|
import { buildIdlePredicate, noteSetupHold } from './command/daemon/lifetime/daemon-usefulness.js';
|
|
53
49
|
import { resolveToolSurface } from './surface/tools/tool-surface.js';
|
|
54
50
|
import { statusPayload } from './status-payload.js';
|
|
55
|
-
import { CdpRealInputProvider, LaunchedRealInputProvider } from './portal/input/real-input.js';
|
|
56
|
-
import { cpus } from 'node:os';
|
|
57
|
-
import { BrowserPool } from './portal/pool/browser-pool.js';
|
|
58
51
|
import { AGENT_ALREADY_DRIVING_ELSEWHERE, shouldGreetWithLeaseNotice, } from './portal/session/lease-visibility.js';
|
|
59
|
-
import { playwrightLauncher, resolveMaxContexts } from './portal/pool/playwright-launcher.js';
|
|
60
52
|
import { LeaseReaper } from './portal/pool/lease-reaper.js';
|
|
61
53
|
import { findProjectConfig, readJournalEnabled, readProjectId, } from './command/cli/ports/resolve/cli-port.js';
|
|
62
54
|
import { probeLaunchableChromium } from './launch-chromium.js';
|
|
63
55
|
import { attachJournal } from './wire-journal.js';
|
|
64
56
|
import { reportOnboardingStep } from './telemetry/onboarding-funnel.js';
|
|
65
|
-
import { AMBIENT_RECORDING } from './language/flows/recording/tape/recordings.js';
|
|
66
57
|
import { readRetainPolicy } from './memory/journal/on-disk/retain-policy.js';
|
|
67
58
|
import { log } from './log.js';
|
|
68
|
-
import {
|
|
59
|
+
import { createBrowserPool, knownProjectRoots, loadHarnessConfig, makeNetworkDetailRouter, platformEnvFor, readerConnect, resolveRealInput, sdkFixForProject, } from './start-wiring.js';
|
|
69
60
|
export { replayVerdictLine } from './language/flows/replay-from-hud.js';
|
|
70
61
|
// Re-exported from the contract, where the names now live: a consumer importing the server should
|
|
71
62
|
// not have to know that the vocabulary moved.
|
|
@@ -108,153 +99,7 @@ export { findContradictions } from '@reticlehq/engine/disagreement/contradiction
|
|
|
108
99
|
/** Default localhost port for the verify HTTP endpoint (see docs/platform-integration.md). */
|
|
109
100
|
export const RETICLE_VERIFY_DEFAULT_PORT = 7331;
|
|
110
101
|
export { resolveBridgeSecurity } from './portal/bridge/bridge-security.js';
|
|
111
|
-
/**
|
|
112
|
-
* Build the shared browser pool (one headless Chromium, N capped isolated leased contexts). Lazy —
|
|
113
|
-
* no Chromium launches until the first lease — so creating it is free even when never used.
|
|
114
|
-
*/
|
|
115
|
-
/** Where the zero-install reader connects: this daemon's own bridge, with its pairing token. */
|
|
116
|
-
function readerConnect(port, token) {
|
|
117
|
-
return { url: bridgeWsUrl(port), ...(token === undefined ? {} : { token }) };
|
|
118
|
-
}
|
|
119
|
-
function createBrowserPool(headless, reader) {
|
|
120
|
-
const maxContexts = resolveMaxContexts(process.env[ReticleEnv.MAX_CONTEXTS], cpus().length);
|
|
121
|
-
const genSessionId = () => `lease-${'function' === typeof globalThis.crypto?.randomUUID
|
|
122
|
-
? globalThis.crypto.randomUUID()
|
|
123
|
-
: String(Date.now())}`;
|
|
124
|
-
// Built on first use and kept: the page that needs it is one whose app never connected.
|
|
125
|
-
let script;
|
|
126
|
-
const zeroInstallScript = () => {
|
|
127
|
-
if (script === undefined) {
|
|
128
|
-
const bundle = readReaderBundle();
|
|
129
|
-
script = bundle === undefined ? null : zeroInstallScriptFor(bundle, reader);
|
|
130
|
-
}
|
|
131
|
-
return script ?? undefined;
|
|
132
|
-
};
|
|
133
|
-
return new BrowserPool(playwrightLauncher({ headless }), {
|
|
134
|
-
maxContexts,
|
|
135
|
-
genSessionId,
|
|
136
|
-
zeroInstallScript,
|
|
137
|
-
launchHeaded: playwrightLauncher({ headless: false }),
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Route CDP-authoritative network detail onto the driven session's journal.
|
|
142
|
-
*
|
|
143
|
-
* The page and the SDK session share an origin, so a NET_DETAIL is pushed to the matching connected
|
|
144
|
-
* session. Shared by both entry points: `startDaemon` previously omitted it entirely, so on the path
|
|
145
|
-
* users actually take, CDP network detail was collected and then dropped on the floor.
|
|
146
|
-
*/
|
|
147
|
-
function makeNetworkDetailRouter(bridge, driveUrl) {
|
|
148
|
-
const driveOrigin = originOf(driveUrl ?? '');
|
|
149
|
-
return (detail) => {
|
|
150
|
-
// Route by the DOCUMENT that issued the request, not by the request's own origin.
|
|
151
|
-
//
|
|
152
|
-
// Matching the request's origin only works for same-origin calls. An app on one origin calling an
|
|
153
|
-
// API on another — most API calls — produced a detail matching no session, and it was dropped
|
|
154
|
-
// without a trace. The drive-URL fallback papered over it on the launched path and did nothing on
|
|
155
|
-
// the CDP-attach path, where driveUrl is undefined and the fallback compares against ''.
|
|
156
|
-
const pageOrigin = originOf(detail.pageUrl ?? '');
|
|
157
|
-
const requestOrigin = originOf(detail.url);
|
|
158
|
-
for (const session of bridge.sessions.all()) {
|
|
159
|
-
const origin = originOf(session.url);
|
|
160
|
-
// originOf returns `string | undefined`, NEVER '' — so the old `!== ''` guards were dead, and a
|
|
161
|
-
// bare `origin === requestOrigin` matched `undefined === undefined` when BOTH the session URL and
|
|
162
|
-
// the detail URL were unparseable. That routed a NET_DETAIL (with its response headers, incl.
|
|
163
|
-
// set-cookie) onto an unrelated session. Require a DEFINED origin; undefined operands then simply
|
|
164
|
-
// fail to match any of the three candidates.
|
|
165
|
-
const matches = origin !== undefined &&
|
|
166
|
-
(origin === pageOrigin || origin === requestOrigin || origin === driveOrigin);
|
|
167
|
-
if (matches) {
|
|
168
|
-
session.pushEvent({
|
|
169
|
-
t: 0,
|
|
170
|
-
type: EventType.NET_DETAIL,
|
|
171
|
-
sessionId: session.id,
|
|
172
|
-
data: { ...detail },
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Resolve the drive/real-input provider from options — shared by start and startDaemon so the
|
|
180
|
-
* precedence (driveUrl launch+own → CDP attach → none) and the storageState/injectConnect plumbing
|
|
181
|
-
* live in ONE place. `onNavigateError` is the entrypoint's own cleanup (close the bridge/shared server)
|
|
182
|
-
* so a failed launch never leaks a WS port. A past divergence between the two paths let daemon mode
|
|
183
|
-
* run with a different setup — this removes that risk.
|
|
184
|
-
*/
|
|
185
|
-
async function resolveRealInput(options, onNavigateError, onNetworkDetail) {
|
|
186
|
-
const driveUrl = options.driveUrl;
|
|
187
|
-
if (driveUrl !== undefined && driveUrl.length > 0) {
|
|
188
|
-
const headless = options.headless ?? true;
|
|
189
|
-
// The one place that knows. Everything downstream reads it rather than re-deriving it, and a
|
|
190
|
-
// daemon that launches nothing keeps the default (ATTACHED) rather than guessing.
|
|
191
|
-
setBrowserMode(headless ? BrowserMode.HEADLESS : BrowserMode.HEADED);
|
|
192
|
-
const injectConnect = options.injectConnect;
|
|
193
|
-
const storageState = options.storageState;
|
|
194
|
-
const factory = options.realInputFactory ??
|
|
195
|
-
((opts) => new LaunchedRealInputProvider({
|
|
196
|
-
driveUrl: opts.driveUrl,
|
|
197
|
-
headless: opts.headless,
|
|
198
|
-
...(injectConnect !== undefined ? { injectConnect } : {}),
|
|
199
|
-
...(storageState !== undefined ? { storageState } : {}),
|
|
200
|
-
...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
|
|
201
|
-
}));
|
|
202
|
-
const launched = factory({ driveUrl, headless });
|
|
203
|
-
try {
|
|
204
|
-
await launched.navigate();
|
|
205
|
-
}
|
|
206
|
-
catch (error) {
|
|
207
|
-
await onNavigateError(); // no leaked WS port on a failed start
|
|
208
|
-
throw error;
|
|
209
|
-
}
|
|
210
|
-
return { realInput: launched, owned: launched };
|
|
211
|
-
}
|
|
212
|
-
const cdpUrl = options.cdpUrl ?? process.env[ReticleEnv.CDP_URL];
|
|
213
|
-
if (cdpUrl !== undefined && cdpUrl.length > 0) {
|
|
214
|
-
// Same network sink as the launched path. Whether Reticle opened the browser or attached to one
|
|
215
|
-
// someone else opened has no bearing on whether it can read that browser's network.
|
|
216
|
-
const cdp = new CdpRealInputProvider({
|
|
217
|
-
cdpUrl,
|
|
218
|
-
...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
|
|
219
|
-
});
|
|
220
|
-
return { realInput: cdp, owned: cdp };
|
|
221
|
-
}
|
|
222
|
-
return {};
|
|
223
|
-
}
|
|
224
102
|
/** Start the Reticle bridge (browser WS endpoint) and, by default, the MCP stdio server. */
|
|
225
|
-
/**
|
|
226
|
-
* The SDK-upgrade sentence for the package.json of the project the page announced, evaluated at
|
|
227
|
-
* each HELLO so a just-edited manifest is what we name. The daemon's cwd only when that project's
|
|
228
|
-
* directory is unknown, and the framework-neutral sensor when that is not an app either (#1135).
|
|
229
|
-
*/
|
|
230
|
-
function sdkFixForProject(projectId) {
|
|
231
|
-
return sdkFixForDirectory(SERVER_VERSION, projectDirectoryFor(projectId) ?? process.cwd());
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Resolve a session's artifact root, from everything this machine knows about where projects live.
|
|
235
|
-
*
|
|
236
|
-
* Built once per daemon and closed over by every tool call. The two sources are read lazily and
|
|
237
|
-
* cheaply on each call rather than snapshotted at startup: `init` can run in another terminal while
|
|
238
|
-
* this daemon is up, and a resolution that used a startup snapshot would keep answering with a map
|
|
239
|
-
* from before the project the agent is now driving existed.
|
|
240
|
-
*/
|
|
241
|
-
/**
|
|
242
|
-
* Every `.reticle` root on this machine that sync should consider, from the same two sources the
|
|
243
|
-
* artifact resolver uses.
|
|
244
|
-
*
|
|
245
|
-
* Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
|
|
246
|
-
* another terminal while this daemon is up, and a startup snapshot would keep that repo silent
|
|
247
|
-
* until somebody restarted a process they have no reason to suspect.
|
|
248
|
-
*
|
|
249
|
-
* Returns directories that MIGHT be linked; the caller resolves each and skips the ones that are
|
|
250
|
-
* not. Deciding that here would mean reading every cloud.json on every tick.
|
|
251
|
-
*/
|
|
252
|
-
function knownProjectRoots() {
|
|
253
|
-
return [...new Set(knownProjectCandidates().map((c) => join(c.directory, ReticleDir.ROOT)))];
|
|
254
|
-
}
|
|
255
|
-
/** This project's platform credential (stored, else the env key), as the env the platform readers take. */
|
|
256
|
-
const platformEnvFor = (root) => platformEnvPort(createNodeFileSystem(), root ?? join(process.cwd(), ReticleDir.ROOT), homedir(), process.env);
|
|
257
|
-
const loadHarnessConfig = async (root) => fetchPlatformConfig(await platformEnvFor(root)());
|
|
258
103
|
export async function start(options = {}) {
|
|
259
104
|
const port = options.port ?? RETICLE_DEFAULT_PORT;
|
|
260
105
|
const configForRoot = harnessConfigsByRoot(loadHarnessConfig);
|
|
@@ -309,7 +154,7 @@ export async function start(options = {}) {
|
|
|
309
154
|
enabled: journalEnabled,
|
|
310
155
|
retain,
|
|
311
156
|
// Bound HERE, where the recorder is already in hand: teardown gets the tape, not the recorder.
|
|
312
|
-
takeAmbientTape: () => recordings.
|
|
157
|
+
takeAmbientTape: (sessionId) => recordings.takeAmbient(sessionId),
|
|
313
158
|
reportStep: reportOnboardingStep,
|
|
314
159
|
flows,
|
|
315
160
|
author: flowAuthor,
|
|
@@ -423,11 +268,11 @@ export async function startDaemon(options = {}) {
|
|
|
423
268
|
sdkFix: sdkFixForProject,
|
|
424
269
|
...security,
|
|
425
270
|
});
|
|
426
|
-
const repaint = (only) => {
|
|
271
|
+
const repaint = (only, ifChanged = false) => {
|
|
427
272
|
for (const session of bridge.sessions.all()) {
|
|
428
273
|
const root = session.artifactRoot ?? options.reticleRoot ?? join(process.cwd(), ReticleDir.ROOT);
|
|
429
|
-
if (only
|
|
430
|
-
session
|
|
274
|
+
if ((only ?? root) === root)
|
|
275
|
+
pushIfMoved(session, () => impactSnapshot(root), ifChanged);
|
|
431
276
|
}
|
|
432
277
|
};
|
|
433
278
|
pushHarnessConfig = repaint;
|
|
@@ -446,7 +291,7 @@ export async function startDaemon(options = {}) {
|
|
|
446
291
|
// `init` holds the daemon it is waiting on, so the idle rule cannot shut it down mid-wait.
|
|
447
292
|
if (held)
|
|
448
293
|
noteSetupHold(Date.now());
|
|
449
|
-
return statusPayload(bridge.sessions.count(), bridge.sessions.list(), bridge.sessions.noSessionHint(), verifyHttp?.port, bridge.sessions.noSessionLead());
|
|
294
|
+
return statusPayload(bridge.sessions.count(), bridge.sessions.list(), bridge.sessions.noSessionHint(), verifyHttp?.port, bridge.sessions.noSessionLead(), bridge.sessions.all());
|
|
450
295
|
});
|
|
451
296
|
// Agent-independent presence: the daemon outlives any single agent, so when the LAST agent's MCP
|
|
452
297
|
// connection drops (it stopped, or is waiting on the human), end every session and push a clear
|
|
@@ -469,7 +314,8 @@ export async function startDaemon(options = {}) {
|
|
|
469
314
|
const retain = readRetainPolicy(findProjectConfig(process.cwd()));
|
|
470
315
|
// See the sibling path: `retain.sessions: 0` stops the capture too, not only the sweep.
|
|
471
316
|
const journalEnabled = readJournalEnabled(process.cwd(), process.env[ReticleEnv.JOURNAL]) && 0 < retain.sessions;
|
|
472
|
-
|
|
317
|
+
// A saved flow wakes sync like a landed run: see FlowStore's `onWrote`.
|
|
318
|
+
const flows = new FlowStore(fs, reticleRoot, { now }, { onWrote: () => syncNudge.run?.() });
|
|
473
319
|
// Built here rather than inside `deps` below, so teardown can save what a drive recorded. Both
|
|
474
320
|
// paths pass the same pair — `daemon-parity.test.ts` is what keeps them from drifting apart.
|
|
475
321
|
const recordings = new RecordingStore(() => currentDrivenBy() !== undefined);
|
|
@@ -481,12 +327,12 @@ export async function startDaemon(options = {}) {
|
|
|
481
327
|
* setup ahead of session capture for the sake of one callback.
|
|
482
328
|
*/
|
|
483
329
|
const syncNudge = {};
|
|
484
|
-
attachJournal(bridge, {
|
|
330
|
+
const endLiveSessions = attachJournal(bridge, {
|
|
485
331
|
fs,
|
|
486
332
|
reticleRoot,
|
|
487
333
|
enabled: journalEnabled,
|
|
488
334
|
retain,
|
|
489
|
-
takeAmbientTape: () => recordings.
|
|
335
|
+
takeAmbientTape: (sessionId) => recordings.takeAmbient(sessionId),
|
|
490
336
|
reportStep: reportOnboardingStep,
|
|
491
337
|
flows,
|
|
492
338
|
author: flowAuthor,
|
|
@@ -522,20 +368,15 @@ export async function startDaemon(options = {}) {
|
|
|
522
368
|
otherRoots: knownProjectRoots,
|
|
523
369
|
});
|
|
524
370
|
syncNudge.run = () => cloudSync.nudge();
|
|
525
|
-
// `syncNow`, not `nudge
|
|
526
|
-
// wrong for a button somebody is watching. Never awaited.
|
|
371
|
+
// `syncNow`, not `nudge` (a cycle soon): somebody is watching the button. Never awaited.
|
|
527
372
|
bridge.attachSyncRequest(() => void cloudSync.syncNow());
|
|
528
|
-
// The panel's harness switch, written through to the platform so console and panel cannot disagree.
|
|
529
373
|
if (options.hudSignIn !== undefined)
|
|
530
|
-
bridge.attachSigninRequest(options.hudSignIn(
|
|
531
|
-
//
|
|
532
|
-
const accountFiles = watchAccountFiles(() => repaint());
|
|
374
|
+
bridge.attachSigninRequest(options.hudSignIn(repaint, projectLinkOnly(options.hudLink)));
|
|
375
|
+
// Logout and link run in another process: repaint when their files change, the rest on a timer.
|
|
376
|
+
const accountFiles = watchAccountFiles(repaint, undefined, () => repaint(undefined, true));
|
|
533
377
|
accountFiles.watch(join(homedir(), ReticleDir.ROOT, SESSION_FILE));
|
|
534
378
|
bridge.attachSessionReady((s) => accountFiles.watch(join(s.artifactRoot ?? reticleRoot, ReticleDir.CLOUD_LINK_FILE)));
|
|
535
|
-
bridge
|
|
536
|
-
const root = s.artifactRoot ?? reticleRoot;
|
|
537
|
-
applyHarnessSwitch(configForRoot, root, on, platformEnvFor(root));
|
|
538
|
-
});
|
|
379
|
+
attachHudHarness(bridge, { deps: () => deps, root: reticleRoot, repaint: () => repaint() }, (r, on) => applyHarnessSwitch(configForRoot, r, on, platformEnvFor(r)), options.hudLink);
|
|
539
380
|
// Scope auto-selection to the active project (from .reticle.json) so a stray tab from another app is
|
|
540
381
|
// never picked when the agent omits a sessionId. Explicit per-call scope/sessionId still overrides.
|
|
541
382
|
// Scope + the no-session diagnosis: "no browser session connected" is the error that ends most
|
|
@@ -544,6 +385,7 @@ export async function startDaemon(options = {}) {
|
|
|
544
385
|
// server for a wired project (see no-session-watch.ts), and it opens it through the pool — the same
|
|
545
386
|
// path reticle_lease takes, in this process, binding nothing.
|
|
546
387
|
wireSessionScope(bridge.sessions, readProjectId(process.cwd()), port, (sessionId) => pool.wasReapedLease(sessionId), (url) => pool.acquire(url));
|
|
388
|
+
const leaseUrl = (url) => runTool(LEASE_ACQUIRE_TOOL, effectiveDeps, { url });
|
|
547
389
|
const deps = {
|
|
548
390
|
sessions: bridge.sessions,
|
|
549
391
|
pool,
|
|
@@ -568,7 +410,7 @@ export async function startDaemon(options = {}) {
|
|
|
568
410
|
now,
|
|
569
411
|
bridgePort: port,
|
|
570
412
|
browserProbe: probeLaunchableChromium,
|
|
571
|
-
|
|
413
|
+
...agentWiring(port, bridge.sessions, leaseUrl),
|
|
572
414
|
// A finished verification should not sit behind a one-minute timer — see ToolDeps.onRunPersisted.
|
|
573
415
|
onRunPersisted: () => cloudSync.nudge(),
|
|
574
416
|
syncNow: () => cloudSync.syncNow(),
|
|
@@ -580,12 +422,12 @@ export async function startDaemon(options = {}) {
|
|
|
580
422
|
shared.attachMcp((peerSkew) => createMcpServer(peerSkew === undefined
|
|
581
423
|
? effectiveDeps
|
|
582
424
|
: { ...effectiveDeps, peerSkew: connectionSkew(peerSkew) }, profile, instructionStateAt(port, bridge.sessions.count())));
|
|
583
|
-
// `reticle drive <url>`
|
|
584
|
-
shared.attachDrive((url) => runTool(LEASE_ACQUIRE_TOOL, effectiveDeps, { url }));
|
|
425
|
+
shared.attachDrive(leaseUrl); // `reticle drive <url>` — see cli/drive/drive-attach.ts.
|
|
585
426
|
// The platform chat's apps and drives, run here. See chat-drives.ts.
|
|
586
427
|
const chatDrives = startChatDrives(effectiveDeps, bridge.sessions, fs, {
|
|
587
428
|
sessionCloud: sessionCloudPort(fs, homedir(), process.env, (id) => sessionRoot(effectiveDeps, id)),
|
|
588
429
|
version: SERVER_VERSION,
|
|
430
|
+
unsynced: () => cloudSync.unsyncedRoots(),
|
|
589
431
|
}, log);
|
|
590
432
|
// Optional OEM/CI verify endpoint: a host platform POSTs to /verify and gets an ReticleVerificationRun,
|
|
591
433
|
// driving the same flow-replay machinery the agent uses — no MCP stdio, no human. Each verdict is
|
|
@@ -678,6 +520,7 @@ export async function startDaemon(options = {}) {
|
|
|
678
520
|
leaseReaper.stop();
|
|
679
521
|
chatDrives.stop();
|
|
680
522
|
accountFiles.close();
|
|
523
|
+
await endLiveSessions(); // first: an open tab's teardown writes the flow this flush sends
|
|
681
524
|
await cloudSync.flush(); // not stop(): the last run written is the one nobody has yet
|
|
682
525
|
await loopbackAlias.close?.();
|
|
683
526
|
await pool.shutdown();
|
|
@@ -45,9 +45,9 @@ declare const CapsuleSchema: z.ZodObject<{
|
|
|
45
45
|
version: 1;
|
|
46
46
|
id: string;
|
|
47
47
|
origin: string;
|
|
48
|
+
createdAt: number;
|
|
48
49
|
expected: string;
|
|
49
50
|
steps: FlowStep[];
|
|
50
|
-
createdAt: number;
|
|
51
51
|
observed: string;
|
|
52
52
|
flow?: string | undefined;
|
|
53
53
|
seen?: number | undefined;
|
|
@@ -56,9 +56,9 @@ declare const CapsuleSchema: z.ZodObject<{
|
|
|
56
56
|
version: 1;
|
|
57
57
|
id: string;
|
|
58
58
|
origin: string;
|
|
59
|
+
createdAt: number;
|
|
59
60
|
expected: string;
|
|
60
61
|
steps: FlowStep[];
|
|
61
|
-
createdAt: number;
|
|
62
62
|
observed: string;
|
|
63
63
|
flow?: string | undefined;
|
|
64
64
|
seen?: number | undefined;
|
|
@@ -40,10 +40,24 @@ export interface CausalSummary {
|
|
|
40
40
|
headline?: string;
|
|
41
41
|
};
|
|
42
42
|
consoleErrors: number;
|
|
43
|
+
/** The first console error's text, capped — so a count is never the only thing an agent can read. */
|
|
44
|
+
firstConsoleError?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The app's requests in this window as `METHOD /path STATUS` (`pending` when unanswered), capped.
|
|
47
|
+
* Origin and query string are left out: the line is for recognising the call, and the full record is
|
|
48
|
+
* one `reticle_observe { since }` away. Present only when there were any.
|
|
49
|
+
*/
|
|
50
|
+
requests?: string[];
|
|
43
51
|
statePathsChanged: string[];
|
|
44
52
|
storageKeysChanged: string[];
|
|
45
53
|
/** Before→after for each changed store path — the diffs, not just the names. Values capped. */
|
|
46
54
|
stateDiffs: StateDiff[];
|
|
55
|
+
/**
|
|
56
|
+
* How many store diffs were left out of `stateDiffs` because they moved only a cache's own
|
|
57
|
+
* bookkeeping (fetchStatus, isStale, dataUpdatedAt — see engine's state-bookkeeping rule). Present
|
|
58
|
+
* only when there were any: a trim is never silent. Predicates still see every transition.
|
|
59
|
+
*/
|
|
60
|
+
ignoredBookkeeping?: number;
|
|
47
61
|
/**
|
|
48
62
|
* How long the store took to stop moving: last state change − first, in ms. Present only when more
|
|
49
63
|
* than one path changed, because with a single change there is no interval to describe.
|
|
@@ -126,6 +140,6 @@ interface SummaryContext {
|
|
|
126
140
|
*/
|
|
127
141
|
export declare const MAX_SUMMARY_ENTRIES = 20;
|
|
128
142
|
/** The lists that are capped, named so `elided` can say which one lost entries. */
|
|
129
|
-
type CappedList = 'statePathsChanged' | 'storageKeysChanged' | 'stateDiffs' | 'storageDiffs' | 'signals' | 'fieldsChanged';
|
|
143
|
+
type CappedList = 'requests' | 'statePathsChanged' | 'storageKeysChanged' | 'stateDiffs' | 'storageDiffs' | 'signals' | 'fieldsChanged';
|
|
130
144
|
export declare function causalSummary(events: readonly ReticleEvent[], context?: SummaryContext): CausalSummary;
|
|
131
145
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EventType, PerfMetric, isDevToolingUrl } from '@reticlehq/core';
|
|
2
2
|
import { routeOfEvent } from '@reticlehq/engine/question/predicate/predicate-route.js';
|
|
3
|
+
import { isCacheBookkeepingDiff } from '@reticlehq/engine/evidence/state-bookkeeping.js';
|
|
3
4
|
/**
|
|
4
5
|
* THE INVARIANT: every field of this summary has a bounded size that does not depend on how much the
|
|
5
6
|
* app did. A verdict travels in the same payload as its evidence, so an unbounded evidence field is
|
|
@@ -57,12 +58,34 @@ function stateSettle(diffs) {
|
|
|
57
58
|
const spread = Math.max(...times) - Math.min(...times);
|
|
58
59
|
return spread > 0 ? { stateSettleMs: spread } : {};
|
|
59
60
|
}
|
|
61
|
+
/** `METHOD /path STATUS` — what an agent recognises a call by. */
|
|
62
|
+
function requestLine(data) {
|
|
63
|
+
const raw = 'string' === typeof data['url'] ? data['url'] : '';
|
|
64
|
+
let path;
|
|
65
|
+
try {
|
|
66
|
+
path = new URL(raw, 'http://local.invalid').pathname;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
path = raw.split('?')[0] ?? raw;
|
|
70
|
+
}
|
|
71
|
+
const method = 'string' === typeof data['method'] ? data['method'].toUpperCase() : 'GET';
|
|
72
|
+
const status = 'number' === typeof data['status'] ? String(data['status']) : 'pending';
|
|
73
|
+
return `${method} ${path} ${status}`;
|
|
74
|
+
}
|
|
75
|
+
/** The first line of a console error, capped. */
|
|
76
|
+
function firstLine(data) {
|
|
77
|
+
const text = ['message', 'text', 'error'].map((k) => data[k]).find((v) => 'string' === typeof v);
|
|
78
|
+
const line = ('string' === typeof text ? text : 'console error').split('\n')[0] ?? '';
|
|
79
|
+
return truncate(line);
|
|
80
|
+
}
|
|
60
81
|
export function causalSummary(events, context = {}) {
|
|
61
82
|
let netTotal = 0;
|
|
62
83
|
let netErrors = 0;
|
|
63
84
|
let ignoredDevTooling = 0;
|
|
64
85
|
let headline;
|
|
65
86
|
let consoleErrors = 0;
|
|
87
|
+
let firstConsoleError;
|
|
88
|
+
const requests = [];
|
|
66
89
|
const statePathsChanged = [];
|
|
67
90
|
const storageKeysChanged = [];
|
|
68
91
|
const stateDiffs = [];
|
|
@@ -72,6 +95,7 @@ export function causalSummary(events, context = {}) {
|
|
|
72
95
|
const fieldsChanged = [];
|
|
73
96
|
let layoutShift;
|
|
74
97
|
let longTasks = 0;
|
|
98
|
+
let ignoredBookkeeping = 0;
|
|
75
99
|
for (const event of events) {
|
|
76
100
|
const data = event.data;
|
|
77
101
|
switch (event.type) {
|
|
@@ -82,6 +106,7 @@ export function causalSummary(events, context = {}) {
|
|
|
82
106
|
}
|
|
83
107
|
netTotal += 1;
|
|
84
108
|
const status = data['status'];
|
|
109
|
+
requests.push(requestLine(data));
|
|
85
110
|
const failed = false === data['ok'] || ('number' === typeof status && status >= 400);
|
|
86
111
|
if (failed) {
|
|
87
112
|
netErrors += 1;
|
|
@@ -93,6 +118,7 @@ export function causalSummary(events, context = {}) {
|
|
|
93
118
|
case EventType.CONSOLE_ERROR:
|
|
94
119
|
case EventType.ERROR_UNCAUGHT:
|
|
95
120
|
consoleErrors += 1;
|
|
121
|
+
firstConsoleError ??= firstLine(data);
|
|
96
122
|
break;
|
|
97
123
|
case EventType.STATE_CHANGE: {
|
|
98
124
|
pushUnique(statePathsChanged, data['name']);
|
|
@@ -103,6 +129,10 @@ export function causalSummary(events, context = {}) {
|
|
|
103
129
|
const hasAfter = 'value' in data || 'new' in data;
|
|
104
130
|
if ('string' === typeof path && path.length > 0 && ('old' in data || hasAfter)) {
|
|
105
131
|
const after = 'value' in data ? data['value'] : data['new'];
|
|
132
|
+
if (isCacheBookkeepingDiff(data['old'], after)) {
|
|
133
|
+
ignoredBookkeeping += 1;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
106
136
|
stateDiffs.push({
|
|
107
137
|
path,
|
|
108
138
|
from: capValue(data['old']),
|
|
@@ -160,9 +190,12 @@ export function causalSummary(events, context = {}) {
|
|
|
160
190
|
...(headline === undefined ? {} : { headline }),
|
|
161
191
|
},
|
|
162
192
|
consoleErrors,
|
|
193
|
+
...(firstConsoleError === undefined ? {} : { firstConsoleError }),
|
|
194
|
+
...(0 === requests.length ? {} : { requests: cap(requests, 'requests', elided) }),
|
|
163
195
|
statePathsChanged: cap(statePathsChanged, 'statePathsChanged', elided),
|
|
164
196
|
storageKeysChanged: cap(storageKeysChanged, 'storageKeysChanged', elided),
|
|
165
197
|
stateDiffs: cap(stateDiffs, 'stateDiffs', elided),
|
|
198
|
+
...(0 === ignoredBookkeeping ? {} : { ignoredBookkeeping }),
|
|
166
199
|
...settle,
|
|
167
200
|
storageDiffs: cap(storageDiffs, 'storageDiffs', elided),
|
|
168
201
|
...(route === undefined ? {} : { route }),
|
|
@@ -25,7 +25,7 @@ export type VerificationRunInput = Omit<ReticleVerificationRun, 'schemaVersion'
|
|
|
25
25
|
* reason those two values now survive into the artifact instead of being dropped at its door.
|
|
26
26
|
* Confidence: nothing ran → LOW; an oracle-backed flow or any check ran → HIGH; only smoke → MEDIUM.
|
|
27
27
|
*/
|
|
28
|
-
export declare function computeVerdict(
|
|
28
|
+
export declare function computeVerdict(raw: VerificationRunInput): RunVerdict;
|
|
29
29
|
/**
|
|
30
30
|
* Assemble the final, schema-valid ReticleVerificationRun. Stamps schemaVersion + createdAt (injected
|
|
31
31
|
* clock) and computes the verdict; the result is parsed through the protocol schema so a malformed
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { ReticleVerificationRunSchema, RUN_FILE_VERSION, Verified, RunConfidence, RunFlowStatus, VerdictStatus, } from '@reticlehq/core';
|
|
10
10
|
import { redactForProfile } from './profile-redact.js';
|
|
11
|
+
import { supersededChecks } from '@reticlehq/engine/evidence/superseded-checks.js';
|
|
11
12
|
/**
|
|
12
13
|
* Compute the verdict deterministically from the run's flows, checks, and risks.
|
|
13
14
|
* Rules (in order): a gated risk blocks → FAIL; mixed pass+fail → PARTIAL; any fail → FAIL;
|
|
@@ -18,12 +19,23 @@ import { redactForProfile } from './profile-redact.js';
|
|
|
18
19
|
* reason those two values now survive into the artifact instead of being dropped at its door.
|
|
19
20
|
* Confidence: nothing ran → LOW; an oracle-backed flow or any check ran → HIGH; only smoke → MEDIUM.
|
|
20
21
|
*/
|
|
21
|
-
export function computeVerdict(
|
|
22
|
+
export function computeVerdict(raw) {
|
|
23
|
+
// A passive check that read too early is superseded by the same claim holding later: the one
|
|
24
|
+
// rule every fold applies (superseded-checks.ts).
|
|
25
|
+
const superseded = supersededChecks(raw.checks.map((c) => ({
|
|
26
|
+
key: c.predicate,
|
|
27
|
+
passive: false === c.declaredBeforeActing,
|
|
28
|
+
held: Verified.YES === c.status,
|
|
29
|
+
failed: Verified.NO === c.status,
|
|
30
|
+
})));
|
|
31
|
+
const input = { ...raw, checks: raw.checks.filter((_, at) => !superseded.has(at)) };
|
|
22
32
|
const passes = input.flows.filter((f) => f.status === RunFlowStatus.PASS || f.status === RunFlowStatus.HEALED)
|
|
23
33
|
.length + input.checks.filter((c) => c.status === Verified.YES).length;
|
|
24
34
|
const fails = input.flows.filter((f) => f.status === RunFlowStatus.FAIL).length +
|
|
25
35
|
input.checks.filter((c) => c.status === Verified.NO).length;
|
|
26
36
|
const skippedFlows = input.flows.filter((f) => f.status === RunFlowStatus.SKIPPED).length;
|
|
37
|
+
// Ran and decided nothing, as the agent's own result block counts them: never part of a pass.
|
|
38
|
+
const undecidedChecks = input.checks.filter((c) => c.status !== Verified.YES && c.status !== Verified.NO).length;
|
|
27
39
|
const blockingRisks = input.risks.filter((r) => r.gated).length;
|
|
28
40
|
const reasons = [];
|
|
29
41
|
for (const f of input.flows) {
|
|
@@ -47,12 +59,16 @@ export function computeVerdict(input) {
|
|
|
47
59
|
let status;
|
|
48
60
|
if (blockingRisks > 0)
|
|
49
61
|
status = VerdictStatus.FAIL;
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
// A failure beside things that passed is a fail, not a partial: the result block, the CLI and the
|
|
63
|
+
// platform's grade all call it that, and a "partial" beside "Reticle result: failed" was one run
|
|
64
|
+
// with two verdicts. A partial is only ever a pass with something skipped or undecided beside it.
|
|
52
65
|
else if (fails > 0)
|
|
53
66
|
status = VerdictStatus.FAIL;
|
|
54
|
-
else if (skippedFlows > 0 && passes > 0)
|
|
67
|
+
else if ((skippedFlows > 0 || undecidedChecks > 0) && passes > 0) {
|
|
55
68
|
status = VerdictStatus.PARTIAL;
|
|
69
|
+
if (0 < undecidedChecks)
|
|
70
|
+
reasons.push(`${String(undecidedChecks)} check(s) undecided`);
|
|
71
|
+
}
|
|
56
72
|
else if (0 === passes) {
|
|
57
73
|
// Nothing passed and nothing failed, so nothing was proved -- an empty run, or one whose every
|
|
58
74
|
// flow was skipped. Reporting that as PASS is the false green this whole file exists to prevent:
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The gap, as a number the person who ran the session can see.
|
|
3
|
-
*
|
|
4
|
-
* Reticle's whole claim is that it measures the distance between what an agent believed happened
|
|
5
|
-
* and what did. It measures that on every verdict, writes the answer into the journal, and shows it
|
|
6
|
-
* to nobody: the counts exist, the reasons exist, the contradictions exist, and no surface anywhere
|
|
7
|
-
* says "you made 14 claims, 9 held, 2 were false, 3 could not be decided, and here is who owns each
|
|
8
|
-
* of those three". The value of the product is the one thing it never reports.
|
|
9
|
-
*
|
|
10
|
-
* A FOLD over the journal, never a second store — the rule `run-context.ts` next door states, for
|
|
11
|
-
* the same reason: two ways to compute one number is worse than one way, because the day they
|
|
12
|
-
* disagree the disagreement lands inside a verdict and a user finds it before we do.
|
|
13
|
-
*
|
|
14
|
-
* Nothing here sends anything anywhere, and that is deliberate rather than incidental. This is the
|
|
15
|
-
* LOCAL half. Whether a fleet-wide version of the same number is worth collecting is a separate
|
|
16
|
-
* decision with a separate owner, and building the local one first is what makes that decision
|
|
17
|
-
* answerable from something other than a guess.
|
|
18
|
-
*/
|
|
19
1
|
import { VerifiedReason, VerdictAttribution, type JournalAction } from '@reticlehq/core';
|
|
20
2
|
/** One claim that did not hold, in the words it was made and the engine's reason for refusing it. */
|
|
21
3
|
export interface GapFailure {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* decision with a separate owner, and building the local one first is what makes that decision
|
|
17
17
|
* answerable from something other than a guess.
|
|
18
18
|
*/
|
|
19
|
+
import { supersededChecks } from '@reticlehq/engine/evidence/superseded-checks.js';
|
|
19
20
|
import { JournalVerdictEffectSchema, Verified, VerifiedReason, VerdictAttribution, verdictAttributionOf, } from '@reticlehq/core';
|
|
20
21
|
/**
|
|
21
22
|
* The reason, as the engine's own enum, or undefined.
|
|
@@ -48,9 +49,17 @@ export function gapSummary(actions) {
|
|
|
48
49
|
falseGreensCaught: 0,
|
|
49
50
|
failures: [],
|
|
50
51
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const verdicts = actions.map(verdictOf).filter((v) => v !== undefined);
|
|
53
|
+
// A passive check that read too early is not counted: the one rule every fold applies
|
|
54
|
+
// (superseded-checks.ts), so this block and the run's verdict cannot disagree.
|
|
55
|
+
const superseded = supersededChecks(verdicts.map((v) => ({
|
|
56
|
+
key: v.claim,
|
|
57
|
+
passive: false === v.declaredBeforeActing,
|
|
58
|
+
held: Verified.YES === v.verified,
|
|
59
|
+
failed: Verified.NO === v.verified,
|
|
60
|
+
})));
|
|
61
|
+
for (const [at, verdict] of verdicts.entries()) {
|
|
62
|
+
if (superseded.has(at))
|
|
54
63
|
continue;
|
|
55
64
|
summary.claims += 1;
|
|
56
65
|
switch (verdict.verified) {
|