@reticlehq/server 3.7.0 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +59 -68
- package/bin/reticle.js +9 -2
- package/dist/command/cli/adhoc-suite.js +1 -1
- package/dist/command/cli/adhoc-verdict.d.ts +12 -0
- package/dist/command/cli/adhoc-verdict.js +62 -4
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +5 -1
- package/dist/command/cli/auth/cloud-session.d.ts +11 -19
- package/dist/command/cli/auth/cloud-session.js +23 -0
- package/dist/command/cli/auth/device-flow.d.ts +3 -37
- package/dist/command/cli/cli-doctor.js +66 -21
- package/dist/command/cli/cli-flow-commands.js +53 -11
- package/dist/command/cli/cli-kill.d.ts +8 -0
- package/dist/command/cli/cli-kill.js +43 -3
- package/dist/command/cli/cli-parse-feedback.d.ts +4 -0
- package/dist/command/cli/cli-parse-feedback.js +13 -1
- package/dist/command/cli/cli-parse-grammar.d.ts +1 -2
- package/dist/command/cli/cli-parse-grammar.js +1 -6
- package/dist/command/cli/cli-parse-serve.d.ts +24 -0
- package/dist/command/cli/cli-parse-serve.js +124 -0
- package/dist/command/cli/cli-parse.d.ts +12 -11
- package/dist/command/cli/cli-parse.js +100 -123
- package/dist/command/cli/cli-usage.d.ts +0 -11
- package/dist/command/cli/cli-usage.js +43 -16
- package/dist/command/cli/cli-verify.d.ts +1 -1
- package/dist/command/cli/cli-verify.js +29 -14
- package/dist/command/cli/cloud-cli.js +27 -9
- package/dist/command/cli/cloud-kit.js +3 -3
- package/dist/command/cli/cloud-link.d.ts +1 -20
- package/dist/command/cli/cloud-link.js +2 -0
- package/dist/command/cli/cloud-login.d.ts +6 -2
- package/dist/command/cli/cloud-login.js +13 -41
- package/dist/command/cli/config/checkout.d.ts +10 -0
- package/dist/command/cli/config/checkout.js +78 -0
- package/dist/command/cli/doctor/doctor-agent-link.d.ts +23 -0
- package/dist/command/cli/doctor/doctor-agent-link.js +28 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +1 -7
- package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
- package/dist/command/cli/doctor/doctor-rows.js +4 -0
- package/dist/command/cli/drive/drive-attach.d.ts +5 -0
- package/dist/command/cli/drive/drive-attach.js +21 -1
- package/dist/command/cli/hook/codex-transcript.d.ts +20 -0
- package/dist/command/cli/hook/codex-transcript.js +224 -0
- package/dist/command/cli/hook/episode-structure.d.ts +24 -0
- package/dist/command/cli/hook/episode-structure.js +138 -0
- package/dist/command/cli/hook/hook-command.d.ts +9 -0
- package/dist/command/cli/hook/hook-command.js +211 -0
- package/dist/command/cli/hook/hook-fast.d.ts +31 -0
- package/dist/command/cli/hook/hook-fast.js +136 -0
- package/dist/command/cli/hook/prompt-hook.d.ts +30 -0
- package/dist/command/cli/hook/prompt-hook.js +199 -0
- package/dist/command/cli/hook/tool-hook.d.ts +21 -0
- package/dist/command/cli/hook/tool-hook.js +259 -0
- package/dist/command/cli/launch/cli-launch.d.ts +2 -0
- package/dist/command/cli/launch/cli-launch.js +22 -2
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +28 -2
- package/dist/command/cli/mcp-command.d.ts +9 -0
- package/dist/command/cli/mcp-command.js +127 -41
- package/dist/command/cli/open-navigate.d.ts +43 -0
- package/dist/command/cli/open-navigate.js +85 -0
- package/dist/command/cli/ports/port-holder.d.ts +16 -4
- package/dist/command/cli/ports/port-holder.js +58 -12
- package/dist/command/cli/ports/resolve/cli-port.js +18 -2
- package/dist/command/cli/project-name.d.ts +1 -7
- package/dist/command/cli/project-name.js +1 -0
- package/dist/command/cli/report-command.d.ts +8 -2
- package/dist/command/cli/report-command.js +95 -18
- package/dist/command/cli/status-fields.d.ts +9 -2
- package/dist/command/cli/status-fields.js +148 -4
- package/dist/command/cli/try-command.d.ts +3 -4
- package/dist/command/cli/try-command.js +6 -11
- package/dist/command/cli/verify-results.d.ts +4 -1
- package/dist/command/cli/verify-results.js +3 -1
- package/dist/command/cli.d.ts +1 -7
- package/dist/command/cli.js +79 -160
- package/dist/command/daemon/daemon-resilience.d.ts +6 -1
- package/dist/command/daemon/daemon-resilience.js +31 -18
- package/dist/command/daemon/daemon.d.ts +11 -0
- package/dist/command/daemon/daemon.js +70 -2
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +2 -0
- package/dist/command/daemon/lifetime/daemon-usefulness.js +13 -2
- package/dist/command/daemon/wake-decision.js +4 -2
- package/dist/command/daemon/win32-escape.d.ts +32 -0
- package/dist/command/daemon/win32-escape.js +119 -0
- package/dist/command/setup/agent-configs.d.ts +9 -0
- package/dist/command/setup/agent-configs.js +9 -0
- package/dist/command/setup/auto-approve.d.ts +10 -3
- package/dist/command/setup/auto-approve.js +51 -3
- package/dist/command/setup/bringup/dev-server-files.d.ts +1 -9
- package/dist/command/setup/bringup/dev-server-wait.js +5 -1
- package/dist/command/setup/bringup/ensure-daemon.js +4 -7
- package/dist/command/setup/init/init-host.js +6 -0
- package/dist/command/setup/init/init-port.js +5 -4
- package/dist/command/setup/init/init-runtime.js +7 -1
- package/dist/command/setup/node-effects.d.ts +8 -0
- package/dist/command/setup/node-effects.js +36 -4
- package/dist/command/setup/probe/dev-port.d.ts +26 -0
- package/dist/command/setup/probe/dev-port.js +117 -0
- package/dist/command/setup/probe/page-probe.d.ts +1 -1
- package/dist/command/setup/probe/page-probe.js +11 -3
- package/dist/command/setup/remaining-steps.d.ts +0 -7
- package/dist/command/setup/remaining-steps.js +3 -2
- package/dist/command/setup/run-setup.d.ts +11 -0
- package/dist/command/setup/run-setup.js +33 -5
- package/dist/command/setup/setup-command.d.ts +2 -0
- package/dist/command/setup/setup-command.js +22 -4
- package/dist/command/update/updater.d.ts +1 -6
- package/dist/command/update/updater.js +4 -5
- package/dist/command/update/version-seen.d.ts +24 -0
- package/dist/command/update/version-seen.js +65 -0
- package/dist/command/version/peer-announce.d.ts +9 -1
- package/dist/command/version/peer-announce.js +25 -2
- package/dist/command/version/sdk-fix.d.ts +5 -6
- package/dist/command/version/sdk-fix.js +17 -32
- package/dist/command/version/version-skew.d.ts +16 -1
- package/dist/command/version/version-skew.js +84 -10
- package/dist/features/crawl/crawl-tools.js +2 -2
- package/dist/features/crawl/crawl.js +2 -0
- package/dist/features/exhaust/ledger.d.ts +15 -96
- package/dist/features/exhaust/ledger.js +3 -3
- package/dist/features/harness/drive-runs.d.ts +28 -4
- package/dist/features/harness/drive-runs.js +99 -7
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/harness.d.ts +5 -0
- package/dist/features/harness/harness.js +24 -12
- package/dist/features/harness/platform/platform-drives.d.ts +7 -1
- package/dist/features/harness/platform/platform-drives.js +12 -7
- package/dist/features/harness/platform/refusal.d.ts +1 -1
- package/dist/features/harness/platform/refusal.js +4 -4
- package/dist/features/harness/platform/remote-drive.js +70 -28
- package/dist/features/harness/platform/server-driver.js +22 -1
- package/dist/features/harness/platform-config.d.ts +1 -10
- package/dist/features/harness/platform-config.js +0 -20
- package/dist/features/license/license.d.ts +2 -14
- package/dist/features/visual/step-shots.d.ts +33 -1
- package/dist/features/visual/step-shots.js +155 -1
- package/dist/features/visual/visual-tools.js +12 -4
- package/dist/hooks/coding-agents.d.ts +6 -0
- package/dist/hooks/coding-agents.js +24 -3
- package/dist/hooks/episode-stamp.d.ts +32 -0
- package/dist/hooks/episode-stamp.js +61 -0
- package/dist/hooks/hook-commands.js +19 -9
- package/dist/index.d.ts +5 -1
- package/dist/index.js +66 -24
- package/dist/judgement/app-graph/journal-steps.d.ts +8 -0
- package/dist/judgement/app-graph/journal-steps.js +92 -0
- package/dist/judgement/capsule/capsule-store.d.ts +2 -39
- package/dist/judgement/domain/domain-model.js +1 -10
- package/dist/judgement/domain/domain-tools.js +4 -2
- package/dist/judgement/runs/artifact/run-store.d.ts +28 -8
- package/dist/judgement/runs/artifact/run-store.js +153 -28
- package/dist/judgement/runs/default-run-id.d.ts +3 -1
- package/dist/judgement/runs/default-run-id.js +15 -3
- package/dist/judgement/runs/drive-run.d.ts +3 -3
- package/dist/judgement/runs/drive-run.js +11 -7
- package/dist/judgement/runs/run-ledger.d.ts +21 -0
- package/dist/judgement/runs/run-ledger.js +143 -0
- package/dist/judgement/runs/runner-port.d.ts +1 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +4 -3
- package/dist/judgement/runs/verification-sync.js +27 -5
- package/dist/language/flows/affected-tools.js +2 -1
- package/dist/language/flows/annotate-notes/annotate.js +8 -3
- package/dist/language/flows/annotate-tools.js +1 -1
- package/dist/language/flows/change/affected.d.ts +8 -0
- package/dist/language/flows/change/affected.js +20 -7
- package/dist/language/flows/decision.js +19 -4
- package/dist/language/flows/fields/flow-secret-field.d.ts +9 -0
- package/dist/language/flows/fields/flow-secret-field.js +67 -5
- package/dist/language/flows/flow-anchor.d.ts +5 -0
- package/dist/language/flows/flow-anchor.js +4 -0
- package/dist/language/flows/flow-cross-step.d.ts +7 -1
- package/dist/language/flows/flow-cross-step.js +9 -0
- package/dist/language/flows/flow-expect-grammar.js +15 -10
- package/dist/language/flows/flow-intent.js +6 -1
- package/dist/language/flows/flow-journey.d.ts +8 -0
- package/dist/language/flows/flow-journey.js +13 -0
- package/dist/language/flows/flow-lease.d.ts +27 -0
- package/dist/language/flows/flow-lease.js +59 -0
- package/dist/language/flows/flow-replay-run.d.ts +1 -87
- package/dist/language/flows/flow-replay-run.js +111 -310
- package/dist/language/flows/flow-replay.js +21 -19
- package/dist/language/flows/flow-replayable.d.ts +38 -0
- package/dist/language/flows/flow-replayable.js +179 -0
- package/dist/language/flows/flow-start-path.d.ts +108 -0
- package/dist/language/flows/flow-start-path.js +313 -0
- package/dist/language/flows/flow-step-runners.d.ts +23 -2
- package/dist/language/flows/flow-step-runners.js +191 -32
- package/dist/language/flows/flow-store-for-session.d.ts +8 -1
- package/dist/language/flows/flow-store-for-session.js +6 -0
- package/dist/language/flows/flow-tools.d.ts +2 -23
- package/dist/language/flows/flow-tools.js +63 -113
- package/dist/language/flows/flows.d.ts +4 -6
- package/dist/language/flows/flows.js +90 -15
- package/dist/language/flows/heal-run.d.ts +10 -4
- package/dist/language/flows/heal-run.js +26 -9
- package/dist/language/flows/recording/flake.d.ts +3 -27
- package/dist/language/flows/recording/flake.js +1 -1
- package/dist/language/flows/recording/recording-backtrack.js +1 -4
- package/dist/language/flows/recording/tape/recordings.d.ts +11 -1
- package/dist/language/flows/recording/tape/recordings.js +9 -3
- package/dist/language/flows/replay.d.ts +25 -5
- package/dist/language/flows/replay.js +83 -16
- package/dist/language/flows/stores/assertion-tiers-store.js +1 -1
- package/dist/language/flows/suite/coverage.d.ts +9 -0
- package/dist/language/flows/suite/coverage.js +12 -1
- package/dist/language/flows/suite-selection.d.ts +25 -0
- package/dist/language/flows/suite-selection.js +41 -9
- package/dist/machine/git-tracks.d.ts +6 -0
- package/dist/machine/git-tracks.js +36 -0
- package/dist/memory/cloud/background-sync.d.ts +25 -0
- package/dist/memory/cloud/background-sync.js +79 -0
- package/dist/memory/cloud/cloud-config.d.ts +12 -1
- package/dist/memory/cloud/cloud-config.js +39 -13
- package/dist/memory/cloud/cloud-sync.d.ts +3 -24
- package/dist/memory/cloud/cloud-sync.js +5 -2
- package/dist/memory/cloud/harness-config.d.ts +0 -7
- package/dist/memory/cloud/memory-scope.d.ts +19 -0
- package/dist/memory/cloud/memory-scope.js +48 -0
- package/dist/memory/cloud/sync-answer.d.ts +43 -0
- package/dist/memory/cloud/sync-answer.js +42 -0
- package/dist/memory/cloud/sync-cycle.d.ts +40 -10
- package/dist/memory/cloud/sync-cycle.js +97 -144
- package/dist/memory/cloud/sync-daemon.d.ts +50 -3
- package/dist/memory/cloud/sync-daemon.js +473 -83
- package/dist/memory/cloud/sync-describe.d.ts +28 -0
- package/dist/memory/cloud/sync-describe.js +92 -0
- package/dist/memory/cloud/sync-disk.d.ts +9 -1
- package/dist/memory/cloud/sync-disk.js +137 -33
- package/dist/memory/cloud/sync-flow-versions.d.ts +26 -0
- package/dist/memory/cloud/sync-flow-versions.js +42 -0
- package/dist/memory/impact/impact-store.js +32 -15
- package/dist/memory/intent/intent-shard.d.ts +41 -266
- package/dist/memory/intent/intent-tools.js +20 -61
- package/dist/memory/intent/record-request.d.ts +27 -0
- package/dist/memory/intent/record-request.js +88 -0
- package/dist/memory/intent/settled-words.js +9 -1
- package/dist/memory/journal/drive-flow.d.ts +3 -0
- package/dist/memory/journal/drive-flow.js +11 -41
- package/dist/memory/journal/envelope-store.js +1 -1
- package/dist/memory/journal/envelope.d.ts +6 -154
- package/dist/memory/journal/episode-log.d.ts +107 -0
- package/dist/memory/journal/episode-log.js +302 -0
- package/dist/memory/journal/journal-recorder.d.ts +7 -0
- package/dist/memory/journal/journal-recorder.js +22 -9
- package/dist/memory/journal/on-disk/ambient-file.d.ts +1 -7
- package/dist/memory/journal/on-disk/ambient-file.js +1 -1
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +24 -3
- package/dist/memory/journal/on-disk/workspace-gitignore.js +38 -7
- package/dist/memory/journal/on-disk/workspace-tiers.js +7 -0
- package/dist/memory/journal/self-observation.js +3 -1
- package/dist/memory/journal/session-end.js +23 -9
- package/dist/memory/journal/session-journal.js +39 -20
- package/dist/memory/project/artifact-root-resolver.d.ts +14 -1
- package/dist/memory/project/artifact-root-resolver.js +68 -23
- package/dist/memory/project/artifact-root.d.ts +17 -3
- package/dist/memory/project/artifact-root.js +47 -9
- package/dist/memory/project/fs/fs-port.d.ts +5 -0
- package/dist/memory/project/fs/fs-port.js +13 -0
- package/dist/memory/project/learned-routes.d.ts +3 -4
- package/dist/memory/project/learned-routes.js +3 -11
- package/dist/memory/project/link-directory.js +5 -2
- package/dist/memory/project/root-claims.d.ts +3 -1
- package/dist/memory/project/root-claims.js +41 -7
- package/dist/memory/project/session-root.d.ts +1 -1
- package/dist/memory/project/session-root.js +1 -15
- package/dist/memory/project/sync-status.js +5 -6
- package/dist/memory/recall/memory-tools.js +2 -2
- package/dist/memory/recall/platform-memory.d.ts +3 -1
- package/dist/memory/recall/platform-memory.js +9 -1
- package/dist/memory/recall/project-memory.js +15 -19
- package/dist/portal/bridge/auth-failure-reason.d.ts +13 -0
- package/dist/portal/bridge/auth-failure-reason.js +19 -0
- package/dist/portal/bridge/bridge.d.ts +19 -4
- package/dist/portal/bridge/bridge.js +150 -177
- package/dist/portal/bridge/harness-request.d.ts +15 -0
- package/dist/portal/bridge/harness-request.js +19 -0
- package/dist/portal/bridge/origin/origin-follow.d.ts +46 -0
- package/dist/portal/bridge/origin/origin-follow.js +110 -0
- package/dist/portal/bridge/pairing-token.d.ts +6 -0
- package/dist/portal/bridge/pairing-token.js +47 -16
- package/dist/portal/bridge/protocol-skew.d.ts +27 -2
- package/dist/portal/bridge/protocol-skew.js +66 -2
- package/dist/portal/bridge/session-nonces.d.ts +46 -0
- package/dist/portal/bridge/session-nonces.js +72 -0
- package/dist/portal/input/viewport-tools.d.ts +31 -0
- package/dist/portal/input/viewport-tools.js +106 -15
- package/dist/portal/pool/bounded-close.d.ts +23 -0
- package/dist/portal/pool/bounded-close.js +38 -0
- package/dist/portal/pool/browser-pool.d.ts +44 -39
- package/dist/portal/pool/browser-pool.js +247 -95
- package/dist/portal/pool/context-permissions.d.ts +9 -1
- package/dist/portal/pool/context-permissions.js +26 -0
- package/dist/portal/pool/lease-emulation.d.ts +37 -0
- package/dist/portal/pool/lease-emulation.js +29 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +74 -7
- package/dist/portal/pool/pool-contract.d.ts +23 -1
- package/dist/portal/pool/pool-lease.d.ts +128 -0
- package/dist/portal/pool/pool-lease.js +49 -0
- package/dist/portal/pool/zero-install.d.ts +8 -1
- package/dist/portal/pool/zero-install.js +24 -2
- package/dist/portal/production/production-activation.d.ts +136 -0
- package/dist/portal/production/production-activation.js +173 -0
- package/dist/portal/production/production-drive.d.ts +52 -0
- package/dist/portal/production/production-drive.js +301 -0
- package/dist/portal/production/production-hello.d.ts +23 -0
- package/dist/portal/production/production-hello.js +23 -0
- package/dist/portal/realm/web-realm.js +42 -15
- package/dist/portal/session/control-envelope.d.ts +1 -1
- package/dist/portal/session/dev-server/served-document.d.ts +0 -5
- package/dist/portal/session/dev-server/served-document.js +6 -8
- package/dist/portal/session/facts/handshake-facts.d.ts +8 -1
- package/dist/portal/session/first-run-wiring.d.ts +3 -36
- package/dist/portal/session/first-run-wiring.js +10 -103
- package/dist/portal/session/live-control-tools.js +61 -19
- package/dist/portal/session/no-session-next-action.d.ts +11 -0
- package/dist/portal/session/no-session-next-action.js +40 -15
- package/dist/portal/session/no-session-watch.d.ts +7 -0
- package/dist/portal/session/no-session-watch.js +67 -23
- package/dist/portal/session/output-budget.d.ts +10 -0
- package/dist/portal/session/output-budget.js +16 -0
- package/dist/portal/session/presence/session-lease.d.ts +2 -0
- package/dist/portal/session/presence/session-lease.js +8 -0
- package/dist/portal/session/recorded-gaps.d.ts +15 -11
- package/dist/portal/session/recorded-gaps.js +39 -18
- package/dist/portal/session/serving-directory.d.ts +24 -2
- package/dist/portal/session/serving-directory.js +93 -5
- package/dist/portal/session/session-info.d.ts +26 -0
- package/dist/portal/session/session-info.js +20 -0
- package/dist/portal/session/session-manager.d.ts +35 -3
- package/dist/portal/session/session-manager.js +69 -14
- package/dist/portal/session/session-successor.js +1 -9
- package/dist/portal/session/session-tools.js +22 -4
- package/dist/portal/session/session.d.ts +10 -10
- package/dist/portal/session/session.js +37 -29
- package/dist/portal/session/zero-install-first-call.d.ts +7 -2
- package/dist/portal/session/zero-install-first-call.js +43 -20
- package/dist/start-wiring.d.ts +2 -2
- package/dist/start-wiring.js +17 -3
- package/dist/status-payload.d.ts +11 -1
- package/dist/status-payload.js +7 -1
- package/dist/surface/agent-presence-grace.d.ts +11 -0
- package/dist/surface/agent-presence-grace.js +34 -0
- package/dist/surface/http-server.d.ts +12 -1
- package/dist/surface/http-server.js +64 -15
- package/dist/surface/mcp/faults/mcp-outage.d.ts +12 -2
- package/dist/surface/mcp/faults/mcp-outage.js +19 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +17 -74
- package/dist/surface/mcp/mcp-proxy.js +194 -267
- package/dist/surface/mcp/mcp.d.ts +20 -3
- package/dist/surface/mcp/mcp.js +88 -25
- package/dist/surface/mcp/proxy/drive-calls.d.ts +44 -0
- package/dist/surface/mcp/proxy/drive-calls.js +114 -5
- package/dist/surface/mcp/proxy/proxy-boot.d.ts +11 -0
- package/dist/surface/mcp/proxy/proxy-boot.js +1 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +6 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +14 -1
- package/dist/surface/mcp/proxy/proxy-handshake.d.ts +34 -2
- package/dist/surface/mcp/proxy/proxy-handshake.js +76 -8
- package/dist/surface/mcp/server-instructions.js +35 -16
- package/dist/surface/mcp/shared-params.d.ts +8 -0
- package/dist/surface/mcp/shared-params.js +15 -1
- package/dist/surface/mcp/sse-frame-parser.d.ts +11 -0
- package/dist/surface/mcp/sse-frame-parser.js +18 -0
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +13 -0
- package/dist/surface/mcp/tool-catalog-cache.d.ts +2 -0
- package/dist/surface/mcp/tool-catalog-cache.js +14 -4
- package/dist/surface/tools/account-tool.d.ts +4 -3
- package/dist/surface/tools/account-tool.js +20 -31
- package/dist/surface/tools/act/act-danger.d.ts +2 -0
- package/dist/surface/tools/act/act-danger.js +41 -14
- package/dist/surface/tools/act/act-observation.d.ts +11 -0
- package/dist/surface/tools/act/act-observation.js +33 -0
- package/dist/surface/tools/act/act-preflight.js +10 -3
- package/dist/surface/tools/act/act-sequence-retry.js +2 -1
- package/dist/surface/tools/act/act-target.js +19 -5
- package/dist/surface/tools/act/durable.js +1 -1
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +9 -7
- package/dist/surface/tools/act/navigation/navigate-arrival.js +11 -14
- package/dist/surface/tools/act/unsettled-find.d.ts +36 -0
- package/dist/surface/tools/act/unsettled-find.js +71 -0
- package/dist/surface/tools/act-sequence-tool.js +53 -24
- package/dist/surface/tools/act-tools.d.ts +2 -3
- package/dist/surface/tools/act-tools.js +49 -47
- package/dist/surface/tools/agent/compact-envelope.d.ts +2 -2
- package/dist/surface/tools/agent/for-the-agent.js +41 -3
- package/dist/surface/tools/assert/assert-grade.js +8 -3
- package/dist/surface/tools/assert/assert-verdict.js +4 -2
- package/dist/surface/tools/browser-tools.js +7 -4
- package/dist/surface/tools/chat-drives.js +50 -25
- package/dist/surface/tools/coverage-tools.js +1 -1
- package/dist/surface/tools/dynamic-tools.d.ts +8 -0
- package/dist/surface/tools/dynamic-tools.js +89 -34
- package/dist/surface/tools/empty-session-list.d.ts +18 -25
- package/dist/surface/tools/empty-session-list.js +67 -38
- package/dist/surface/tools/error-recovery.d.ts +17 -7
- package/dist/surface/tools/error-recovery.js +53 -20
- package/dist/surface/tools/explore-tools.d.ts +10 -0
- package/dist/surface/tools/explore-tools.js +72 -19
- package/dist/surface/tools/feedback-tools.js +23 -2
- package/dist/surface/tools/gap-novelty.d.ts +6 -0
- package/dist/surface/tools/gap-novelty.js +9 -0
- package/dist/surface/tools/gaps/capability-absences.js +4 -3
- package/dist/surface/tools/harness-explore.d.ts +1 -1
- package/dist/surface/tools/harness-explore.js +6 -4
- package/dist/surface/tools/harness-gate.d.ts +43 -21
- package/dist/surface/tools/harness-gate.js +55 -81
- package/dist/surface/tools/harness-script.d.ts +2 -0
- package/dist/surface/tools/harness-script.js +11 -6
- package/dist/surface/tools/harness-toolset.js +3 -4
- package/dist/surface/tools/invoke-tool.d.ts +0 -8
- package/dist/surface/tools/invoke-tool.js +164 -178
- package/dist/surface/tools/lease-hint.d.ts +9 -0
- package/dist/surface/tools/lease-hint.js +22 -3
- package/dist/surface/tools/lease-permissions.d.ts +1 -1
- package/dist/surface/tools/lease-readiness.d.ts +55 -0
- package/dist/surface/tools/lease-readiness.js +150 -2
- package/dist/surface/tools/lease-tools.d.ts +3 -75
- package/dist/surface/tools/lease-tools.js +124 -188
- package/dist/surface/tools/map-tools.d.ts +20 -0
- package/dist/surface/tools/map-tools.js +145 -0
- package/dist/surface/tools/merge-tools.js +11 -7
- package/dist/surface/tools/next-step.js +6 -3
- package/dist/surface/tools/observe-tools.js +46 -35
- package/dist/surface/tools/platform-moment.d.ts +3 -12
- package/dist/surface/tools/platform-moment.js +12 -24
- package/dist/surface/tools/read/complete-snapshot.d.ts +7 -1
- package/dist/surface/tools/read/complete-snapshot.js +13 -2
- package/dist/surface/tools/read/query-paginate.js +6 -0
- package/dist/surface/tools/read/query-shape.d.ts +9 -0
- package/dist/surface/tools/read/query-shape.js +15 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.d.ts +1 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.js +73 -0
- package/dist/surface/tools/read-tools.js +5 -5
- package/dist/surface/tools/real-input-attempt.d.ts +11 -0
- package/dist/surface/tools/real-input-attempt.js +206 -38
- package/dist/surface/tools/reconcile-tools.js +21 -8
- package/dist/surface/tools/reticle-result.d.ts +3 -0
- package/dist/surface/tools/reticle-result.js +8 -1
- package/dist/surface/tools/run-report.d.ts +22 -0
- package/dist/surface/tools/run-report.js +141 -0
- package/dist/surface/tools/session-ports.d.ts +57 -0
- package/dist/surface/tools/session-ports.js +102 -0
- package/dist/surface/tools/tool-kit.d.ts +58 -4
- package/dist/surface/tools/tool-kit.js +140 -6
- package/dist/surface/tools/tool-surface.d.ts +2 -0
- package/dist/surface/tools/tool-surface.js +45 -0
- package/dist/surface/tools/tools.js +49 -87
- package/dist/telemetry/automation-hint.d.ts +5 -0
- package/dist/telemetry/automation-hint.js +7 -0
- package/dist/telemetry/cli-telemetry.d.ts +22 -0
- package/dist/telemetry/cli-telemetry.js +80 -11
- package/dist/telemetry/daemon-telemetry.d.ts +3 -1
- package/dist/telemetry/daemon-telemetry.js +9 -2
- package/dist/telemetry/feedback-cli.d.ts +1 -1
- package/dist/telemetry/feedback-cli.js +8 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/feedback.js +51 -4
- package/dist/telemetry/harness-run.d.ts +3 -3
- package/dist/telemetry/harness-run.js +18 -7
- package/dist/telemetry/hud-events.d.ts +1 -1
- package/dist/telemetry/hud-metrics.d.ts +6 -3
- package/dist/telemetry/hud-metrics.js +20 -8
- package/dist/telemetry/install-source.js +1 -1
- package/dist/telemetry/mcp-connection.d.ts +1 -1
- package/dist/telemetry/mcp-connection.js +21 -2
- package/dist/telemetry/onboarding-firsts.d.ts +6 -1
- package/dist/telemetry/onboarding-firsts.js +41 -1
- package/dist/telemetry/proxy-telemetry.d.ts +42 -0
- package/dist/telemetry/proxy-telemetry.js +70 -1
- package/dist/telemetry/session-metrics.d.ts +1 -3
- package/dist/telemetry/session-metrics.js +16 -12
- package/dist/telemetry/telemetry.d.ts +9 -1
- package/dist/telemetry/telemetry.js +16 -1
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +7 -1
- package/dist/wire-journal.js +12 -2
- package/docs/README.md +4 -2
- package/docs/actions.mdx +7 -6
- package/docs/adapters.md +2 -1
- package/docs/agent-cheatsheet.md +19 -5
- package/docs/architecture.md +13 -10
- package/docs/autodrive.md +6 -5
- package/docs/benchmarks.md +2 -2
- package/docs/capabilities.mdx +1 -1
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +6 -6
- package/docs/cli/doctor.mdx +3 -1
- package/docs/cli/feedback.mdx +11 -7
- package/docs/cli/gate.mdx +1 -1
- package/docs/cli/help.mdx +1 -1
- package/docs/cli/init.mdx +20 -16
- package/docs/cli/mcp.mdx +5 -2
- package/docs/cli/open.mdx +5 -2
- package/docs/cli/report.mdx +1 -1
- package/docs/cli/restart.mdx +1 -1
- package/docs/cli/rollback.mdx +4 -4
- package/docs/cli/serve.mdx +7 -5
- package/docs/cli/setup.mdx +1 -1
- package/docs/cli/status.mdx +6 -2
- package/docs/cli/stop.mdx +3 -3
- package/docs/cli/telemetry.mdx +5 -1
- package/docs/cli/try.mdx +8 -8
- package/docs/cli/update.mdx +8 -5
- package/docs/cli/verify.mdx +12 -5
- package/docs/cli/version.mdx +1 -1
- package/docs/cli.mdx +10 -6
- package/docs/debugging.md +1 -1
- package/docs/deploy-checks.md +8 -6
- package/docs/desktop.mdx +14 -18
- package/docs/enterprise.md +6 -6
- package/docs/environment.mdx +5 -3
- package/docs/faq.mdx +9 -6
- package/docs/first-drive.md +19 -9
- package/docs/flows.md +3 -4
- package/docs/for-agents.md +1 -1
- package/docs/frameworks.mdx +34 -11
- package/docs/getting-started.md +46 -29
- package/docs/http-transport.md +2 -2
- package/docs/human-control.md +8 -8
- package/docs/index.mdx +2 -2
- package/docs/install-agentic.mdx +18 -19
- package/docs/install-manual.mdx +8 -4
- package/docs/integration-patterns.md +5 -5
- package/docs/multi-agent-testing.md +7 -5
- package/docs/packages/browser.mdx +34 -2
- package/docs/packages/core.mdx +2 -1
- package/docs/packages/electron.mdx +15 -3
- package/docs/packages/eslint-plugin.mdx +1 -1
- package/docs/packages/next.mdx +17 -5
- package/docs/packages/react.mdx +8 -1
- package/docs/packages/server.mdx +3 -3
- package/docs/packages/tauri.mdx +3 -3
- package/docs/packages/vite-plugin.mdx +1 -1
- package/docs/packages.mdx +19 -6
- package/docs/platform-integration.md +12 -4
- package/docs/predicates.mdx +18 -7
- package/docs/production-mode.md +108 -0
- package/docs/prompt-capture.md +99 -0
- package/docs/quickstart.mdx +14 -12
- package/docs/recipes.mdx +9 -8
- package/docs/required-checks.md +3 -2
- package/docs/skill-file.mdx +4 -3
- package/docs/skill-setup.md +2 -2
- package/docs/skill.md +62 -70
- package/docs/state-files.md +1 -0
- package/docs/state-management.mdx +11 -9
- package/docs/system-map.md +14 -13
- package/docs/telemetry.md +32 -24
- package/docs/testing.md +9 -5
- package/docs/tools/act-and-wait.mdx +17 -13
- package/docs/tools/act-sequence.mdx +40 -66
- package/docs/tools/act.mdx +7 -5
- package/docs/tools/assert.mdx +1 -1
- package/docs/tools/look.mdx +1 -1
- package/docs/tools/navigate.mdx +1 -1
- package/docs/tools/network.mdx +13 -11
- package/docs/tools/overview.mdx +3 -3
- package/docs/tools/query.mdx +3 -3
- package/docs/tools/session-and-feedback.mdx +9 -6
- package/docs/tools/sessions.mdx +7 -0
- package/docs/tools/snapshot.mdx +9 -7
- package/docs/tools/tools-and-run.mdx +11 -10
- package/docs/tools/verify.mdx +1 -1
- package/docs/troubleshooting.mdx +21 -9
- package/docs/usage.md +58 -43
- package/docs/use-cases.mdx +2 -2
- package/docs/vs-chrome-devtools-mcp.mdx +5 -5
- package/docs/vs-playwright-mcp.mdx +5 -4
- package/docs/what-is-recorded.md +12 -7
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/dev/stale-issue-guard.d.ts +0 -34
- package/dist/command/dev/stale-issue-guard.js +0 -69
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* user-level credential. "Cloud attached" = a valid link file AND a key for its project id (or env creds).
|
|
11
11
|
*/
|
|
12
12
|
import { join } from 'node:path';
|
|
13
|
-
import { DEFAULT_PLATFORM_URL, ReticleDir, ReticleEnv } from '@reticlehq/core';
|
|
13
|
+
import { DEFAULT_PLATFORM_URL, ReticleDir, ReticleEnv, mainCheckoutTwin } from '@reticlehq/core';
|
|
14
|
+
import { readTextOrUndefined } from '../project/fs/fs-port.js';
|
|
14
15
|
import { resolveCloudConfig } from './cloud-sync.js';
|
|
15
16
|
/** `<reticleRoot>/cloud.json` — the project's cloud binding + sync policy (non-secret). */
|
|
16
17
|
/** Re-exported so the existing importers keep working; the string itself lives in core. */
|
|
@@ -23,6 +24,7 @@ const DEFAULT_SYNC_POLICY = {
|
|
|
23
24
|
flows: true,
|
|
24
25
|
capsules: true,
|
|
25
26
|
screenshots: true,
|
|
27
|
+
video: true,
|
|
26
28
|
};
|
|
27
29
|
/** Where a verification actually executes. Reserved for the hosted-runner path; default local. */
|
|
28
30
|
export const VerifyMode = { LOCAL: 'local', SERVER: 'server' };
|
|
@@ -30,8 +32,9 @@ const asBool = (v, fallback) => ('boolean' === typeof v ? v : fallback);
|
|
|
30
32
|
/** Read + JSON-parse a file, or null on any problem (missing/malformed) — never throws. */
|
|
31
33
|
async function readJson(fs, path) {
|
|
32
34
|
try {
|
|
33
|
-
if (!(await fs.exists(path)))
|
|
35
|
+
if (!(await fs.exists(path))) {
|
|
34
36
|
return null;
|
|
37
|
+
}
|
|
35
38
|
return JSON.parse(await fs.readFile(path));
|
|
36
39
|
}
|
|
37
40
|
catch {
|
|
@@ -40,13 +43,16 @@ async function readJson(fs, path) {
|
|
|
40
43
|
}
|
|
41
44
|
/** Validate the shape of `.reticle/cloud.json`. Requires projectId + url; policy/verify default in. */
|
|
42
45
|
function parseLink(raw) {
|
|
43
|
-
if (typeof raw !== 'object' || null === raw)
|
|
46
|
+
if (typeof raw !== 'object' || null === raw) {
|
|
44
47
|
return null;
|
|
48
|
+
}
|
|
45
49
|
const o = raw;
|
|
46
|
-
if (typeof o.projectId !== 'string' || 0 === o.projectId.length)
|
|
50
|
+
if (typeof o.projectId !== 'string' || 0 === o.projectId.length) {
|
|
47
51
|
return null;
|
|
48
|
-
|
|
52
|
+
}
|
|
53
|
+
if (typeof o.url !== 'string' || 0 === o.url.length) {
|
|
49
54
|
return null;
|
|
55
|
+
}
|
|
50
56
|
const sync = 'object' === typeof o.sync && o.sync !== null ? o.sync : {};
|
|
51
57
|
return {
|
|
52
58
|
projectId: o.projectId,
|
|
@@ -58,6 +64,8 @@ function parseLink(raw) {
|
|
|
58
64
|
flows: asBool(sync.flows, DEFAULT_SYNC_POLICY.flows),
|
|
59
65
|
capsules: asBool(sync.capsules, DEFAULT_SYNC_POLICY.capsules),
|
|
60
66
|
screenshots: asBool(sync.screenshots, asBool(sync.runs, DEFAULT_SYNC_POLICY.screenshots)),
|
|
67
|
+
video: asBool(sync.video, asBool(sync.screenshots, asBool(sync.runs, DEFAULT_SYNC_POLICY.video))),
|
|
68
|
+
...(true === sync.episodes ? { episodes: true } : {}),
|
|
61
69
|
},
|
|
62
70
|
verify: o.verify === VerifyMode.SERVER ? VerifyMode.SERVER : VerifyMode.LOCAL,
|
|
63
71
|
};
|
|
@@ -85,8 +93,9 @@ export const credentialSlot = (url, projectId, orgId) => orgId === undefined ||
|
|
|
85
93
|
? `${normalizeCloudUrl(url)}::${projectId}`
|
|
86
94
|
: `${normalizeCloudUrl(url)}::org::${orgId}::${projectId}`;
|
|
87
95
|
function credentialFor(raw, projectId, url, orgId) {
|
|
88
|
-
if (typeof raw !== 'object' || null === raw)
|
|
96
|
+
if (typeof raw !== 'object' || null === raw) {
|
|
89
97
|
return null;
|
|
98
|
+
}
|
|
90
99
|
const store = raw;
|
|
91
100
|
/*
|
|
92
101
|
* The ORG slot first, because cloud + project is still not an identity.
|
|
@@ -98,41 +107,56 @@ function credentialFor(raw, projectId, url, orgId) {
|
|
|
98
107
|
* two tenants colliding.
|
|
99
108
|
*/
|
|
100
109
|
const orgScoped = orgId === undefined ? undefined : store[credentialSlot(url, projectId, orgId)];
|
|
101
|
-
if ('string' === typeof orgScoped && orgScoped.length > 0)
|
|
110
|
+
if ('string' === typeof orgScoped && orgScoped.length > 0) {
|
|
102
111
|
return orgScoped;
|
|
112
|
+
}
|
|
103
113
|
/*
|
|
104
114
|
* Then the cloud+project slot, which is what every repo linked before this change still holds. It
|
|
105
115
|
* is ambiguous between tenants by construction, which is why it is consulted second and why the
|
|
106
116
|
* writer above stopped producing it as the only entry.
|
|
107
117
|
*/
|
|
108
118
|
const composite = store[credentialSlot(url, projectId)];
|
|
109
|
-
if ('string' === typeof composite && composite.length > 0)
|
|
119
|
+
if ('string' === typeof composite && composite.length > 0) {
|
|
110
120
|
return composite;
|
|
121
|
+
}
|
|
111
122
|
const entry = store[projectId];
|
|
112
|
-
if ('string' === typeof entry)
|
|
123
|
+
if ('string' === typeof entry) {
|
|
113
124
|
return entry.length > 0 ? entry : null;
|
|
114
|
-
|
|
125
|
+
}
|
|
126
|
+
if (typeof entry !== 'object' || null === entry) {
|
|
115
127
|
return null;
|
|
128
|
+
}
|
|
116
129
|
const record = entry;
|
|
117
130
|
const key = record['key'];
|
|
118
131
|
const forUrl = record['url'];
|
|
119
|
-
if ('string' !== typeof key || 0 === key.length)
|
|
132
|
+
if ('string' !== typeof key || 0 === key.length) {
|
|
120
133
|
return null;
|
|
134
|
+
}
|
|
121
135
|
// A credential stamped with a DIFFERENT cloud is not this project's credential, however much the
|
|
122
136
|
// project ids match. Refuse rather than dial somewhere with somebody else's key.
|
|
123
|
-
if ('string' === typeof forUrl && normalizeCloudUrl(forUrl) !== normalizeCloudUrl(url))
|
|
137
|
+
if ('string' === typeof forUrl && normalizeCloudUrl(forUrl) !== normalizeCloudUrl(url)) {
|
|
124
138
|
return null;
|
|
139
|
+
}
|
|
125
140
|
return key;
|
|
126
141
|
}
|
|
127
142
|
/** Trailing slashes are not identity: `https://x/` and `https://x` are one cloud. */
|
|
128
143
|
const normalizeCloudUrl = (url) => url.replace(/\/+$/, '');
|
|
144
|
+
/**
|
|
145
|
+
* A linked worktree's link, read from its main checkout. `.reticle/` is often git-ignored, so a new
|
|
146
|
+
* worktree has no `cloud.json`, and `reticle connect` once in the main checkout must cover it.
|
|
147
|
+
*/
|
|
148
|
+
async function linkOfMainCheckout(fs, reticleRoot) {
|
|
149
|
+
const twin = mainCheckoutTwin(reticleRoot, readTextOrUndefined);
|
|
150
|
+
return twin === undefined ? null : parseLink(await readJson(fs, join(twin, CLOUD_LINK_FILE)));
|
|
151
|
+
}
|
|
129
152
|
/**
|
|
130
153
|
* Resolve the cloud picture for a project rooted at `reticleRoot`. Reads the project's link file + the
|
|
131
154
|
* user credential store, else the env key; if the project isn't linked (no cloud.json), the env creds
|
|
132
155
|
* are the whole story (the single-project / CI flow). `homeDir` is injected (testable; `os.homedir()` at call).
|
|
133
156
|
*/
|
|
134
157
|
export async function resolveProjectCloud(fs, reticleRoot, homeDir, env) {
|
|
135
|
-
const link = parseLink(await readJson(fs, join(reticleRoot, CLOUD_LINK_FILE)))
|
|
158
|
+
const link = parseLink(await readJson(fs, join(reticleRoot, CLOUD_LINK_FILE))) ??
|
|
159
|
+
(await linkOfMainCheckout(fs, reticleRoot));
|
|
136
160
|
if (null === link) {
|
|
137
161
|
// No per-project link → the env vars are the whole story (legacy single-project / CI behaviour).
|
|
138
162
|
const config = resolveCloudConfig(env);
|
|
@@ -152,6 +176,8 @@ export async function resolveProjectCloud(fs, reticleRoot, homeDir, env) {
|
|
|
152
176
|
flows: link.sync.flows ?? DEFAULT_SYNC_POLICY.flows,
|
|
153
177
|
capsules: link.sync.capsules ?? DEFAULT_SYNC_POLICY.capsules,
|
|
154
178
|
screenshots: link.sync.screenshots ?? DEFAULT_SYNC_POLICY.screenshots,
|
|
179
|
+
video: link.sync.video ?? DEFAULT_SYNC_POLICY.video,
|
|
180
|
+
...(true === link.sync.episodes ? { episodes: true } : {}),
|
|
155
181
|
};
|
|
156
182
|
const stored = credentialFor(await readJson(fs, join(homeDir, ReticleDir.ROOT, CREDENTIALS_FILE)), link.projectId, link.url, link.orgId);
|
|
157
183
|
/*
|
|
@@ -42,6 +42,7 @@ export declare function syncRequest(url: string, init: {
|
|
|
42
42
|
}, timeoutMs?: number): Promise<{
|
|
43
43
|
status: number;
|
|
44
44
|
text: string;
|
|
45
|
+
etag?: string;
|
|
45
46
|
}>;
|
|
46
47
|
export declare const SyncOutcome: {
|
|
47
48
|
readonly SYNCED: "synced";
|
|
@@ -117,31 +118,9 @@ declare const ServerVerificationSchema: z.ZodObject<{
|
|
|
117
118
|
flows: z.ZodArray<z.ZodObject<{
|
|
118
119
|
name: z.ZodString;
|
|
119
120
|
status: z.ZodString;
|
|
120
|
-
},
|
|
121
|
-
status: string;
|
|
122
|
-
name: string;
|
|
123
|
-
}, {
|
|
124
|
-
status: string;
|
|
125
|
-
name: string;
|
|
126
|
-
}>, "many">;
|
|
121
|
+
}, z.core.$strip>>;
|
|
127
122
|
summary: z.ZodString;
|
|
128
|
-
},
|
|
129
|
-
flows: {
|
|
130
|
-
status: string;
|
|
131
|
-
name: string;
|
|
132
|
-
}[];
|
|
133
|
-
verificationId: string;
|
|
134
|
-
verdict: string | null;
|
|
135
|
-
summary: string;
|
|
136
|
-
}, {
|
|
137
|
-
flows: {
|
|
138
|
-
status: string;
|
|
139
|
-
name: string;
|
|
140
|
-
}[];
|
|
141
|
-
verificationId: string;
|
|
142
|
-
verdict: string | null;
|
|
143
|
-
summary: string;
|
|
144
|
-
}>;
|
|
123
|
+
}, z.core.$strip>;
|
|
145
124
|
export type ServerVerification = z.infer<typeof ServerVerificationSchema>;
|
|
146
125
|
/**
|
|
147
126
|
* Delegate a verification to the hosted runner: submit the preview URL + flow names to `POST
|
|
@@ -105,7 +105,9 @@ export async function cloudFetch(url, init, timeoutMs = CLOUD_FETCH_TIMEOUT_MS)
|
|
|
105
105
|
*/
|
|
106
106
|
export async function syncRequest(url, init, timeoutMs = CLOUD_FETCH_TIMEOUT_MS) {
|
|
107
107
|
const res = await cloudFetch(url, init, timeoutMs);
|
|
108
|
-
|
|
108
|
+
// The tag a conditional read names next time (the idle memory poll); absent when none was sent.
|
|
109
|
+
const etag = res.headers.get('etag');
|
|
110
|
+
return { status: res.status, text: await res.text(), ...(null === etag ? {} : { etag }) };
|
|
109
111
|
}
|
|
110
112
|
export const SyncOutcome = {
|
|
111
113
|
SYNCED: 'synced',
|
|
@@ -153,7 +155,8 @@ export async function syncRunToCloud(run, config, fetchImpl) {
|
|
|
153
155
|
'content-type': 'application/json',
|
|
154
156
|
authorization: `Bearer ${config.apiKey}`,
|
|
155
157
|
},
|
|
156
|
-
// The prompt context leaves the
|
|
158
|
+
// The prompt context leaves with the run when it was captured shared: on by default for a
|
|
159
|
+
// linked project, off with `"shareRequests": false`.
|
|
157
160
|
body: JSON.stringify(shareableRun(run)),
|
|
158
161
|
});
|
|
159
162
|
return res.ok
|
|
@@ -32,13 +32,6 @@ export interface HarnessConfigView {
|
|
|
32
32
|
kind?: CreditKind | undefined;
|
|
33
33
|
endsAt?: number;
|
|
34
34
|
};
|
|
35
|
-
/** The platform's coverage gate, when it sent one: the HUD prefers it to the local score. */
|
|
36
|
-
gate?: {
|
|
37
|
-
unlocked: boolean;
|
|
38
|
-
percent?: number;
|
|
39
|
-
reason?: string;
|
|
40
|
-
prompt?: string;
|
|
41
|
-
};
|
|
42
35
|
plan?: {
|
|
43
36
|
kind: CreditKind;
|
|
44
37
|
daysLeft?: number;
|
|
@@ -48,7 +48,12 @@
|
|
|
48
48
|
export declare const MemoryScopeField: {
|
|
49
49
|
readonly PROJECT_ID: "projectId";
|
|
50
50
|
readonly SUBJECT: "subject";
|
|
51
|
+
readonly LIMIT: "limit";
|
|
52
|
+
readonly CURSOR: "cursor";
|
|
53
|
+
readonly NEXT_CURSOR: "nextCursor";
|
|
51
54
|
};
|
|
55
|
+
/** One page of a memory read: the platform's own maximum. */
|
|
56
|
+
export declare const MEMORY_PAGE_LIMIT = 100;
|
|
52
57
|
/**
|
|
53
58
|
* What a read is asked about: the linked project, and optionally one subject within it.
|
|
54
59
|
*
|
|
@@ -60,6 +65,10 @@ export interface MemoryReadScope {
|
|
|
60
65
|
/** The cloud project the link file names. Absent, `null` and empty all mean "no project to name". */
|
|
61
66
|
projectId: string | null | undefined;
|
|
62
67
|
subject?: string | undefined;
|
|
68
|
+
/** One page's size; absent asks for everything, which a server that does not page also answers. */
|
|
69
|
+
limit?: number | undefined;
|
|
70
|
+
/** The `nextCursor` of the page before this one. */
|
|
71
|
+
cursor?: string | undefined;
|
|
63
72
|
}
|
|
64
73
|
/**
|
|
65
74
|
* Who a memory read is for. An agent's read names the agent and the platform counts it as a
|
|
@@ -159,3 +168,13 @@ export declare function scopedMemoryEntries(body: unknown, projectId: string | n
|
|
|
159
168
|
* The caller therefore checks for `undefined` and refuses out loud, instead of asking twice.
|
|
160
169
|
*/
|
|
161
170
|
export declare function scopeMemoryResponse(body: unknown, projectId: string | null | undefined): unknown;
|
|
171
|
+
/**
|
|
172
|
+
* Every page of a memory read, as one envelope: the first page's, with every page's entries.
|
|
173
|
+
*
|
|
174
|
+
* The platform pages `GET /v1/memory` when asked, so every reader asks a page at a time and follows
|
|
175
|
+
* `nextCursor`; a server that does not page answers once with everything and no cursor. A page whose
|
|
176
|
+
* envelope is not this project's is handed back as it arrived, so the reader's scope check refuses
|
|
177
|
+
* the whole read rather than mixing it in. `fetchBody` answers `undefined` for a failed request, and
|
|
178
|
+
* so does this.
|
|
179
|
+
*/
|
|
180
|
+
export declare function readMemoryPages(baseUrl: string, scope: Omit<MemoryReadScope, 'limit' | 'cursor'>, fetchBody: (url: string) => Promise<unknown>): Promise<unknown>;
|
|
@@ -57,7 +57,14 @@ const CLOUD_MEMORY_PATH = '/v1/memory';
|
|
|
57
57
|
export const MemoryScopeField = {
|
|
58
58
|
PROJECT_ID: 'projectId',
|
|
59
59
|
SUBJECT: 'subject',
|
|
60
|
+
LIMIT: 'limit',
|
|
61
|
+
CURSOR: 'cursor',
|
|
62
|
+
NEXT_CURSOR: 'nextCursor',
|
|
60
63
|
};
|
|
64
|
+
/** One page of a memory read: the platform's own maximum. */
|
|
65
|
+
export const MEMORY_PAGE_LIMIT = 100;
|
|
66
|
+
/** ponytail: 100 pages = 10,000 entries per read; a project past that needs a subject-scoped read. */
|
|
67
|
+
const MAX_MEMORY_PAGES = 100;
|
|
61
68
|
/**
|
|
62
69
|
* The project id to name, or `undefined` when there is none.
|
|
63
70
|
*
|
|
@@ -109,6 +116,11 @@ export function memoryReadUrl(baseUrl, scope) {
|
|
|
109
116
|
if (projectId !== undefined) {
|
|
110
117
|
parts.push(`${MemoryScopeField.PROJECT_ID}=${encodeURIComponent(projectId)}`);
|
|
111
118
|
}
|
|
119
|
+
if (scope.limit !== undefined)
|
|
120
|
+
parts.push(`${MemoryScopeField.LIMIT}=${String(scope.limit)}`);
|
|
121
|
+
if (scope.cursor !== undefined) {
|
|
122
|
+
parts.push(`${MemoryScopeField.CURSOR}=${encodeURIComponent(scope.cursor)}`);
|
|
123
|
+
}
|
|
112
124
|
const url = `${baseUrl}${CLOUD_MEMORY_PATH}`;
|
|
113
125
|
return 0 === parts.length ? url : `${url}?${parts.join('&')}`;
|
|
114
126
|
}
|
|
@@ -225,3 +237,39 @@ export function scopeMemoryResponse(body, projectId) {
|
|
|
225
237
|
return body;
|
|
226
238
|
return { ...envelope, entries: keepOwnProject(entries, projectId) };
|
|
227
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Every page of a memory read, as one envelope: the first page's, with every page's entries.
|
|
242
|
+
*
|
|
243
|
+
* The platform pages `GET /v1/memory` when asked, so every reader asks a page at a time and follows
|
|
244
|
+
* `nextCursor`; a server that does not page answers once with everything and no cursor. A page whose
|
|
245
|
+
* envelope is not this project's is handed back as it arrived, so the reader's scope check refuses
|
|
246
|
+
* the whole read rather than mixing it in. `fetchBody` answers `undefined` for a failed request, and
|
|
247
|
+
* so does this.
|
|
248
|
+
*/
|
|
249
|
+
export async function readMemoryPages(baseUrl, scope, fetchBody) {
|
|
250
|
+
let first;
|
|
251
|
+
const entries = [];
|
|
252
|
+
let cursor;
|
|
253
|
+
let more = false;
|
|
254
|
+
for (let page = 0; page < MAX_MEMORY_PAGES; page += 1) {
|
|
255
|
+
const body = await fetchBody(memoryReadUrl(baseUrl, { ...scope, limit: MEMORY_PAGE_LIMIT, cursor }));
|
|
256
|
+
if (null === body || 'object' !== typeof body)
|
|
257
|
+
return body;
|
|
258
|
+
if (!isReadableMemoryScope(scopeOfMemoryResponse(body, scope.projectId)))
|
|
259
|
+
return body;
|
|
260
|
+
const envelope = body;
|
|
261
|
+
first ??= envelope;
|
|
262
|
+
const pageEntries = envelope['entries'];
|
|
263
|
+
if (!Array.isArray(pageEntries))
|
|
264
|
+
return 0 === page ? body : { ...first, entries };
|
|
265
|
+
entries.push(...pageEntries);
|
|
266
|
+
const next = envelope[MemoryScopeField.NEXT_CURSOR];
|
|
267
|
+
more = 'string' === typeof next && 0 < next.length;
|
|
268
|
+
if (!more)
|
|
269
|
+
break;
|
|
270
|
+
cursor = next;
|
|
271
|
+
}
|
|
272
|
+
const { [MemoryScopeField.NEXT_CURSOR]: _paged, ...rest } = first ?? {};
|
|
273
|
+
// Said, never silent: a reader past the page ceiling holds less than the project knows.
|
|
274
|
+
return { ...rest, entries, ...(more ? { truncated: true } : {}) };
|
|
275
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading what the dashboard answers. Every field is read defensively: an older platform, a proxy
|
|
3
|
+
* or a half-written body must degrade to "nothing confirmed", never to a throw inside the cycle.
|
|
4
|
+
* Kept apart from the cycle (`sync-cycle.ts`), which is the protocol; this is only how its replies
|
|
5
|
+
* are parsed.
|
|
6
|
+
*/
|
|
7
|
+
export interface StatusResponse {
|
|
8
|
+
knownRunIds?: string[];
|
|
9
|
+
truncated?: boolean;
|
|
10
|
+
stateHashes?: Record<string, string | null>;
|
|
11
|
+
/** What this platform reads. Absent on a platform that predates the handshake. */
|
|
12
|
+
accepts?: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface PullResponse {
|
|
15
|
+
triage?: Array<{
|
|
16
|
+
fingerprint: string;
|
|
17
|
+
status: string;
|
|
18
|
+
flowName?: string | null;
|
|
19
|
+
title?: string;
|
|
20
|
+
at: number;
|
|
21
|
+
}>;
|
|
22
|
+
cursor?: string;
|
|
23
|
+
more?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const asJson: (text: string) => unknown;
|
|
26
|
+
export declare const isRecord: (v: unknown) => v is Record<string, unknown>;
|
|
27
|
+
/** A list of numbers, or undefined when the server did not send a list at all. */
|
|
28
|
+
export declare const numbersIn: (v: unknown) => number[] | undefined;
|
|
29
|
+
/** A numeric field of an artifact, or undefined when it has none. */
|
|
30
|
+
export declare const numberAt: (v: unknown, field: string) => number | undefined;
|
|
31
|
+
/** The name a person knows a flow by, falling back to its position. */
|
|
32
|
+
export declare const flowName: (flow: unknown, index: number) => string;
|
|
33
|
+
/** The server's per-part answer: accepted count and rejection list, each read defensively. */
|
|
34
|
+
export declare function partResult(body: Record<string, unknown>, part: string): {
|
|
35
|
+
accepted: number;
|
|
36
|
+
rejected: {
|
|
37
|
+
index: number;
|
|
38
|
+
reason: string;
|
|
39
|
+
code: unknown;
|
|
40
|
+
version: unknown;
|
|
41
|
+
current: unknown;
|
|
42
|
+
}[];
|
|
43
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading what the dashboard answers. Every field is read defensively: an older platform, a proxy
|
|
3
|
+
* or a half-written body must degrade to "nothing confirmed", never to a throw inside the cycle.
|
|
4
|
+
* Kept apart from the cycle (`sync-cycle.ts`), which is the protocol; this is only how its replies
|
|
5
|
+
* are parsed.
|
|
6
|
+
*/
|
|
7
|
+
export const asJson = (text) => {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(text);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
export const isRecord = (v) => 'object' === typeof v && null !== v;
|
|
16
|
+
/** A list of numbers, or undefined when the server did not send a list at all. */
|
|
17
|
+
export const numbersIn = (v) => Array.isArray(v) ? v.filter((n) => 'number' === typeof n) : undefined;
|
|
18
|
+
/** A numeric field of an artifact, or undefined when it has none. */
|
|
19
|
+
export const numberAt = (v, field) => {
|
|
20
|
+
const n = isRecord(v) ? v[field] : undefined;
|
|
21
|
+
return 'number' === typeof n ? n : undefined;
|
|
22
|
+
};
|
|
23
|
+
/** The name a person knows a flow by, falling back to its position. */
|
|
24
|
+
export const flowName = (flow, index) => {
|
|
25
|
+
const name = isRecord(flow) ? flow['name'] : undefined;
|
|
26
|
+
return 'string' === typeof name && name.length > 0 ? name : `flow #${String(index)}`;
|
|
27
|
+
};
|
|
28
|
+
/** The server's per-part answer: accepted count and rejection list, each read defensively. */
|
|
29
|
+
export function partResult(body, part) {
|
|
30
|
+
const raw = isRecord(body[part]) ? body[part] : {};
|
|
31
|
+
const accepted = 'number' === typeof raw['accepted'] ? raw['accepted'] : 0;
|
|
32
|
+
const rejected = (Array.isArray(raw['rejected']) ? raw['rejected'] : [])
|
|
33
|
+
.filter(isRecord)
|
|
34
|
+
.map((r) => ({
|
|
35
|
+
index: 'number' === typeof r['index'] ? r['index'] : -1,
|
|
36
|
+
reason: 'string' === typeof r['reason'] ? r['reason'] : 'no reason given',
|
|
37
|
+
code: r['code'],
|
|
38
|
+
version: r['version'],
|
|
39
|
+
current: r['current'],
|
|
40
|
+
}));
|
|
41
|
+
return { accepted, rejected };
|
|
42
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ScreenshotSyncState } from './sync-screenshots.js';
|
|
2
|
+
export { FLOW_CONFLICT_CODE } from './sync-flow-versions.js';
|
|
2
3
|
/**
|
|
3
4
|
* The derived records that ride along with runs, and the file each one lives in.
|
|
4
5
|
*
|
|
@@ -56,6 +57,11 @@ export interface SyncSink {
|
|
|
56
57
|
writeIssues: (issues: PulledIssues) => void;
|
|
57
58
|
/** Persist the cursor and the bookkeeping. */
|
|
58
59
|
writeState: (state: CloudSyncState) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Keep this machine's edit of a flow as a named copy beside it and write the platform's version in
|
|
62
|
+
* its place; answers the copy's name. Absent (a dry run): the conflict is reported as a refusal.
|
|
63
|
+
*/
|
|
64
|
+
resolveFlowConflict?: (name: string, theirs: unknown) => string | undefined;
|
|
59
65
|
}
|
|
60
66
|
/** A decision a human made on the dashboard, as the machine stores it. */
|
|
61
67
|
interface PulledIssue {
|
|
@@ -106,6 +112,17 @@ export interface CloudSyncState extends ScreenshotSyncState {
|
|
|
106
112
|
* a changed set is sent on its own, and an unchanged one is not sent again.
|
|
107
113
|
*/
|
|
108
114
|
sentFlowsHash?: string;
|
|
115
|
+
/**
|
|
116
|
+
* The hash of each flow, by name, as the platform last took it from here. A flow goes when IT
|
|
117
|
+
* changed: re-sending the whole set on every save sent each of a repo's flows once per save, and
|
|
118
|
+
* the platform stamped every one of them as updated. `sentFlowsHash` is read only to adopt a
|
|
119
|
+
* record from before this existed, so an upgrade does not re-send an unchanged set.
|
|
120
|
+
*/
|
|
121
|
+
sentFlowHashes?: Record<string, string>;
|
|
122
|
+
/** The platform's version of each flow as last taken or adopted here: what a push is based on. */
|
|
123
|
+
flowVersions?: Record<string, string>;
|
|
124
|
+
/** Conflict copies still on disk: this machine's edits kept beside the platform's version. */
|
|
125
|
+
flowConflicts?: string[];
|
|
109
126
|
sentCapsulesHash?: string;
|
|
110
127
|
/**
|
|
111
128
|
* The hash of each derived record the platform last ACCEPTED from here. A platform that reports
|
|
@@ -129,16 +146,29 @@ export interface CloudSyncState extends ScreenshotSyncState {
|
|
|
129
146
|
refusedSets?: Partial<Record<SetPart, RefusedSet>>;
|
|
130
147
|
}
|
|
131
148
|
type SetPart = 'flow' | 'capsule';
|
|
132
|
-
interface RefusedSet {
|
|
149
|
+
interface RefusedSet extends RefusalStamp {
|
|
133
150
|
hash: string;
|
|
134
|
-
acceptsHash: string;
|
|
135
151
|
count: number;
|
|
136
152
|
reason: string;
|
|
137
153
|
}
|
|
138
|
-
|
|
154
|
+
/**
|
|
155
|
+
* What could change a refusal's answer besides the item itself. A refusal used to stand until the
|
|
156
|
+
* item changed or the platform's `accepts` did, so a refused flow set stayed refused after the
|
|
157
|
+
* platform relaxed its rule, until somebody deleted the entry by hand. The platform sends no version
|
|
158
|
+
* of its own, so the CLI's version stands in for "the conversation changed", and age bounds the rest.
|
|
159
|
+
*/
|
|
160
|
+
interface RefusalStamp {
|
|
161
|
+
acceptsHash: string;
|
|
162
|
+
/** The CLI version that heard the refusal. Absent on a refusal recorded before this existed. */
|
|
163
|
+
version?: string;
|
|
164
|
+
/** When it was heard. Absent on a refusal recorded before this existed. */
|
|
165
|
+
at?: number;
|
|
166
|
+
}
|
|
167
|
+
/** A refusal older than this is offered again, whatever else is unchanged. */
|
|
168
|
+
export declare const REFUSAL_RETRY_AFTER_MS: number;
|
|
169
|
+
interface RefusedRun extends RefusalStamp {
|
|
139
170
|
reason: string;
|
|
140
171
|
payloadHash: string;
|
|
141
|
-
acceptsHash: string;
|
|
142
172
|
}
|
|
143
173
|
export interface SyncReport {
|
|
144
174
|
/**
|
|
@@ -157,6 +187,8 @@ export interface SyncReport {
|
|
|
157
187
|
reason: string;
|
|
158
188
|
}>;
|
|
159
189
|
flowsSent: number;
|
|
190
|
+
/** Open conflict copies: edits of a flow another machine saved over first, kept beside it. */
|
|
191
|
+
flowConflicts?: string[];
|
|
160
192
|
/** Capsules the server accepted. Zero when it reported none, which includes not knowing the field. */
|
|
161
193
|
capsulesSent: number;
|
|
162
194
|
/** Derived records the server ACCEPTED this cycle. Empty on a quiet cycle, the normal case. */
|
|
@@ -219,6 +251,8 @@ interface SyncDeps {
|
|
|
219
251
|
sink: SyncSink;
|
|
220
252
|
state: CloudSyncState;
|
|
221
253
|
now: () => number;
|
|
254
|
+
/** This CLI's version, stamped on each refusal: a new one asks the platform again. */
|
|
255
|
+
clientVersion?: string;
|
|
222
256
|
/** Injected so a cycle can be driven against a scripted server with no network. */
|
|
223
257
|
request: (url: string, init: {
|
|
224
258
|
method: string;
|
|
@@ -229,16 +263,12 @@ interface SyncDeps {
|
|
|
229
263
|
text: string;
|
|
230
264
|
}>;
|
|
231
265
|
}
|
|
232
|
-
/** The server's per-part answer: accepted count and rejection list, each read defensively. */
|
|
233
266
|
/** A 200 that never confirmed the runs it was sent. Kept queued, and said, rather than dropped. */
|
|
234
267
|
export declare const MSG_RUNS_UNCONFIRMED = "sync 200 without a runs result: the server did not confirm the runs it was sent, so they stay queued";
|
|
268
|
+
/** The command that moves a folder's earlier runs to the link it has now. */
|
|
269
|
+
export declare const MOVE_HISTORY_COMMAND = "reticle sync --move-history";
|
|
235
270
|
/**
|
|
236
271
|
* Run one cycle. Never throws: the local record is already safe on disk, and a sync that can take
|
|
237
272
|
* down the thing it is backing up is worse than no sync.
|
|
238
273
|
*/
|
|
239
|
-
/** The command that moves a folder's earlier runs to the link it has now. */
|
|
240
|
-
export declare const MOVE_HISTORY_COMMAND = "reticle sync --move-history";
|
|
241
274
|
export declare function runSyncCycle(given: SyncDeps): Promise<SyncReport>;
|
|
242
|
-
/** One line a human can read, for the CLI and the daemon log. */
|
|
243
|
-
export declare function describeSync(report: SyncReport): string;
|
|
244
|
-
export {};
|