@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
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { SyncStatus, dashboardRunUrl, describeSync, keyRefusalAtLastSync, overallStatus, readSyncSummary, } from '../project/sync-status.js';
|
|
3
|
+
import { describeUnsynced, unsentFlowCount, unsentRunCount, } from '../cloud/unsynced-roots.js';
|
|
4
|
+
import { readDashboardUrl } from '../project/sync-status.js';
|
|
2
5
|
import { dirname, join } from 'node:path';
|
|
3
6
|
import { homedir } from 'node:os';
|
|
4
7
|
import { readAccountState } from '../cloud/account-state.js';
|
|
5
|
-
import {
|
|
8
|
+
import { configForHud } from '../cloud/harness-config.js';
|
|
9
|
+
import { hudNoticesSource } from '../cloud/hud-notices-source.js';
|
|
10
|
+
import { selectNotices } from '@reticlehq/core/hud';
|
|
6
11
|
import { ReticleDir, IMPACT_DAILY_BUCKETS, IMPACT_DEFECT_LIMIT, IMPACT_SCHEMA_VERSION, ImpactScopeSchema, addImpactCounts, emptyImpactCounts, emptyImpactRecords, estimateImpactSavings, } from '@reticlehq/core';
|
|
7
12
|
/**
|
|
8
13
|
* Where Reticle keeps the record of what it has done for you.
|
|
9
14
|
*
|
|
10
|
-
* Two scopes, two files
|
|
11
|
-
*
|
|
12
|
-
*
|
|
15
|
+
* Two scopes, two files: the project's own `.reticle/impact.json`, and a machine-wide
|
|
16
|
+
* `~/.reticle/impact.json` that answers "what has Reticle done for me overall" across every app you
|
|
17
|
+
* have instrumented.
|
|
13
18
|
*
|
|
14
|
-
* This is NOT telemetry. Telemetry answers our questions about the product
|
|
15
|
-
*
|
|
19
|
+
* This is NOT telemetry. Telemetry answers our questions about the product; this answers the user's
|
|
20
|
+
* question about their own work. A linked project's record syncs to that user's own dashboard (the
|
|
21
|
+
* sync cycle's `impact` kind); the machine-wide record never leaves the machine.
|
|
16
22
|
*/
|
|
17
23
|
/** Writes are debounced: a verification loop is 50-200 calls, and each one is a counter bump. */
|
|
18
24
|
const WRITE_DEBOUNCE_MS = 800;
|
|
19
|
-
/** The project's cloud binding, written by `reticle link`. Absent for an unlinked project. */
|
|
20
|
-
const CLOUD_LINK_FILE = 'cloud.json';
|
|
21
25
|
/**
|
|
22
26
|
* `reticleRoot` is the project's own `.reticle` directory (what every other store here is handed);
|
|
23
27
|
* the global scope lives beside the daemon's own state in `~/.reticle`.
|
|
@@ -32,26 +36,6 @@ function impactPaths(reticleRoot, globalRoot) {
|
|
|
32
36
|
global: join(globalRoot, ReticleDir.ROOT, ReticleDir.IMPACT_FILE),
|
|
33
37
|
};
|
|
34
38
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Where this project's dashboard lives, if `reticle link` recorded one.
|
|
37
|
-
*
|
|
38
|
-
* Read from the link file rather than derived from the API url, because the API origin and the
|
|
39
|
-
* console origin are different hosts in every deployment that is not a laptop. Synchronous and
|
|
40
|
-
* best-effort, like every other read in this file: a missing or malformed link file means no link
|
|
41
|
-
* in the HUD, never a failed tool call.
|
|
42
|
-
*/
|
|
43
|
-
function readDashboardUrl(reticleRoot) {
|
|
44
|
-
try {
|
|
45
|
-
const raw = JSON.parse(readFileSync(join(reticleRoot, CLOUD_LINK_FILE), 'utf8'));
|
|
46
|
-
if ('object' !== typeof raw || null === raw)
|
|
47
|
-
return undefined;
|
|
48
|
-
const value = raw['dashboardUrl'];
|
|
49
|
-
return 'string' === typeof value && value.length > 0 ? value : undefined;
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
39
|
function emptyScope(now) {
|
|
56
40
|
const counts = emptyImpactCounts();
|
|
57
41
|
return {
|
|
@@ -92,6 +76,12 @@ function writeScope(path, scope) {
|
|
|
92
76
|
// memory and the next write attempt carries them.
|
|
93
77
|
}
|
|
94
78
|
}
|
|
79
|
+
/** The daemon's cached copy of the HUD notices file, beside the machine-wide impact record. */
|
|
80
|
+
const HUD_NOTICES_CACHE_FILE = 'hud-notices.json';
|
|
81
|
+
/** How long a sync status is reused before it is read again. */
|
|
82
|
+
const SYNC_STATUS_EVERY_MS = 10_000;
|
|
83
|
+
/** When the caller did not say which build this is: matches only notices with no `minSdk`. */
|
|
84
|
+
const UNKNOWN_SDK_VERSION = '0.0.0';
|
|
95
85
|
/** YYYY-MM-DD in local time - the day boundary a person recognises, not UTC's. */
|
|
96
86
|
export function isoDay(now) {
|
|
97
87
|
const d = new Date(now);
|
|
@@ -105,33 +95,55 @@ function isNextDay(a, b) {
|
|
|
105
95
|
const next = new Date(`${b}T00:00:00`);
|
|
106
96
|
return 1 === Math.round((next.getTime() - prev.getTime()) / 86_400_000);
|
|
107
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Consecutive days ending at the newest recorded day, read from the days themselves.
|
|
100
|
+
*
|
|
101
|
+
* It was a counter bumped when a fold opened a new day and compared only with the bucket before it,
|
|
102
|
+
* so one stray day in between (a late flush from another daemon, a writer with a frozen clock) reset
|
|
103
|
+
* it to 1. Counting back from the newest date means no out-of-order write can shorten it.
|
|
104
|
+
*/
|
|
105
|
+
function streakEndingAtLatest(sortedDates) {
|
|
106
|
+
let streak = 0;
|
|
107
|
+
let later;
|
|
108
|
+
for (let i = sortedDates.length - 1; i >= 0; i -= 1) {
|
|
109
|
+
const date = sortedDates[i];
|
|
110
|
+
if (date === undefined)
|
|
111
|
+
break;
|
|
112
|
+
if (later !== undefined && !isNextDay(date, later))
|
|
113
|
+
break;
|
|
114
|
+
streak += 1;
|
|
115
|
+
later = date;
|
|
116
|
+
}
|
|
117
|
+
return streak;
|
|
118
|
+
}
|
|
108
119
|
/** Fold one delta into a scope: totals, today's bucket, records and streak. Pure. */
|
|
109
120
|
export function applyDelta(scope, delta, now, meta = {}) {
|
|
110
121
|
const today = isoDay(now);
|
|
111
122
|
const counts = addImpactCounts(scope.counts, delta);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
days.push({ date: today, counts: addImpactCounts(emptyImpactCounts(), delta) });
|
|
123
|
+
// One bucket per date, wherever the delta's date falls. The machine-wide record has many writers
|
|
124
|
+
// and a late flush carries an older date, so "the last bucket is today" is not something a fold
|
|
125
|
+
// may assume — appending on that assumption duplicated dates and put them out of order.
|
|
126
|
+
const byDate = new Map();
|
|
127
|
+
for (const day of scope.days) {
|
|
128
|
+
byDate.set(day.date, addImpactCounts(byDate.get(day.date) ?? emptyImpactCounts(), day.counts));
|
|
119
129
|
}
|
|
130
|
+
const todayCounts = addImpactCounts(byDate.get(today) ?? emptyImpactCounts(), delta);
|
|
131
|
+
byDate.set(today, todayCounts);
|
|
132
|
+
const dates = [...byDate.keys()].sort();
|
|
133
|
+
const days = dates.map((date) => ({ date, counts: byDate.get(date) ?? emptyImpactCounts() }));
|
|
120
134
|
while (days.length > IMPACT_DAILY_BUCKETS)
|
|
121
135
|
days.shift();
|
|
122
|
-
const todayCounts = days[days.length - 1]?.counts ?? emptyImpactCounts();
|
|
123
|
-
const previousDay = days[days.length - 2];
|
|
124
136
|
const records = { ...scope.records };
|
|
125
137
|
records.bestVerdictDay = Math.max(records.bestVerdictDay, todayCounts.verdicts);
|
|
126
138
|
records.bestDefectDay = Math.max(records.bestDefectDay, todayCounts.failed);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
records.streakDays
|
|
134
|
-
|
|
139
|
+
// The window keeps IMPACT_DAILY_BUCKETS days, so a streak longer than it cannot be read off the
|
|
140
|
+
// dates alone: when the whole window is one unbroken run, it continues the streak already held.
|
|
141
|
+
const inWindow = streakEndingAtLatest(dates);
|
|
142
|
+
const unbroken = inWindow === dates.length && scope.days.length >= IMPACT_DAILY_BUCKETS;
|
|
143
|
+
const newDay = !scope.days.some((day) => day.date === today);
|
|
144
|
+
records.streakDays = unbroken
|
|
145
|
+
? Math.max(inWindow, scope.records.streakDays + (newDay ? 1 : 0))
|
|
146
|
+
: inWindow;
|
|
135
147
|
records.bestStreakDays = Math.max(records.bestStreakDays, records.streakDays);
|
|
136
148
|
records.longestRunMs = Math.max(records.longestRunMs, meta.runMs ?? 0);
|
|
137
149
|
/*
|
|
@@ -150,6 +162,41 @@ export function applyDelta(scope, delta, now, meta = {}) {
|
|
|
150
162
|
defects,
|
|
151
163
|
};
|
|
152
164
|
}
|
|
165
|
+
/** The larger of two counters, key by key. */
|
|
166
|
+
function maxEach(a, b) {
|
|
167
|
+
const out = { ...a };
|
|
168
|
+
for (const key of Object.keys(b))
|
|
169
|
+
out[key] = Math.max(a[key] ?? 0, b[key] ?? 0);
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* All time, never smaller than the project being looked at.
|
|
174
|
+
*
|
|
175
|
+
* The two scopes live in different files: the project's in its `.reticle`, the machine's in the
|
|
176
|
+
* home directory. A project whose history began before this machine's ledger (an upgrade, a new
|
|
177
|
+
* laptop, a moved checkout) showed more under "This project" than under "All time", which no reader
|
|
178
|
+
* can believe. The machine has done at least what any one of its projects has.
|
|
179
|
+
*/
|
|
180
|
+
export function atLeastProject(global, project) {
|
|
181
|
+
// The earlier of the two starts; zero is "never recorded", not the epoch.
|
|
182
|
+
const starts = [global.since, project.since].filter((t) => 0 < t);
|
|
183
|
+
return {
|
|
184
|
+
...global,
|
|
185
|
+
counts: maxEach(global.counts, project.counts),
|
|
186
|
+
records: maxEach(global.records, project.records),
|
|
187
|
+
savings: {
|
|
188
|
+
tokens: {
|
|
189
|
+
...global.savings.tokens,
|
|
190
|
+
value: Math.max(global.savings.tokens.value, project.savings.tokens.value),
|
|
191
|
+
},
|
|
192
|
+
minutes: {
|
|
193
|
+
...global.savings.minutes,
|
|
194
|
+
value: Math.max(global.savings.minutes.value, project.savings.minutes.value),
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
since: 0 === starts.length ? 0 : Math.min(...starts),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
153
200
|
/**
|
|
154
201
|
* The live impact record for one project.
|
|
155
202
|
*
|
|
@@ -158,6 +205,9 @@ export function applyDelta(scope, delta, now, meta = {}) {
|
|
|
158
205
|
*/
|
|
159
206
|
export class ImpactStore {
|
|
160
207
|
#paths;
|
|
208
|
+
#root;
|
|
209
|
+
/** The sync status, re-read at most every SYNC_STATUS_EVERY_MS: it reads every run file. */
|
|
210
|
+
#sync;
|
|
161
211
|
#now;
|
|
162
212
|
#projectName;
|
|
163
213
|
#dashboardUrl;
|
|
@@ -175,10 +225,12 @@ export class ImpactStore {
|
|
|
175
225
|
#timer;
|
|
176
226
|
#onChange;
|
|
177
227
|
#account;
|
|
178
|
-
/** Where this workspace stands with the free harness offer. Cached; see harness-offer.ts. */
|
|
179
|
-
#offer;
|
|
180
228
|
#config;
|
|
229
|
+
#notices;
|
|
230
|
+
#sdkVersion;
|
|
231
|
+
#coverage;
|
|
181
232
|
constructor(opts) {
|
|
233
|
+
this.#coverage = opts.coverage;
|
|
182
234
|
this.#paths = impactPaths(opts.reticleRoot, opts.globalRoot ?? homedir());
|
|
183
235
|
// Resolved per snapshot, not cached: a user who runs `reticle login` in another terminal must
|
|
184
236
|
// see the HUD change without restarting the daemon that is watching their app.
|
|
@@ -186,9 +238,13 @@ export class ImpactStore {
|
|
|
186
238
|
this.#now = opts.now ?? (() => Date.now());
|
|
187
239
|
this.#projectName = opts.projectName;
|
|
188
240
|
this.#dashboardUrl = readDashboardUrl(opts.reticleRoot);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
241
|
+
this.#root = opts.reticleRoot;
|
|
242
|
+
this.#notices =
|
|
243
|
+
opts.notices ??
|
|
244
|
+
hudNoticesSource({
|
|
245
|
+
cacheFile: join(opts.globalRoot ?? homedir(), ReticleDir.ROOT, HUD_NOTICES_CACHE_FILE),
|
|
246
|
+
});
|
|
247
|
+
this.#sdkVersion = opts.sdkVersion ?? UNKNOWN_SDK_VERSION;
|
|
192
248
|
// No default: the loader lives in `features/harness` and this file may not reach for it.
|
|
193
249
|
// A store built without one simply reports no harness config, which the HUD renders as no row.
|
|
194
250
|
this.#config = opts.config ?? { read: () => undefined };
|
|
@@ -196,6 +252,46 @@ export class ImpactStore {
|
|
|
196
252
|
this.#project = readScope(this.#paths.project, now);
|
|
197
253
|
this.#global = readScope(this.#paths.global, now);
|
|
198
254
|
}
|
|
255
|
+
#syncStatus(dashboardUrl) {
|
|
256
|
+
const now = this.#now();
|
|
257
|
+
if (this.#sync !== undefined && now - this.#sync.at < SYNC_STATUS_EVERY_MS)
|
|
258
|
+
return this.#sync.value;
|
|
259
|
+
// Not linked: one line when runs or flows sit here that nothing will send, and nothing otherwise.
|
|
260
|
+
// `pending` counts both, so the HUD's existing "N not sent" includes a flow saved with no run.
|
|
261
|
+
if (dashboardUrl === undefined) {
|
|
262
|
+
const runs = unsentRunCount(this.#root);
|
|
263
|
+
const flows = unsentFlowCount(this.#root, false);
|
|
264
|
+
const value = 0 === runs + flows
|
|
265
|
+
? undefined
|
|
266
|
+
: {
|
|
267
|
+
status: SyncStatus.LOCAL_ONLY,
|
|
268
|
+
pending: runs + flows,
|
|
269
|
+
runs,
|
|
270
|
+
flows,
|
|
271
|
+
said: describeUnsynced({ root: this.#root, runs, flows, linked: false }, dirname(this.#root)),
|
|
272
|
+
};
|
|
273
|
+
this.#sync = { at: now, value };
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
276
|
+
const summary = readSyncSummary(this.#root, true);
|
|
277
|
+
const refusal = keyRefusalAtLastSync(this.#root);
|
|
278
|
+
const latest = summary.latestOnPlatform;
|
|
279
|
+
const value = {
|
|
280
|
+
status: overallStatus(summary),
|
|
281
|
+
runs: summary.runs,
|
|
282
|
+
onPlatform: summary.onPlatform,
|
|
283
|
+
pending: summary.pending,
|
|
284
|
+
refused: summary.refused.length + summary.refusedMore,
|
|
285
|
+
...(summary.lastPushAt === undefined ? {} : { lastPushAt: summary.lastPushAt }),
|
|
286
|
+
// The run that just synced, on its own page — the HUD's "see it in your dashboard".
|
|
287
|
+
...(latest === undefined ? {} : { runUrl: dashboardRunUrl(dashboardUrl, latest) }),
|
|
288
|
+
said: describeSync(summary, now),
|
|
289
|
+
// The HUD's chip: a refused key is not "0 waiting".
|
|
290
|
+
...(refusal === undefined ? {} : { keyRefused: refusal }),
|
|
291
|
+
};
|
|
292
|
+
this.#sync = { at: now, value };
|
|
293
|
+
return value;
|
|
294
|
+
}
|
|
199
295
|
/** Notified after every fold, so the HUD can be pushed a fresh snapshot. */
|
|
200
296
|
onChange(fn) {
|
|
201
297
|
this.#onChange = fn;
|
|
@@ -214,28 +310,38 @@ export class ImpactStore {
|
|
|
214
310
|
const snap = {
|
|
215
311
|
schemaVersion: IMPACT_SCHEMA_VERSION,
|
|
216
312
|
project: this.#project,
|
|
217
|
-
global: this.#global,
|
|
313
|
+
global: atLeastProject(this.#global, this.#project),
|
|
218
314
|
};
|
|
219
315
|
if (this.#projectName !== undefined)
|
|
220
316
|
snap.projectName = this.#projectName;
|
|
317
|
+
// Re-read, like the account: `reticle link` runs in another terminal while this store lives as
|
|
318
|
+
// long as the daemon, so a construction-time read said "Not linked" until a restart.
|
|
319
|
+
this.#dashboardUrl = readDashboardUrl(this.#root);
|
|
221
320
|
if (this.#dashboardUrl !== undefined)
|
|
222
321
|
snap.dashboardUrl = this.#dashboardUrl;
|
|
223
322
|
snap.account = this.#account();
|
|
224
|
-
const cfgForOffer = this.#config.read();
|
|
225
|
-
const offer = this.#offer.read();
|
|
226
|
-
// Joined here because this is the one place that holds BOTH the offer and the platform config.
|
|
227
|
-
// The card reads the offer, so readiness has to travel on it rather than being re-derived in a
|
|
228
|
-
// presenter that has no business knowing what a provider key is.
|
|
229
|
-
if (offer !== undefined && cfgForOffer !== undefined)
|
|
230
|
-
offer.drivable = cfgForOffer.providerReady;
|
|
231
|
-
// Absent means "we have not heard", which the HUD renders as nothing at all. Never defaulted to
|
|
232
|
-
// `{claimed:false}`: that would advertise the offer to everyone who is offline.
|
|
233
|
-
if (offer !== undefined)
|
|
234
|
-
snap.harnessOffer = offer;
|
|
235
323
|
// Absent stays absent: the HUD reads that as "we have not heard" and renders no control.
|
|
236
324
|
const cfg = this.#config.read();
|
|
237
325
|
if (cfg !== undefined)
|
|
238
|
-
snap.harnessConfig = cfg;
|
|
326
|
+
snap.harnessConfig = configForHud(cfg, this.#now());
|
|
327
|
+
// Chosen here, where the account and the entitlement are both known. Absent when nothing applies,
|
|
328
|
+
// so the HUD falls back to the slides bundled with the SDK.
|
|
329
|
+
const notices = selectNotices(this.#notices.read(), {
|
|
330
|
+
signedIn: snap.account?.signedIn,
|
|
331
|
+
entitled: cfg?.harnessEntitled,
|
|
332
|
+
sdkVersion: this.#sdkVersion,
|
|
333
|
+
now: this.#now(),
|
|
334
|
+
});
|
|
335
|
+
if (0 < notices.length)
|
|
336
|
+
snap.notices = notices;
|
|
337
|
+
const coverage = this.#coverage?.();
|
|
338
|
+
if (coverage !== undefined)
|
|
339
|
+
snap.coverage = coverage;
|
|
340
|
+
// Only for a linked project: an unlinked one has nothing on the platform, and the HUD already
|
|
341
|
+
// offers the way to link it.
|
|
342
|
+
const sync = this.#syncStatus(this.#dashboardUrl);
|
|
343
|
+
if (sync !== undefined)
|
|
344
|
+
snap.sync = sync;
|
|
239
345
|
return snap;
|
|
240
346
|
}
|
|
241
347
|
/** Write now (process exit, tests). */
|
|
@@ -55,6 +55,7 @@ export declare function dischargeInlineIntent(deps: ToolDeps, sessionId: string
|
|
|
55
55
|
verdictId: string;
|
|
56
56
|
grade: string;
|
|
57
57
|
at: number;
|
|
58
|
+
runId?: string;
|
|
58
59
|
},
|
|
59
60
|
/** `file:line` of the element this verdict acted on, when there was one. */
|
|
60
61
|
sourceLabel?: string): Promise<void>;
|
|
@@ -25,7 +25,7 @@ import { IntentFileSchema, IntentState, amendIntent, isActionLabel, } from '@ret
|
|
|
25
25
|
import { IntentDir, ReticleDir } from '@reticlehq/core';
|
|
26
26
|
import { reticleDirPaths } from '../project/dir/reticle-dir.js';
|
|
27
27
|
import { withFileLock } from '../project/file-lock.js';
|
|
28
|
-
import { subjectFor } from './intent-subject.js';
|
|
28
|
+
import { subjectFor, UNSORTED_SUBJECT } from './intent-subject.js';
|
|
29
29
|
import { emptyShard, indexFrom, IntentShardSchema, IntentStatus, recordFromIntent, serialise, shardsFrom, statusFromState, } from './intent-shard.js';
|
|
30
30
|
import { writeFileAtomic } from '../project/fs/write-atomic.js';
|
|
31
31
|
const JSON_SUFFIX = '.json';
|
|
@@ -199,13 +199,25 @@ export class IntentShardStore {
|
|
|
199
199
|
const subject = flow !== undefined
|
|
200
200
|
? subjectFor({ surface: { flow } })
|
|
201
201
|
: (facts.subject ??
|
|
202
|
-
|
|
202
|
+
// `unsorted` is the absence of a subject, so new evidence may still file the record.
|
|
203
|
+
(UNSORTED_SUBJECT === existing?.subject ? undefined : existing?.subject) ??
|
|
203
204
|
subjectFor({ surface: next.surface, binding: next.binding }));
|
|
204
205
|
const why = facts.why ?? existing?.why;
|
|
205
206
|
const source = facts.source ?? existing?.source;
|
|
207
|
+
// New words keep no check bound to the old ones: a later green on it would "prove" words it
|
|
208
|
+
// never tested. A binding the change brings with it stands.
|
|
209
|
+
const kept = existing !== undefined && existing.statement !== next.statement
|
|
210
|
+
? { ...existing, binding: undefined }
|
|
211
|
+
: existing;
|
|
212
|
+
// Bound only while a check is bound: a record whose check was taken off (new words, a decision)
|
|
213
|
+
// said `bound` with none, and a check naming it then proved nothing and said nothing.
|
|
214
|
+
const merged = { ...kept, ...next };
|
|
215
|
+
const state = IntentState.BOUND === merged.state && merged.binding === undefined
|
|
216
|
+
? IntentState.DECLARED
|
|
217
|
+
: merged.state;
|
|
206
218
|
return {
|
|
207
|
-
...
|
|
208
|
-
|
|
219
|
+
...merged,
|
|
220
|
+
state,
|
|
209
221
|
subject,
|
|
210
222
|
status: this.#statusOf(next, existing, facts.status),
|
|
211
223
|
updatedAt: this.#clock.now(),
|
|
@@ -63,14 +63,17 @@ declare const IntentRecordSchema: z.ZodObject<{
|
|
|
63
63
|
verdictId: z.ZodString;
|
|
64
64
|
grade: z.ZodString;
|
|
65
65
|
at: z.ZodNumber;
|
|
66
|
+
runId: z.ZodOptional<z.ZodString>;
|
|
66
67
|
}, "strip", z.ZodTypeAny, {
|
|
67
68
|
at: number;
|
|
68
69
|
grade: string;
|
|
69
70
|
verdictId: string;
|
|
71
|
+
runId?: string | undefined;
|
|
70
72
|
}, {
|
|
71
73
|
at: number;
|
|
72
74
|
grade: string;
|
|
73
75
|
verdictId: string;
|
|
76
|
+
runId?: string | undefined;
|
|
74
77
|
}>>;
|
|
75
78
|
amended: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
76
79
|
statement: z.ZodString;
|
|
@@ -112,6 +115,7 @@ declare const IntentRecordSchema: z.ZodObject<{
|
|
|
112
115
|
at: number;
|
|
113
116
|
grade: string;
|
|
114
117
|
verdictId: string;
|
|
118
|
+
runId?: string | undefined;
|
|
115
119
|
} | undefined;
|
|
116
120
|
amended?: {
|
|
117
121
|
at: number;
|
|
@@ -137,6 +141,7 @@ declare const IntentRecordSchema: z.ZodObject<{
|
|
|
137
141
|
at: number;
|
|
138
142
|
grade: string;
|
|
139
143
|
verdictId: string;
|
|
144
|
+
runId?: string | undefined;
|
|
140
145
|
} | undefined;
|
|
141
146
|
amended?: {
|
|
142
147
|
at: number;
|
|
@@ -170,14 +175,17 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
170
175
|
verdictId: z.ZodString;
|
|
171
176
|
grade: z.ZodString;
|
|
172
177
|
at: z.ZodNumber;
|
|
178
|
+
runId: z.ZodOptional<z.ZodString>;
|
|
173
179
|
}, "strip", z.ZodTypeAny, {
|
|
174
180
|
at: number;
|
|
175
181
|
grade: string;
|
|
176
182
|
verdictId: string;
|
|
183
|
+
runId?: string | undefined;
|
|
177
184
|
}, {
|
|
178
185
|
at: number;
|
|
179
186
|
grade: string;
|
|
180
187
|
verdictId: string;
|
|
188
|
+
runId?: string | undefined;
|
|
181
189
|
}>>;
|
|
182
190
|
amended: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
183
191
|
statement: z.ZodString;
|
|
@@ -219,6 +227,7 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
219
227
|
at: number;
|
|
220
228
|
grade: string;
|
|
221
229
|
verdictId: string;
|
|
230
|
+
runId?: string | undefined;
|
|
222
231
|
} | undefined;
|
|
223
232
|
amended?: {
|
|
224
233
|
at: number;
|
|
@@ -244,6 +253,7 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
244
253
|
at: number;
|
|
245
254
|
grade: string;
|
|
246
255
|
verdictId: string;
|
|
256
|
+
runId?: string | undefined;
|
|
247
257
|
} | undefined;
|
|
248
258
|
amended?: {
|
|
249
259
|
at: number;
|
|
@@ -252,7 +262,6 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
252
262
|
}>>;
|
|
253
263
|
}, "strip", z.ZodTypeAny, {
|
|
254
264
|
version: 1;
|
|
255
|
-
subject: string;
|
|
256
265
|
intents: Record<string, {
|
|
257
266
|
status: "proved" | "proposed" | "agreed" | "stale";
|
|
258
267
|
state: "proved" | "declared" | "bound";
|
|
@@ -273,15 +282,16 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
273
282
|
at: number;
|
|
274
283
|
grade: string;
|
|
275
284
|
verdictId: string;
|
|
285
|
+
runId?: string | undefined;
|
|
276
286
|
} | undefined;
|
|
277
287
|
amended?: {
|
|
278
288
|
at: number;
|
|
279
289
|
statement: string;
|
|
280
290
|
}[] | undefined;
|
|
281
291
|
}>;
|
|
292
|
+
subject: string;
|
|
282
293
|
}, {
|
|
283
294
|
version: 1;
|
|
284
|
-
subject: string;
|
|
285
295
|
intents: Record<string, {
|
|
286
296
|
status: "proved" | "proposed" | "agreed" | "stale";
|
|
287
297
|
state: "proved" | "declared" | "bound";
|
|
@@ -302,12 +312,14 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
302
312
|
at: number;
|
|
303
313
|
grade: string;
|
|
304
314
|
verdictId: string;
|
|
315
|
+
runId?: string | undefined;
|
|
305
316
|
} | undefined;
|
|
306
317
|
amended?: {
|
|
307
318
|
at: number;
|
|
308
319
|
statement: string;
|
|
309
320
|
}[] | undefined;
|
|
310
321
|
}>;
|
|
322
|
+
subject: string;
|
|
311
323
|
}>;
|
|
312
324
|
export type IntentShard = z.infer<typeof IntentShardSchema>;
|
|
313
325
|
export declare const IntentIndexSchema: z.ZodObject<{
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
1
3
|
import { z } from 'zod';
|
|
4
|
+
import { StatementSource, classifyStatement, splitStatements, } from '@reticlehq/core/artifacts';
|
|
5
|
+
import { redactFeedbackText } from '../../telemetry/feedback.js';
|
|
6
|
+
import { reticleDirPaths } from '../project/dir/reticle-dir.js';
|
|
2
7
|
import { IntentStore } from './intent-store.js';
|
|
3
8
|
import { IntentShardStore } from './intent-shard-store.js';
|
|
4
9
|
import { IntentStatus } from './intent-shard.js';
|
|
5
|
-
import {
|
|
10
|
+
import { UNSORTED_SUBJECT } from './intent-subject.js';
|
|
11
|
+
import { ReticleDir, ReticleTool, apiKeyFrom } from '@reticlehq/core';
|
|
6
12
|
import { sessionIdShape } from '../../surface/tools/tool-kit.js';
|
|
7
13
|
import { PredicateSchema } from '@reticlehq/engine/question/predicate/predicate.js';
|
|
8
14
|
import { sessionRoot } from '../project/session-root.js';
|
|
@@ -32,7 +38,7 @@ const MIGRATE = 'migrate';
|
|
|
32
38
|
export const INTENT_TOOLS = [
|
|
33
39
|
{
|
|
34
40
|
name: ReticleTool.INTENT,
|
|
35
|
-
description: 'Record what a change is SUPPOSED to make true, as a durable statement ABOUT THE PRODUCT that a teammate who was not here will understand in six months — name the behaviour, not this run or its step number, and never "renders cleanly", which nothing can check. It is SHARED memory: pooled per project and read back by later agents. Capture it while you still know — then verification does not have to re-derive it from the DOM later. { action:"declare", intents:[{ id, statement, surface? }] } takes prose and needs NO predicate: at declare time there is often no route, no ref and no code yet, and a predicate demanded there is just a mechanism. Declare EARLY (as you build) and batch them — one call per feature is the whole budget. { action:"bind", id, binding } attaches the predicate that would prove it once you know how; an intent with no binding is not a failure, it is the most interesting row in the ledger — something meant that nothing can currently prove. { action:"list" } returns what is still open.
|
|
41
|
+
description: 'Record what a change is SUPPOSED to make true, as a durable statement ABOUT THE PRODUCT that a teammate who was not here will understand in six months — name the behaviour, not this run or its step number, and never "renders cleanly", which nothing can check. It is SHARED memory: pooled per project and read back by later agents. Capture it while you still know — then verification does not have to re-derive it from the DOM later. { action:"declare", intents:[{ id, statement, surface? }] } takes prose and needs NO predicate: at declare time there is often no route, no ref and no code yet, and a predicate demanded there is just a mechanism. Declare EARLY (as you build) and batch them — one call per feature is the whole budget. { action:"bind", id, binding } attaches the predicate that would prove it once you know how; an intent with no binding is not a failure, it is the most interesting row in the ledger — something meant that nothing can currently prove. { action:"list" } returns what is still open. Pass `request` (what the user asked, verbatim) once per task. Stored in .reticle/intent/, git-checked.',
|
|
36
42
|
example: {
|
|
37
43
|
action: DECLARE,
|
|
38
44
|
intents: [
|
|
@@ -74,6 +80,7 @@ export const INTENT_TOOLS = [
|
|
|
74
80
|
.min(1)
|
|
75
81
|
.optional()
|
|
76
82
|
.describe('declare only. Batchable — declare every intent for a feature in one call.'),
|
|
83
|
+
request: z.string().optional().describe("declare: the user's words, verbatim."),
|
|
77
84
|
id: z.string().optional().describe('bind only: which intent the predicate proves.'),
|
|
78
85
|
/*
|
|
79
86
|
* The predicate schema, not `unknown`.
|
|
@@ -101,6 +108,11 @@ export const INTENT_TOOLS = [
|
|
|
101
108
|
.optional()
|
|
102
109
|
.describe('declare only: statements not stored, and why.'),
|
|
103
110
|
path: z.string().optional().describe('Where the ledger was written.'),
|
|
111
|
+
filesNotFound: z.array(z.string()).optional().describe('surface.files not in the project'),
|
|
112
|
+
noSubject: z
|
|
113
|
+
.object({ ids: z.array(z.string()), fix: z.string() })
|
|
114
|
+
.optional()
|
|
115
|
+
.describe('declare only: intents filed under nothing, and how to file them'),
|
|
104
116
|
entries: z
|
|
105
117
|
.array(z.unknown())
|
|
106
118
|
.optional()
|
|
@@ -155,19 +167,125 @@ export const INTENT_TOOLS = [
|
|
|
155
167
|
return { intents: await store.open() };
|
|
156
168
|
}
|
|
157
169
|
const raw = args['intents'];
|
|
170
|
+
const request = asString(args['request']);
|
|
171
|
+
if (request !== undefined && 0 < request.trim().length) {
|
|
172
|
+
await recordRequest(deps, root, request, Array.isArray(raw) ? raw : []);
|
|
173
|
+
if (!Array.isArray(raw) || 0 === raw.length)
|
|
174
|
+
return { request: 'recorded', path: root };
|
|
175
|
+
}
|
|
158
176
|
// Refused, not read as an empty list: `declare` with nothing to declare stored nothing and
|
|
159
177
|
// answered `{ intents: [] }`, which an agent reads as a declaration that worked (#1118).
|
|
160
178
|
if (!Array.isArray(raw) || 0 === raw.length) {
|
|
161
179
|
throw new Error(`${ReticleTool.INTENT} declare: \`intents\` must be a non-empty array of { id, statement }, got ${raw === undefined ? 'nothing' : JSON.stringify(raw)} — nothing was stored`);
|
|
162
180
|
}
|
|
163
|
-
const entries = raw;
|
|
181
|
+
const { entries, missing } = await withExistingFiles(deps, dirname(root), raw);
|
|
164
182
|
const declared = await store.declare(entries);
|
|
165
183
|
// Said, not swallowed: an agent that declared something and finds nothing stored would
|
|
166
184
|
// otherwise conclude the ledger lost it.
|
|
167
185
|
const refused = entries
|
|
168
186
|
.filter((entry) => isActionLabel(entry.statement))
|
|
169
187
|
.map((entry) => ({ id: entry.id, reason: STEP_LABEL_REFUSAL }));
|
|
170
|
-
|
|
188
|
+
// Asked, not refused: prose with nowhere to live is still worth keeping, but an agent
|
|
189
|
+
// looking for it later finds it by its subject, and the Memory page warns about these.
|
|
190
|
+
const unsorted = declared
|
|
191
|
+
.filter((intent) => UNSORTED_SUBJECT === intent.subject)
|
|
192
|
+
.map((intent) => intent.id);
|
|
193
|
+
return {
|
|
194
|
+
intents: declared,
|
|
195
|
+
...(0 === refused.length ? {} : { refused }),
|
|
196
|
+
// Named, never kept as a fact's source: a path that is not in the project is a guess.
|
|
197
|
+
...(0 === missing.length ? {} : { filesNotFound: missing }),
|
|
198
|
+
...(0 === unsorted.length ? {} : { noSubject: { ids: unsorted, fix: NO_SUBJECT_FIX } }),
|
|
199
|
+
path: root,
|
|
200
|
+
};
|
|
171
201
|
},
|
|
172
202
|
},
|
|
173
203
|
];
|
|
204
|
+
/**
|
|
205
|
+
* The entries with each `surface.files` path that is not in the project left out, and those paths.
|
|
206
|
+
* An agent declared `src/pages/SavedItems.tsx` for `src/views/SavedItems.tsx`, and the dashboard
|
|
207
|
+
* showed the wrong file as the fact's source.
|
|
208
|
+
*/
|
|
209
|
+
async function withExistingFiles(deps, projectDir, entries) {
|
|
210
|
+
const missing = [];
|
|
211
|
+
const kept = await Promise.all(entries.map(async (entry) => {
|
|
212
|
+
const surface = entry.surface;
|
|
213
|
+
if (!Array.isArray(surface?.files))
|
|
214
|
+
return entry;
|
|
215
|
+
const files = [];
|
|
216
|
+
for (const file of surface.files)
|
|
217
|
+
if ('string' === typeof file && (await deps.fs.exists(join(projectDir, file))))
|
|
218
|
+
files.push(file);
|
|
219
|
+
else if ('string' === typeof file)
|
|
220
|
+
missing.push(file);
|
|
221
|
+
return { ...entry, surface: { ...surface, files } };
|
|
222
|
+
}));
|
|
223
|
+
return { entries: kept, missing };
|
|
224
|
+
}
|
|
225
|
+
const NO_SUBJECT_FIX = 'Nothing says what these are about, so an agent looking for them cannot find them: declare each again with surface.route (the page it is about) or surface.flow.';
|
|
226
|
+
const MAX_REQUEST = 20_000;
|
|
227
|
+
const MAX_STATEMENT = 500;
|
|
228
|
+
const MAX_STATEMENTS = 100;
|
|
229
|
+
const PROJECT_CONFIG = '.reticle.json';
|
|
230
|
+
/** Credentials and personal data out, length capped: the same rules feedback reports follow. */
|
|
231
|
+
function redactSecrets(text, max) {
|
|
232
|
+
return redactFeedbackText(text, max).text;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Whether the request goes to the platform with the runs that verify it.
|
|
236
|
+
*
|
|
237
|
+
* A LINKED project shares it unless `.reticle.json` says `"shareRequests": false`: the platform
|
|
238
|
+
* reads what each run was for, which is half of what a run means. An unlinked project has nowhere
|
|
239
|
+
* to send it, and `"shareRequests": true` still shares from one that links later.
|
|
240
|
+
*/
|
|
241
|
+
function sharesRequests(projectDir, reticleRoot) {
|
|
242
|
+
let setting;
|
|
243
|
+
try {
|
|
244
|
+
const config = JSON.parse(readFileSync(join(projectDir, PROJECT_CONFIG), 'utf8'));
|
|
245
|
+
setting = config?.shareRequests;
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
setting = undefined;
|
|
249
|
+
}
|
|
250
|
+
if (false === setting)
|
|
251
|
+
return false;
|
|
252
|
+
if (true === setting)
|
|
253
|
+
return true;
|
|
254
|
+
// Linked by `reticle connect` (cloud.json), or by a key in the environment, the way CI syncs.
|
|
255
|
+
return (existsSync(join(reticleRoot, ReticleDir.CLOUD_LINK_FILE)) ||
|
|
256
|
+
apiKeyFrom(process.env) !== undefined);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Keep the user's request, and every statement in it and in the declared intents, classified and
|
|
260
|
+
* attributed, for the runs that verify it. Secrets are redacted before anything is written.
|
|
261
|
+
*
|
|
262
|
+
* Shared with the platform from a linked project unless `.reticle.json` says `"shareRequests": false`.
|
|
263
|
+
*/
|
|
264
|
+
async function recordRequest(deps, root, request, declared) {
|
|
265
|
+
const text = redactSecrets(request, MAX_REQUEST);
|
|
266
|
+
const agentStatements = declared.flatMap((d) => {
|
|
267
|
+
const statement = d?.statement;
|
|
268
|
+
return 'string' === typeof statement ? [statement] : [];
|
|
269
|
+
});
|
|
270
|
+
const context = {
|
|
271
|
+
request: text,
|
|
272
|
+
statements: [
|
|
273
|
+
...splitStatements(text).map((t) => ({ text: t, source: StatementSource.USER })),
|
|
274
|
+
...agentStatements.map((t) => ({
|
|
275
|
+
text: redactSecrets(t, MAX_STATEMENT),
|
|
276
|
+
source: StatementSource.AGENT,
|
|
277
|
+
})),
|
|
278
|
+
]
|
|
279
|
+
.slice(0, MAX_STATEMENTS)
|
|
280
|
+
.map((s) => ({
|
|
281
|
+
...s,
|
|
282
|
+
text: s.text.slice(0, MAX_STATEMENT),
|
|
283
|
+
kind: classifyStatement(s.text),
|
|
284
|
+
})),
|
|
285
|
+
at: deps.now(),
|
|
286
|
+
shared: sharesRequests(dirname(root), root),
|
|
287
|
+
};
|
|
288
|
+
const path = reticleDirPaths(root).request;
|
|
289
|
+
await deps.fs.mkdir(dirname(path));
|
|
290
|
+
await deps.fs.writeFile(path, `${JSON.stringify(context, null, 2)}\n`);
|
|
291
|
+
}
|