@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,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The step screenshots of each run the platform has accepted, sent once each.
|
|
3
|
+
*
|
|
4
|
+
* A run goes up first, through the sync; its screenshots follow, one request per image, to
|
|
5
|
+
* `POST /v1/runs/:runId/screenshots` — only once the platform holds the run, because the endpoint
|
|
6
|
+
* answers 404 for a run it does not. What was sent is remembered by `seq:sha256`, like runs by hash,
|
|
7
|
+
* so a quiet cycle sends nothing.
|
|
8
|
+
*
|
|
9
|
+
* An OLDER platform has no such endpoint and answers 404 or 405. That run's screenshots stay on
|
|
10
|
+
* this machine and are not offered again: the alternative is one refused request per image on every
|
|
11
|
+
* cycle, forever. A newer platform picks up the next run's. Anything else that failed (the network,
|
|
12
|
+
* a 5xx) is simply retried next cycle.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
15
|
+
import { RunScreenshotSchema, STEP_SCREENSHOT } from '@reticlehq/core';
|
|
16
|
+
const SCREENSHOTS_PATH = (runId) => `/v1/runs/${encodeURIComponent(runId)}/screenshots`;
|
|
17
|
+
const HTTP_CREATED = 201;
|
|
18
|
+
const HTTP_OK = 200;
|
|
19
|
+
/** An older platform: no route (404), or a route that takes no POST (405). */
|
|
20
|
+
const NOT_THERE = new Set([404, 405]);
|
|
21
|
+
/** Refused for good: too large (413), too many for one run (409). Retrying cannot change it. */
|
|
22
|
+
const REFUSED_FOR_GOOD = new Set([409, 413]);
|
|
23
|
+
/** The screenshots a run artifact lists, read defensively: a malformed entry is skipped. */
|
|
24
|
+
function listed(payload) {
|
|
25
|
+
const raw = 'object' === typeof payload && null !== payload
|
|
26
|
+
? payload['screenshots']
|
|
27
|
+
: undefined;
|
|
28
|
+
if (!Array.isArray(raw))
|
|
29
|
+
return [];
|
|
30
|
+
return raw.flatMap((entry) => {
|
|
31
|
+
const parsed = RunScreenshotSchema.safeParse(entry);
|
|
32
|
+
return parsed.success ? [parsed.data] : [];
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const keyOf = (shot) => `${String(shot.seq)}:${shot.sha256}`;
|
|
36
|
+
/** The upload body for one screenshot — the shape `ScreenshotUploadSchema` reads. */
|
|
37
|
+
function bodyOf(shot, image) {
|
|
38
|
+
return {
|
|
39
|
+
seq: shot.seq,
|
|
40
|
+
file: shot.file,
|
|
41
|
+
...(shot.step === undefined ? {} : { step: shot.step }),
|
|
42
|
+
tool: shot.tool,
|
|
43
|
+
...(shot.checkId === undefined ? {} : { checkId: shot.checkId }),
|
|
44
|
+
source: shot.source,
|
|
45
|
+
width: shot.width,
|
|
46
|
+
height: shot.height,
|
|
47
|
+
sha256: shot.sha256,
|
|
48
|
+
jpeg: Buffer.from(image).toString('base64'),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Send what is owed. Never throws; the record is bounded by the runs still on disk. */
|
|
52
|
+
export async function syncScreenshots(deps) {
|
|
53
|
+
const onDisk = new Set(deps.runs.map((run) => run.runId));
|
|
54
|
+
const sent = {};
|
|
55
|
+
for (const [runId, keys] of Object.entries(deps.state.sentScreenshots ?? {}))
|
|
56
|
+
if (onDisk.has(runId) && Array.isArray(keys))
|
|
57
|
+
sent[runId] = keys.filter((k) => 'string' === typeof k);
|
|
58
|
+
const heldLocal = new Set((deps.state.screenshotsHeldLocal ?? []).filter((id) => onDisk.has(id)));
|
|
59
|
+
const finish = (count, error) => ({
|
|
60
|
+
sent: count,
|
|
61
|
+
state: { sentScreenshots: sent, screenshotsHeldLocal: [...heldLocal] },
|
|
62
|
+
...(error === undefined ? {} : { error }),
|
|
63
|
+
});
|
|
64
|
+
let count = 0;
|
|
65
|
+
try {
|
|
66
|
+
for (const run of deps.runs) {
|
|
67
|
+
if (heldLocal.has(run.runId) || !deps.accepted(run.runId))
|
|
68
|
+
continue;
|
|
69
|
+
const done = new Set(sent[run.runId] ?? []);
|
|
70
|
+
for (const shot of listed(run.payload)) {
|
|
71
|
+
if (done.has(keyOf(shot)))
|
|
72
|
+
continue;
|
|
73
|
+
const image = deps.readImage(run.runId, shot.file);
|
|
74
|
+
// Gone (retention took it) or changed under its name: nothing true is left to send.
|
|
75
|
+
if (image === undefined || createHash('sha256').update(image).digest('hex') !== shot.sha256)
|
|
76
|
+
continue;
|
|
77
|
+
const markDone = () => {
|
|
78
|
+
done.add(keyOf(shot));
|
|
79
|
+
sent[run.runId] = [...done];
|
|
80
|
+
};
|
|
81
|
+
if (image.byteLength > STEP_SCREENSHOT.MAX_BYTES) {
|
|
82
|
+
markDone();
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const res = await deps.post(SCREENSHOTS_PATH(run.runId), JSON.stringify(bodyOf(shot, image)));
|
|
86
|
+
if (HTTP_CREATED === res.status || HTTP_OK === res.status) {
|
|
87
|
+
markDone();
|
|
88
|
+
count += 1;
|
|
89
|
+
}
|
|
90
|
+
else if (NOT_THERE.has(res.status)) {
|
|
91
|
+
heldLocal.add(run.runId);
|
|
92
|
+
return finish(count, `screenshots ${String(res.status)}: this platform does not take screenshots yet, so run ${run.runId}'s stay on this machine`);
|
|
93
|
+
}
|
|
94
|
+
else if (REFUSED_FOR_GOOD.has(res.status))
|
|
95
|
+
markDone();
|
|
96
|
+
else
|
|
97
|
+
return finish(count, `screenshots ${String(res.status)}: ${res.text.slice(0, 200)}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
return finish(count, error instanceof Error ? error.message : String(error));
|
|
103
|
+
}
|
|
104
|
+
return finish(count);
|
|
105
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface UnsyncedRoot {
|
|
2
|
+
root: string;
|
|
3
|
+
/** Runs on disk the platform has not accepted. */
|
|
4
|
+
runs: number;
|
|
5
|
+
/** Flows on disk nothing will send: see `unsentFlowCount`. */
|
|
6
|
+
flows: number;
|
|
7
|
+
/** Whether this folder holds a link. False is the case nothing will ever send. */
|
|
8
|
+
linked: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The project it belongs to: the linked one, else the id its `.reticle.json` names. A machine
|
|
11
|
+
* reports every folder to each workspace it is linked to; this is how a board keeps only its own.
|
|
12
|
+
*/
|
|
13
|
+
projectId?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run files in `root` the platform never accepted. Ids only — a run file is named by its id — so
|
|
17
|
+
* this costs a directory listing, never a payload read. Never throws.
|
|
18
|
+
*/
|
|
19
|
+
export declare function unsentRunCount(root: string): number;
|
|
20
|
+
/**
|
|
21
|
+
* Flows in `root` that will not reach the platform: all of them when nothing sends them (the root is
|
|
22
|
+
* not linked, has no key for its host, or has flow sync switched off), else the ones the platform
|
|
23
|
+
* refused. A flow waiting on a root that does send them is not counted: a save wakes the next cycle.
|
|
24
|
+
* Never throws.
|
|
25
|
+
*/
|
|
26
|
+
export declare function unsentFlowCount(root: string, sendsFlows: boolean): number;
|
|
27
|
+
/**
|
|
28
|
+
* Every root here with runs or flows the platform does not have. Roots are deduped; order is kept.
|
|
29
|
+
* `sendsFlows` defaults to `isLinked`: a linked root sends its flows unless flow sync is off.
|
|
30
|
+
*/
|
|
31
|
+
export declare function unsyncedRoots(roots: readonly string[], isLinked: (root: string) => Promise<boolean>, sendsFlows?: (root: string) => Promise<boolean>): Promise<UnsyncedRoot[]>;
|
|
32
|
+
/**
|
|
33
|
+
* The buckets under `~/.reticle/unmatched/` — evidence no project claimed, which nothing sends. After
|
|
34
|
+
* the first warning nothing named them again: not `status`, not `connect`, not the dashboard's
|
|
35
|
+
* unsent list. Never throws.
|
|
36
|
+
*/
|
|
37
|
+
export declare function unmatchedRoots(home: string): string[];
|
|
38
|
+
/** The project a `.reticle` folder belongs to: where a person runs the command that sends it. */
|
|
39
|
+
export declare function projectFolderOf(root: string): string;
|
|
40
|
+
/** One line a person can act on: where the runs are, and the command that sends them. */
|
|
41
|
+
export declare function describeUnsynced(entry: UnsyncedRoot, from: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* The unsent folders as a command's few lines: every unclaimed bucket in one (they all need the same
|
|
44
|
+
* thing, and `reticle connect` printed ninety near-identical lines of them before "Connected"), the
|
|
45
|
+
* rest one by one up to a handful, then a count and where the full list is.
|
|
46
|
+
*/
|
|
47
|
+
export declare function describeUnsyncedBriefly(entries: readonly UnsyncedRoot[], from: string): string[];
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.reticle` folders whose runs never reached the platform, and why.
|
|
3
|
+
*
|
|
4
|
+
* The daemon skipped every root without a link and said nothing: one repo held 31 runs nobody sent
|
|
5
|
+
* while the log repeated `reticle_cloud_unlinked` about a different folder. Counted here, from run
|
|
6
|
+
* ids on disk against the ids the platform accepted, so `reticle sync`, `doctor`, the HUD and the
|
|
7
|
+
* platform report can each name the folder and the one command that fixes it.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
10
|
+
import { basename, dirname, join, relative, sep } from 'node:path';
|
|
11
|
+
import { ReticleDir } from '@reticlehq/core';
|
|
12
|
+
import { DRIVE_RECORD_SUFFIX, UNMATCHED_SUBDIR, isUnmatchedRoot, } from '../project/dir/reticle-dir.js';
|
|
13
|
+
import { diskSource, readCloudState } from './sync-disk.js';
|
|
14
|
+
/** The project's own config, beside its `.reticle` folder. */
|
|
15
|
+
const PROJECT_CONFIG = '.reticle.json';
|
|
16
|
+
/** `projectId` out of a JSON file, or undefined. Never throws. */
|
|
17
|
+
function projectIdIn(path) {
|
|
18
|
+
try {
|
|
19
|
+
const id = JSON.parse(readFileSync(path, 'utf8'))?.['projectId'];
|
|
20
|
+
return 'string' === typeof id && 0 < id.length ? id : undefined;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** The project a `.reticle` folder belongs to, as the platform keys it. */
|
|
27
|
+
function projectOfRoot(root) {
|
|
28
|
+
return (projectIdIn(join(root, ReticleDir.CLOUD_LINK_FILE)) ??
|
|
29
|
+
projectIdIn(join(projectFolderOf(root), PROJECT_CONFIG)));
|
|
30
|
+
}
|
|
31
|
+
const RUN_SUFFIX = '.json';
|
|
32
|
+
/** The folder the command is run from, named when it is the one the person is already in. */
|
|
33
|
+
const HERE = 'this folder';
|
|
34
|
+
/**
|
|
35
|
+
* Run files in `root` the platform never accepted. Ids only — a run file is named by its id — so
|
|
36
|
+
* this costs a directory listing, never a payload read. Never throws.
|
|
37
|
+
*/
|
|
38
|
+
export function unsentRunCount(root) {
|
|
39
|
+
try {
|
|
40
|
+
const dir = join(root, ReticleDir.RUNS_SUBDIR);
|
|
41
|
+
if (!existsSync(dir))
|
|
42
|
+
return 0;
|
|
43
|
+
const state = readCloudState(root);
|
|
44
|
+
const sent = new Set([...Object.keys(state.sentRunHashes ?? {}), ...(state.sentRunIds ?? [])]);
|
|
45
|
+
// Made before the folder was linked here: held for `--move-history`, so not waiting for a sync.
|
|
46
|
+
const linkedAt = state.linkedAt;
|
|
47
|
+
const heldBack = (file) => {
|
|
48
|
+
if (linkedAt === undefined)
|
|
49
|
+
return false;
|
|
50
|
+
try {
|
|
51
|
+
const at = JSON.parse(readFileSync(join(dir, file), 'utf8'))
|
|
52
|
+
.createdAt;
|
|
53
|
+
return !('number' === typeof at && at >= linkedAt);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return readdirSync(dir)
|
|
60
|
+
.filter((file) => file.endsWith(RUN_SUFFIX) && !file.endsWith(DRIVE_RECORD_SUFFIX))
|
|
61
|
+
.filter((file) => !sent.has(file.slice(0, -RUN_SUFFIX.length)) && !heldBack(file)).length;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Flows in `root` that will not reach the platform: all of them when nothing sends them (the root is
|
|
69
|
+
* not linked, has no key for its host, or has flow sync switched off), else the ones the platform
|
|
70
|
+
* refused. A flow waiting on a root that does send them is not counted: a save wakes the next cycle.
|
|
71
|
+
* Never throws.
|
|
72
|
+
*/
|
|
73
|
+
export function unsentFlowCount(root, sendsFlows) {
|
|
74
|
+
try {
|
|
75
|
+
if (!sendsFlows)
|
|
76
|
+
return diskSource(root).flows().length;
|
|
77
|
+
return readCloudState(root).refusedSets?.flow?.count ?? 0;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Every root here with runs or flows the platform does not have. Roots are deduped; order is kept.
|
|
85
|
+
* `sendsFlows` defaults to `isLinked`: a linked root sends its flows unless flow sync is off.
|
|
86
|
+
*/
|
|
87
|
+
export async function unsyncedRoots(roots, isLinked, sendsFlows = isLinked) {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const root of new Set(roots)) {
|
|
90
|
+
const runs = unsentRunCount(root);
|
|
91
|
+
const linked = await isLinked(root).catch(() => false);
|
|
92
|
+
const flows = unsentFlowCount(root, linked && (await sendsFlows(root).catch(() => false)));
|
|
93
|
+
if (0 === runs && 0 === flows)
|
|
94
|
+
continue;
|
|
95
|
+
const projectId = projectOfRoot(root);
|
|
96
|
+
out.push({ root, runs, flows, linked, ...(projectId === undefined ? {} : { projectId }) });
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The buckets under `~/.reticle/unmatched/` — evidence no project claimed, which nothing sends. After
|
|
102
|
+
* the first warning nothing named them again: not `status`, not `connect`, not the dashboard's
|
|
103
|
+
* unsent list. Never throws.
|
|
104
|
+
*/
|
|
105
|
+
export function unmatchedRoots(home) {
|
|
106
|
+
const dir = join(home, ReticleDir.ROOT, UNMATCHED_SUBDIR);
|
|
107
|
+
try {
|
|
108
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
109
|
+
.filter((entry) => entry.isDirectory())
|
|
110
|
+
.map((entry) => join(dir, entry.name));
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** The project a `.reticle` folder belongs to: where a person runs the command that sends it. */
|
|
117
|
+
export function projectFolderOf(root) {
|
|
118
|
+
return ReticleDir.ROOT === basename(root) ? dirname(root) : root;
|
|
119
|
+
}
|
|
120
|
+
/** One line a person can act on: where the runs are, and the command that sends them. */
|
|
121
|
+
export function describeUnsynced(entry, from) {
|
|
122
|
+
// Forward slashes on every platform, as the platform report writes `~/...`: one spelling of a
|
|
123
|
+
// folder whether it is read in a Windows terminal, the HUD or the dashboard.
|
|
124
|
+
const folder = projectFolderOf(entry.root);
|
|
125
|
+
const where = 0 === relative(from, folder).length ? HERE : relative(from, folder).split(sep).join('/');
|
|
126
|
+
const what = [
|
|
127
|
+
...(0 < entry.runs ? [`${String(entry.runs)} run(s)`] : []),
|
|
128
|
+
...(0 < entry.flows ? [`${String(entry.flows)} flow(s)`] : []),
|
|
129
|
+
].join(' and ');
|
|
130
|
+
if (isUnmatchedRoot(entry.root)) {
|
|
131
|
+
return (`${what} in ${entry.root.split(sep).join('/')} are not on your dashboard: no project claimed ` +
|
|
132
|
+
'them — the checkout that made them shares its project id with another, or has none. They stay ' +
|
|
133
|
+
'on this machine; serve the app from the checkout that owns the id, or give this one its own, so new work reaches it');
|
|
134
|
+
}
|
|
135
|
+
// `connect`, not `link`: it signs in first when it has to, so it is the one command that works.
|
|
136
|
+
if (!entry.linked)
|
|
137
|
+
return `${what} in ${where} are not on your dashboard: run \`reticle connect\` there`;
|
|
138
|
+
// A linked root counts flows only when flow sync is off or the platform refused them.
|
|
139
|
+
return 0 < entry.flows
|
|
140
|
+
? `${what} in ${where} are not on your dashboard: \`reticle config --flows on\` there if flow ` +
|
|
141
|
+
'sync is off; `reticle sync` names any the platform refused'
|
|
142
|
+
: `${what} in ${where} are waiting to be sent: run \`reticle sync\` there`;
|
|
143
|
+
}
|
|
144
|
+
/** Folders named one by one before the rest are counted. */
|
|
145
|
+
const FOLDERS_SHOWN = 5;
|
|
146
|
+
/**
|
|
147
|
+
* The unsent folders as a command's few lines: every unclaimed bucket in one (they all need the same
|
|
148
|
+
* thing, and `reticle connect` printed ninety near-identical lines of them before "Connected"), the
|
|
149
|
+
* rest one by one up to a handful, then a count and where the full list is.
|
|
150
|
+
*/
|
|
151
|
+
export function describeUnsyncedBriefly(entries, from) {
|
|
152
|
+
const unclaimed = entries.filter((entry) => isUnmatchedRoot(entry.root));
|
|
153
|
+
const claimed = entries.filter((entry) => !isUnmatchedRoot(entry.root));
|
|
154
|
+
if (entries.length <= FOLDERS_SHOWN)
|
|
155
|
+
return entries.map((entry) => describeUnsynced(entry, from));
|
|
156
|
+
const runs = unclaimed.reduce((sum, entry) => sum + entry.runs, 0);
|
|
157
|
+
const lines = claimed.slice(0, FOLDERS_SHOWN).map((entry) => describeUnsynced(entry, from));
|
|
158
|
+
if (0 < unclaimed.length)
|
|
159
|
+
lines.unshift(`${String(runs)} run(s) in ${String(unclaimed.length)} folders under ~/${ReticleDir.ROOT}/${UNMATCHED_SUBDIR} ` +
|
|
160
|
+
'are not on your dashboard: no project claimed them, so they stay on this machine');
|
|
161
|
+
const more = claimed.length - FOLDERS_SHOWN;
|
|
162
|
+
if (0 < more || 0 < unclaimed.length)
|
|
163
|
+
lines.push(`${0 < more ? `${String(more)} more folder(s) hold work not on your dashboard. ` : ''}` +
|
|
164
|
+
'`reticle doctor` lists every one');
|
|
165
|
+
return lines;
|
|
166
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repaint the HUD when sign-in or a project link changes on disk.
|
|
3
|
+
*
|
|
4
|
+
* The impact snapshot already reads both files fresh, but it is only PUSHED when a tab attaches,
|
|
5
|
+
* a tool call lands, or the HUD's own Sign in completes. `reticle logout` and `reticle link` run in
|
|
6
|
+
* another process, so neither caused a push: a signed-out machine kept showing the old name, and a
|
|
7
|
+
* freshly linked project kept saying "Not linked", until somebody reloaded or drove something.
|
|
8
|
+
*
|
|
9
|
+
* ponytail: stat polling (`fs.watchFile`), not `fs.watch`. It works on a file that does not exist
|
|
10
|
+
* yet — the usual state of `cloud.json` before a link — and costs one stat per file per interval.
|
|
11
|
+
*/
|
|
12
|
+
import type { ImpactSnapshot } from '@reticlehq/core';
|
|
13
|
+
/** How often each watched file is stat'ed. A second reads as live to somebody switching windows. */
|
|
14
|
+
export declare const ACCOUNT_WATCH_INTERVAL_MS = 1000;
|
|
15
|
+
/** How often `onTick` re-reads what has no file to watch; the platform config is polled as often. */
|
|
16
|
+
export declare const HUD_REFRESH_MS = 30000;
|
|
17
|
+
export interface AccountFilesWatch {
|
|
18
|
+
/** Start watching one file. Watching the same path twice is a no-op. */
|
|
19
|
+
watch(path: string): void;
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function watchAccountFiles(onChange: () => void, intervalMs?: number,
|
|
23
|
+
/** The rest of the platform's side of the HUD, which has no file to watch: run every 30s. */
|
|
24
|
+
onTick?: () => void): AccountFilesWatch;
|
|
25
|
+
/**
|
|
26
|
+
* Push a tab its impact snapshot, or, with `ifChanged`, only when it moved since this last pushed it.
|
|
27
|
+
*
|
|
28
|
+
* The daemon re-reads every tab on a timer so the platform's side of the HUD (sync status, runs on
|
|
29
|
+
* the dashboard, days left) reaches an idle tab without a tool call; resending an unchanged snapshot
|
|
30
|
+
* on every tick would repaint every HUD for nothing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function pushIfMoved(tab: {
|
|
33
|
+
pushImpact(read: () => ImpactSnapshot | undefined, immediate: boolean): void;
|
|
34
|
+
}, read: () => ImpactSnapshot | undefined, ifChanged: boolean): void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repaint the HUD when sign-in or a project link changes on disk.
|
|
3
|
+
*
|
|
4
|
+
* The impact snapshot already reads both files fresh, but it is only PUSHED when a tab attaches,
|
|
5
|
+
* a tool call lands, or the HUD's own Sign in completes. `reticle logout` and `reticle link` run in
|
|
6
|
+
* another process, so neither caused a push: a signed-out machine kept showing the old name, and a
|
|
7
|
+
* freshly linked project kept saying "Not linked", until somebody reloaded or drove something.
|
|
8
|
+
*
|
|
9
|
+
* ponytail: stat polling (`fs.watchFile`), not `fs.watch`. It works on a file that does not exist
|
|
10
|
+
* yet — the usual state of `cloud.json` before a link — and costs one stat per file per interval.
|
|
11
|
+
*/
|
|
12
|
+
import { unwatchFile, watchFile } from 'node:fs';
|
|
13
|
+
/** How often each watched file is stat'ed. A second reads as live to somebody switching windows. */
|
|
14
|
+
export const ACCOUNT_WATCH_INTERVAL_MS = 1_000;
|
|
15
|
+
/** How often `onTick` re-reads what has no file to watch; the platform config is polled as often. */
|
|
16
|
+
export const HUD_REFRESH_MS = 30_000;
|
|
17
|
+
export function watchAccountFiles(onChange, intervalMs = ACCOUNT_WATCH_INTERVAL_MS,
|
|
18
|
+
/** The rest of the platform's side of the HUD, which has no file to watch: run every 30s. */
|
|
19
|
+
onTick) {
|
|
20
|
+
const watched = new Set();
|
|
21
|
+
const ticker = onTick === undefined ? undefined : setInterval(onTick, HUD_REFRESH_MS);
|
|
22
|
+
ticker?.unref();
|
|
23
|
+
const listener = () => {
|
|
24
|
+
onChange();
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
watch(path) {
|
|
28
|
+
if (watched.has(path))
|
|
29
|
+
return;
|
|
30
|
+
watched.add(path);
|
|
31
|
+
// Not persistent: a watcher must never be the reason a daemon cannot exit.
|
|
32
|
+
watchFile(path, { persistent: false, interval: intervalMs }, listener);
|
|
33
|
+
},
|
|
34
|
+
close() {
|
|
35
|
+
if (ticker !== undefined)
|
|
36
|
+
clearInterval(ticker);
|
|
37
|
+
for (const path of watched)
|
|
38
|
+
unwatchFile(path, listener);
|
|
39
|
+
watched.clear();
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** What each tab was last sent by `pushIfMoved`, so an unchanged snapshot is not sent again. */
|
|
44
|
+
const sent = new WeakMap();
|
|
45
|
+
/**
|
|
46
|
+
* Push a tab its impact snapshot, or, with `ifChanged`, only when it moved since this last pushed it.
|
|
47
|
+
*
|
|
48
|
+
* The daemon re-reads every tab on a timer so the platform's side of the HUD (sync status, runs on
|
|
49
|
+
* the dashboard, days left) reaches an idle tab without a tool call; resending an unchanged snapshot
|
|
50
|
+
* on every tick would repaint every HUD for nothing.
|
|
51
|
+
*/
|
|
52
|
+
export function pushIfMoved(tab, read, ifChanged) {
|
|
53
|
+
const snapshot = read();
|
|
54
|
+
const json = JSON.stringify(snapshot);
|
|
55
|
+
if (ifChanged && sent.get(tab) === json)
|
|
56
|
+
return;
|
|
57
|
+
sent.set(tab, json);
|
|
58
|
+
tab.pushImpact(() => snapshot, true);
|
|
59
|
+
}
|
|
@@ -16,9 +16,17 @@ export declare function initImpact(opts: {
|
|
|
16
16
|
* directory may not reach for it. The daemon owns both sides.
|
|
17
17
|
*/
|
|
18
18
|
config?: ConfigSource;
|
|
19
|
+
/** Resolve credentials per project when one daemon serves multiple linked apps. */
|
|
20
|
+
configForRoot?: (root: string) => ConfigSource;
|
|
21
|
+
/** Reticle Coverage for a project root, supplied by the daemon (the ledger is a feature's). */
|
|
22
|
+
coverageForRoot?: (root: string) => () => Record<string, number> | undefined;
|
|
19
23
|
reticleRoot: string | undefined;
|
|
20
24
|
projectName?: string;
|
|
21
25
|
now?: () => number;
|
|
26
|
+
/** Where the machine-wide `~/.reticle` lives. Tests pass a temp dir so they never write the real one. */
|
|
27
|
+
globalRoot?: string;
|
|
28
|
+
/** This build's version, for HUD notices that need a newer SDK. */
|
|
29
|
+
sdkVersion?: string;
|
|
22
30
|
}): ImpactStore | undefined;
|
|
23
31
|
/** The live store for a root (default when omitted), if one has been initialised. */
|
|
24
32
|
export declare function impactStore(root?: string): ImpactStore | undefined;
|
|
@@ -31,7 +31,13 @@ function storeFor(root) {
|
|
|
31
31
|
return undefined;
|
|
32
32
|
let found = stores.get(key);
|
|
33
33
|
if (found === undefined) {
|
|
34
|
-
|
|
34
|
+
const { configForRoot, coverageForRoot, ...opts } = storeOpts;
|
|
35
|
+
found = new ImpactStore({
|
|
36
|
+
...opts,
|
|
37
|
+
...(configForRoot === undefined ? {} : { config: configForRoot(key) }),
|
|
38
|
+
...(coverageForRoot === undefined ? {} : { coverage: coverageForRoot(key) }),
|
|
39
|
+
reticleRoot: key,
|
|
40
|
+
});
|
|
35
41
|
stores.set(key, found);
|
|
36
42
|
}
|
|
37
43
|
return found;
|
|
@@ -50,11 +56,15 @@ export function initImpact(opts) {
|
|
|
50
56
|
return storeFor(undefined);
|
|
51
57
|
if (defaultRoot === undefined) {
|
|
52
58
|
defaultRoot = opts.reticleRoot;
|
|
53
|
-
const { projectName, now, config } = opts;
|
|
59
|
+
const { projectName, now, config, configForRoot, coverageForRoot, globalRoot, sdkVersion } = opts;
|
|
54
60
|
storeOpts = {
|
|
55
61
|
...(projectName === undefined ? {} : { projectName }),
|
|
56
62
|
...(now === undefined ? {} : { now }),
|
|
63
|
+
...(globalRoot === undefined ? {} : { globalRoot }),
|
|
64
|
+
...(sdkVersion === undefined ? {} : { sdkVersion }),
|
|
57
65
|
...(config === undefined ? {} : { config }),
|
|
66
|
+
...(configForRoot === undefined ? {} : { configForRoot }),
|
|
67
|
+
...(coverageForRoot === undefined ? {} : { coverageForRoot }),
|
|
58
68
|
};
|
|
59
69
|
}
|
|
60
70
|
return storeFor(opts.reticleRoot);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type
|
|
1
|
+
import { type ConfigSource } from '../cloud/harness-config.js';
|
|
2
|
+
import { type NoticesSource } from '../cloud/hud-notices-source.js';
|
|
3
3
|
import { type ImpactCounts, type ImpactDefect, type AccountState, type ImpactScope, type ImpactSnapshot } from '@reticlehq/core';
|
|
4
4
|
/** Read a scope, tolerating absence and corruption: a broken file starts over rather than throwing. */
|
|
5
5
|
export declare function readScope(path: string, now: number): ImpactScope;
|
|
@@ -23,6 +23,15 @@ export interface ImpactFoldMeta {
|
|
|
23
23
|
}
|
|
24
24
|
/** Fold one delta into a scope: totals, today's bucket, records and streak. Pure. */
|
|
25
25
|
export declare function applyDelta(scope: ImpactScope, delta: Partial<ImpactCounts>, now: number, meta?: ImpactFoldMeta): ImpactScope;
|
|
26
|
+
/**
|
|
27
|
+
* All time, never smaller than the project being looked at.
|
|
28
|
+
*
|
|
29
|
+
* The two scopes live in different files: the project's in its `.reticle`, the machine's in the
|
|
30
|
+
* home directory. A project whose history began before this machine's ledger (an upgrade, a new
|
|
31
|
+
* laptop, a moved checkout) showed more under "This project" than under "All time", which no reader
|
|
32
|
+
* can believe. The machine has done at least what any one of its projects has.
|
|
33
|
+
*/
|
|
34
|
+
export declare function atLeastProject(global: ImpactScope, project: ImpactScope): ImpactScope;
|
|
26
35
|
/**
|
|
27
36
|
* The live impact record for one project.
|
|
28
37
|
*
|
|
@@ -39,9 +48,13 @@ export declare class ImpactStore {
|
|
|
39
48
|
globalRoot?: string;
|
|
40
49
|
/** Reads whether this machine is signed in. Injected so the store stays testable and pure-ish. */
|
|
41
50
|
account?: () => AccountState;
|
|
42
|
-
/** Where the workspace stands with the free harness offer. Injected so no test touches a network. */
|
|
43
|
-
offer?: OfferSource;
|
|
44
51
|
config?: ConfigSource;
|
|
52
|
+
/** The HUD rail's notices. Defaults to the daemon's cached copy of the published file. */
|
|
53
|
+
notices?: NoticesSource;
|
|
54
|
+
/** This build's version, for notices that need a newer SDK. Passed in: the store reads no package. */
|
|
55
|
+
sdkVersion?: string;
|
|
56
|
+
/** Reticle Coverage per level, as percentages. Injected: the ledger lives in `features/exhaust`. */
|
|
57
|
+
coverage?: () => Record<string, number> | undefined;
|
|
45
58
|
});
|
|
46
59
|
/** Notified after every fold, so the HUD can be pushed a fresh snapshot. */
|
|
47
60
|
onChange(fn: () => void): void;
|