@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,7 +10,7 @@
|
|
|
10
10
|
* the person can fix in ten seconds (open the app), and leaving it unclaimed lets the chat tell them
|
|
11
11
|
* exactly that. One drive at a time: a second request waits for the first to finish.
|
|
12
12
|
*/
|
|
13
|
-
import { DriveMode, DriveTarget, LinkPath, PLATFORM_LINK_VERSION, PresenterTone, TOOL_SESSION_LIMITS, parseDriveSpec, parseToolSessionReply, sessionAskRetryable, } from '@reticlehq/core';
|
|
13
|
+
import { DriveMode, DriveTarget, LinkPath, PLATFORM_LINK_VERSION, PresenterTone, RunFlowStatus, TOOL_SESSION_LIMITS, driveFlowStatus, parseDriveSpec, parseToolSessionReply, sessionAskRetryable, } from '@reticlehq/core';
|
|
14
14
|
import { serverOptionsFromEnv } from './server-driver.js';
|
|
15
15
|
/**
|
|
16
16
|
* How often to ask while an app is connected.
|
|
@@ -141,7 +141,7 @@ export function startRemoteDrives(deps) {
|
|
|
141
141
|
let outcome;
|
|
142
142
|
let framesSent = 0;
|
|
143
143
|
try {
|
|
144
|
-
outcome = await deps.drive(drive.goal, sessionId);
|
|
144
|
+
outcome = await deps.drive(drive.goal, sessionId, parsed.spec);
|
|
145
145
|
}
|
|
146
146
|
catch (error) {
|
|
147
147
|
outcome = { ok: false, summary: error instanceof Error ? error.message : String(error) };
|
|
@@ -288,14 +288,23 @@ export const NO_OWN_TAB = "No tab of this project is connected to Reticle on thi
|
|
|
288
288
|
* daemon serves every project on the machine but polls with ONE credential, so without this a
|
|
289
289
|
* request made in project A drove project B's tab and sent pictures of it to A's chat.
|
|
290
290
|
*/
|
|
291
|
-
export async function pickOwnDriveSession(tabs, goal, apiKey, keyOf
|
|
291
|
+
export async function pickOwnDriveSession(tabs, goal, apiKey, keyOf,
|
|
292
|
+
/**
|
|
293
|
+
* Open the project's app when none of its tabs is connected, and the session it opened. A
|
|
294
|
+
* dashboard Re-verify with the dev server up and no tab open was answered "Open this project's
|
|
295
|
+
* app, then ask again" by a daemon that knew the app's address.
|
|
296
|
+
*/
|
|
297
|
+
reopen) {
|
|
292
298
|
const own = [];
|
|
293
299
|
for (const tab of tabs) {
|
|
294
300
|
const key = await keyOf(tab.sessionId).catch(() => undefined);
|
|
295
301
|
if (key === apiKey)
|
|
296
302
|
own.push(tab);
|
|
297
303
|
}
|
|
298
|
-
|
|
304
|
+
const picked = pickDriveSession(own, goal);
|
|
305
|
+
if (picked !== undefined)
|
|
306
|
+
return picked;
|
|
307
|
+
return (await reopen?.().catch(() => undefined)) ?? null;
|
|
299
308
|
}
|
|
300
309
|
/** The address of an http(s) URL, `host:port`, for matching a tab to the app a request names. */
|
|
301
310
|
const hostOf = (url) => {
|
|
@@ -341,10 +350,14 @@ export function pickDriveSession(tabs, goal) {
|
|
|
341
350
|
export function driveVerdict(out) {
|
|
342
351
|
if (out.error !== undefined)
|
|
343
352
|
return 'unknown';
|
|
344
|
-
// A
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
// A check that came back "no" is a failed drive whatever else held. A goal the model judged unmet
|
|
354
|
+
// is its opinion, not evidence: with no check against it the drive is not proved, never failed.
|
|
355
|
+
const graded = driveFlowStatus({
|
|
356
|
+
held: out.checks?.held ?? 0,
|
|
357
|
+
failed: out.checks?.failed ?? 0,
|
|
358
|
+
goalMet: out.goalMet,
|
|
359
|
+
});
|
|
360
|
+
if (RunFlowStatus.FAIL === graded)
|
|
348
361
|
return 'no';
|
|
349
362
|
// The quoted texts are looked for on the page the drive ENDED on. None there refutes the goal;
|
|
350
363
|
// some missing does not, because a goal that quotes where it starts ("from "Count is 0" to
|
|
@@ -355,7 +368,7 @@ export function driveVerdict(out) {
|
|
|
355
368
|
if (0 < goals.length && !goals.some((g) => 'yes' === g.verified))
|
|
356
369
|
return 'unknown';
|
|
357
370
|
// A yes needs a check that held behind it: the model saying the goal was met is not evidence.
|
|
358
|
-
if (!out.proved ||
|
|
371
|
+
if (!out.proved || RunFlowStatus.PASS !== graded)
|
|
359
372
|
return 'unknown';
|
|
360
373
|
if (true === out.goalMet)
|
|
361
374
|
return 'yes';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ScriptStatus, type FlowFile, type FlowStep, type PlanView } from '@reticlehq/core';
|
|
2
|
-
import { type DriveScript } from '@reticlehq/core/artifacts';
|
|
2
|
+
import { type JourneyBy, type DriveScript } from '@reticlehq/core/artifacts';
|
|
3
|
+
import { type PlatformCredential } from './server-driver.js';
|
|
3
4
|
type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
|
|
4
5
|
export interface ScriptAsk {
|
|
5
6
|
about: string;
|
|
@@ -25,24 +26,69 @@ export declare function personasIn(flows: readonly FlowFile[]): {
|
|
|
25
26
|
}[];
|
|
26
27
|
/** Equal for two steps that drive the same control the same way; the values never leave. */
|
|
27
28
|
export declare function stepHash(step: FlowStep): string;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}, ask: ScriptAsk, doFetch?: FetchLike): Promise<{
|
|
29
|
+
/** What a run that names nothing asks for: the whole app, which the platform splits into journeys. */
|
|
30
|
+
export declare const WHOLE_APP_REQUEST = "Test my app: plan the journeys this app offers and drive them";
|
|
31
|
+
export declare function proposeScript(platform: PlatformCredential, ask: ScriptAsk, doFetch?: FetchLike): Promise<{
|
|
32
32
|
script: DriveScript;
|
|
33
33
|
planId?: string;
|
|
34
|
+
creditsSpent?: number;
|
|
35
|
+
} | {
|
|
36
|
+
refused: string;
|
|
34
37
|
} | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* A plan the platform saved, as it stands now: somebody may have edited it on the dashboard since it
|
|
40
|
+
* last ran. Checked like a proposed one; `undefined` when it cannot be read or cannot run.
|
|
41
|
+
*/
|
|
42
|
+
export declare function fetchScript(platform: PlatformCredential, planId: string, doFetch?: FetchLike): Promise<DriveScript | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* A rerun replays what passed before. A journey the plan's history shows passing, with the flows it
|
|
45
|
+
* saved, replays those flows; the model drives its goal only when they decide nothing (`fallback`),
|
|
46
|
+
* and a replay that fails is a regression, never re-driven. A rerun re-drove a journey that had
|
|
47
|
+
* passed, at a model's cost, and failed it twice. Journeys that already replay are left as planned.
|
|
48
|
+
*/
|
|
49
|
+
export declare function replayFirst(script: DriveScript, plan: unknown): DriveScript;
|
|
35
50
|
/** One journey's outcome, as the platform keeps it beside the plan. */
|
|
36
51
|
export interface JourneyResult {
|
|
37
52
|
id: string;
|
|
38
53
|
title: string;
|
|
39
54
|
status: ScriptStatus;
|
|
55
|
+
/** What happened, in a line: why a journey that never ran was blocked. */
|
|
56
|
+
line?: string;
|
|
57
|
+
/** Replayed with no model, or driven by it. Absent for a journey that never ran. */
|
|
58
|
+
by?: JourneyBy;
|
|
59
|
+
/** Model tokens it spent; 0 for a pure replay. */
|
|
60
|
+
tokens?: number;
|
|
61
|
+
/** Credits its model drives spent, when the platform said. */
|
|
62
|
+
credits?: number;
|
|
63
|
+
/** The flows it replayed or recorded: the platform links the journey to these. */
|
|
64
|
+
flows?: string[];
|
|
65
|
+
/** Whether the goals the run was asked were reached, once graded. Absent when none were judged. */
|
|
66
|
+
goalMet?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/** How one journey that ran was answered, from the run (`JourneyRun`). */
|
|
69
|
+
export interface JourneyAnswer {
|
|
70
|
+
id: string;
|
|
71
|
+
by?: JourneyBy;
|
|
72
|
+
tokens: number;
|
|
73
|
+
credits?: number;
|
|
74
|
+
flows: string[];
|
|
40
75
|
}
|
|
41
|
-
/**
|
|
42
|
-
|
|
76
|
+
/**
|
|
77
|
+
* The plan only replays saved flows: no step anywhere, branch cases included, hands the model
|
|
78
|
+
* anything to do. Such a run spends no model turns, so the gates that guard a model drive do not
|
|
79
|
+
* apply to it.
|
|
80
|
+
*/
|
|
81
|
+
export declare function drivesNothing(script: DriveScript): boolean;
|
|
82
|
+
/** The saved plan reads as one that only replays saved flows. Unreadable: not known to, so false. */
|
|
83
|
+
export declare function savedPlanDrivesNothing(platform: PlatformCredential, planId: string, doFetch?: FetchLike): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* A saved plan the run was refused for, or that broke before any journey ran, told to the plan
|
|
86
|
+
* anyway: every journey blocked, with the reason, so the plan's history records the attempt instead
|
|
87
|
+
* of showing nothing. Best-effort, like every report to the plan.
|
|
88
|
+
*/
|
|
89
|
+
export declare function reportPlanBlocked(platform: PlatformCredential, planId: string, reason: string, doFetch?: FetchLike): Promise<boolean>;
|
|
90
|
+
/** How each journey of a run plan went, once each, matched to how it was answered by id. */
|
|
91
|
+
export declare function journeyResults(view: PlanView, answers?: readonly JourneyAnswer[]): JourneyResult[];
|
|
43
92
|
/** Tell the platform how its plan went. A failure costs the next plan its memory, never this run. */
|
|
44
|
-
export declare function reportPlanResults(platform:
|
|
45
|
-
url: string;
|
|
46
|
-
apiKey: string;
|
|
47
|
-
}, planId: string, results: readonly JourneyResult[], doFetch?: FetchLike): Promise<boolean>;
|
|
93
|
+
export declare function reportPlanResults(platform: PlatformCredential, planId: string, results: readonly JourneyResult[], runIds?: readonly string[], doFetch?: FetchLike): Promise<boolean>;
|
|
48
94
|
export {};
|
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
* The platform keeps every plan under an id, and is told afterwards how each journey went: that is
|
|
13
13
|
* what the next plan learns from (what failed is driven first).
|
|
14
14
|
*/
|
|
15
|
+
import { readRefusal, refusalSentence } from './refusal.js';
|
|
15
16
|
import { createHash } from 'node:crypto';
|
|
16
|
-
import { ScriptStatus, StepEffect, } from '@reticlehq/core';
|
|
17
|
-
import { DriveScriptSchema, checkScript } from '@reticlehq/core/artifacts';
|
|
17
|
+
import { ScriptStatus, asRecord, asString, StepEffect, } from '@reticlehq/core';
|
|
18
|
+
import { DriveScriptSchema, ScriptStepKind, checkScript, } from '@reticlehq/core/artifacts';
|
|
19
|
+
import { platformHeaders } from './server-driver.js';
|
|
18
20
|
const SCRIPTS_PATH = '/v1/harness/scripts';
|
|
19
21
|
const RESULTS_PATH = '/results';
|
|
20
22
|
const TIMEOUT_MS = 90_000;
|
|
@@ -50,11 +52,21 @@ export function stepHash(step) {
|
|
|
50
52
|
.digest('hex')
|
|
51
53
|
.slice(0, STEP_HASH_CHARS);
|
|
52
54
|
}
|
|
55
|
+
/** What a run that names nothing asks for: the whole app, which the platform splits into journeys. */
|
|
56
|
+
export const WHOLE_APP_REQUEST = 'Test my app: plan the journeys this app offers and drive them';
|
|
57
|
+
/**
|
|
58
|
+
* The goals a plan request carries. The platform refuses one that names nothing — no journey, no
|
|
59
|
+
* persona, nothing to replay — and no longer invents personas, so such a run asks for the whole app.
|
|
60
|
+
*/
|
|
61
|
+
function goalsToAsk(ask) {
|
|
62
|
+
const named = 0 < ask.goals.length || 0 < ask.replay.length || 0 < (ask.personas?.length ?? 0);
|
|
63
|
+
return named ? ask.goals : [WHOLE_APP_REQUEST];
|
|
64
|
+
}
|
|
53
65
|
export async function proposeScript(platform, ask, doFetch = (url, init) => fetch(url, init)) {
|
|
54
66
|
try {
|
|
55
67
|
const res = await doFetch(`${platform.url}${SCRIPTS_PATH}`, {
|
|
56
68
|
method: 'POST',
|
|
57
|
-
headers:
|
|
69
|
+
headers: platformHeaders(platform),
|
|
58
70
|
body: JSON.stringify({
|
|
59
71
|
about: ask.about,
|
|
60
72
|
flows: ask.flows.map((flow) => ({
|
|
@@ -67,7 +79,7 @@ export async function proposeScript(platform, ask, doFetch = (url, init) => fetc
|
|
|
67
79
|
checks: flow.steps.filter((step) => step.expect !== undefined || true === step.steps?.some((s) => s.expect !== undefined)).length,
|
|
68
80
|
})),
|
|
69
81
|
replay: ask.replay,
|
|
70
|
-
goals: ask
|
|
82
|
+
goals: goalsToAsk(ask),
|
|
71
83
|
gaps: ask.gaps,
|
|
72
84
|
rules: ask.rules,
|
|
73
85
|
...(ask.personas === undefined || 0 === ask.personas.length
|
|
@@ -76,8 +88,9 @@ export async function proposeScript(platform, ask, doFetch = (url, init) => fetc
|
|
|
76
88
|
}),
|
|
77
89
|
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
78
90
|
});
|
|
91
|
+
// The platform's own reason, so a drive that goes on without a plan can say why.
|
|
79
92
|
if (!res.ok)
|
|
80
|
-
return
|
|
93
|
+
return { refused: await refusalOf(res) };
|
|
81
94
|
const body = (await res.json());
|
|
82
95
|
const parsed = DriveScriptSchema.safeParse(body.script);
|
|
83
96
|
if (!parsed.success || 0 < checkScript(parsed.data).length)
|
|
@@ -85,39 +98,158 @@ export async function proposeScript(platform, ask, doFetch = (url, init) => fetc
|
|
|
85
98
|
return {
|
|
86
99
|
script: parsed.data,
|
|
87
100
|
...('string' === typeof body.planId ? { planId: body.planId } : {}),
|
|
101
|
+
// What writing the plan cost: part of the run's spend, not free.
|
|
102
|
+
...('number' === typeof body.creditsSpent ? { creditsSpent: body.creditsSpent } : {}),
|
|
88
103
|
};
|
|
89
104
|
}
|
|
90
105
|
catch {
|
|
91
106
|
return undefined;
|
|
92
107
|
}
|
|
93
108
|
}
|
|
109
|
+
async function refusalOf(res) {
|
|
110
|
+
// The code picks the lead sentence (refusal.ts), so what this says never rests on the wording.
|
|
111
|
+
return refusalSentence(readRefusal(await res.text().catch(() => '')), res.status);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A plan the platform saved, as it stands now: somebody may have edited it on the dashboard since it
|
|
115
|
+
* last ran. Checked like a proposed one; `undefined` when it cannot be read or cannot run.
|
|
116
|
+
*/
|
|
117
|
+
export async function fetchScript(platform, planId, doFetch = (url, init) => fetch(url, init)) {
|
|
118
|
+
try {
|
|
119
|
+
const res = await doFetch(`${platform.url}${SCRIPTS_PATH}/${encodeURIComponent(planId)}`, {
|
|
120
|
+
method: 'GET',
|
|
121
|
+
headers: platformHeaders(platform),
|
|
122
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
123
|
+
});
|
|
124
|
+
if (!res.ok)
|
|
125
|
+
return undefined;
|
|
126
|
+
const plan = (await res.json());
|
|
127
|
+
const parsed = DriveScriptSchema.safeParse(plan.script);
|
|
128
|
+
return parsed.success && 0 === checkScript(parsed.data).length
|
|
129
|
+
? replayFirst(parsed.data, plan)
|
|
130
|
+
: undefined;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* A rerun replays what passed before. A journey the plan's history shows passing, with the flows it
|
|
138
|
+
* saved, replays those flows; the model drives its goal only when they decide nothing (`fallback`),
|
|
139
|
+
* and a replay that fails is a regression, never re-driven. A rerun re-drove a journey that had
|
|
140
|
+
* passed, at a model's cost, and failed it twice. Journeys that already replay are left as planned.
|
|
141
|
+
*/
|
|
142
|
+
export function replayFirst(script, plan) {
|
|
143
|
+
const passedFlows = new Map();
|
|
144
|
+
const record = asRecord(plan);
|
|
145
|
+
const runs = Array.isArray(record['runs']) ? record['runs'] : [];
|
|
146
|
+
const batches = [...runs.map((run) => asRecord(run)['results']), record['results']];
|
|
147
|
+
for (const batch of batches) {
|
|
148
|
+
if (!Array.isArray(batch))
|
|
149
|
+
continue;
|
|
150
|
+
for (const raw of batch) {
|
|
151
|
+
const result = asRecord(raw);
|
|
152
|
+
const id = asString(result['id']);
|
|
153
|
+
const flows = Array.isArray(result['flows'])
|
|
154
|
+
? result['flows'].filter((f) => 'string' === typeof f && 0 < f.length)
|
|
155
|
+
: [];
|
|
156
|
+
if (id !== undefined && ScriptStatus.PASSED === result['status'] && 0 < flows.length)
|
|
157
|
+
passedFlows.set(id, flows);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (0 === passedFlows.size)
|
|
161
|
+
return script;
|
|
162
|
+
return {
|
|
163
|
+
...script,
|
|
164
|
+
journeys: script.journeys.map((journey) => {
|
|
165
|
+
const flows = passedFlows.get(journey.id);
|
|
166
|
+
const goals = journey.steps.map((step) => ScriptStepKind.ACT === step.kind ? step.goal : undefined);
|
|
167
|
+
if (flows === undefined || journey.fallback !== undefined || goals.includes(undefined))
|
|
168
|
+
return journey;
|
|
169
|
+
return {
|
|
170
|
+
...journey,
|
|
171
|
+
steps: flows.map((flow) => ({ kind: ScriptStepKind.REPLAY, flow })),
|
|
172
|
+
fallback: { goal: goals.join('; ') },
|
|
173
|
+
};
|
|
174
|
+
}),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* The plan only replays saved flows: no step anywhere, branch cases included, hands the model
|
|
179
|
+
* anything to do. Such a run spends no model turns, so the gates that guard a model drive do not
|
|
180
|
+
* apply to it.
|
|
181
|
+
*/
|
|
182
|
+
export function drivesNothing(script) {
|
|
183
|
+
return script.journeys.every((journey) => journey.steps.every((step) => ScriptStepKind.BRANCH === step.kind
|
|
184
|
+
? step.cases.every((c) => c.steps.every((leaf) => ScriptStepKind.ACT !== leaf.kind))
|
|
185
|
+
: ScriptStepKind.ACT !== step.kind));
|
|
186
|
+
}
|
|
187
|
+
/** The saved plan reads as one that only replays saved flows. Unreadable: not known to, so false. */
|
|
188
|
+
export async function savedPlanDrivesNothing(platform, planId, doFetch = (url, init) => fetch(url, init)) {
|
|
189
|
+
const script = await fetchScript(platform, planId, doFetch);
|
|
190
|
+
return script !== undefined && drivesNothing(script);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* A saved plan the run was refused for, or that broke before any journey ran, told to the plan
|
|
194
|
+
* anyway: every journey blocked, with the reason, so the plan's history records the attempt instead
|
|
195
|
+
* of showing nothing. Best-effort, like every report to the plan.
|
|
196
|
+
*/
|
|
197
|
+
export async function reportPlanBlocked(platform, planId, reason, doFetch = (url, init) => fetch(url, init)) {
|
|
198
|
+
const script = await fetchScript(platform, planId, doFetch);
|
|
199
|
+
const results = (script?.journeys ?? []).map((journey) => ({
|
|
200
|
+
id: journey.id,
|
|
201
|
+
title: journey.title,
|
|
202
|
+
status: ScriptStatus.BLOCKED,
|
|
203
|
+
line: reason,
|
|
204
|
+
}));
|
|
205
|
+
return reportPlanResults(platform, planId, results, [], doFetch);
|
|
206
|
+
}
|
|
94
207
|
/** Worst first: a journey that ran in two lanes reports the worse of the two. */
|
|
95
208
|
const SEVERITY = [
|
|
96
209
|
ScriptStatus.FAILED,
|
|
97
210
|
ScriptStatus.BLOCKED,
|
|
98
211
|
ScriptStatus.RUNNING,
|
|
99
212
|
ScriptStatus.PENDING,
|
|
213
|
+
ScriptStatus.UNDECIDED,
|
|
100
214
|
ScriptStatus.NOT_TAKEN,
|
|
101
215
|
ScriptStatus.PASSED,
|
|
102
216
|
];
|
|
103
|
-
/** How each journey of a run plan went, once each. */
|
|
104
|
-
export function journeyResults(view) {
|
|
217
|
+
/** How each journey of a run plan went, once each, matched to how it was answered by id. */
|
|
218
|
+
export function journeyResults(view, answers = []) {
|
|
105
219
|
const byId = new Map();
|
|
106
220
|
for (const lane of view.lanes)
|
|
107
221
|
for (const card of lane.journeys) {
|
|
108
222
|
const seen = byId.get(card.id);
|
|
109
223
|
if (seen === undefined || SEVERITY.indexOf(card.status) < SEVERITY.indexOf(seen.status))
|
|
110
|
-
byId.set(card.id, {
|
|
224
|
+
byId.set(card.id, {
|
|
225
|
+
id: card.id,
|
|
226
|
+
title: card.title,
|
|
227
|
+
status: card.status,
|
|
228
|
+
...(card.why === undefined ? {} : { line: card.why }),
|
|
229
|
+
});
|
|
111
230
|
}
|
|
112
|
-
|
|
231
|
+
const answered = new Map(answers.map((a) => [a.id, a]));
|
|
232
|
+
return [...byId.values()].map((result) => {
|
|
233
|
+
const answer = answered.get(result.id);
|
|
234
|
+
if (answer === undefined)
|
|
235
|
+
return result;
|
|
236
|
+
return {
|
|
237
|
+
...result,
|
|
238
|
+
...(answer.by === undefined ? {} : { by: answer.by }),
|
|
239
|
+
tokens: answer.tokens,
|
|
240
|
+
...(answer.credits === undefined ? {} : { credits: answer.credits }),
|
|
241
|
+
...(0 === answer.flows.length ? {} : { flows: [...answer.flows] }),
|
|
242
|
+
};
|
|
243
|
+
});
|
|
113
244
|
}
|
|
114
245
|
/** Tell the platform how its plan went. A failure costs the next plan its memory, never this run. */
|
|
115
|
-
export async function reportPlanResults(platform, planId, results, doFetch = (url, init) => fetch(url, init)) {
|
|
246
|
+
export async function reportPlanResults(platform, planId, results, runIds = [], doFetch = (url, init) => fetch(url, init)) {
|
|
116
247
|
try {
|
|
117
248
|
const res = await doFetch(`${platform.url}${SCRIPTS_PATH}/${encodeURIComponent(planId)}${RESULTS_PATH}`, {
|
|
118
249
|
method: 'POST',
|
|
119
|
-
headers:
|
|
120
|
-
|
|
250
|
+
headers: platformHeaders(platform),
|
|
251
|
+
// The runs it made, so the plan's history opens each one.
|
|
252
|
+
body: JSON.stringify({ results, ...(0 === runIds.length ? {} : { runIds }) }),
|
|
121
253
|
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
122
254
|
});
|
|
123
255
|
return res.ok;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ModelDriver } from '../harness.js';
|
|
2
|
+
import { DRIVE_HEADER } from '../platform-config.js';
|
|
3
|
+
export { DRIVE_HEADER };
|
|
2
4
|
export declare const SERVER_DRIVER_NAME = "server";
|
|
3
5
|
type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
|
|
4
6
|
export interface ServerDriverOptions {
|
|
@@ -19,16 +21,28 @@ export interface ServerDriverOptions {
|
|
|
19
21
|
}[];
|
|
20
22
|
/** The signal names the app declares, so the engine can claim one by name. */
|
|
21
23
|
vocabulary?: readonly string[];
|
|
24
|
+
/** The survey of the app taken before the drive: where each text and control lives. */
|
|
25
|
+
siteMap?: unknown;
|
|
22
26
|
/** Where secret field values live. Only their NAMES go to the platform. Defaults to `process.env`. */
|
|
23
27
|
env?: Record<string, string | undefined>;
|
|
24
28
|
maxSteps?: number;
|
|
29
|
+
/** The free drive this run is billed to, sent as `DRIVE_HEADER` on every turn. */
|
|
30
|
+
driveId?: string;
|
|
25
31
|
fetch?: FetchLike;
|
|
26
32
|
}
|
|
27
|
-
/**
|
|
28
|
-
export
|
|
33
|
+
/** Where to reach the platform, as which key, and for which free drive when there is one. */
|
|
34
|
+
export interface PlatformCredential {
|
|
29
35
|
url: string;
|
|
30
36
|
apiKey: string;
|
|
31
|
-
|
|
37
|
+
driveId?: string;
|
|
38
|
+
}
|
|
39
|
+
/** The platform's url and this project's key, when the machine is linked. */
|
|
40
|
+
export declare function serverOptionsFromEnv(env: Record<string, string | undefined>): PlatformCredential | undefined;
|
|
41
|
+
/** The headers every Harness call carries: JSON, the key, and the free drive it is billed to. */
|
|
42
|
+
export declare function platformHeaders(platform: {
|
|
43
|
+
apiKey: string;
|
|
44
|
+
driveId?: string | undefined;
|
|
45
|
+
}): Record<string, string>;
|
|
32
46
|
export declare class ServerHarnessError extends Error {
|
|
33
47
|
readonly status: number;
|
|
34
48
|
constructor(message: string, status: number);
|
|
@@ -38,4 +52,3 @@ export declare function serverDriver(options: ServerDriverOptions): ModelDriver;
|
|
|
38
52
|
export declare function secretNames(env: Record<string, string | undefined>): string[];
|
|
39
53
|
/** The call's arguments with every secret placeholder replaced by its value from this machine. */
|
|
40
54
|
export declare function withSecrets(args: Record<string, unknown>, env: Record<string, string | undefined>): Record<string, unknown>;
|
|
41
|
-
export {};
|
|
@@ -10,22 +10,37 @@
|
|
|
10
10
|
* This is the only Harness driver: every decision is the platform's, for a workspace with a plan or
|
|
11
11
|
* trial. A secret field travels by name only, and its value is filled in here before the call runs.
|
|
12
12
|
*/
|
|
13
|
+
import { PlatformRefusalCode, readRefusal, refusalSentence } from './refusal.js';
|
|
13
14
|
import { ReticleEnv, cloudUrlFrom } from '@reticlehq/core';
|
|
14
15
|
import { DriveStoppedError, } from '../harness.js';
|
|
16
|
+
import { DRIVE_HEADER } from '../platform-config.js';
|
|
17
|
+
export { DRIVE_HEADER };
|
|
15
18
|
export const SERVER_DRIVER_NAME = 'server';
|
|
16
19
|
const RUNS_PATH = '/v1/harness/runs';
|
|
17
20
|
const TURN_TIMEOUT_MS = 110_000;
|
|
18
21
|
const RETRIES = 1;
|
|
19
22
|
/** The platform's code for a run whose project had autonomous driving switched off. */
|
|
20
|
-
const HARNESS_OFF = 'harness_off';
|
|
21
23
|
const FINISH = 'finish';
|
|
22
24
|
/** The platform's url and this project's key, when the machine is linked. */
|
|
23
25
|
export function serverOptionsFromEnv(env) {
|
|
24
26
|
const url = cloudUrlFrom(env);
|
|
25
27
|
const apiKey = env[ReticleEnv.API_KEY];
|
|
28
|
+
const driveId = env[ReticleEnv.DRIVE_ID];
|
|
26
29
|
return url === undefined || apiKey === undefined || 0 === apiKey.length
|
|
27
30
|
? undefined
|
|
28
|
-
: {
|
|
31
|
+
: {
|
|
32
|
+
url: url.replace(/\/+$/, ''),
|
|
33
|
+
apiKey,
|
|
34
|
+
...(driveId === undefined || 0 === driveId.length ? {} : { driveId }),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** The headers every Harness call carries: JSON, the key, and the free drive it is billed to. */
|
|
38
|
+
export function platformHeaders(platform) {
|
|
39
|
+
return {
|
|
40
|
+
'content-type': 'application/json',
|
|
41
|
+
authorization: `Bearer ${platform.apiKey}`,
|
|
42
|
+
...(platform.driveId === undefined ? {} : { [DRIVE_HEADER]: platform.driveId }),
|
|
43
|
+
};
|
|
29
44
|
}
|
|
30
45
|
export class ServerHarnessError extends Error {
|
|
31
46
|
status;
|
|
@@ -45,18 +60,16 @@ export function serverDriver(options) {
|
|
|
45
60
|
try {
|
|
46
61
|
const res = await doFetch(`${options.url}${path}`, {
|
|
47
62
|
method: 'POST',
|
|
48
|
-
headers:
|
|
49
|
-
'content-type': 'application/json',
|
|
50
|
-
authorization: `Bearer ${options.apiKey}`,
|
|
51
|
-
},
|
|
63
|
+
headers: platformHeaders(options),
|
|
52
64
|
body: JSON.stringify(body),
|
|
53
65
|
signal: AbortSignal.timeout(TURN_TIMEOUT_MS),
|
|
54
66
|
});
|
|
55
67
|
const text = await res.text();
|
|
56
68
|
if (!res.ok) {
|
|
57
|
-
const
|
|
69
|
+
const refusal = readRefusal(text);
|
|
70
|
+
const message = refusalSentence(refusal, res.status);
|
|
58
71
|
// A person turned it off: the drive ends, and the result says that rather than "broken".
|
|
59
|
-
if (HARNESS_OFF ===
|
|
72
|
+
if (PlatformRefusalCode.HARNESS_OFF === refusal.code)
|
|
60
73
|
throw new DriveStoppedError(message);
|
|
61
74
|
// A refusal is an answer; only a network failure is worth asking again.
|
|
62
75
|
throw new ServerHarnessError(message, res.status);
|
|
@@ -82,6 +95,7 @@ export function serverDriver(options) {
|
|
|
82
95
|
...(options.maxSteps === undefined ? {} : { maxSteps: options.maxSteps }),
|
|
83
96
|
...(options.planSteps === undefined ? {} : { planSteps: options.planSteps }),
|
|
84
97
|
...(options.vocabulary === undefined ? {} : { vocabulary: options.vocabulary }),
|
|
98
|
+
...(options.siteMap === undefined ? {} : { siteMap: options.siteMap }),
|
|
85
99
|
secrets: secretNames(options.env ?? process.env),
|
|
86
100
|
tools: input.tools.filter((t) => FINISH !== t.name).map(toolSpec),
|
|
87
101
|
}));
|
|
@@ -93,9 +107,13 @@ export function serverDriver(options) {
|
|
|
93
107
|
const fresh = input.history.slice(seen);
|
|
94
108
|
seen = input.history.length;
|
|
95
109
|
const outcomes = fresh.flatMap((entry) => 'tool' === entry.role ? entry.outcomes.map(outcomeOf) : []);
|
|
110
|
+
// What somebody said to the drive since the last turn. The opening line is the loop's own and
|
|
111
|
+
// the platform writes its own, so only words that arrived after it travel.
|
|
112
|
+
const say = fresh.flatMap((entry, i) => 'user' === entry.role && (0 < turn || 0 < i) ? [entry.text] : []);
|
|
96
113
|
const reply = (await call(`${RUNS_PATH}/${encodeURIComponent(runId)}/turn`, {
|
|
97
114
|
turn,
|
|
98
115
|
outcomes,
|
|
116
|
+
...(0 === say.length ? {} : { say }),
|
|
99
117
|
}));
|
|
100
118
|
turn = reply.turn + 1;
|
|
101
119
|
// The platform's spend, reported so the drive's cost is visible here as it is for a local one.
|
|
@@ -112,6 +130,9 @@ export function serverDriver(options) {
|
|
|
112
130
|
args: {
|
|
113
131
|
summary: reply.summary ?? reply.text,
|
|
114
132
|
...('boolean' === typeof reply.goalMet ? { goalMet: reply.goalMet } : {}),
|
|
133
|
+
...('number' === typeof reply.creditsSpent
|
|
134
|
+
? { creditsSpent: reply.creditsSpent }
|
|
135
|
+
: {}),
|
|
115
136
|
},
|
|
116
137
|
},
|
|
117
138
|
],
|
|
@@ -133,24 +154,6 @@ function toolSpec(tool) {
|
|
|
133
154
|
function outcomeOf(o) {
|
|
134
155
|
return { id: o.id, name: o.name, result: o.result, isError: o.isError };
|
|
135
156
|
}
|
|
136
|
-
function errorCode(text) {
|
|
137
|
-
try {
|
|
138
|
-
const body = JSON.parse(text);
|
|
139
|
-
return 'string' === typeof body.error?.code ? body.error.code : undefined;
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
function errorMessage(text) {
|
|
146
|
-
try {
|
|
147
|
-
const body = JSON.parse(text);
|
|
148
|
-
return 'string' === typeof body.error?.message ? body.error.message : undefined;
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
157
|
/** The prefix of a variable holding one secret field: `RETICLE_SECRET_AUTH_PASSWORD`. */
|
|
155
158
|
const SECRET_ENV_PREFIX = 'RETICLE_SECRET_';
|
|
156
159
|
/** What the platform types into a field whose secret this machine holds. */
|
|
@@ -16,11 +16,15 @@
|
|
|
16
16
|
* - it never overrides someone who was EXPLICIT. A driver named in the call, or set in the
|
|
17
17
|
* environment, wins over the stored preference. Precedence lives in the caller.
|
|
18
18
|
*/
|
|
19
|
+
import { CreditKind } from '@reticlehq/core';
|
|
20
|
+
import type { Credits } from '@reticlehq/core/hud';
|
|
21
|
+
/** The header naming the free drive a call belongs to. See `ReticleEnv.DRIVE_ID`. */
|
|
22
|
+
export declare const DRIVE_HEADER = "x-reticle-drive";
|
|
19
23
|
/** The subset of the platform's answer the harness acts on. */
|
|
20
24
|
export interface PlatformModelConfig {
|
|
21
25
|
/** `jev` | `anthropic` | `openai`, as the platform spells it. Not validated here. */
|
|
22
26
|
provider: string;
|
|
23
|
-
/** Whether the person
|
|
27
|
+
/** Whether the person switched the Harness on. Off unless the platform says on. */
|
|
24
28
|
harnessEnabled: boolean;
|
|
25
29
|
/**
|
|
26
30
|
* Whether this workspace may drive on OUR model spend — a claimed free period, or a paid plan.
|
|
@@ -40,13 +44,42 @@ export interface PlatformModelConfig {
|
|
|
40
44
|
* not have its silence treated as a refusal.
|
|
41
45
|
*/
|
|
42
46
|
providerReady: boolean;
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Harness credits used and held this 30 days, and when the grant ends (`endsAt`, epoch ms) when
|
|
49
|
+
* the platform says. Absent when the plan is unbounded or the API is older.
|
|
50
|
+
*/
|
|
51
|
+
credits?: Credits & {
|
|
52
|
+
endsAt?: number;
|
|
47
53
|
};
|
|
48
54
|
/** The platform that answered, no trailing slash: where the HUD's settings and plan links go. */
|
|
49
55
|
platformUrl?: string;
|
|
56
|
+
/**
|
|
57
|
+
* The page where credits and the trial are bought (`planUrl`), on the console's origin. The API
|
|
58
|
+
* and the console are different origins on every deployment but a laptop, so a link built from
|
|
59
|
+
* the API's origin 404s. Absent from an older platform.
|
|
60
|
+
*/
|
|
61
|
+
planUrl?: string;
|
|
62
|
+
/** The platform's coverage gate (`harnessUnlocked`, `coverageScore`, `harnessLock`), when it sent one. */
|
|
63
|
+
gate?: PlatformGate;
|
|
64
|
+
/** The plan in force (`plan`), for the HUD's account menu. */
|
|
65
|
+
plan?: PlatformPlan;
|
|
66
|
+
/** Harness runs the platform holds for this project (`harnessRuns.total`). */
|
|
67
|
+
harnessRuns?: number;
|
|
68
|
+
/** Memory entries the platform holds for this project (`memory.entries`). */
|
|
69
|
+
memoryEntries?: number;
|
|
70
|
+
}
|
|
71
|
+
/** The plan as the HUD is pushed it: which grant, and the trial's days and seats when said. */
|
|
72
|
+
export interface PlatformPlan {
|
|
73
|
+
kind: CreditKind;
|
|
74
|
+
daysLeft?: number;
|
|
75
|
+
seats?: number;
|
|
76
|
+
}
|
|
77
|
+
/** The platform's Harness coverage gate, as the HUD is pushed it. */
|
|
78
|
+
export interface PlatformGate {
|
|
79
|
+
unlocked: boolean;
|
|
80
|
+
percent?: number;
|
|
81
|
+
reason?: string;
|
|
82
|
+
prompt?: string;
|
|
50
83
|
}
|
|
51
84
|
/** A GET, narrowed to what this file uses, so a test can answer it without a network. */
|
|
52
85
|
export type ConfigFetch = (url: string, init: {
|