@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
|
@@ -22,19 +22,40 @@
|
|
|
22
22
|
* outcome is four-valued now, so all four are recorded, and the run verdict counts an undetermined
|
|
23
23
|
* check as neither a pass nor a failure -- which is what those words already meant everywhere else.
|
|
24
24
|
*/
|
|
25
|
+
import { supersededChecks } from '@reticlehq/engine/evidence/superseded-checks.js';
|
|
25
26
|
import { isValidRunId } from '../../memory/project/dir/reticle-dir.js';
|
|
26
27
|
import { defaultRunId } from './runner-port.js';
|
|
27
|
-
import {
|
|
28
|
+
import { currentShotRun } from './default-run-id.js';
|
|
29
|
+
import { currentDrivenBy } from '../../hooks/driven-by.js';
|
|
30
|
+
import { JournalVerdictEffectSchema, RunAgentKind, asRecord, asString, RunFramework, RunProfile, RunTrigger, PredicateKind, Verified, VerifiedReason, driveFlowStatus, } from '@reticlehq/core';
|
|
28
31
|
import { withCorrections } from './late-answer.js';
|
|
29
32
|
/** The author of record when no MCP peer introduced itself. Mirrors verification-sync's default. */
|
|
30
33
|
const UNNAMED_AGENT = 'reticle-mcp';
|
|
34
|
+
/**
|
|
35
|
+
* The one MCP client every stamped action came from. Two clients in one tab is undefined, never a
|
|
36
|
+
* pick: crediting either would put the other's verdicts under its name.
|
|
37
|
+
*/
|
|
38
|
+
function soleAgent(actions) {
|
|
39
|
+
const named = new Set(actions.flatMap((action) => (action.agent === undefined ? [] : [action.agent])));
|
|
40
|
+
return 1 === named.size ? [...named][0] : undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* What a verdict required and what it saw, as the journal keeps them for its check. One place, so
|
|
44
|
+
* the act and assert paths cannot keep different halves.
|
|
45
|
+
*/
|
|
46
|
+
export function checkWords(verdict) {
|
|
47
|
+
return {
|
|
48
|
+
...(verdict.expected === undefined ? {} : { expected: verdict.expected }),
|
|
49
|
+
...(verdict.observed === undefined ? {} : { observed: verdict.observed }),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
31
52
|
/** Every verdict a verification tool recorded on this session's actions, in order. */
|
|
32
53
|
function verdicts(actions) {
|
|
33
54
|
const out = [];
|
|
34
55
|
for (const action of actions) {
|
|
35
56
|
const parsed = JournalVerdictEffectSchema.safeParse(action.effect);
|
|
36
57
|
if (parsed.success)
|
|
37
|
-
out.push(parsed.data);
|
|
58
|
+
out.push({ ...parsed.data, actionId: action.actionId });
|
|
38
59
|
}
|
|
39
60
|
return out;
|
|
40
61
|
}
|
|
@@ -66,6 +87,87 @@ export function driveRunId(sessionId) {
|
|
|
66
87
|
const candidate = `${DRIVE_RUN_PREFIX}${sessionId}`;
|
|
67
88
|
return isValidRunId(candidate) ? candidate : defaultRunId();
|
|
68
89
|
}
|
|
90
|
+
/** The run of the `segment`th agent session in a tab: the tab's id first, then `-2`, `-3`… */
|
|
91
|
+
function segmentRunId(base, segment) {
|
|
92
|
+
if (0 === segment)
|
|
93
|
+
return base;
|
|
94
|
+
const id = `${base}-${String(segment + 1)}`;
|
|
95
|
+
return isValidRunId(id) ? id : base;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Where each agent session in a tab ended: how many of the agent's own actions the tab held then,
|
|
99
|
+
* and the tab's clock. Every agent session in a tab wrote one run id, so a later end overwrote the
|
|
100
|
+
* earlier run on the dashboard.
|
|
101
|
+
* ponytail: daemon memory; a restart forgets the ends and the next fold is one run, as before.
|
|
102
|
+
*/
|
|
103
|
+
const agentEnds = new Map();
|
|
104
|
+
/** The agent's own actions: the Harness drives in the same tab are runs of their own. */
|
|
105
|
+
const agentsOwn = (actions) => actions.filter((action) => action.drivenBy === undefined);
|
|
106
|
+
/** The run the agent's session now open in this tab is kept under. */
|
|
107
|
+
export function agentRunId(sessionId) {
|
|
108
|
+
return segmentRunId(driveRunId(sessionId), agentEnds.get(sessionId)?.length ?? 0);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The run the current call lands in: the flow being replayed, else the Harness drive, else the
|
|
112
|
+
* agent session open in the tab. One answer for a call's screenshot and an intent its check proves.
|
|
113
|
+
*/
|
|
114
|
+
export function runIdOfCall(sessionId) {
|
|
115
|
+
const scoped = currentShotRun();
|
|
116
|
+
if (scoped !== undefined)
|
|
117
|
+
return scoped;
|
|
118
|
+
const by = currentDrivenBy();
|
|
119
|
+
const harness = by === undefined ? undefined : harnessRunId(by.harness);
|
|
120
|
+
return harness ?? agentRunId(sessionId);
|
|
121
|
+
}
|
|
122
|
+
/** The ends recorded for a tab, as counts of the agent's own actions, for the fold. */
|
|
123
|
+
export function agentEndCounts(sessionId) {
|
|
124
|
+
return (agentEnds.get(sessionId) ?? []).map((end) => end.count);
|
|
125
|
+
}
|
|
126
|
+
/** What the agent claimed at each end of a tab, by the index `agentEndCounts` uses. */
|
|
127
|
+
export function agentEndClaims(sessionId) {
|
|
128
|
+
return (agentEnds.get(sessionId) ?? []).map((end) => end.claim);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* An agent session ends: its own actions since the previous end, the run they are kept under, and
|
|
132
|
+
* how long it ran. Recorded, so what the agent drives next is the next session's.
|
|
133
|
+
*/
|
|
134
|
+
export function endAgentSession(sessionId, actions, at, claim) {
|
|
135
|
+
const own = agentsOwn(actions);
|
|
136
|
+
const ends = agentEnds.get(sessionId) ?? [];
|
|
137
|
+
const last = ends.at(-1);
|
|
138
|
+
const runId = agentRunId(sessionId);
|
|
139
|
+
ends.push({
|
|
140
|
+
count: own.length,
|
|
141
|
+
at: at ?? last?.at ?? 0,
|
|
142
|
+
...(claim === undefined ? {} : { claim }),
|
|
143
|
+
});
|
|
144
|
+
agentEnds.set(sessionId, ends);
|
|
145
|
+
// The end splits the tab's runs: written again now, not when the tab disconnects, so the run this
|
|
146
|
+
// end names is on disk (and the dashboard) while the tab stays open.
|
|
147
|
+
tellNoted();
|
|
148
|
+
const mine = own.slice(Math.min(last?.count ?? 0, own.length));
|
|
149
|
+
const wallMs = at === undefined ? undefined : wallOf(mine, last?.at, at);
|
|
150
|
+
return { actions: mine, runId, ...(wallMs === undefined ? {} : { wallMs }) };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* How long a session ran, `since` the previous end (else its first action) to `end`, on the tab's
|
|
154
|
+
* clock, which restarts at every page load: an action stamped before the one ahead of it starts a
|
|
155
|
+
* new stretch, and the stretches add up. Measured from the last load alone, a ten-second session
|
|
156
|
+
* that navigated read "1.2s". ponytail: the gap between a reload and the next action is not counted.
|
|
157
|
+
*/
|
|
158
|
+
function wallOf(actions, since, end) {
|
|
159
|
+
let start = since ?? actions[0]?.tRange.from ?? end;
|
|
160
|
+
let prev = start;
|
|
161
|
+
let total = 0;
|
|
162
|
+
for (const action of actions) {
|
|
163
|
+
if (action.at < prev) {
|
|
164
|
+
total += prev - start;
|
|
165
|
+
start = action.tRange.from;
|
|
166
|
+
}
|
|
167
|
+
prev = action.at;
|
|
168
|
+
}
|
|
169
|
+
return total + (prev <= end ? end - start : prev - start + end);
|
|
170
|
+
}
|
|
69
171
|
/**
|
|
70
172
|
* Fold a session's journal into a run, or return undefined when there is nothing honest to report.
|
|
71
173
|
*
|
|
@@ -74,12 +176,27 @@ export function driveRunId(sessionId) {
|
|
|
74
176
|
*/
|
|
75
177
|
export function driveRunFrom(actions, deps) {
|
|
76
178
|
const found = verdicts(actions);
|
|
179
|
+
const intentOf = new Map(actions.map((a) => [a.actionId, asString(asRecord(a.args)['intent'])]));
|
|
77
180
|
const checks = [];
|
|
78
181
|
for (const verdict of found) {
|
|
182
|
+
const intent = intentOf.get(verdict.actionId);
|
|
79
183
|
checks.push({
|
|
80
184
|
predicate: verdict.claim,
|
|
81
185
|
status: verdict.verified,
|
|
82
|
-
|
|
186
|
+
actionId: verdict.actionId,
|
|
187
|
+
...(intent === undefined || 0 === intent.length ? {} : { intent }),
|
|
188
|
+
// Where it was written, and on a miss the calls of its window: what an issue page shows.
|
|
189
|
+
...(verdict.source === undefined && verdict.net === undefined
|
|
190
|
+
? {}
|
|
191
|
+
: {
|
|
192
|
+
evidence: {
|
|
193
|
+
...(verdict.source === undefined ? {} : { source: verdict.source }),
|
|
194
|
+
...(verdict.net === undefined ? {} : { net: verdict.net }),
|
|
195
|
+
},
|
|
196
|
+
}),
|
|
197
|
+
// What it required and what it saw, so a failed check can say both on the platform.
|
|
198
|
+
...(verdict.expected === undefined ? {} : { expected: verdict.expected }),
|
|
199
|
+
...(verdict.observed === undefined ? {} : { observed: verdict.observed }),
|
|
83
200
|
// Carried through rather than recomputed. These were established at the moment the verdict
|
|
84
201
|
// was made and written down then; a run built later cannot know any of them, and inferring
|
|
85
202
|
// them here would be inventing evidence about evidence.
|
|
@@ -114,10 +231,14 @@ export function driveRunFrom(actions, deps) {
|
|
|
114
231
|
durationMs: spanOf(actions),
|
|
115
232
|
profile: RunProfile.DEV,
|
|
116
233
|
project: {
|
|
117
|
-
name:
|
|
234
|
+
// Never the daemon's own name: a tab that reported no project is named by its folder.
|
|
235
|
+
name: deps.projectId ?? deps.projectName ?? UNNAMED_AGENT,
|
|
118
236
|
framework: deps.framework ?? RunFramework.OTHER,
|
|
119
237
|
},
|
|
120
|
-
agent: {
|
|
238
|
+
agent: {
|
|
239
|
+
id: deps.agentId ?? soleAgent(actions) ?? UNNAMED_AGENT,
|
|
240
|
+
kind: RunAgentKind.CODING_AGENT,
|
|
241
|
+
},
|
|
121
242
|
trigger: {
|
|
122
243
|
kind: RunTrigger.EDIT,
|
|
123
244
|
note: 'driven live through the Reticle tools',
|
|
@@ -131,6 +252,7 @@ export function driveRunFrom(actions, deps) {
|
|
|
131
252
|
// about what was WRONG, and a fold that guessed at anomalies would be inventing findings — the
|
|
132
253
|
// failure this artifact is supposed to make impossible. Checks are the evidence here.
|
|
133
254
|
evidence: { consoleErrors: [], networkAnomalies: [], stateAssertions: [], timeline: [] },
|
|
255
|
+
...(deps.agentClaim === undefined ? {} : { agentClaim: deps.agentClaim }),
|
|
134
256
|
};
|
|
135
257
|
}
|
|
136
258
|
/** Marks a run as one Harness drive, so it never collides with the session's own `drive-` run. */
|
|
@@ -148,16 +270,46 @@ export function harnessRunId(harness) {
|
|
|
148
270
|
return isValidRunId(candidate) ? candidate : undefined;
|
|
149
271
|
}
|
|
150
272
|
/** The journey a Harness drive was named for, or what it did when nobody named one. */
|
|
151
|
-
|
|
273
|
+
// Never "Harness drive": that read as the title of every unnamed drive's flow and finding.
|
|
274
|
+
const UNNAMED_JOURNEY = 'Exploring the app';
|
|
152
275
|
/** Goal verdicts kept for the drives a session has not yet been graded on. */
|
|
153
276
|
const MAX_GOALS_HELD = 200;
|
|
154
277
|
const goalsMissed = new Map();
|
|
155
278
|
/**
|
|
156
279
|
* What the Harness judged of a drive's goal, noted the moment the drive finishes, before its
|
|
157
280
|
* session ends and is graded. A drive whose checks held but whose goal was not reached synced as
|
|
158
|
-
* "Proved"
|
|
159
|
-
*
|
|
281
|
+
* "Proved"; it is not proved. Unmet once is unmet: a later journey of the same drive reaching its
|
|
282
|
+
* goal does not undo it.
|
|
283
|
+
*/
|
|
284
|
+
/** Told when a Harness drive's goal or comparison is noted, or an agent session ends, so its run is written again. */
|
|
285
|
+
const noted = new Set();
|
|
286
|
+
/**
|
|
287
|
+
* Hear about every Harness note. A drive is graded after its last verdict, and the run that verdict
|
|
288
|
+
* flushed never carried the grade: live, the platform filed a failed check instead of "Hard to find".
|
|
160
289
|
*/
|
|
290
|
+
export function onHarnessNoted(listener) {
|
|
291
|
+
noted.add(listener);
|
|
292
|
+
return () => noted.delete(listener);
|
|
293
|
+
}
|
|
294
|
+
const tellNoted = () => {
|
|
295
|
+
for (const listener of noted)
|
|
296
|
+
listener();
|
|
297
|
+
};
|
|
298
|
+
/** How long each Harness drive took, timed by the drive on the injected clock. */
|
|
299
|
+
const spans = new Map();
|
|
300
|
+
/**
|
|
301
|
+
* The drive's own measure of how long it ran. The span of one tab's journal is not it: a lane in a
|
|
302
|
+
* leased browser left only the grade's assert in the tab, and its run read "Took 0 ms".
|
|
303
|
+
*/
|
|
304
|
+
export function noteHarnessSpan(harness, ms) {
|
|
305
|
+
if (MAX_GOALS_HELD <= spans.size && !spans.has(harness)) {
|
|
306
|
+
const oldest = spans.keys().next().value;
|
|
307
|
+
if (oldest !== undefined)
|
|
308
|
+
spans.delete(oldest);
|
|
309
|
+
}
|
|
310
|
+
spans.set(harness, Math.max(0, ms));
|
|
311
|
+
tellNoted();
|
|
312
|
+
}
|
|
161
313
|
export function noteHarnessGoal(harness, met) {
|
|
162
314
|
if (met === undefined)
|
|
163
315
|
return;
|
|
@@ -170,11 +322,42 @@ export function noteHarnessGoal(harness, met) {
|
|
|
170
322
|
goalsMissed.delete(oldest);
|
|
171
323
|
}
|
|
172
324
|
goalsMissed.set(harness, met);
|
|
325
|
+
tellNoted();
|
|
326
|
+
}
|
|
327
|
+
/** How each Harness drive's goals compared with the agent's verdicts, until its run is folded. */
|
|
328
|
+
const disparities = new Map();
|
|
329
|
+
/**
|
|
330
|
+
* Noted when a drive is graded, like its goal: its run artifact carries the comparison, so the
|
|
331
|
+
* platform can file a goal the agent proved and the Harness could not find.
|
|
332
|
+
*/
|
|
333
|
+
export function noteHarnessDisparity(harness, found) {
|
|
334
|
+
if (0 === found.length)
|
|
335
|
+
return;
|
|
336
|
+
if (MAX_GOALS_HELD <= disparities.size && !disparities.has(harness)) {
|
|
337
|
+
const oldest = disparities.keys().next().value;
|
|
338
|
+
if (oldest !== undefined)
|
|
339
|
+
disparities.delete(oldest);
|
|
340
|
+
}
|
|
341
|
+
disparities.set(harness, found);
|
|
342
|
+
tellNoted();
|
|
343
|
+
}
|
|
344
|
+
/** The phrase `describeWaitTarget` opens a route claim with, as the journal records it. */
|
|
345
|
+
const ROUTE_CLAIM = 'a route change';
|
|
346
|
+
const ABSENCE_OF = 'the absence of ';
|
|
347
|
+
/**
|
|
348
|
+
* Whether a recorded check claimed nothing but a route (or leaving one): the Harness driver's guess
|
|
349
|
+
* about where a click goes, which `harness/route-guess.ts` explains. Kept here because a run fold
|
|
350
|
+
* reads the journal's words, not the predicate.
|
|
351
|
+
*/
|
|
352
|
+
function claimsOnlyRoute(claim, kind) {
|
|
353
|
+
if (PredicateKind.ROUTE === kind)
|
|
354
|
+
return true;
|
|
355
|
+
return PredicateKind.NOT === kind && claim.startsWith(`${ABSENCE_OF}${ROUTE_CLAIM}`);
|
|
173
356
|
}
|
|
174
357
|
/**
|
|
175
358
|
* One Harness drive, as its own run: named for the journey it was asked to complete, and credited to
|
|
176
|
-
* the Harness rather than to the agent whose tab it shared. The journey reads as one flow,
|
|
177
|
-
*
|
|
359
|
+
* the Harness rather than to the agent whose tab it shared. The journey reads as one flow, graded by
|
|
360
|
+
* `driveFlowStatus`: failed only on a check that came back no.
|
|
178
361
|
*/
|
|
179
362
|
function harnessRunFrom(by, actions, deps) {
|
|
180
363
|
const input = driveRunFrom(actions, {
|
|
@@ -183,16 +366,40 @@ function harnessRunFrom(by, actions, deps) {
|
|
|
183
366
|
});
|
|
184
367
|
if (input === undefined)
|
|
185
368
|
return undefined;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
369
|
+
// The driver's own wrong guess about where a click goes is not a failed check of the app; nor is
|
|
370
|
+
// its second press of a control whose claim already held (Save again on a field the app emptied).
|
|
371
|
+
const refOf = new Map(actions.map((a) => [a.actionId, asString(asRecord(a.args)['ref'])]));
|
|
372
|
+
const heldBefore = new Set();
|
|
373
|
+
const checks = input.checks.map((check) => {
|
|
374
|
+
const ref = check.actionId === undefined ? undefined : refOf.get(check.actionId);
|
|
375
|
+
const key = ref === undefined ? undefined : `${ref}|${check.predicate}`;
|
|
376
|
+
const repress = Verified.NO === check.status && key !== undefined && heldBefore.has(key);
|
|
377
|
+
if (Verified.YES === check.status && key !== undefined)
|
|
378
|
+
heldBefore.add(key);
|
|
379
|
+
return Verified.NO === check.status && (repress || claimsOnlyRoute(check.predicate, check.kind))
|
|
380
|
+
? { ...check, status: Verified.UNKNOWN, reason: VerifiedReason.INCONCLUSIVE }
|
|
381
|
+
: check;
|
|
382
|
+
});
|
|
383
|
+
// A passive check that read too early is not counted: the one rule (superseded-checks.ts).
|
|
384
|
+
const superseded = supersededChecks(input.checks.map((c) => ({
|
|
385
|
+
key: c.predicate,
|
|
386
|
+
passive: false === c.declaredBeforeActing,
|
|
387
|
+
held: Verified.YES === c.status,
|
|
388
|
+
failed: Verified.NO === c.status,
|
|
389
|
+
})));
|
|
390
|
+
const count = (verified) => checks.filter((check, at) => verified === check.status && !superseded.has(at)).length;
|
|
391
|
+
const status = driveFlowStatus({
|
|
392
|
+
held: count(Verified.YES),
|
|
393
|
+
failed: count(Verified.NO),
|
|
394
|
+
goalMet: goalsMissed.get(by.harness),
|
|
395
|
+
});
|
|
192
396
|
const first = actions.reduce((min, action) => Math.min(min, action.at), Number.MAX_SAFE_INTEGER);
|
|
397
|
+
const durationMs = spans.get(by.harness) ?? Math.max(0, input.durationMs - first);
|
|
193
398
|
return {
|
|
194
399
|
...input,
|
|
195
|
-
|
|
400
|
+
checks,
|
|
401
|
+
...(disparities.has(by.harness) ? { disparity: [...(disparities.get(by.harness) ?? [])] } : {}),
|
|
402
|
+
durationMs,
|
|
196
403
|
agent: { id: harnessAgentId(by.driver), kind: RunAgentKind.CODING_AGENT },
|
|
197
404
|
trigger: {
|
|
198
405
|
kind: RunTrigger.EDIT,
|
|
@@ -203,7 +410,7 @@ function harnessRunFrom(by, actions, deps) {
|
|
|
203
410
|
name: by.persona ?? UNNAMED_JOURNEY,
|
|
204
411
|
status,
|
|
205
412
|
steps: actions.length,
|
|
206
|
-
durationMs
|
|
413
|
+
durationMs,
|
|
207
414
|
},
|
|
208
415
|
],
|
|
209
416
|
};
|
|
@@ -216,7 +423,14 @@ function harnessRunFrom(by, actions, deps) {
|
|
|
216
423
|
* agent with what the Harness proved and named neither.
|
|
217
424
|
*/
|
|
218
425
|
export function driveRunsFrom(actions, deps) {
|
|
219
|
-
const own = actions
|
|
426
|
+
const own = agentsOwn(actions);
|
|
427
|
+
// Each agent session in the tab is its own run: cut at the ends `reticle_session {end}` recorded.
|
|
428
|
+
const cuts = [0, ...(deps.agentEnds ?? []).map((n) => Math.min(n, own.length)), own.length];
|
|
429
|
+
const sessions = cuts.slice(1).map((to, i) => driveRunFrom(own.slice(cuts[i] ?? 0, to), {
|
|
430
|
+
...deps,
|
|
431
|
+
runId: segmentRunId(deps.runId, i),
|
|
432
|
+
agentClaim: deps.agentClaims?.[i],
|
|
433
|
+
}));
|
|
220
434
|
const drives = new Map();
|
|
221
435
|
for (const action of actions) {
|
|
222
436
|
const by = action.drivenBy;
|
|
@@ -227,7 +441,7 @@ export function driveRunsFrom(actions, deps) {
|
|
|
227
441
|
drives.set(by.harness, held);
|
|
228
442
|
}
|
|
229
443
|
return [
|
|
230
|
-
|
|
444
|
+
...sessions,
|
|
231
445
|
...[...drives.values()].map((drive) => harnessRunFrom(drive.by, drive.actions, deps)),
|
|
232
446
|
].filter((run) => run !== undefined);
|
|
233
447
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type JournalAction } from '@reticlehq/core';
|
|
2
|
+
import type { ToolDeps } from '../../surface/tools/tool-kit.js';
|
|
3
|
+
/** The primer, short form. The full one lives in the agent's rules file (CLAUDE.md / AGENTS.md). */
|
|
4
|
+
export declare const RESUME_PRIMER: readonly string[];
|
|
5
|
+
export interface ResumeFacts {
|
|
6
|
+
actions: readonly JournalAction[];
|
|
7
|
+
/** Intents the ledger still owes (statements). */
|
|
8
|
+
openIntents: readonly string[];
|
|
9
|
+
/** The user's request as declared with reticle_intent, if one is current. */
|
|
10
|
+
request?: string | undefined;
|
|
11
|
+
/** The tab this was about, and where it is now. */
|
|
12
|
+
sessionId?: string | undefined;
|
|
13
|
+
route?: string | undefined;
|
|
14
|
+
/** The cursor to observe from. */
|
|
15
|
+
cursor?: number | undefined;
|
|
16
|
+
/** What this app's notes say (hints for targeting; never evidence). */
|
|
17
|
+
notes: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
/** Each claim's LATEST verdict, in the order the claims were first made. */
|
|
20
|
+
export declare function latestVerdicts(actions: readonly JournalAction[]): {
|
|
21
|
+
claim: string;
|
|
22
|
+
verified: string;
|
|
23
|
+
observed?: string;
|
|
24
|
+
}[];
|
|
25
|
+
/** The resume block, as lines. */
|
|
26
|
+
export declare function resumeLines(facts: ResumeFacts): string[];
|
|
27
|
+
/** The session whose action ledger was written most recently, if any. */
|
|
28
|
+
export declare function newestSessionId(root: string): string | undefined;
|
|
29
|
+
/** The user's request, when one was declared recently enough to be this session's. */
|
|
30
|
+
export declare function recentRequest(root: string, now: number): string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Everything the resume block needs, read from disk — no daemon, which is what a SessionStart hook
|
|
33
|
+
* has the moment after a compaction. The caller supplies the journal reader: the MCP tool holds the
|
|
34
|
+
* live journal, the CLI reads the newest session's ledger.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resumeFromDisk(input: {
|
|
37
|
+
root: string;
|
|
38
|
+
now: number;
|
|
39
|
+
fs: ToolDeps['fs'];
|
|
40
|
+
readActions: (sessionId: string) => Promise<readonly JournalAction[]>;
|
|
41
|
+
sessionId?: string | undefined;
|
|
42
|
+
route?: string | undefined;
|
|
43
|
+
cursor?: number | undefined;
|
|
44
|
+
}): Promise<string[]>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The resume block: what an agent needs back after its context was compacted, in under ~1k tokens.
|
|
3
|
+
*
|
|
4
|
+
* Reticle holds the memory, never the agent. After a compaction the agent's copy of the session is a
|
|
5
|
+
* summary written by a model, and a summary is exactly where "the checkout step failed" becomes
|
|
6
|
+
* "checkout was tested". So this is folded from the daemon's OWN records — the journal on disk, the
|
|
7
|
+
* intent ledger, the declared request, the app notes — and a claim whose latest verdict is not `yes`
|
|
8
|
+
* is listed as failed or not proved, however the agent remembers it.
|
|
9
|
+
*
|
|
10
|
+
* Served two ways from this one fold: `reticle_context { compact: true }` over MCP, and
|
|
11
|
+
* `reticle context --compact` at the terminal (no daemon needed), which a Claude Code SessionStart
|
|
12
|
+
* hook with matcher `compact` prints straight back into the fresh context.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { JournalVerdictEffectSchema, ReticleDir, Verified, } from '@reticlehq/core';
|
|
17
|
+
import { PromptContextSchema } from '@reticlehq/core/artifacts';
|
|
18
|
+
import { IntentStore } from '../../memory/intent/intent-store.js';
|
|
19
|
+
import { readAppNotes } from '../../surface/tools/agent/app-notes.js';
|
|
20
|
+
/** How many claims of each state are named before the rest are counted. Bounds the block. */
|
|
21
|
+
const SHOWN = 5;
|
|
22
|
+
/** Any one line, capped: the block must stay well under ~1k tokens whatever the journal holds. */
|
|
23
|
+
const LINE_MAX = 160;
|
|
24
|
+
/** The primer, short form. The full one lives in the agent's rules file (CLAUDE.md / AGENTS.md). */
|
|
25
|
+
export const RESUME_PRIMER = [
|
|
26
|
+
'Only verified:"yes" passes; "unknown" and "no-fault" are neither pass nor fail.',
|
|
27
|
+
'Declare the consequence before acting: reticle_act_and_wait { target, action, until }. Several steps: one reticle_act { steps: [{ target, action, expect }] }, last expect = end state.',
|
|
28
|
+
'Text is exact-case (ignoreCase only when case does not matter); target by testid or role+name. On a failure read expected/observed/nearest first; never weaken a check.',
|
|
29
|
+
];
|
|
30
|
+
function cap(text) {
|
|
31
|
+
const one = text.replace(/\s+/g, ' ').trim();
|
|
32
|
+
return one.length > LINE_MAX ? `${one.slice(0, LINE_MAX - 1)}…` : one;
|
|
33
|
+
}
|
|
34
|
+
function listed(label, items) {
|
|
35
|
+
if (0 === items.length)
|
|
36
|
+
return [];
|
|
37
|
+
const shown = items.slice(-SHOWN).map((item) => ` - ${cap(item)}`);
|
|
38
|
+
const more = items.length - Math.min(items.length, SHOWN);
|
|
39
|
+
return [
|
|
40
|
+
`${label} (${String(items.length)}):`,
|
|
41
|
+
...(more > 0 ? [` … ${String(more)} earlier`] : []),
|
|
42
|
+
...shown,
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
/** Each claim's LATEST verdict, in the order the claims were first made. */
|
|
46
|
+
export function latestVerdicts(actions) {
|
|
47
|
+
const latest = new Map();
|
|
48
|
+
for (const action of actions) {
|
|
49
|
+
const parsed = JournalVerdictEffectSchema.safeParse(action.effect);
|
|
50
|
+
if (!parsed.success)
|
|
51
|
+
continue;
|
|
52
|
+
const { claim, verified, observed } = parsed.data;
|
|
53
|
+
latest.set(claim, { claim, verified, ...(observed === undefined ? {} : { observed }) });
|
|
54
|
+
}
|
|
55
|
+
return [...latest.values()];
|
|
56
|
+
}
|
|
57
|
+
/** The resume block, as lines. */
|
|
58
|
+
export function resumeLines(facts) {
|
|
59
|
+
const verdicts = latestVerdicts(facts.actions);
|
|
60
|
+
const failed = verdicts
|
|
61
|
+
.filter((v) => Verified.NO === v.verified)
|
|
62
|
+
.map((v) => (v.observed === undefined ? v.claim : `${v.claim} — saw: ${v.observed}`));
|
|
63
|
+
const unproved = verdicts
|
|
64
|
+
.filter((v) => Verified.YES !== v.verified && Verified.NO !== v.verified)
|
|
65
|
+
.map((v) => `${v.claim} (${v.verified})`);
|
|
66
|
+
const held = verdicts.filter((v) => Verified.YES === v.verified).map((v) => v.claim);
|
|
67
|
+
const where = [
|
|
68
|
+
facts.sessionId === undefined ? undefined : `tab ${facts.sessionId}`,
|
|
69
|
+
facts.route === undefined ? undefined : `on ${facts.route}`,
|
|
70
|
+
facts.cursor === undefined ? undefined : `cursor ${String(facts.cursor)}`,
|
|
71
|
+
].filter((p) => p !== undefined);
|
|
72
|
+
return [
|
|
73
|
+
`Reticle resume${0 === where.length ? '' : ` — ${where.join(', ')}`}. This is the daemon's record, not a summary: trust it over your memory.`,
|
|
74
|
+
...(facts.request === undefined ? [] : [`Asked: ${cap(facts.request)}`]),
|
|
75
|
+
`Claims: ${String(held.length)} proved · ${String(failed.length)} failed · ${String(unproved.length)} not proved.`,
|
|
76
|
+
...listed('FAILED — not done', failed),
|
|
77
|
+
...listed('NOT PROVED — not done', unproved),
|
|
78
|
+
...listed('Proved', held),
|
|
79
|
+
...listed('Intents still owed', facts.openIntents),
|
|
80
|
+
...listed('App notes (hints for targeting, never evidence)', facts.notes),
|
|
81
|
+
'Rules:',
|
|
82
|
+
...RESUME_PRIMER.map((line) => ` - ${line}`),
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
/** How long a declared request counts as this session's task (matches next-step.ts). */
|
|
86
|
+
const REQUEST_FRESH_MS = 6 * 60 * 60 * 1000;
|
|
87
|
+
/** The session whose action ledger was written most recently, if any. */
|
|
88
|
+
export function newestSessionId(root) {
|
|
89
|
+
const dir = join(root, ReticleDir.SESSIONS_SUBDIR);
|
|
90
|
+
if (!existsSync(dir))
|
|
91
|
+
return undefined;
|
|
92
|
+
let newest;
|
|
93
|
+
for (const id of readdirSync(dir)) {
|
|
94
|
+
const ledger = join(dir, id, ReticleDir.JOURNAL_ACTIONS_FILE);
|
|
95
|
+
if (!existsSync(ledger))
|
|
96
|
+
continue;
|
|
97
|
+
const at = statSync(ledger).mtimeMs;
|
|
98
|
+
if (newest === undefined || at > newest.at)
|
|
99
|
+
newest = { id, at };
|
|
100
|
+
}
|
|
101
|
+
return newest?.id;
|
|
102
|
+
}
|
|
103
|
+
/** The user's request, when one was declared recently enough to be this session's. */
|
|
104
|
+
export function recentRequest(root, now) {
|
|
105
|
+
try {
|
|
106
|
+
const parsed = PromptContextSchema.safeParse(JSON.parse(readFileSync(join(root, ReticleDir.REQUEST_FILE), 'utf8')));
|
|
107
|
+
if (!parsed.success || parsed.data.request === undefined)
|
|
108
|
+
return undefined;
|
|
109
|
+
const at = parsed.data.at;
|
|
110
|
+
return at !== undefined && now - at <= REQUEST_FRESH_MS ? parsed.data.request : undefined;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Everything the resume block needs, read from disk — no daemon, which is what a SessionStart hook
|
|
118
|
+
* has the moment after a compaction. The caller supplies the journal reader: the MCP tool holds the
|
|
119
|
+
* live journal, the CLI reads the newest session's ledger.
|
|
120
|
+
*/
|
|
121
|
+
export async function resumeFromDisk(input) {
|
|
122
|
+
const sessionId = input.sessionId ?? newestSessionId(input.root);
|
|
123
|
+
// Asked even with no session on disk: a caller holding the live journal answers from it.
|
|
124
|
+
const actions = await input.readActions(sessionId ?? '').catch(() => []);
|
|
125
|
+
const open = await new IntentStore(input.fs, input.root, { now: () => input.now })
|
|
126
|
+
.open()
|
|
127
|
+
.catch(() => []);
|
|
128
|
+
return resumeLines({
|
|
129
|
+
actions,
|
|
130
|
+
openIntents: open.map((intent) => intent.statement),
|
|
131
|
+
request: recentRequest(input.root, input.now),
|
|
132
|
+
sessionId,
|
|
133
|
+
route: input.route,
|
|
134
|
+
cursor: input.cursor,
|
|
135
|
+
notes: readAppNotes(input.root),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
@@ -14,6 +14,7 @@ import { boundFlowName, RunFlowStatus, VerifyPhase, } from '@reticlehq/core';
|
|
|
14
14
|
import { buildVerificationRun, } from './artifact/build-verification-run.js';
|
|
15
15
|
import { mapReplayToFlowResult } from './artifact/replay-mapping.js';
|
|
16
16
|
import { buildRepairPackets } from './repair-prompt.js';
|
|
17
|
+
import { withShotRun } from './default-run-id.js';
|
|
17
18
|
import { buildRisks, classifyChangedFiles, } from './risk-classify.js';
|
|
18
19
|
export class ReticleRunner {
|
|
19
20
|
#port;
|
|
@@ -44,6 +45,8 @@ export class ReticleRunner {
|
|
|
44
45
|
// Announced BEFORE the loop: "step 3" without "of 12" does not answer the only question a
|
|
45
46
|
// person watching is actually asking, which is whether to keep waiting.
|
|
46
47
|
emit({ phase: VerifyPhase.FLOWS_FOUND, total, at: this.#port.now() });
|
|
48
|
+
// Minted first, so each replayed step's screenshot is filed under the run it belongs to.
|
|
49
|
+
const runId = this.#port.newRunId();
|
|
47
50
|
const replays = [];
|
|
48
51
|
const flows = [];
|
|
49
52
|
for (const [index, name] of names.entries()) {
|
|
@@ -55,7 +58,7 @@ export class ReticleRunner {
|
|
|
55
58
|
name: boundFlowName(name),
|
|
56
59
|
at: start,
|
|
57
60
|
});
|
|
58
|
-
const replay = await this.#port.replayFlow(name);
|
|
61
|
+
const replay = await withShotRun(runId, () => this.#port.replayFlow(name));
|
|
59
62
|
replays.push(replay);
|
|
60
63
|
const mapped = mapReplayToFlowResult(replay, this.#port.now() - start);
|
|
61
64
|
flows.push(mapped);
|
|
@@ -75,7 +78,7 @@ export class ReticleRunner {
|
|
|
75
78
|
const risks = buildRisks(changedFiles, opts.policy);
|
|
76
79
|
const failurePackets = buildRepairPackets(replays);
|
|
77
80
|
const input = {
|
|
78
|
-
runId
|
|
81
|
+
runId,
|
|
79
82
|
durationMs: flows.reduce((sum, f) => sum + f.durationMs, 0),
|
|
80
83
|
profile: opts.profile,
|
|
81
84
|
project: opts.project,
|
|
@@ -8,4 +8,8 @@ import type { ToolDeps } from '../../surface/tools/tool-kit.js';
|
|
|
8
8
|
import type { RunnerPort } from './reticle-runner.js';
|
|
9
9
|
export { defaultRunId } from './default-run-id.js';
|
|
10
10
|
/** Wire a RunnerPort to the live session. Pass sessionId to disambiguate when several tabs are open. */
|
|
11
|
-
export declare function createRunnerPort(deps: ToolDeps, sessionId?: string
|
|
11
|
+
export declare function createRunnerPort(deps: ToolDeps, sessionId?: string,
|
|
12
|
+
/** `reticle verify --confirm-dangerous`: this run acknowledges the steps held as destructive. */
|
|
13
|
+
opts?: {
|
|
14
|
+
confirmDangerous?: boolean;
|
|
15
|
+
}): RunnerPort;
|
|
@@ -8,10 +8,16 @@ import { replayAndLearn } from '../../language/flows/flow-learning.js';
|
|
|
8
8
|
import { defaultRunId } from './default-run-id.js';
|
|
9
9
|
export { defaultRunId } from './default-run-id.js';
|
|
10
10
|
/** Wire a RunnerPort to the live session. Pass sessionId to disambiguate when several tabs are open. */
|
|
11
|
-
export function createRunnerPort(deps, sessionId
|
|
11
|
+
export function createRunnerPort(deps, sessionId,
|
|
12
|
+
/** `reticle verify --confirm-dangerous`: this run acknowledges the steps held as destructive. */
|
|
13
|
+
opts = {}) {
|
|
12
14
|
return {
|
|
13
15
|
listFlows: () => deps.flows.list(),
|
|
14
|
-
replayFlow: (name) => replayAndLearn(deps,
|
|
16
|
+
replayFlow: (name) => replayAndLearn(deps, {
|
|
17
|
+
flowName: name,
|
|
18
|
+
...(sessionId === undefined ? {} : { sessionId }),
|
|
19
|
+
...(true === opts.confirmDangerous ? { confirmDangerous: true } : {}),
|
|
20
|
+
}),
|
|
15
21
|
now: () => deps.now(),
|
|
16
22
|
newRunId: defaultRunId,
|
|
17
23
|
};
|
|
@@ -8,6 +8,8 @@ export interface TimedReplay {
|
|
|
8
8
|
/** The flow file that was replayed, so the synced run can carry its recording. */
|
|
9
9
|
flow?: FlowFile;
|
|
10
10
|
}
|
|
11
|
+
/** The MCP client name `reticle verify` (the command line, CI's path) connects to a daemon as. */
|
|
12
|
+
export declare const CLI_CLIENT_NAME = "reticle-cli";
|
|
11
13
|
/**
|
|
12
14
|
* Persist the suite's run artifact and best-effort mirror it to the cloud. Never throws into the verify
|
|
13
15
|
* tool — a disk or network failure is logged and swallowed so the verdict the agent asked for is
|