@reticlehq/server 3.5.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/README.md +1 -1
- package/SKILL.md +123 -116
- package/dist/chromium-launch-options.d.ts +3 -1
- package/dist/chromium-launch-options.js +2 -1
- 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 +19 -2
- package/dist/command/cli/adhoc-verdict.js +76 -9
- 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/answers/open-note.d.ts +2 -0
- package/dist/command/cli/answers/open-note.js +22 -0
- 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 +31 -112
- 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 +35 -5
- package/dist/command/cli/cli-verify.js +114 -35
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +192 -341
- 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 +22 -0
- package/dist/command/cli/cloud-login.js +96 -8
- 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/browser/chromium-hint.d.ts +46 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
- 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/drive/drive-attach.d.ts +27 -2
- package/dist/command/cli/drive/drive-attach.js +71 -4
- package/dist/command/cli/drive/drive-command.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +13 -7
- 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 +15 -3
- 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.d.ts +10 -0
- package/dist/command/cli/ports/port-holder.js +25 -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 +35 -12
- 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 -181
- 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 +20 -0
- package/dist/command/cli.js +130 -104
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +23 -1
- package/dist/command/daemon/daemon-resolve.js +79 -9
- package/dist/command/setup/agent-writer.d.ts +1 -1
- package/dist/command/setup/agent-writer.js +3 -2
- 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/connect-lease.d.ts +1 -0
- package/dist/command/setup/bringup/connect-lease.js +1 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
- package/dist/command/setup/bringup/dev-server-wait.js +19 -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 +14 -1
- package/dist/command/setup/init/init-port.js +32 -2
- package/dist/command/setup/init/init-runtime.d.ts +22 -2
- package/dist/command/setup/init/init-runtime.js +114 -38
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +38 -9
- 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 +2 -1
- package/dist/command/setup/run-setup.d.ts +34 -9
- package/dist/command/setup/run-setup.js +65 -51
- package/dist/command/setup/setup-command.d.ts +25 -1
- package/dist/command/setup/setup-command.js +59 -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 +49 -4
- package/dist/features/crawl/crawl-tools.js +4 -0
- package/dist/features/crawl/crawl.d.ts +6 -0
- package/dist/features/crawl/crawl.js +23 -2
- package/dist/features/exhaust/ledger.d.ts +21 -14
- package/dist/features/exhaust/ledger.js +35 -9
- package/dist/features/harness/app-findings.d.ts +2 -0
- package/dist/features/harness/app-findings.js +52 -0
- package/dist/features/harness/drive-report.d.ts +61 -1
- package/dist/features/harness/drive-report.js +394 -26
- 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 +10 -14
- package/dist/features/harness/drivers.js +10 -14
- 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/fill-values.d.ts +3 -73
- package/dist/features/harness/fill-values.js +3 -169
- package/dist/features/harness/goals.d.ts +82 -0
- package/dist/features/harness/goals.js +330 -0
- package/dist/features/harness/harness.d.ts +51 -1
- package/dist/features/harness/harness.js +207 -6
- package/dist/features/harness/platform/drive-target.d.ts +30 -0
- package/dist/features/harness/platform/drive-target.js +81 -0
- package/dist/features/harness/platform/local-apps.d.ts +127 -0
- package/dist/features/harness/platform/local-apps.js +280 -0
- 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 +186 -0
- package/dist/features/harness/platform/remote-drive.js +378 -0
- package/dist/features/harness/platform/script.d.ts +94 -0
- package/dist/features/harness/platform/script.js +260 -0
- package/dist/features/harness/platform/server-driver.d.ts +54 -0
- package/dist/features/harness/platform/server-driver.js +182 -0
- package/dist/features/harness/platform-config.d.ts +41 -1
- package/dist/features/harness/platform-config.js +106 -9
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/app-controls.d.ts +5 -0
- package/dist/features/harness/script/app-controls.js +40 -0
- package/dist/features/harness/script/lane-ids.d.ts +14 -0
- package/dist/features/harness/script/lane-ids.js +16 -0
- package/dist/features/harness/script/script-run.d.ts +70 -0
- package/dist/features/harness/script/script-run.js +606 -0
- 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.d.ts +10 -1
- package/dist/features/visual/visual-tools.js +62 -17
- 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 +23 -0
- package/dist/hooks/driven-by.js +56 -0
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/hooks/hook-commands.js +15 -4
- package/dist/hooks/tool-log.d.ts +9 -0
- package/dist/hooks/tool-log.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +80 -243
- 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 +25 -3
- 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.d.ts +1 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
- package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
- package/dist/judgement/runs/artifact/run-store.js +195 -3
- 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 +71 -1
- package/dist/judgement/runs/drive-run.js +317 -5
- package/dist/judgement/runs/repair-prompt.js +1 -1
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +13 -3
- 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 +5 -2
- package/dist/judgement/runs/verification-sync.js +40 -18
- package/dist/language/flows/change/gate.d.ts +10 -0
- package/dist/language/flows/change/gate.js +22 -0
- package/dist/language/flows/decision.js +36 -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 +61 -10
- package/dist/language/flows/flow-anchor.js +98 -6
- package/dist/language/flows/flow-cross-step.d.ts +15 -0
- package/dist/language/flows/flow-cross-step.js +21 -0
- 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 +45 -14
- package/dist/language/flows/flow-mutate-tools.js +5 -3
- package/dist/language/flows/flow-replay-run.d.ts +23 -9
- package/dist/language/flows/flow-replay-run.js +115 -110
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +40 -1
- package/dist/language/flows/flow-replay.js +110 -22
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-scope.js +5 -1
- package/dist/language/flows/flow-step-runners.d.ts +22 -2
- package/dist/language/flows/flow-step-runners.js +247 -47
- package/dist/language/flows/flow-store-for-session.d.ts +2 -2
- package/dist/language/flows/flow-store-for-session.js +7 -3
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +112 -89
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +74 -12
- package/dist/language/flows/heal-run.js +6 -4
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/flake.d.ts +2 -2
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
- package/dist/language/flows/recording/tape/recordings.js +95 -13
- package/dist/language/flows/replay-from-hud.d.ts +20 -0
- package/dist/language/flows/replay-from-hud.js +51 -0
- package/dist/language/flows/replay.d.ts +9 -5
- package/dist/language/flows/replay.js +56 -15
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/suite/suite-flakes.js +2 -0
- package/dist/language/flows/suite-selection.d.ts +2 -15
- package/dist/language/flows/suite-selection.js +4 -3
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +202 -191
- package/dist/launch-chromium.d.ts +27 -5
- package/dist/launch-chromium.js +38 -8
- package/dist/memory/cloud/cloud-config.d.ts +22 -1
- package/dist/memory/cloud/cloud-config.js +34 -5
- package/dist/memory/cloud/cloud-sync.d.ts +17 -14
- package/dist/memory/cloud/cloud-sync.js +15 -4
- package/dist/memory/cloud/harness-config.d.ts +75 -1
- package/dist/memory/cloud/harness-config.js +115 -24
- package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
- package/dist/memory/cloud/hud-notices-source.js +128 -0
- package/dist/memory/cloud/memory-scope.d.ts +161 -0
- package/dist/memory/cloud/memory-scope.js +227 -0
- package/dist/memory/cloud/sync-cycle.d.ts +44 -7
- package/dist/memory/cloud/sync-cycle.js +129 -15
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +121 -9
- package/dist/memory/cloud/sync-disk.d.ts +1 -1
- package/dist/memory/cloud/sync-disk.js +31 -10
- 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 +34 -0
- package/dist/memory/impact/account-watch.js +59 -0
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +12 -2
- package/dist/memory/impact/impact-store.d.ts +17 -4
- package/dist/memory/impact/impact-store.js +169 -63
- 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 +14 -2
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +122 -4
- 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/envelope.d.ts +8 -8
- package/dist/memory/journal/journal-recorder.js +52 -3
- package/dist/memory/journal/on-disk/retention.d.ts +8 -0
- package/dist/memory/journal/on-disk/retention.js +32 -2
- package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
- package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +42 -9
- package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
- package/dist/memory/project/artifact-root-resolver.js +125 -16
- package/dist/memory/project/artifact-root.d.ts +46 -8
- package/dist/memory/project/artifact-root.js +89 -10
- package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
- package/dist/memory/project/dir/reticle-dir.js +26 -3
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/project-tools.js +22 -3
- 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 +26 -1
- package/dist/memory/project/session-root.js +49 -5
- package/dist/memory/project/sync-status.d.ts +85 -0
- package/dist/memory/project/sync-status.js +224 -0
- package/dist/memory/recall/memory-tools.js +47 -2
- 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.d.ts +19 -0
- package/dist/memory/recall/project-memory.js +80 -13
- package/dist/portal/bridge/bridge.d.ts +9 -3
- package/dist/portal/bridge/bridge.js +82 -22
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/pairing-token.d.ts +9 -0
- package/dist/portal/bridge/pairing-token.js +17 -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 +83 -10
- package/dist/portal/input/real-input.js +218 -30
- package/dist/portal/input/viewport-tools.js +3 -3
- package/dist/portal/pool/browser-pool.d.ts +70 -9
- package/dist/portal/pool/browser-pool.js +190 -37
- 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 +35 -0
- package/dist/portal/pool/playwright-launcher.js +64 -3
- package/dist/portal/pool/pool-contract.d.ts +28 -5
- 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.d.ts +8 -0
- package/dist/portal/session/command-payload.js +24 -0
- 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 +21 -0
- package/dist/portal/session/dev-server/dev-command.js +87 -12
- package/dist/portal/session/facts/departure-note.d.ts +22 -0
- package/dist/portal/session/facts/departure-note.js +47 -0
- 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/facts/session-replaced.d.ts +5 -0
- package/dist/portal/session/facts/session-replaced.js +5 -0
- package/dist/portal/session/first-run-wiring.d.ts +42 -0
- package/dist/portal/session/first-run-wiring.js +132 -0
- 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/human/notes-ledger.d.ts +20 -0
- package/dist/portal/session/human/notes-ledger.js +55 -0
- package/dist/portal/session/human/review-store.d.ts +12 -0
- package/dist/portal/session/human/review-store.js +18 -10
- package/dist/portal/session/live-control-tools.d.ts +0 -13
- package/dist/portal/session/live-control-tools.js +107 -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 +8 -1
- package/dist/portal/session/no-session-diagnosis.js +46 -9
- package/dist/portal/session/no-session-next-action.d.ts +31 -0
- package/dist/portal/session/no-session-next-action.js +159 -60
- package/dist/portal/session/no-session-watch.d.ts +14 -1
- package/dist/portal/session/no-session-watch.js +227 -17
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/presence/session-mirror.js +3 -0
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/serving-directory.d.ts +27 -0
- package/dist/portal/session/serving-directory.js +45 -0
- package/dist/portal/session/session-health.d.ts +18 -0
- package/dist/portal/session/session-health.js +9 -1
- package/dist/portal/session/session-info.d.ts +8 -1
- package/dist/portal/session/session-info.js +8 -1
- package/dist/portal/session/session-manager.d.ts +39 -0
- package/dist/portal/session/session-manager.js +98 -11
- package/dist/portal/session/session-reaper.js +4 -1
- package/dist/portal/session/session-successor.d.ts +13 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session-tools.js +26 -3
- package/dist/portal/session/session.d.ts +22 -30
- package/dist/portal/session/session.js +81 -79
- 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 +12 -0
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +23 -1
- package/dist/status-payload.js +36 -1
- package/dist/surface/http-server.js +18 -2
- 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 +9 -0
- package/dist/surface/mcp/mcp-proxy.js +65 -13
- package/dist/surface/mcp/mcp.d.ts +34 -6
- package/dist/surface/mcp/mcp.js +61 -17
- 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.d.ts +4 -2
- package/dist/surface/mcp/server-instructions.js +32 -14
- package/dist/surface/mcp/shared-params.js +2 -2
- 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/navigation/navigate-arrival.d.ts +8 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
- 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/settle-in-flight.js +25 -3
- package/dist/surface/tools/act-sequence-tool.js +138 -29
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +71 -41
- 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.d.ts +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +42 -17
- package/dist/surface/tools/browser-tools.js +51 -2
- package/dist/surface/tools/chat-drives.d.ts +101 -0
- package/dist/surface/tools/chat-drives.js +409 -0
- 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 +51 -0
- package/dist/surface/tools/empty-session-list.js +120 -0
- package/dist/surface/tools/error-recovery.d.ts +14 -0
- package/dist/surface/tools/error-recovery.js +105 -8
- package/dist/surface/tools/explore-tools.d.ts +31 -1
- package/dist/surface/tools/explore-tools.js +438 -66
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +18 -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 +118 -57
- package/dist/surface/tools/harness-explore.js +344 -292
- 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 +17 -0
- package/dist/surface/tools/harness-plan.js +38 -0
- package/dist/surface/tools/harness-script.d.ts +30 -0
- package/dist/surface/tools/harness-script.js +560 -0
- 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 +22 -1
- package/dist/surface/tools/harness-toolset.js +101 -7
- 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 +263 -85
- 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 +49 -0
- package/dist/surface/tools/lease-seed.js +167 -0
- package/dist/surface/tools/lease-tools.d.ts +13 -24
- package/dist/surface/tools/lease-tools.js +146 -197
- package/dist/surface/tools/live-call-text.js +4 -4
- 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 +29 -0
- package/dist/surface/tools/next-step.js +214 -0
- package/dist/surface/tools/observe-tools.js +45 -9
- package/dist/surface/tools/platform-moment.d.ts +72 -0
- package/dist/surface/tools/platform-moment.js +296 -0
- package/dist/surface/tools/query-hint-schema.d.ts +7 -0
- package/dist/surface/tools/query-hint-schema.js +10 -0
- package/dist/surface/tools/read-tools.js +71 -14
- package/dist/surface/tools/real-input-attempt.js +96 -13
- 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 +83 -3
- package/dist/surface/tools/tool-kit.js +77 -7
- package/dist/surface/tools/tools.js +43 -59
- 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 +29 -6
- package/dist/telemetry/hud-metrics.js +116 -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 +38 -2
- package/dist/telemetry/telemetry.js +144 -34
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +13 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +20 -6
- package/docs/README.md +3 -3
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +25 -28
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +33 -28
- 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 +14 -3
- package/docs/cli/drive.mdx +20 -14
- 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 +43 -28
- 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 +18 -5
- 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 +5 -4
- package/docs/cli.mdx +111 -42
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +9 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +7 -8
- 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 +65 -61
- package/docs/human-control.md +16 -16
- package/docs/index.mdx +15 -42
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +23 -13
- 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 +9 -9
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +32 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +69 -30
- 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 +23 -25
- 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 +22 -13
- 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 +55 -46
- 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 +17 -5
- package/docs/what-is-reticle.mdx +5 -3
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -241
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/features/harness/driver.d.ts +0 -50
- package/dist/features/harness/driver.js +0 -236
- package/dist/features/harness/jev-driver.d.ts +0 -188
- package/dist/features/harness/jev-driver.js +0 -678
- package/dist/features/harness/openai-driver.d.ts +0 -58
- package/dist/features/harness/openai-driver.js +0 -206
- 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/memory/project/dir/fill-value-store.d.ts +0 -32
- package/dist/memory/project/dir/fill-value-store.js +0 -88
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
- package/docs/local-registry.md +0 -143
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The drive plan, asked of the platform.
|
|
3
|
+
*
|
|
4
|
+
* The platform plans the whole drive: it proposes the personas, orders the saved flows, finds the
|
|
5
|
+
* shared starts to branch from and writes the product's rules into each open journey. What it is
|
|
6
|
+
* sent is what the project already knows, and each saved step goes as a short hash, never its values,
|
|
7
|
+
* which is all a plan needs to tell two steps apart.
|
|
8
|
+
*
|
|
9
|
+
* The answer is not trusted: it must parse as a drive script and pass the same checks a local plan
|
|
10
|
+
* does, or it is dropped and the daemon plans locally.
|
|
11
|
+
*
|
|
12
|
+
* The platform keeps every plan under an id, and is told afterwards how each journey went: that is
|
|
13
|
+
* what the next plan learns from (what failed is driven first).
|
|
14
|
+
*/
|
|
15
|
+
import { readRefusal, refusalSentence } from './refusal.js';
|
|
16
|
+
import { createHash } from 'node:crypto';
|
|
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';
|
|
20
|
+
const SCRIPTS_PATH = '/v1/harness/scripts';
|
|
21
|
+
const RESULTS_PATH = '/results';
|
|
22
|
+
const TIMEOUT_MS = 90_000;
|
|
23
|
+
/** Characters of a step hash: enough to tell a flow's steps apart, too few to carry anything. */
|
|
24
|
+
const STEP_HASH_CHARS = 12;
|
|
25
|
+
/** How long a persona's name may be, read back out of a flow's intent. */
|
|
26
|
+
const MAX_PERSONA_NAME = 80;
|
|
27
|
+
const MAX_PERSONAS = 5;
|
|
28
|
+
/**
|
|
29
|
+
* The personas earlier drives used, read from their flows' intents (`Name: journey`). Proposed
|
|
30
|
+
* afresh on every run, they were different people each time, so each run's flows had new names
|
|
31
|
+
* and the old ones were never replayed or updated.
|
|
32
|
+
*/
|
|
33
|
+
export function personasIn(flows) {
|
|
34
|
+
const seen = new Map();
|
|
35
|
+
for (const flow of flows) {
|
|
36
|
+
// The first line only: an older drive saved the product's rules below the journey.
|
|
37
|
+
const intent = (flow.intent ?? '').split('\n')[0] ?? '';
|
|
38
|
+
const at = intent.indexOf(':');
|
|
39
|
+
if (at <= 0 || MAX_PERSONA_NAME < at)
|
|
40
|
+
continue;
|
|
41
|
+
const name = intent.slice(0, at).trim();
|
|
42
|
+
const journey = intent.slice(at + 1).trim();
|
|
43
|
+
if (0 < name.length && 0 < journey.length && !seen.has(name))
|
|
44
|
+
seen.set(name, journey);
|
|
45
|
+
}
|
|
46
|
+
return [...seen].slice(0, MAX_PERSONAS).map(([name, journey]) => ({ name, journey }));
|
|
47
|
+
}
|
|
48
|
+
/** Equal for two steps that drive the same control the same way; the values never leave. */
|
|
49
|
+
export function stepHash(step) {
|
|
50
|
+
return createHash('sha256')
|
|
51
|
+
.update(JSON.stringify([step.tool, step.anchor, step.action, step.args, step.steps, step.invoke]))
|
|
52
|
+
.digest('hex')
|
|
53
|
+
.slice(0, STEP_HASH_CHARS);
|
|
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
|
+
}
|
|
65
|
+
export async function proposeScript(platform, ask, doFetch = (url, init) => fetch(url, init)) {
|
|
66
|
+
try {
|
|
67
|
+
const res = await doFetch(`${platform.url}${SCRIPTS_PATH}`, {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: platformHeaders(platform),
|
|
70
|
+
body: JSON.stringify({
|
|
71
|
+
about: ask.about,
|
|
72
|
+
flows: ask.flows.map((flow) => ({
|
|
73
|
+
name: flow.name,
|
|
74
|
+
...(flow.intent === undefined ? {} : { intent: flow.intent }),
|
|
75
|
+
needs: flow.needs ?? [],
|
|
76
|
+
steps: flow.steps.map(stepHash),
|
|
77
|
+
commits: flow.steps.flatMap((step, i) => (StepEffect.COMMITS === step.effect ? [i] : [])),
|
|
78
|
+
// How much it proves: a journey whose flows assert nothing is driven again, not replayed.
|
|
79
|
+
checks: flow.steps.filter((step) => step.expect !== undefined || true === step.steps?.some((s) => s.expect !== undefined)).length,
|
|
80
|
+
})),
|
|
81
|
+
replay: ask.replay,
|
|
82
|
+
goals: goalsToAsk(ask),
|
|
83
|
+
gaps: ask.gaps,
|
|
84
|
+
rules: ask.rules,
|
|
85
|
+
...(ask.personas === undefined || 0 === ask.personas.length
|
|
86
|
+
? {}
|
|
87
|
+
: { personas: ask.personas }),
|
|
88
|
+
}),
|
|
89
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
90
|
+
});
|
|
91
|
+
// The platform's own reason, so a drive that goes on without a plan can say why.
|
|
92
|
+
if (!res.ok)
|
|
93
|
+
return { refused: await refusalOf(res) };
|
|
94
|
+
const body = (await res.json());
|
|
95
|
+
const parsed = DriveScriptSchema.safeParse(body.script);
|
|
96
|
+
if (!parsed.success || 0 < checkScript(parsed.data).length)
|
|
97
|
+
return undefined;
|
|
98
|
+
return {
|
|
99
|
+
script: parsed.data,
|
|
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 } : {}),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
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
|
+
}
|
|
207
|
+
/** Worst first: a journey that ran in two lanes reports the worse of the two. */
|
|
208
|
+
const SEVERITY = [
|
|
209
|
+
ScriptStatus.FAILED,
|
|
210
|
+
ScriptStatus.BLOCKED,
|
|
211
|
+
ScriptStatus.RUNNING,
|
|
212
|
+
ScriptStatus.PENDING,
|
|
213
|
+
ScriptStatus.UNDECIDED,
|
|
214
|
+
ScriptStatus.NOT_TAKEN,
|
|
215
|
+
ScriptStatus.PASSED,
|
|
216
|
+
];
|
|
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 = []) {
|
|
219
|
+
const byId = new Map();
|
|
220
|
+
for (const lane of view.lanes)
|
|
221
|
+
for (const card of lane.journeys) {
|
|
222
|
+
const seen = byId.get(card.id);
|
|
223
|
+
if (seen === undefined || SEVERITY.indexOf(card.status) < SEVERITY.indexOf(seen.status))
|
|
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
|
+
});
|
|
230
|
+
}
|
|
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
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/** Tell the platform how its plan went. A failure costs the next plan its memory, never this run. */
|
|
246
|
+
export async function reportPlanResults(platform, planId, results, runIds = [], doFetch = (url, init) => fetch(url, init)) {
|
|
247
|
+
try {
|
|
248
|
+
const res = await doFetch(`${platform.url}${SCRIPTS_PATH}/${encodeURIComponent(planId)}${RESULTS_PATH}`, {
|
|
249
|
+
method: 'POST',
|
|
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 }) }),
|
|
253
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
254
|
+
});
|
|
255
|
+
return res.ok;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ModelDriver } from '../harness.js';
|
|
2
|
+
import { DRIVE_HEADER } from '../platform-config.js';
|
|
3
|
+
export { DRIVE_HEADER };
|
|
4
|
+
export declare const SERVER_DRIVER_NAME = "server";
|
|
5
|
+
type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
|
|
6
|
+
export interface ServerDriverOptions {
|
|
7
|
+
url: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
persona?: string;
|
|
10
|
+
/** The goal a drive with no persona is for: the platform names its flows after it. */
|
|
11
|
+
journey?: string;
|
|
12
|
+
/** journey | brute-force | stress | madman | security. The platform defaults to journey. */
|
|
13
|
+
mode?: string;
|
|
14
|
+
/** What `.reticle` already knows, as text: saved journeys and open intents. */
|
|
15
|
+
plan?: string;
|
|
16
|
+
/** The same plan, structured, for the platform's Jev engine. */
|
|
17
|
+
planSteps?: readonly {
|
|
18
|
+
kind: string;
|
|
19
|
+
target: string;
|
|
20
|
+
why: string;
|
|
21
|
+
}[];
|
|
22
|
+
/** The signal names the app declares, so the engine can claim one by name. */
|
|
23
|
+
vocabulary?: readonly string[];
|
|
24
|
+
/** The survey of the app taken before the drive: where each text and control lives. */
|
|
25
|
+
siteMap?: unknown;
|
|
26
|
+
/** Where secret field values live. Only their NAMES go to the platform. Defaults to `process.env`. */
|
|
27
|
+
env?: Record<string, string | undefined>;
|
|
28
|
+
maxSteps?: number;
|
|
29
|
+
/** The free drive this run is billed to, sent as `DRIVE_HEADER` on every turn. */
|
|
30
|
+
driveId?: string;
|
|
31
|
+
fetch?: FetchLike;
|
|
32
|
+
}
|
|
33
|
+
/** Where to reach the platform, as which key, and for which free drive when there is one. */
|
|
34
|
+
export interface PlatformCredential {
|
|
35
|
+
url: string;
|
|
36
|
+
apiKey: string;
|
|
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>;
|
|
46
|
+
export declare class ServerHarnessError extends Error {
|
|
47
|
+
readonly status: number;
|
|
48
|
+
constructor(message: string, status: number);
|
|
49
|
+
}
|
|
50
|
+
export declare function serverDriver(options: ServerDriverOptions): ModelDriver;
|
|
51
|
+
/** The secret fields this machine can fill, by name only. */
|
|
52
|
+
export declare function secretNames(env: Record<string, string | undefined>): string[];
|
|
53
|
+
/** The call's arguments with every secret placeholder replaced by its value from this machine. */
|
|
54
|
+
export declare function withSecrets(args: Record<string, unknown>, env: Record<string, string | undefined>): Record<string, unknown>;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform's Harness, seen from the daemon: the platform decides, this machine executes.
|
|
3
|
+
*
|
|
4
|
+
* Every turn is one HTTPS request this daemon makes: it posts what the last calls did, and the
|
|
5
|
+
* platform answers with the next calls, chosen by its own model, persona and verification mode. The
|
|
6
|
+
* loop around it (`runHarness`) is unchanged: it executes the calls through Reticle's own tools and
|
|
7
|
+
* hands the outcomes back here. Nothing is held open between turns, a lost response is retried with
|
|
8
|
+
* the same turn number, and the platform answers that from its record without a second model call.
|
|
9
|
+
*
|
|
10
|
+
* This is the only Harness driver: every decision is the platform's, for a workspace with a plan or
|
|
11
|
+
* trial. A secret field travels by name only, and its value is filled in here before the call runs.
|
|
12
|
+
*/
|
|
13
|
+
import { PlatformRefusalCode, readRefusal, refusalSentence } from './refusal.js';
|
|
14
|
+
import { ReticleEnv, cloudUrlFrom } from '@reticlehq/core';
|
|
15
|
+
import { DriveStoppedError, } from '../harness.js';
|
|
16
|
+
import { DRIVE_HEADER } from '../platform-config.js';
|
|
17
|
+
export { DRIVE_HEADER };
|
|
18
|
+
export const SERVER_DRIVER_NAME = 'server';
|
|
19
|
+
const RUNS_PATH = '/v1/harness/runs';
|
|
20
|
+
const TURN_TIMEOUT_MS = 110_000;
|
|
21
|
+
const RETRIES = 1;
|
|
22
|
+
/** The platform's code for a run whose project had autonomous driving switched off. */
|
|
23
|
+
const FINISH = 'finish';
|
|
24
|
+
/** The platform's url and this project's key, when the machine is linked. */
|
|
25
|
+
export function serverOptionsFromEnv(env) {
|
|
26
|
+
const url = cloudUrlFrom(env);
|
|
27
|
+
const apiKey = env[ReticleEnv.API_KEY];
|
|
28
|
+
const driveId = env[ReticleEnv.DRIVE_ID];
|
|
29
|
+
return url === undefined || apiKey === undefined || 0 === apiKey.length
|
|
30
|
+
? undefined
|
|
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
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export class ServerHarnessError extends Error {
|
|
46
|
+
status;
|
|
47
|
+
constructor(message, status) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.status = status;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function serverDriver(options) {
|
|
53
|
+
const doFetch = options.fetch ?? ((url, init) => fetch(url, init));
|
|
54
|
+
let runId;
|
|
55
|
+
let turn = 0;
|
|
56
|
+
let seen = 0;
|
|
57
|
+
const call = async (path, body) => {
|
|
58
|
+
let last;
|
|
59
|
+
for (let attempt = 0; attempt <= RETRIES; attempt += 1) {
|
|
60
|
+
try {
|
|
61
|
+
const res = await doFetch(`${options.url}${path}`, {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: platformHeaders(options),
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
signal: AbortSignal.timeout(TURN_TIMEOUT_MS),
|
|
66
|
+
});
|
|
67
|
+
const text = await res.text();
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
const refusal = readRefusal(text);
|
|
70
|
+
const message = refusalSentence(refusal, res.status);
|
|
71
|
+
// A person turned it off: the drive ends, and the result says that rather than "broken".
|
|
72
|
+
if (PlatformRefusalCode.HARNESS_OFF === refusal.code)
|
|
73
|
+
throw new DriveStoppedError(message);
|
|
74
|
+
// A refusal is an answer; only a network failure is worth asking again.
|
|
75
|
+
throw new ServerHarnessError(message, res.status);
|
|
76
|
+
}
|
|
77
|
+
return JSON.parse(text);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (error instanceof ServerHarnessError || error instanceof DriveStoppedError)
|
|
81
|
+
throw error;
|
|
82
|
+
last = error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
throw last instanceof Error ? last : new Error(String(last));
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
async turn(input) {
|
|
89
|
+
if (runId === undefined) {
|
|
90
|
+
const started = (await call(RUNS_PATH, {
|
|
91
|
+
...(options.persona === undefined ? {} : { persona: options.persona }),
|
|
92
|
+
...(options.journey === undefined ? {} : { journey: options.journey }),
|
|
93
|
+
...(options.mode === undefined ? {} : { mode: options.mode }),
|
|
94
|
+
...(options.plan === undefined ? {} : { plan: options.plan }),
|
|
95
|
+
...(options.maxSteps === undefined ? {} : { maxSteps: options.maxSteps }),
|
|
96
|
+
...(options.planSteps === undefined ? {} : { planSteps: options.planSteps }),
|
|
97
|
+
...(options.vocabulary === undefined ? {} : { vocabulary: options.vocabulary }),
|
|
98
|
+
...(options.siteMap === undefined ? {} : { siteMap: options.siteMap }),
|
|
99
|
+
secrets: secretNames(options.env ?? process.env),
|
|
100
|
+
tools: input.tools.filter((t) => FINISH !== t.name).map(toolSpec),
|
|
101
|
+
}));
|
|
102
|
+
if ('string' !== typeof started.runId)
|
|
103
|
+
throw new ServerHarnessError('the platform started no run', 502);
|
|
104
|
+
runId = started.runId;
|
|
105
|
+
}
|
|
106
|
+
// Only what happened since the last turn: the platform holds everything before it.
|
|
107
|
+
const fresh = input.history.slice(seen);
|
|
108
|
+
seen = input.history.length;
|
|
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] : []);
|
|
113
|
+
const reply = (await call(`${RUNS_PATH}/${encodeURIComponent(runId)}/turn`, {
|
|
114
|
+
turn,
|
|
115
|
+
outcomes,
|
|
116
|
+
...(0 === say.length ? {} : { say }),
|
|
117
|
+
}));
|
|
118
|
+
turn = reply.turn + 1;
|
|
119
|
+
// The platform's spend, reported so the drive's cost is visible here as it is for a local one.
|
|
120
|
+
const usage = reply.usage === undefined ? {} : { usage: reply.usage };
|
|
121
|
+
if (reply.done) {
|
|
122
|
+
// The platform has finished: `finish` ends the local loop the same way a local model would.
|
|
123
|
+
return {
|
|
124
|
+
text: reply.text,
|
|
125
|
+
...usage,
|
|
126
|
+
calls: [
|
|
127
|
+
{
|
|
128
|
+
id: `server-finish-${String(reply.turn)}`,
|
|
129
|
+
name: FINISH,
|
|
130
|
+
args: {
|
|
131
|
+
summary: reply.summary ?? reply.text,
|
|
132
|
+
...('boolean' === typeof reply.goalMet ? { goalMet: reply.goalMet } : {}),
|
|
133
|
+
...('number' === typeof reply.creditsSpent
|
|
134
|
+
? { creditsSpent: reply.creditsSpent }
|
|
135
|
+
: {}),
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// A field the platform knows only by name is filled here, from this machine, and never sent.
|
|
142
|
+
const env = options.env ?? process.env;
|
|
143
|
+
return {
|
|
144
|
+
text: reply.text,
|
|
145
|
+
calls: reply.calls.map((c) => ({ ...c, args: withSecrets(c.args, env) })),
|
|
146
|
+
...usage,
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function toolSpec(tool) {
|
|
152
|
+
return { name: tool.name, description: tool.description, inputSchema: tool.inputSchema };
|
|
153
|
+
}
|
|
154
|
+
function outcomeOf(o) {
|
|
155
|
+
return { id: o.id, name: o.name, result: o.result, isError: o.isError };
|
|
156
|
+
}
|
|
157
|
+
/** The prefix of a variable holding one secret field: `RETICLE_SECRET_AUTH_PASSWORD`. */
|
|
158
|
+
const SECRET_ENV_PREFIX = 'RETICLE_SECRET_';
|
|
159
|
+
/** What the platform types into a field whose secret this machine holds. */
|
|
160
|
+
const SECRET_PLACEHOLDER = 'reticle-secret:';
|
|
161
|
+
/** The secret fields this machine can fill, by name only. */
|
|
162
|
+
export function secretNames(env) {
|
|
163
|
+
return Object.keys(env)
|
|
164
|
+
.filter((key) => key.startsWith(SECRET_ENV_PREFIX) && 0 < (env[key] ?? '').length)
|
|
165
|
+
.map((key) => key.slice(SECRET_ENV_PREFIX.length));
|
|
166
|
+
}
|
|
167
|
+
/** The call's arguments with every secret placeholder replaced by its value from this machine. */
|
|
168
|
+
export function withSecrets(args, env) {
|
|
169
|
+
const swap = (value) => {
|
|
170
|
+
if ('string' === typeof value && value.startsWith(SECRET_PLACEHOLDER)) {
|
|
171
|
+
const field = value.slice(SECRET_PLACEHOLDER.length);
|
|
172
|
+
const name = field.replace(/[^a-zA-Z0-9]+/g, '_').toUpperCase();
|
|
173
|
+
return env[`${SECRET_ENV_PREFIX}${name}`] ?? value;
|
|
174
|
+
}
|
|
175
|
+
if (Array.isArray(value))
|
|
176
|
+
return value.map(swap);
|
|
177
|
+
if ('object' === typeof value && null !== value)
|
|
178
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, swap(v)]));
|
|
179
|
+
return value;
|
|
180
|
+
};
|
|
181
|
+
return swap(args);
|
|
182
|
+
}
|
|
@@ -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,6 +44,42 @@ export interface PlatformModelConfig {
|
|
|
40
44
|
* not have its silence treated as a refusal.
|
|
41
45
|
*/
|
|
42
46
|
providerReady: boolean;
|
|
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;
|
|
53
|
+
};
|
|
54
|
+
/** The platform that answered, no trailing slash: where the HUD's settings and plan links go. */
|
|
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;
|
|
43
83
|
}
|
|
44
84
|
/** A GET, narrowed to what this file uses, so a test can answer it without a network. */
|
|
45
85
|
export type ConfigFetch = (url: string, init: {
|