@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
|
@@ -10,14 +10,26 @@
|
|
|
10
10
|
import { type FlowFile } from '@reticlehq/core';
|
|
11
11
|
import type { ToolDeps } from './tool-kit.js';
|
|
12
12
|
import { type HarnessPlan } from './harness-plan.js';
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
13
|
+
import type { ConfigFetch } from '../../features/harness/platform-config.js';
|
|
14
|
+
import type { JourneyResult } from '../../features/harness/platform/script.js';
|
|
15
|
+
import { type HarnessOptions, type HarnessResult, type HarnessToolset, type ModelDriver, type ToolOutcome } from '../../features/harness/harness.js';
|
|
15
16
|
import { type GoalCheck } from '../../features/harness/goals.js';
|
|
17
|
+
import type { RunDisparity } from '@reticlehq/core';
|
|
18
|
+
import type { HarnessMap } from '@reticlehq/core/artifacts';
|
|
19
|
+
export { MSG_HARNESS_DISABLED, MSG_HARNESS_UNCLAIMED, MSG_HARNESS_UNCONFIRMED, } from '../../features/harness/platform/refusal.js';
|
|
20
|
+
export { MSG_GATE_PROMPT_LEAD, MSG_NO_HARNESS_KEY, coverageRefusal, firstLine, harnessAvailable, harnessLockRefusal, refusedByPlatform, withLinkedCredential, } from './harness-gate.js';
|
|
16
21
|
export interface ExploreOptions {
|
|
17
22
|
/** Who to be, or what to accomplish. Appended to the standing instruction. */
|
|
18
23
|
focus?: string;
|
|
24
|
+
/**
|
|
25
|
+
* A person started this run (Run plan from the dashboard) and acknowledged the saved flows' own
|
|
26
|
+
* destructive steps: a planned replay may take them. Never a step the model decides.
|
|
27
|
+
*/
|
|
28
|
+
confirmDangerous?: boolean;
|
|
19
29
|
/** Texts the drive must leave on the page. Default: whatever `focus` quoted. See goals.ts. */
|
|
20
30
|
goals?: readonly string[];
|
|
31
|
+
/** The outcome the journey must end in, as a reticle_assert predicate. See `checkExpect`. */
|
|
32
|
+
expect?: Record<string, unknown>;
|
|
21
33
|
/** Pinned tab, when the app has more than one connected. */
|
|
22
34
|
sessionId?: string;
|
|
23
35
|
/** Hard ceiling on model turns. Bounds cost, not value — the drive is usable however it ends. */
|
|
@@ -48,6 +60,14 @@ export interface ExploreOptions {
|
|
|
48
60
|
* supposed to cover the OFF switch was asserting on a path where the platform is never asked.
|
|
49
61
|
*/
|
|
50
62
|
configFetch?: ConfigFetch;
|
|
63
|
+
/** The drive's harness id, minted by the caller so its run id is known before the drive starts. */
|
|
64
|
+
harnessId?: string;
|
|
65
|
+
/** A plan the platform saved (`hp_…`): run it as it stands, instead of asking for a new one. */
|
|
66
|
+
planId?: string;
|
|
67
|
+
/** Asked between turns: whoever started the drive asked it to stop. */
|
|
68
|
+
stopped?: () => boolean;
|
|
69
|
+
/** Asked between turns: what whoever started the drive said to it since. */
|
|
70
|
+
inbox?: () => readonly string[];
|
|
51
71
|
}
|
|
52
72
|
export interface ExploreResult {
|
|
53
73
|
drive: HarnessResult;
|
|
@@ -85,40 +105,17 @@ export interface ExploreResult {
|
|
|
85
105
|
driverName: string;
|
|
86
106
|
/** The run this drive syncs as (`harness-<id>`), so a caller can find it on the platform. */
|
|
87
107
|
runIds?: readonly string[];
|
|
108
|
+
/** The run's page on the dashboard, when the project is linked. */
|
|
109
|
+
runUrl?: string;
|
|
110
|
+
/** How each journey of a platform plan ended, worst lane first. Absent for an unplanned drive. */
|
|
111
|
+
journeys?: readonly JourneyResult[];
|
|
112
|
+
/** The platform plan this run drove, which the dashboard keeps, edits and runs again. */
|
|
113
|
+
planId?: string;
|
|
114
|
+
/** That plan's page on the dashboard. */
|
|
115
|
+
planUrl?: string;
|
|
116
|
+
/** Each goal the session's coding agent also judged, and how the two verdicts compare. */
|
|
117
|
+
disparity?: readonly RunDisparity[];
|
|
88
118
|
}
|
|
89
|
-
/**
|
|
90
|
-
* Why the harness is unavailable, phrased as the way to make it available.
|
|
91
|
-
*
|
|
92
|
-
* A missing key is a configuration fact, not a fault, and the sentence a user reads has to tell them
|
|
93
|
-
* the one thing to do about it. Named here because both the CLI and the honest no-flows refusal
|
|
94
|
-
* print it, and two copies of this sentence would drift.
|
|
95
|
-
*/
|
|
96
|
-
export declare const MSG_NO_HARNESS_KEY: string;
|
|
97
|
-
/**
|
|
98
|
-
* The environment, plus the credential this machine already has.
|
|
99
|
-
*
|
|
100
|
-
* `reticle link` mints a project-scoped key and files it in `~/.reticle/credentials.json`; the CLI
|
|
101
|
-
* has read it from there for as long as it has existed. The harness did not, and read only
|
|
102
|
-
* `process.env` — so somebody who had signed in, linked their project and been told they were
|
|
103
|
-
* connected still got "no model configured to drive the app", and the only way out was to find the
|
|
104
|
-
* key in the console and export it by hand. Five manual steps to reach a feature they had already
|
|
105
|
-
* finished setting up.
|
|
106
|
-
*
|
|
107
|
-
* Resolved into the env rather than threaded through four call sites: the drivers and the
|
|
108
|
-
* preference lookup all read an env record, and giving them a completed one leaves each of them
|
|
109
|
-
* exactly as simple as it was. The key precedence is the resolver's, the same as sync's and the
|
|
110
|
-
* CLI's: the stored key for the link's host, else the exported one (which is how CI, with no
|
|
111
|
-
* keystore, gets here). An explicitly exported HOST still wins, so a proxy is not overridden.
|
|
112
|
-
*
|
|
113
|
-
* The credential arrives through `deps.linkedCloud`, a port, because resolving it here would make
|
|
114
|
-
* the tool surface reach into `memory/cloud` — a reach the directory guard refused, correctly.
|
|
115
|
-
*/
|
|
116
|
-
export declare function withLinkedCredential(deps: ToolDeps, env: Record<string, string | undefined>): Promise<Record<string, string | undefined>>;
|
|
117
|
-
/**
|
|
118
|
-
* Can this machine reach the Harness? Only through the platform: a linked project or a platform
|
|
119
|
-
* key. Whether the workspace is entitled is the platform's answer, asked when the drive starts.
|
|
120
|
-
*/
|
|
121
|
-
export declare function harnessAvailable(env: Record<string, string | undefined>): boolean;
|
|
122
119
|
/**
|
|
123
120
|
* Read the step ceiling out of the environment.
|
|
124
121
|
*
|
|
@@ -135,10 +132,11 @@ export declare function maxStepsFromEnv(env: Record<string, string | undefined>)
|
|
|
135
132
|
* that says it saved a flow and did not is the same false green as an app that says it saved a
|
|
136
133
|
* record and did not — and this product does not get to make that mistake about its own work.
|
|
137
134
|
*/
|
|
138
|
-
export declare function exploreApp(deps: ToolDeps,
|
|
135
|
+
export declare function exploreApp(deps: ToolDeps, given: Record<string, string | undefined>, asked?: ExploreOptions): Promise<ExploreResult>;
|
|
136
|
+
/** The stop and the words of whoever started the drive, for `runHarness`. */
|
|
137
|
+
export declare function steering(options: ExploreOptions): Pick<HarnessOptions, 'stopped' | 'inbox'>;
|
|
139
138
|
/** A line in the HUD's Agent Log for the person watching; nobody watching is not an error. */
|
|
140
|
-
export declare function narrator(deps: ToolDeps, options: ExploreOptions): (text: string) => void;
|
|
141
|
-
/** What this project's memory says must hold, in its own words. Nothing recorded is none. */
|
|
139
|
+
export declare function narrator(deps: ToolDeps, options: ExploreOptions): (text: string, summary?: boolean) => void;
|
|
142
140
|
export declare function productRules(deps: ToolDeps, sessionId?: string): Promise<string[]>;
|
|
143
141
|
/** `deps` whose flow store is the session's own project, where the drive's saves land. */
|
|
144
142
|
export declare function withProjectFlows(deps: ToolDeps, sessionId?: string): ToolDeps;
|
|
@@ -181,39 +179,16 @@ export declare function reconcileFlows(before: ReadonlySet<string>, after: reado
|
|
|
181
179
|
rewroteFlows: readonly string[];
|
|
182
180
|
};
|
|
183
181
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* turning the harness OFF changed a value in a database and nothing else. A control that does not
|
|
188
|
-
* control anything is worse than no control: somebody turns it off, watches Reticle drive their app
|
|
189
|
-
* anyway, and now correctly distrusts every other switch in the product.
|
|
190
|
-
*
|
|
191
|
-
* Absent means ON. The platform's own default is on, and a machine that cannot reach the platform —
|
|
192
|
-
* offline, CI, no link — must not silently lose a feature it was never told to stop using.
|
|
193
|
-
*/
|
|
194
|
-
export declare const MSG_HARNESS_DISABLED: string;
|
|
195
|
-
/**
|
|
196
|
-
* The other reason a drive can be refused, and it is NOT the same reason.
|
|
197
|
-
*
|
|
198
|
-
* A drive through the platform spends Reticle's model budget, bounded by the workspace's monthly
|
|
199
|
-
* Harness credits. The platform answers this only when something other than the switch stops it.
|
|
200
|
-
*/
|
|
201
|
-
export declare const MSG_HARNESS_UNCLAIMED: string;
|
|
202
|
-
/** The platform could not be asked, and the drive would spend Reticle's budget without its yes. */
|
|
203
|
-
export declare const MSG_HARNESS_UNCONFIRMED: string;
|
|
204
|
-
/**
|
|
205
|
-
* The reason this drive must not start, or `undefined` to go ahead.
|
|
206
|
-
*
|
|
207
|
-
* A drive on somebody's OWN model key never waits on the platform beyond the off switch: their key,
|
|
208
|
-
* their spend. A drive through the platform proxy bills Reticle, and that one needs a confirmed yes
|
|
209
|
-
* — enabled, entitled, and a model ready. It used to fail open: `fetchPlatformConfig` answers
|
|
210
|
-
* `undefined` on a network error, a non-2xx, a body that does not parse, or a two-second timeout,
|
|
211
|
-
* and all four read as "carry on", so a slow second on a settings endpoint let an unentitled
|
|
212
|
-
* workspace drive on Reticle's budget. Now the same silence refuses with a message that says to
|
|
213
|
-
* retry or bring a key. Fields an older platform omits still default to yes inside
|
|
214
|
-
* `fetchPlatformConfig`; only an answer that never arrived is a no.
|
|
182
|
+
* Why a drive must not be replayed into a verdict, or undefined when it may. A drive the platform
|
|
183
|
+
* cut off (credits gone: 402 needs_card) had saved one partial flow, and replaying it printed PASS
|
|
184
|
+
* with no word about the credits. The one test both CLI explore paths answer through.
|
|
215
185
|
*/
|
|
216
|
-
export declare function
|
|
186
|
+
export declare function cutOffReason(drive: {
|
|
187
|
+
stopReason?: unknown;
|
|
188
|
+
error?: unknown;
|
|
189
|
+
}): string | undefined;
|
|
190
|
+
/** The Agent Log's last line for a drive the platform cut off: its reason, and that it proved nothing. */
|
|
191
|
+
export declare const msgDriveCutOff: (error: string | undefined) => string;
|
|
217
192
|
/**
|
|
218
193
|
* Close and save whatever recording the drive left open.
|
|
219
194
|
*
|
|
@@ -232,8 +207,10 @@ export declare function refusedByPlatform(env: Record<string, string | undefined
|
|
|
232
207
|
* It used to be "Autonomous drive of X, banked after the run ended" whatever the caller asked for,
|
|
233
208
|
* so a replay could never say which journey the flow was meant to prove.
|
|
234
209
|
*/
|
|
235
|
-
export declare function bankedIntent(persona: string | undefined, open: string
|
|
236
|
-
|
|
210
|
+
export declare function bankedIntent(persona: string | undefined, open: string,
|
|
211
|
+
/** The journey the drive was for, when no persona was named. */
|
|
212
|
+
journey?: string): string;
|
|
213
|
+
export declare function bankOpenRecording(toolset: HarnessToolset, drive: HarnessResult, persona: string | undefined, journey?: string): Promise<ToolOutcome[]>;
|
|
237
214
|
/** The recording started and never stopped, if there is one. Exported because it is the decision. */
|
|
238
215
|
export declare function openRecordingName(toolCalls: readonly ToolOutcome[]): string | undefined;
|
|
239
216
|
/**
|
|
@@ -254,7 +231,9 @@ export declare function pinned(options: ExploreOptions): {
|
|
|
254
231
|
*/
|
|
255
232
|
export declare function buildDriver(env: Record<string, string | undefined>, maxSteps: number, plan: HarnessPlan, requested?: string, persona?: string,
|
|
256
233
|
/** A goal driven with no persona: it names the drive's flows as a persona would. */
|
|
257
|
-
journey?: string
|
|
234
|
+
journey?: string,
|
|
235
|
+
/** The survey of the app, which the platform's engine looks goals up in. */
|
|
236
|
+
siteMap?: HarnessMap): {
|
|
258
237
|
driver: ModelDriver;
|
|
259
238
|
name: string;
|
|
260
239
|
};
|
|
@@ -10,78 +10,32 @@
|
|
|
10
10
|
import { serverDriver, serverOptionsFromEnv } from '../../features/harness/platform/server-driver.js';
|
|
11
11
|
import { exploreScript } from './harness-script.js';
|
|
12
12
|
import { randomUUID } from 'node:crypto';
|
|
13
|
-
import { harnessRunId } from '../../judgement/runs/drive-run.js';
|
|
14
|
-
import { ReticleEnv, ReticleTool, asProjectId,
|
|
13
|
+
import { harnessRunId, noteHarnessDisparity, noteHarnessGoal, noteHarnessSpan, } from '../../judgement/runs/drive-run.js';
|
|
14
|
+
import { ReticleEnv, ReticleTool, asProjectId, asRecord } from '@reticlehq/core';
|
|
15
15
|
import { flowsForSession } from '../../language/flows/flow-store-for-session.js';
|
|
16
16
|
import { projectForRoot } from '../../memory/project/project-for-root.js';
|
|
17
|
-
import { checkTally, verdictLine } from '../../features/harness/drive-report.js';
|
|
17
|
+
import { actedOnApp, checkTally, pagesReached, typedValues, verdictLine, } from '../../features/harness/drive-report.js';
|
|
18
18
|
import { CUSTOM_DRIVER_NAME, SERVER_DRIVER } from '../../features/harness/drivers.js';
|
|
19
19
|
import { buildDomainModel } from '../../judgement/domain/domain-model.js';
|
|
20
20
|
import { readContract } from '../../memory/project/dir/reticle-dir.js';
|
|
21
21
|
import { sessionRoot, sessionTarget } from '../../memory/project/session-root.js';
|
|
22
|
-
import {
|
|
22
|
+
import { dashboardPlanUrl, dashboardRunUrl, readDashboardUrl, readLinkedProjectId, } from '../../memory/project/sync-status.js';
|
|
23
|
+
import { buildHarnessPlan, drivingPlan, planAsText } from './harness-plan.js';
|
|
23
24
|
import { allSessionIntents } from '../../memory/intent/open-intents.js';
|
|
24
|
-
import { fetchPlatformConfig } from '../../features/harness/platform-config.js';
|
|
25
25
|
import { DEFAULT_MAX_STEPS, runHarness, StopReason, } from '../../features/harness/harness.js';
|
|
26
26
|
import { reticleToolset } from './harness-toolset.js';
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export
|
|
36
|
-
`monthly Harness credits): run \`reticle connect\` to link this project and sign in. ` +
|
|
37
|
-
`Without it, drive the journey yourself with reticle_act_and_wait and an \`until\` on its last step: ` +
|
|
38
|
-
`what you drive is saved as a flow just the same.`;
|
|
27
|
+
import { DriveRefusedError, noteDriveLine } from '../../features/harness/drive-runs.js';
|
|
28
|
+
import { personaCredentials } from '../../features/harness/platform/persona-credentials.js';
|
|
29
|
+
import { endOf, goalOfDrive, parseGoals, readOpening, unprovedGoals, } from '../../features/harness/goals.js';
|
|
30
|
+
import { mapForPlatform } from '../../features/harness/explore/site-map.js';
|
|
31
|
+
import { huntAndGrade, knownRoutes, refreshMap, siteMapFor } from './harness-hunt.js';
|
|
32
|
+
export { MSG_HARNESS_DISABLED, MSG_HARNESS_UNCLAIMED, MSG_HARNESS_UNCONFIRMED, } from '../../features/harness/platform/refusal.js';
|
|
33
|
+
import { MSG_NO_HARNESS_KEY, refusedForPlan } from './harness-gate.js';
|
|
34
|
+
// The gate a drive passes before it starts moved to its own module; its names are still asked for here.
|
|
35
|
+
export { MSG_GATE_PROMPT_LEAD, MSG_NO_HARNESS_KEY, coverageRefusal, firstLine, harnessAvailable, harnessLockRefusal, refusedByPlatform, withLinkedCredential, } from './harness-gate.js';
|
|
39
36
|
/** A driver named that this build no longer has: every Harness decision is the platform's now. */
|
|
40
37
|
const msgUnknownDriver = (asked) => `The Harness driver \`${asked}\` is not available: the Harness runs on the Reticle platform, ` +
|
|
41
38
|
`which drives with the model set for the project in the dashboard.`;
|
|
42
|
-
/**
|
|
43
|
-
* The environment, plus the credential this machine already has.
|
|
44
|
-
*
|
|
45
|
-
* `reticle link` mints a project-scoped key and files it in `~/.reticle/credentials.json`; the CLI
|
|
46
|
-
* has read it from there for as long as it has existed. The harness did not, and read only
|
|
47
|
-
* `process.env` — so somebody who had signed in, linked their project and been told they were
|
|
48
|
-
* connected still got "no model configured to drive the app", and the only way out was to find the
|
|
49
|
-
* key in the console and export it by hand. Five manual steps to reach a feature they had already
|
|
50
|
-
* finished setting up.
|
|
51
|
-
*
|
|
52
|
-
* Resolved into the env rather than threaded through four call sites: the drivers and the
|
|
53
|
-
* preference lookup all read an env record, and giving them a completed one leaves each of them
|
|
54
|
-
* exactly as simple as it was. The key precedence is the resolver's, the same as sync's and the
|
|
55
|
-
* CLI's: the stored key for the link's host, else the exported one (which is how CI, with no
|
|
56
|
-
* keystore, gets here). An explicitly exported HOST still wins, so a proxy is not overridden.
|
|
57
|
-
*
|
|
58
|
-
* The credential arrives through `deps.linkedCloud`, a port, because resolving it here would make
|
|
59
|
-
* the tool surface reach into `memory/cloud` — a reach the directory guard refused, correctly.
|
|
60
|
-
*/
|
|
61
|
-
export async function withLinkedCredential(deps, env) {
|
|
62
|
-
try {
|
|
63
|
-
const linked = await deps.linkedCloud?.();
|
|
64
|
-
if (linked === undefined || null === linked)
|
|
65
|
-
return env;
|
|
66
|
-
return {
|
|
67
|
-
...env,
|
|
68
|
-
[ReticleEnv.API_KEY]: linked.apiKey,
|
|
69
|
-
[ReticleEnv.CLOUD_URL]: cloudUrlFrom(env) ?? linked.url,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// A credential store that cannot be read is "not linked", not an error. The harness is optional
|
|
74
|
-
// and its absence is a routine answer; a drive must never fail because a JSON file was odd.
|
|
75
|
-
return env;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Can this machine reach the Harness? Only through the platform: a linked project or a platform
|
|
80
|
-
* key. Whether the workspace is entitled is the platform's answer, asked when the drive starts.
|
|
81
|
-
*/
|
|
82
|
-
export function harnessAvailable(env) {
|
|
83
|
-
return serverOptionsFromEnv(env) !== undefined;
|
|
84
|
-
}
|
|
85
39
|
/**
|
|
86
40
|
* Read the step ceiling out of the environment.
|
|
87
41
|
*
|
|
@@ -104,10 +58,15 @@ export function maxStepsFromEnv(env) {
|
|
|
104
58
|
* that says it saved a flow and did not is the same false green as an app that says it saved a
|
|
105
59
|
* record and did not — and this product does not get to make that mistake about its own work.
|
|
106
60
|
*/
|
|
107
|
-
export async function exploreApp(deps,
|
|
108
|
-
|
|
61
|
+
export async function exploreApp(deps, given, asked = {}) {
|
|
62
|
+
// Every drive starts here. The credentials a persona names fill its sign-in fields on this
|
|
63
|
+
// machine, and only the redacted text travels on: to the platform, into flows and synced runs.
|
|
64
|
+
const named = asked.focus === undefined ? undefined : personaCredentials(asked.focus);
|
|
65
|
+
const env = named === undefined ? given : { ...given, ...named.secrets };
|
|
66
|
+
const options = named === undefined ? asked : { ...asked, focus: named.persona };
|
|
67
|
+
const refusal = await refusedForPlan(env, options);
|
|
109
68
|
if (refusal !== undefined)
|
|
110
|
-
throw new
|
|
69
|
+
throw new DriveRefusedError(refusal);
|
|
111
70
|
// The flows a drive reads and diffs are the PROJECT's, which is where its saves land.
|
|
112
71
|
const reads = withProjectFlows(deps, options.sessionId);
|
|
113
72
|
// No journey named: plan the drive first. The platform's Harness proposes the people worth being;
|
|
@@ -116,36 +75,56 @@ export async function exploreApp(deps, env, options = {}) {
|
|
|
116
75
|
const before = new Set(await reads.flows.list());
|
|
117
76
|
// Without a named journey the drive is always planned; with one, it is planned by the platform
|
|
118
77
|
// when there is one, and driven here as before when there is not.
|
|
119
|
-
if (options.focus === undefined ||
|
|
78
|
+
if (options.focus === undefined ||
|
|
79
|
+
options.planId !== undefined ||
|
|
80
|
+
serverOptionsFromEnv(env) !== undefined) {
|
|
120
81
|
const scripted = await exploreScript(deps, env, options, before);
|
|
82
|
+
// Where the person opens it: the run, and the plan the dashboard keeps and runs again.
|
|
121
83
|
if (scripted !== undefined)
|
|
122
|
-
return
|
|
84
|
+
return {
|
|
85
|
+
...scripted,
|
|
86
|
+
...runUrlFor(deps, options.sessionId, scripted.runIds?.[0]),
|
|
87
|
+
...planUrlFor(deps, options.sessionId, scripted.planId),
|
|
88
|
+
};
|
|
123
89
|
}
|
|
124
90
|
const maxSteps = options.maxSteps ?? maxStepsFromEnv(env);
|
|
125
91
|
// `.reticle` FIRST, before the app and before anything reads a line of source. It already holds
|
|
126
92
|
// every saved flow, the consequence that must hold for each, and the declared intent nobody has
|
|
127
93
|
// tested — which is the whole of what a drive should be deciding against.
|
|
128
94
|
const plan = await readPlan(reads, options.sessionId);
|
|
129
|
-
const driving =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const driver = built.driver;
|
|
95
|
+
const driving = drivingPlan(plan, options.focus);
|
|
96
|
+
// Refused before anything touches the app: an unknown driver, or no platform to drive with.
|
|
97
|
+
if (options.driver === undefined)
|
|
98
|
+
buildDriver(env, maxSteps, driving, options.driverName, options.focus);
|
|
134
99
|
// Every action this drive takes carries who took it, so the run it folds into is the Harness's own
|
|
135
100
|
// and not mixed into the run of whichever agent shares the tab.
|
|
136
|
-
const harnessId = randomUUID();
|
|
101
|
+
const harnessId = options.harnessId ?? randomUUID();
|
|
102
|
+
const driverLabel = options.driver === undefined ? SERVER_DRIVER : CUSTOM_DRIVER_NAME;
|
|
137
103
|
const toolset = reticleToolset(deps, {
|
|
138
104
|
...pinned(options),
|
|
139
105
|
drivenBy: {
|
|
140
106
|
harness: harnessId,
|
|
141
|
-
driver:
|
|
107
|
+
driver: driverLabel,
|
|
142
108
|
...(options.focus === undefined ? {} : { persona: options.focus }),
|
|
143
109
|
},
|
|
110
|
+
...(options.focus === undefined ? {} : { asked: options.focus }),
|
|
144
111
|
});
|
|
145
112
|
const narrate = narrator(deps, options);
|
|
146
|
-
|
|
113
|
+
const invoke = (name, args) => toolset.invoke(name, args);
|
|
114
|
+
// Map first: survey the app (no model) unless this app's map is fresh, and leave the tab at start.
|
|
115
|
+
const map = await siteMapFor(deps, options.sessionId, invoke);
|
|
116
|
+
const built = options.driver === undefined
|
|
117
|
+
? buildDriver(env, maxSteps, driving, options.driverName, options.focus, undefined, map)
|
|
118
|
+
: { driver: options.driver, name: CUSTOM_DRIVER_NAME };
|
|
119
|
+
const driver = built.driver;
|
|
120
|
+
// Read before anything is driven: a goal this page already shows proves nothing at the end.
|
|
121
|
+
const opening = await readOpening(invoke);
|
|
122
|
+
narrate(`Harness is driving${options.focus === undefined ? '' : `: ${options.focus}`}`, true);
|
|
123
|
+
const driveStarted = deps.now();
|
|
147
124
|
const drive = await runHarness(driver, toolset, {
|
|
125
|
+
...steering(options),
|
|
148
126
|
maxSteps,
|
|
127
|
+
routes: knownRoutes(map),
|
|
149
128
|
// The plan rides in as standing instruction, so it is in front of the model on every turn
|
|
150
129
|
// rather than remembered from a first one. `focus` is the caller's own words and goes last:
|
|
151
130
|
// somebody who named a journey meant that journey, whatever the project's backlog says.
|
|
@@ -153,18 +132,48 @@ export async function exploreApp(deps, env, options = {}) {
|
|
|
153
132
|
planAsText(driving),
|
|
154
133
|
...(options.focus === undefined ? [] : [`Focus: ${options.focus}`]),
|
|
155
134
|
].join('\n\n'),
|
|
135
|
+
// The end the caller's words quote stops the drive once it shows: see HarnessOptions.endsAt.
|
|
136
|
+
...((end) => end === undefined || options.focus === undefined
|
|
137
|
+
? {}
|
|
138
|
+
: { endsAt: { text: end, own: [options.focus] } })(endOf(options.focus ?? '')),
|
|
156
139
|
});
|
|
140
|
+
// Before the session ends and is graded: a drive whose goal was missed, or that was cut off part-way,
|
|
141
|
+
// must not sync as "Proved" on the checks that held before it stopped.
|
|
142
|
+
noteHarnessGoal(harnessId, drive.goalMet);
|
|
157
143
|
narrate(StopReason.STOPPED === drive.stopReason
|
|
158
144
|
? `Autonomous driving switched off — the Harness stopped after ${String(drive.steps)} steps. What it drove is kept.`
|
|
159
|
-
:
|
|
145
|
+
: StopReason.BROKEN === drive.stopReason
|
|
146
|
+
? msgDriveCutOff(drive.error)
|
|
147
|
+
: `Harness finished — ${verdictLine(checkTally(drive.toolCalls))}`, true);
|
|
160
148
|
// MANDATORY, and deliberately outside the loop. A drive that runs out of budget mid-journey, or
|
|
161
149
|
// breaks, or whose model simply stops asking for tools, leaves a recording open and everything it
|
|
162
150
|
// drove unsaved — work paid for and thrown away. Saving is not a decision any model gets to make
|
|
163
151
|
// and not something a step budget gets to cut off, so it happens here, after the loop, always.
|
|
164
|
-
await bankOpenRecording(toolset, drive, options.focus);
|
|
165
|
-
|
|
152
|
+
const banked = await bankOpenRecording(toolset, drive, options.focus);
|
|
153
|
+
await refreshMap(deps, options.sessionId, map, drive.toolCalls);
|
|
154
|
+
// Hunt for the journey's end before grading: never a `no` from where the drive happened to stop.
|
|
155
|
+
const graded = await huntAndGrade(deps, invoke, {
|
|
156
|
+
sessionId: options.sessionId,
|
|
157
|
+
goals: options.goals ?? parseGoals(options.focus),
|
|
158
|
+
expect: options.expect,
|
|
159
|
+
opening,
|
|
160
|
+
journey: options.focus,
|
|
161
|
+
map,
|
|
162
|
+
reached: pagesReached(drive.toolCalls),
|
|
163
|
+
typed: typedValues(drive.toolCalls),
|
|
164
|
+
});
|
|
165
|
+
const goals = graded.goals;
|
|
166
|
+
noteHarnessDisparity(harnessId, graded.disparity);
|
|
167
|
+
// The goals it was given decide whether the journey was done, not a click that held on the way,
|
|
168
|
+
// and never the driver's word over a drive that did nothing.
|
|
169
|
+
const goalMet = goalOfDrive(drive.goalMet, goals, actedOnApp(drive.toolCalls));
|
|
170
|
+
noteHarnessGoal(harnessId, goalMet);
|
|
171
|
+
noteHarnessSpan(harnessId, deps.now() - driveStarted);
|
|
172
|
+
const unproved = unprovedGoals(goals);
|
|
173
|
+
if (unproved !== undefined)
|
|
174
|
+
narrate(unproved, true);
|
|
166
175
|
const after = await reads.flows.list();
|
|
167
|
-
const reconciled = reconcileFlows(before, after, drive.toolCalls);
|
|
176
|
+
const reconciled = reconcileFlows(before, after, [...drive.toolCalls, ...banked]);
|
|
168
177
|
if (options.focus !== undefined) {
|
|
169
178
|
await recordPersona(reads, [...reconciled.savedFlows, ...reconciled.rewroteFlows], options.focus);
|
|
170
179
|
}
|
|
@@ -174,27 +183,80 @@ export async function exploreApp(deps, env, options = {}) {
|
|
|
174
183
|
]);
|
|
175
184
|
const runId = harnessRunId(harnessId);
|
|
176
185
|
return {
|
|
177
|
-
drive
|
|
186
|
+
// The hunt's navigations after the drive's own calls: they are the Harness driving the app too.
|
|
187
|
+
// After the goal is decided, which counts only what the drive itself did.
|
|
188
|
+
drive: {
|
|
189
|
+
...drive,
|
|
190
|
+
toolCalls: [...drive.toolCalls, ...graded.moved],
|
|
191
|
+
...(goalMet === undefined ? {} : { goalMet }),
|
|
192
|
+
},
|
|
178
193
|
plan,
|
|
179
194
|
driverName: built.name,
|
|
180
195
|
...reconciled,
|
|
181
196
|
unverifiedFlows,
|
|
182
197
|
goals,
|
|
198
|
+
...(0 === graded.disparity.length ? {} : { disparity: graded.disparity }),
|
|
183
199
|
...(runId === undefined ? {} : { runIds: [runId] }),
|
|
200
|
+
...runUrlFor(deps, options.sessionId, runId),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/** The stop and the words of whoever started the drive, for `runHarness`. */
|
|
204
|
+
export function steering(options) {
|
|
205
|
+
return {
|
|
206
|
+
...(options.stopped === undefined ? {} : { stopped: options.stopped }),
|
|
207
|
+
...(options.inbox === undefined ? {} : { inbox: options.inbox }),
|
|
184
208
|
};
|
|
185
209
|
}
|
|
186
210
|
/** A line in the HUD's Agent Log for the person watching; nobody watching is not an error. */
|
|
187
211
|
export function narrator(deps, options) {
|
|
188
|
-
return (text) => {
|
|
212
|
+
return (text, summary = false) => {
|
|
213
|
+
// The drive's poll answers with its latest line, whether or not a tab is watching.
|
|
214
|
+
if (options.harnessId !== undefined)
|
|
215
|
+
noteDriveLine(options.harnessId, text);
|
|
189
216
|
try {
|
|
190
|
-
|
|
217
|
+
// Filed in the HUD's Harness log; its start and end lines in the Agent Log too.
|
|
218
|
+
deps.sessions
|
|
219
|
+
.resolve(options.sessionId)
|
|
220
|
+
.pushNarration(text, true, { harness: true, summary });
|
|
191
221
|
}
|
|
192
222
|
catch {
|
|
193
223
|
/* nobody is watching: the drive still runs */
|
|
194
224
|
}
|
|
195
225
|
};
|
|
196
226
|
}
|
|
197
|
-
/**
|
|
227
|
+
/** The plan's page on the dashboard, where it is edited and run again; nothing when unlinked. */
|
|
228
|
+
function planUrlFor(deps, sessionId, planId) {
|
|
229
|
+
if (planId === undefined)
|
|
230
|
+
return {};
|
|
231
|
+
try {
|
|
232
|
+
const root = sessionRoot(deps, sessionId);
|
|
233
|
+
const dashboard = readDashboardUrl(root);
|
|
234
|
+
return dashboard === undefined
|
|
235
|
+
? {}
|
|
236
|
+
: {
|
|
237
|
+
planUrl: dashboardPlanUrl({
|
|
238
|
+
dashboardUrl: dashboard,
|
|
239
|
+
planId,
|
|
240
|
+
projectId: readLinkedProjectId(root),
|
|
241
|
+
}),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return {};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/** The run's page on the dashboard, when the tab's project is linked; nothing when it is not. */
|
|
249
|
+
function runUrlFor(deps, sessionId, runId) {
|
|
250
|
+
if (runId === undefined)
|
|
251
|
+
return {};
|
|
252
|
+
try {
|
|
253
|
+
const dashboard = readDashboardUrl(sessionRoot(deps, sessionId));
|
|
254
|
+
return dashboard === undefined ? {} : { runUrl: dashboardRunUrl(dashboard, runId) };
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return {}; // no tab, no project: the run is still reported, without a link
|
|
258
|
+
}
|
|
259
|
+
}
|
|
198
260
|
export async function productRules(deps, sessionId) {
|
|
199
261
|
try {
|
|
200
262
|
return (await allSessionIntents(deps, sessionId)).map((intent) => intent.statement);
|
|
@@ -293,69 +355,30 @@ export function reconcileFlows(before, after, toolCalls) {
|
|
|
293
355
|
return 'string' === typeof flowName ? flowName : undefined;
|
|
294
356
|
})
|
|
295
357
|
.filter((name) => name !== undefined && present.has(name));
|
|
358
|
+
// Only what this drive's own saves wrote: a before/after diff of the project's flows claimed the
|
|
359
|
+
// flows other agents saved in the same project at the same time.
|
|
296
360
|
return {
|
|
297
|
-
savedFlows:
|
|
361
|
+
savedFlows: [...new Set(claimed.filter((name) => !before.has(name)))],
|
|
298
362
|
rewroteFlows: [...new Set(claimed.filter((name) => before.has(name)))],
|
|
299
363
|
};
|
|
300
364
|
}
|
|
301
365
|
/**
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
* turning the harness OFF changed a value in a database and nothing else. A control that does not
|
|
306
|
-
* control anything is worse than no control: somebody turns it off, watches Reticle drive their app
|
|
307
|
-
* anyway, and now correctly distrusts every other switch in the product.
|
|
308
|
-
*
|
|
309
|
-
* Absent means ON. The platform's own default is on, and a machine that cannot reach the platform —
|
|
310
|
-
* offline, CI, no link — must not silently lose a feature it was never told to stop using.
|
|
311
|
-
*/
|
|
312
|
-
export const MSG_HARNESS_DISABLED = 'Autonomous driving is turned OFF for this project. Turn it back on in the Reticle dashboard ' +
|
|
313
|
-
'(Settings → Verification model), or drive the app yourself through the MCP tools.';
|
|
314
|
-
/**
|
|
315
|
-
* The other reason a drive can be refused, and it is NOT the same reason.
|
|
316
|
-
*
|
|
317
|
-
* A drive through the platform spends Reticle's model budget, bounded by the workspace's monthly
|
|
318
|
-
* Harness credits. The platform answers this only when something other than the switch stops it.
|
|
366
|
+
* Why a drive must not be replayed into a verdict, or undefined when it may. A drive the platform
|
|
367
|
+
* cut off (credits gone: 402 needs_card) had saved one partial flow, and replaying it printed PASS
|
|
368
|
+
* with no word about the credits. The one test both CLI explore paths answer through.
|
|
319
369
|
*/
|
|
320
|
-
export
|
|
321
|
-
|
|
322
|
-
/** The platform could not be asked, and the drive would spend Reticle's budget without its yes. */
|
|
323
|
-
export const MSG_HARNESS_UNCONFIRMED = 'Could not confirm Harness access with the Reticle platform, so the drive did not start. Try ' +
|
|
324
|
-
'again in a moment.';
|
|
325
|
-
/** One read, however many questions are asked of the answer. */
|
|
326
|
-
function platformConfig(env, options) {
|
|
327
|
-
return options.configFetch === undefined
|
|
328
|
-
? fetchPlatformConfig(env)
|
|
329
|
-
: fetchPlatformConfig(env, options.configFetch);
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* The reason this drive must not start, or `undefined` to go ahead.
|
|
333
|
-
*
|
|
334
|
-
* A drive on somebody's OWN model key never waits on the platform beyond the off switch: their key,
|
|
335
|
-
* their spend. A drive through the platform proxy bills Reticle, and that one needs a confirmed yes
|
|
336
|
-
* — enabled, entitled, and a model ready. It used to fail open: `fetchPlatformConfig` answers
|
|
337
|
-
* `undefined` on a network error, a non-2xx, a body that does not parse, or a two-second timeout,
|
|
338
|
-
* and all four read as "carry on", so a slow second on a settings endpoint let an unentitled
|
|
339
|
-
* workspace drive on Reticle's budget. Now the same silence refuses with a message that says to
|
|
340
|
-
* retry or bring a key. Fields an older platform omits still default to yes inside
|
|
341
|
-
* `fetchPlatformConfig`; only an answer that never arrived is a no.
|
|
342
|
-
*/
|
|
343
|
-
export async function refusedByPlatform(env, options) {
|
|
344
|
-
if (true === options.skipPlatformConfig)
|
|
370
|
+
export function cutOffReason(drive) {
|
|
371
|
+
if (StopReason.BROKEN !== drive.stopReason && StopReason.STOPPED !== drive.stopReason)
|
|
345
372
|
return undefined;
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return MSG_HARNESS_UNCONFIRMED;
|
|
353
|
-
if (!config.harnessEnabled)
|
|
354
|
-
return MSG_HARNESS_DISABLED;
|
|
355
|
-
if (!config.harnessEntitled)
|
|
356
|
-
return MSG_HARNESS_UNCLAIMED;
|
|
357
|
-
return undefined;
|
|
373
|
+
const why = 'string' === typeof drive.error && 0 < drive.error.length
|
|
374
|
+
? drive.error
|
|
375
|
+
: StopReason.STOPPED === drive.stopReason
|
|
376
|
+
? 'autonomous driving was switched off.'
|
|
377
|
+
: 'the drive broke.';
|
|
378
|
+
return `The drive stopped before it finished: ${why} Nothing was proved; what it saved stays, and the next run replays it.`;
|
|
358
379
|
}
|
|
380
|
+
/** The Agent Log's last line for a drive the platform cut off: its reason, and that it proved nothing. */
|
|
381
|
+
export const msgDriveCutOff = (error) => `Harness stopped before it finished, so nothing is proved: ${error ?? 'the drive broke.'}`;
|
|
359
382
|
/**
|
|
360
383
|
* Close and save whatever recording the drive left open.
|
|
361
384
|
*
|
|
@@ -374,25 +397,28 @@ export async function refusedByPlatform(env, options) {
|
|
|
374
397
|
* It used to be "Autonomous drive of X, banked after the run ended" whatever the caller asked for,
|
|
375
398
|
* so a replay could never say which journey the flow was meant to prove.
|
|
376
399
|
*/
|
|
377
|
-
export function bankedIntent(persona, open
|
|
378
|
-
|
|
400
|
+
export function bankedIntent(persona, open,
|
|
401
|
+
/** The journey the drive was for, when no persona was named. */
|
|
402
|
+
journey) {
|
|
403
|
+
const named = (persona ?? journey)?.trim();
|
|
379
404
|
return named !== undefined && 0 < named.length
|
|
380
405
|
? named
|
|
381
|
-
: `
|
|
406
|
+
: `Exploring the app, recorded as ${open} and saved after the run ended.`;
|
|
382
407
|
}
|
|
383
|
-
export async function bankOpenRecording(toolset, drive, persona) {
|
|
408
|
+
export async function bankOpenRecording(toolset, drive, persona, journey) {
|
|
384
409
|
const open = openRecordingName(drive.toolCalls);
|
|
385
410
|
if (open === undefined)
|
|
386
|
-
return;
|
|
411
|
+
return [];
|
|
412
|
+
const args = { flowName: open, intent: bankedIntent(persona, open, journey) };
|
|
387
413
|
try {
|
|
388
414
|
await toolset.invoke(ReticleTool.RECORD, { action: 'stop', recordingName: open });
|
|
389
|
-
await toolset.invoke(ReticleTool.FLOW_SAVE,
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
});
|
|
415
|
+
const result = await toolset.invoke(ReticleTool.FLOW_SAVE, args);
|
|
416
|
+
// Returned so the save is this drive's own, as a save the model made is.
|
|
417
|
+
return [{ id: 'bank', name: ReticleTool.FLOW_SAVE, args, result, isError: false }];
|
|
393
418
|
}
|
|
394
419
|
catch {
|
|
395
420
|
/* last chance, not a checkpoint */
|
|
421
|
+
return [];
|
|
396
422
|
}
|
|
397
423
|
}
|
|
398
424
|
/** The recording started and never stopped, if there is one. Exported because it is the decision. */
|
|
@@ -458,7 +484,9 @@ export function pinned(options) {
|
|
|
458
484
|
*/
|
|
459
485
|
export function buildDriver(env, maxSteps, plan, requested, persona,
|
|
460
486
|
/** A goal driven with no persona: it names the drive's flows as a persona would. */
|
|
461
|
-
journey
|
|
487
|
+
journey,
|
|
488
|
+
/** The survey of the app, which the platform's engine looks goals up in. */
|
|
489
|
+
siteMap) {
|
|
462
490
|
if (requested !== undefined && SERVER_DRIVER !== requested)
|
|
463
491
|
throw new Error(msgUnknownDriver(requested));
|
|
464
492
|
const platform = serverOptionsFromEnv(env);
|
|
@@ -473,6 +501,9 @@ journey) {
|
|
|
473
501
|
planSteps: plan.steps,
|
|
474
502
|
vocabulary: plan.vocabulary,
|
|
475
503
|
maxSteps,
|
|
504
|
+
...(siteMap === undefined ? {} : { siteMap: mapForPlatform(siteMap) }),
|
|
505
|
+
// Secret fields fill from the drive's own env: a persona's credentials ride in it.
|
|
506
|
+
env,
|
|
476
507
|
}),
|
|
477
508
|
name: SERVER_DRIVER,
|
|
478
509
|
};
|