@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
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* tokens on that and not on politeness.
|
|
13
13
|
*/
|
|
14
14
|
import { z } from 'zod';
|
|
15
|
-
import { FeedbackKind, FeedbackSource, FEEDBACK_RATING_MAX, FEEDBACK_RATING_MIN, } from '@reticlehq/core/telemetry';
|
|
15
|
+
import { FeedbackKind, FeedbackSource, FEEDBACK_CONTACT_MAX, FEEDBACK_RATING_MAX, FEEDBACK_RATING_MIN, isFeedbackContact, } from '@reticlehq/core/telemetry';
|
|
16
16
|
import { ReticleTool } from '@reticlehq/core';
|
|
17
17
|
import { asNumber, asString } from '@reticlehq/core';
|
|
18
18
|
import { submitFeedback, feedbackDisabled } from '../../telemetry/feedback.js';
|
|
@@ -68,6 +68,8 @@ function sessionFacts(deps, sessionId) {
|
|
|
68
68
|
}
|
|
69
69
|
/** Said when a report arrives with no body at all. Names both accepted fields so the retry can work. */
|
|
70
70
|
const NO_BODY_REASON = 'the report has no body — send it as `text` (or `summary`, which is the same field). Nothing was filed.';
|
|
71
|
+
/** Said when `contact` is not one plain address. Nothing is filed, so the agent can fix it and retry. */
|
|
72
|
+
const BAD_CONTACT_REASON = `\`contact\` must be one email address of at most ${String(FEEDBACK_CONTACT_MAX)} characters, such as you@example.com. Send only an address the user typed for a reply, or leave \`contact\` out. Nothing was filed.`;
|
|
71
73
|
/** `text`, or the `summary` alias, whichever arrived. Empty when neither did — the handler refuses. */
|
|
72
74
|
function feedbackBody(args) {
|
|
73
75
|
const text = asString(args['text'])?.trim();
|
|
@@ -135,6 +137,10 @@ export const FEEDBACK_TOOLS = [
|
|
|
135
137
|
.string()
|
|
136
138
|
.optional()
|
|
137
139
|
.describe('The literal tool calls and responses that led here, so the failure can be reproduced without guessing.'),
|
|
140
|
+
contact: z
|
|
141
|
+
.string()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe('An email address for a reply from the maintainers. Only an address the user typed for this purpose. Never guess or reuse one.'),
|
|
138
144
|
sessionId: z
|
|
139
145
|
.string()
|
|
140
146
|
.optional()
|
|
@@ -147,7 +153,7 @@ export const FEEDBACK_TOOLS = [
|
|
|
147
153
|
accepted: z.boolean(),
|
|
148
154
|
reason: z.string().optional(),
|
|
149
155
|
redacted: z.array(z.string()),
|
|
150
|
-
context: z.unknown(),
|
|
156
|
+
context: z.unknown().optional(),
|
|
151
157
|
note: z.string(),
|
|
152
158
|
},
|
|
153
159
|
example: {
|
|
@@ -174,6 +180,17 @@ export const FEEDBACK_TOOLS = [
|
|
|
174
180
|
note: 'NOT accepted (see reason). Tell the human what you found so it is not lost.',
|
|
175
181
|
};
|
|
176
182
|
}
|
|
183
|
+
const contact = asString(args['contact'])?.trim();
|
|
184
|
+
if (contact !== undefined && '' !== contact && !isFeedbackContact(contact)) {
|
|
185
|
+
return {
|
|
186
|
+
sent: false,
|
|
187
|
+
accepted: false,
|
|
188
|
+
reason: BAD_CONTACT_REASON,
|
|
189
|
+
redacted: [],
|
|
190
|
+
context: undefined,
|
|
191
|
+
note: 'NOT accepted (see reason). Tell the human what you found so it is not lost.',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
177
194
|
const receipt = await submitFeedback({
|
|
178
195
|
source: FeedbackSource.AGENT,
|
|
179
196
|
kind: asString(args['kind']),
|
|
@@ -184,6 +201,7 @@ export const FEEDBACK_TOOLS = [
|
|
|
184
201
|
...optionalText(args, 'currentApproach'),
|
|
185
202
|
...optionalText(args, 'model'),
|
|
186
203
|
...optionalRating(args),
|
|
204
|
+
...(contact !== undefined && '' !== contact ? { contact } : {}),
|
|
187
205
|
}, {
|
|
188
206
|
session: sessionFacts(deps, asString(args['sessionId'])),
|
|
189
207
|
// A report that cannot be sent is written into the project being verified, never into
|
|
@@ -232,6 +250,9 @@ export const VERDICT_TOOLS = new Set([
|
|
|
232
250
|
// ACT_AND_WAIT has -- and the guard that checks SHAPE rather than tool NAME is what caught it
|
|
233
251
|
// here rather than six months from now in a metric that had quietly read low the whole time.
|
|
234
252
|
ReticleTool.ACT_SEQUENCE,
|
|
253
|
+
// `reticle_act { steps }` runs the sequence under ACT's name on the default surface (#1770).
|
|
254
|
+
// A single act carries no `verified`, so `verificationOf` counts only the sequence verdict.
|
|
255
|
+
ReticleTool.ACT,
|
|
235
256
|
ReticleTool.ASSERT,
|
|
236
257
|
// `reticle_assert { action: "wait" }` lands here, and grades its answer as `assert` does.
|
|
237
258
|
ReticleTool.WAIT_FOR,
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* Scoped per session id, because a new session is a new agent that has been told nothing.
|
|
22
22
|
*/
|
|
23
|
+
import { z } from 'zod';
|
|
23
24
|
/** Just enough shape to route on. Deliberately NOT an index signature: `InstrumentationGap` is a
|
|
24
25
|
* union of concrete object types and would not be assignable to one. */
|
|
25
26
|
interface GapLike {
|
|
@@ -38,4 +39,9 @@ now?: number): T[];
|
|
|
38
39
|
export declare function forgetGapNovelty(sessionId: string): void;
|
|
39
40
|
/** Test seam: drop every session's memory. */
|
|
40
41
|
export declare function resetGapNovelty(): void;
|
|
42
|
+
/**
|
|
43
|
+
* The output-schema entry for `engineBlindSpots`, shared by every verdict tool so they cannot word
|
|
44
|
+
* it two ways. See `EngineBlindSpotKind` in core.
|
|
45
|
+
*/
|
|
46
|
+
export declare const engineBlindSpotsOutput: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
41
47
|
export {};
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* Scoped per session id, because a new session is a new agent that has been told nothing.
|
|
22
22
|
*/
|
|
23
|
+
import { z } from 'zod';
|
|
23
24
|
import { recordGaps } from '../../portal/session/recorded-gaps.js';
|
|
24
25
|
/** The fields worth repeating. Everything else on a gap is the remedy, said once. */
|
|
25
26
|
const FACT_KEYS = ['kind', 'ref', 'source'];
|
|
@@ -74,3 +75,11 @@ export function forgetGapNovelty(sessionId) {
|
|
|
74
75
|
export function resetGapNovelty() {
|
|
75
76
|
toldBySession.clear();
|
|
76
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* The output-schema entry for `engineBlindSpots`, shared by every verdict tool so they cannot word
|
|
80
|
+
* it two ways. See `EngineBlindSpotKind` in core.
|
|
81
|
+
*/
|
|
82
|
+
export const engineBlindSpotsOutput = z
|
|
83
|
+
.array(z.unknown())
|
|
84
|
+
.optional()
|
|
85
|
+
.describe('What this engine could not observe in the session so far, cumulative: each entry is { kind, detail }, kind "pixels-unobserved" or "claim-arithmetic-unchecked". [] when nothing. The last verdict of a run carries the run\'s list; a host must not call a run clean while it holds an entry.');
|
|
@@ -27,9 +27,10 @@ export function capabilityAbsences(session) {
|
|
|
27
27
|
if (false === session.captureBodies) {
|
|
28
28
|
absences.push({
|
|
29
29
|
capability: 'network-bodies',
|
|
30
|
-
meaning: 'request and response bodies are not recorded
|
|
31
|
-
'
|
|
32
|
-
|
|
30
|
+
meaning: 'request bodies and successful response bodies are not recorded (a failed response keeps ' +
|
|
31
|
+
'its body by default), so an assertion that reads one cannot be answered here and will be ' +
|
|
32
|
+
'refused before it spends an action',
|
|
33
|
+
remedy: "pass captureNetworkBodies: true to connect() in this app's Reticle setup, then reload the page. " +
|
|
33
34
|
'Bodies can carry personal data, so this is off unless a project asks for it.',
|
|
34
35
|
});
|
|
35
36
|
}
|
|
@@ -17,7 +17,7 @@ import { type GoalCheck } from '../../features/harness/goals.js';
|
|
|
17
17
|
import type { RunDisparity } from '@reticlehq/core';
|
|
18
18
|
import type { HarnessMap } from '@reticlehq/core/artifacts';
|
|
19
19
|
export { MSG_HARNESS_DISABLED, MSG_HARNESS_UNCLAIMED, MSG_HARNESS_UNCONFIRMED, } from '../../features/harness/platform/refusal.js';
|
|
20
|
-
export {
|
|
20
|
+
export { HarnessNotLinkedError, MSG_NO_HARNESS_KEY, firstLine, harnessAvailable, harnessStartRefusal, refusedByPlatform, withLinkedCredential, } from './harness-gate.js';
|
|
21
21
|
export interface ExploreOptions {
|
|
22
22
|
/** Who to be, or what to accomplish. Appended to the standing instruction. */
|
|
23
23
|
focus?: string;
|
|
@@ -30,9 +30,9 @@ import { endOf, goalOfDrive, parseGoals, readOpening, unprovedGoals, } from '../
|
|
|
30
30
|
import { mapForPlatform } from '../../features/harness/explore/site-map.js';
|
|
31
31
|
import { huntAndGrade, knownRoutes, refreshMap, siteMapFor } from './harness-hunt.js';
|
|
32
32
|
export { MSG_HARNESS_DISABLED, MSG_HARNESS_UNCLAIMED, MSG_HARNESS_UNCONFIRMED, } from '../../features/harness/platform/refusal.js';
|
|
33
|
-
import { MSG_NO_HARNESS_KEY, refusedForPlan } from './harness-gate.js';
|
|
33
|
+
import { HarnessNotLinkedError, MSG_NO_HARNESS_KEY, refusedForPlan } from './harness-gate.js';
|
|
34
34
|
// The gate a drive passes before it starts moved to its own module; its names are still asked for here.
|
|
35
|
-
export {
|
|
35
|
+
export { HarnessNotLinkedError, MSG_NO_HARNESS_KEY, firstLine, harnessAvailable, harnessStartRefusal, refusedByPlatform, withLinkedCredential, } from './harness-gate.js';
|
|
36
36
|
/** A driver named that this build no longer has: every Harness decision is the platform's now. */
|
|
37
37
|
const msgUnknownDriver = (asked) => `The Harness driver \`${asked}\` is not available: the Harness runs on the Reticle platform, ` +
|
|
38
38
|
`which drives with the model set for the project in the dashboard.`;
|
|
@@ -66,7 +66,9 @@ export async function exploreApp(deps, given, asked = {}) {
|
|
|
66
66
|
const options = named === undefined ? asked : { ...asked, focus: named.persona };
|
|
67
67
|
const refusal = await refusedForPlan(env, options);
|
|
68
68
|
if (refusal !== undefined)
|
|
69
|
-
throw
|
|
69
|
+
throw MSG_NO_HARNESS_KEY === refusal.text
|
|
70
|
+
? new HarnessNotLinkedError()
|
|
71
|
+
: new DriveRefusedError(refusal.text, refusal.reason);
|
|
70
72
|
// The flows a drive reads and diffs are the PROJECT's, which is where its saves land.
|
|
71
73
|
const reads = withProjectFlows(deps, options.sessionId);
|
|
72
74
|
// No journey named: plan the drive first. The platform's Harness proposes the people worth being;
|
|
@@ -491,7 +493,7 @@ siteMap) {
|
|
|
491
493
|
throw new Error(msgUnknownDriver(requested));
|
|
492
494
|
const platform = serverOptionsFromEnv(env);
|
|
493
495
|
if (platform === undefined)
|
|
494
|
-
throw new
|
|
496
|
+
throw new HarnessNotLinkedError();
|
|
495
497
|
return {
|
|
496
498
|
driver: serverDriver({
|
|
497
499
|
...platform,
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the Harness may drive at all, and with which credential — answered before a drive starts.
|
|
3
|
+
*
|
|
4
|
+
* Split from `harness-explore.ts`, which runs the drive. This is the gate every Harness start passes
|
|
5
|
+
* through (an agent's explore, Run Harness, `reticle try`, the platform's chat): the linked
|
|
6
|
+
* credential, a page and daemon from different builds, and the platform's own yes or no. No setup
|
|
7
|
+
* score gates it: the Harness runs at any instrumentation.
|
|
8
|
+
*/
|
|
9
|
+
import { HarnessRunReason } from '@reticlehq/core/telemetry';
|
|
10
|
+
import { DriveRefusedError } from '../../features/harness/drive-runs.js';
|
|
1
11
|
import type { ToolDeps } from './tool-kit.js';
|
|
2
12
|
import { type ConfigFetch } from '../../features/harness/platform-config.js';
|
|
3
13
|
/** What the platform half of the gate reads off a drive's options; `ExploreOptions` satisfies it. */
|
|
@@ -9,11 +19,27 @@ export interface HarnessAsk {
|
|
|
9
19
|
/**
|
|
10
20
|
* Why the harness is unavailable, phrased as the way to make it available.
|
|
11
21
|
*
|
|
12
|
-
* A missing key is a configuration fact, not a fault
|
|
13
|
-
*
|
|
14
|
-
*
|
|
22
|
+
* A missing key is a configuration fact, not a fault. This is the AGENT's sentence: who does what
|
|
23
|
+
* next, short, and no credit number (free credit is granted once per person, so the engine cannot
|
|
24
|
+
* know what is left). Named here because the CLI and the honest no-flows refusal print it too.
|
|
15
25
|
*/
|
|
16
26
|
export declare const MSG_NO_HARNESS_KEY: string;
|
|
27
|
+
/**
|
|
28
|
+
* The not-linked refusal, thrown. Its code and next steps ride on the error envelope beside the
|
|
29
|
+
* sentence (`codedRefusalOf`), so the agent reads who does what as data and error-recovery keys on
|
|
30
|
+
* the code. The person reads `HARNESS_NOT_LINKED_HUMAN` on the HUD instead.
|
|
31
|
+
*/
|
|
32
|
+
export declare class HarnessNotLinkedError extends DriveRefusedError {
|
|
33
|
+
readonly code: "harness_not_linked";
|
|
34
|
+
readonly next: readonly ({
|
|
35
|
+
who: "human";
|
|
36
|
+
run: string;
|
|
37
|
+
} | {
|
|
38
|
+
who: "agent";
|
|
39
|
+
tool: string;
|
|
40
|
+
})[];
|
|
41
|
+
constructor();
|
|
42
|
+
}
|
|
17
43
|
/**
|
|
18
44
|
* The environment, plus the credential this machine already has.
|
|
19
45
|
*
|
|
@@ -42,24 +68,15 @@ export declare function withLinkedCredential(deps: ToolDeps, env: Record<string,
|
|
|
42
68
|
tab?: {
|
|
43
69
|
sessionId: string | undefined;
|
|
44
70
|
}): Promise<Record<string, string | undefined>>;
|
|
45
|
-
/**
|
|
46
|
-
export declare const
|
|
47
|
-
/**
|
|
48
|
-
* Why the Harness must not drive this tab's app yet, or undefined when it may: below the coverage
|
|
49
|
-
* gate (core's `instrumentation-coverage.ts`), one reason sentence and the prompt that closes it. Every Harness
|
|
50
|
-
* start passes here (an agent's explore, Run Harness, `reticle try`, the platform's chat), so the
|
|
51
|
-
* gate holds wherever a drive starts; every other tool works at any coverage. A tab that cannot be
|
|
52
|
-
* resolved is not refused here: the drive itself answers for a missing tab. Counted once per refusal.
|
|
53
|
-
*/
|
|
54
|
-
export declare function coverageRefusal(deps: ToolDeps, sessionId: string | undefined): string | undefined;
|
|
71
|
+
/** Opens a refusal for version skew: the one thing to fix before a drive can decide anything. */
|
|
72
|
+
export declare const MSG_SKEW_LEAD: string;
|
|
55
73
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* the
|
|
60
|
-
* case the daemon's sentence names what this tab can fix.
|
|
74
|
+
* Why a Harness drive must not start on this tab, or undefined when it may. Only a page and daemon
|
|
75
|
+
* from different builds refuse here. The setup score never does: the Harness runs at any
|
|
76
|
+
* instrumentation, so an app works out of the box. A tab that cannot be resolved is not refused
|
|
77
|
+
* here: the drive itself answers for a missing tab.
|
|
61
78
|
*/
|
|
62
|
-
export declare function
|
|
79
|
+
export declare function harnessStartRefusal(deps: ToolDeps, sessionId: string | undefined): Promise<HarnessRefusal | undefined>;
|
|
63
80
|
/**
|
|
64
81
|
* Can this machine reach the Harness? Only through the platform: a linked project or a platform
|
|
65
82
|
* key. Whether the workspace is entitled is the platform's answer, asked when the drive starts.
|
|
@@ -77,12 +94,17 @@ export declare function harnessAvailable(env: Record<string, string | undefined>
|
|
|
77
94
|
* retry or bring a key. Fields an older platform omits still default to yes inside
|
|
78
95
|
* `fetchPlatformConfig`; only an answer that never arrived is a no.
|
|
79
96
|
*/
|
|
80
|
-
export declare function refusedByPlatform(env: Record<string, string | undefined>, options: HarnessAsk): Promise<
|
|
97
|
+
export declare function refusedByPlatform(env: Record<string, string | undefined>, options: HarnessAsk): Promise<HarnessRefusal | undefined>;
|
|
81
98
|
/**
|
|
82
99
|
* `refusedByPlatform`, for a run that may be a saved plan. A plan that only replays saved flows
|
|
83
100
|
* spends no model turn, so a model drive's gates do not stop it; a refused plan is still reported to
|
|
84
101
|
* the plan, every journey blocked with the reason, so its history records the attempt.
|
|
85
102
|
*/
|
|
86
|
-
export declare function refusedForPlan(env: Record<string, string | undefined>, options: HarnessAsk): Promise<
|
|
103
|
+
export declare function refusedForPlan(env: Record<string, string | undefined>, options: HarnessAsk): Promise<HarnessRefusal | undefined>;
|
|
104
|
+
/** A refusal: the sentence the person or agent reads, and the reason `harness_run` reports. */
|
|
105
|
+
export interface HarnessRefusal {
|
|
106
|
+
text: string;
|
|
107
|
+
reason: HarnessRunReason;
|
|
108
|
+
}
|
|
87
109
|
/** The sentence a refusal leads with, without the prompt that follows it. */
|
|
88
110
|
export declare const firstLine: (text: string) => string;
|
|
@@ -3,31 +3,44 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Split from `harness-explore.ts`, which runs the drive. This is the gate every Harness start passes
|
|
5
5
|
* through (an agent's explore, Run Harness, `reticle try`, the platform's chat): the linked
|
|
6
|
-
* credential,
|
|
6
|
+
* credential, a page and daemon from different builds, and the platform's own yes or no. No setup
|
|
7
|
+
* score gates it: the Harness runs at any instrumentation.
|
|
7
8
|
*/
|
|
9
|
+
import { HarnessRunReason } from '@reticlehq/core/telemetry';
|
|
8
10
|
import { reportAppsNow } from '../../features/harness/platform/local-apps.js';
|
|
9
11
|
import { serverOptionsFromEnv } from '../../features/harness/platform/server-driver.js';
|
|
10
|
-
import { ReticleEnv, cloudUrlFrom } from '@reticlehq/core';
|
|
12
|
+
import { CONNECT_COMMAND, HARNESS_NOT_LINKED_NEXT, RefusalCode, ReticleEnv, ReticleTool, cloudUrlFrom, } from '@reticlehq/core';
|
|
13
|
+
import { DriveRefusedError } from '../../features/harness/drive-runs.js';
|
|
11
14
|
import { creditsSpent, creditsUsedLine } from '@reticlehq/core/hud';
|
|
12
15
|
import { planUrl } from '../../features/harness/platform/platform-drives.js';
|
|
13
16
|
import { isUnmatchedRoot } from '../../memory/project/dir/reticle-dir.js';
|
|
14
17
|
import { sessionRoot } from '../../memory/project/session-root.js';
|
|
15
18
|
import { fetchPlatformConfig } from '../../features/harness/platform-config.js';
|
|
16
19
|
import { reportPlanBlocked, savedPlanDrivesNothing } from '../../features/harness/platform/script.js';
|
|
17
|
-
import {
|
|
18
|
-
import { getSessionMetrics } from '../../telemetry/session-metrics.js';
|
|
20
|
+
import { probeMarkers } from '../../portal/session/recorded-gaps.js';
|
|
19
21
|
import { MSG_HARNESS_DISABLED, MSG_HARNESS_UNCLAIMED, MSG_HARNESS_UNCONFIRMED, } from '../../features/harness/platform/refusal.js';
|
|
20
22
|
/**
|
|
21
23
|
* Why the harness is unavailable, phrased as the way to make it available.
|
|
22
24
|
*
|
|
23
|
-
* A missing key is a configuration fact, not a fault
|
|
24
|
-
*
|
|
25
|
-
*
|
|
25
|
+
* A missing key is a configuration fact, not a fault. This is the AGENT's sentence: who does what
|
|
26
|
+
* next, short, and no credit number (free credit is granted once per person, so the engine cannot
|
|
27
|
+
* know what is left). Named here because the CLI and the honest no-flows refusal print it too.
|
|
26
28
|
*/
|
|
27
|
-
export const MSG_NO_HARNESS_KEY = `The Reticle Harness runs on the Reticle platform, and
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
export const MSG_NO_HARNESS_KEY = `The Reticle Harness runs on the Reticle platform, and this project is not linked to it. ` +
|
|
30
|
+
`Ask the person to run \`${CONNECT_COMMAND}\`, or drive the journey yourself with ` +
|
|
31
|
+
`${ReticleTool.ACT_AND_WAIT} and an \`until\` on its last step.`;
|
|
32
|
+
/**
|
|
33
|
+
* The not-linked refusal, thrown. Its code and next steps ride on the error envelope beside the
|
|
34
|
+
* sentence (`codedRefusalOf`), so the agent reads who does what as data and error-recovery keys on
|
|
35
|
+
* the code. The person reads `HARNESS_NOT_LINKED_HUMAN` on the HUD instead.
|
|
36
|
+
*/
|
|
37
|
+
export class HarnessNotLinkedError extends DriveRefusedError {
|
|
38
|
+
code = RefusalCode.HARNESS_NOT_LINKED;
|
|
39
|
+
next = HARNESS_NOT_LINKED_NEXT;
|
|
40
|
+
constructor() {
|
|
41
|
+
super(MSG_NO_HARNESS_KEY, HarnessRunReason.NOT_LINKED);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
31
44
|
/**
|
|
32
45
|
* The environment, plus the credential this machine already has.
|
|
33
46
|
*
|
|
@@ -83,21 +96,9 @@ function tabRoot(deps, tab) {
|
|
|
83
96
|
return undefined;
|
|
84
97
|
}
|
|
85
98
|
}
|
|
86
|
-
/**
|
|
87
|
-
export const
|
|
88
|
-
|
|
89
|
-
* Why the Harness must not drive this tab's app yet, or undefined when it may: below the coverage
|
|
90
|
-
* gate (core's `instrumentation-coverage.ts`), one reason sentence and the prompt that closes it. Every Harness
|
|
91
|
-
* start passes here (an agent's explore, Run Harness, `reticle try`, the platform's chat), so the
|
|
92
|
-
* gate holds wherever a drive starts; every other tool works at any coverage. A tab that cannot be
|
|
93
|
-
* resolved is not refused here: the drive itself answers for a missing tab. Counted once per refusal.
|
|
94
|
-
*/
|
|
95
|
-
export function coverageRefusal(deps, sessionId) {
|
|
96
|
-
const refused = localGateRefusal(deps, sessionId);
|
|
97
|
-
if (refused !== undefined)
|
|
98
|
-
getSessionMetrics().recordHarnessRefused(refused.percent);
|
|
99
|
-
return refused?.text;
|
|
100
|
-
}
|
|
99
|
+
/** Opens a refusal for version skew: the one thing to fix before a drive can decide anything. */
|
|
100
|
+
export const MSG_SKEW_LEAD = "The page's Reticle SDK and this daemon are different builds, so a Harness drive could only " +
|
|
101
|
+
'answer "unknown" on every step. It did not start. Fix the versions first:';
|
|
101
102
|
/** This tab and every other live tab of its app, or undefined when the tab cannot be resolved. */
|
|
102
103
|
function appTabsOf(deps, sessionId) {
|
|
103
104
|
let tab;
|
|
@@ -107,8 +108,7 @@ function appTabsOf(deps, sessionId) {
|
|
|
107
108
|
catch {
|
|
108
109
|
return undefined;
|
|
109
110
|
}
|
|
110
|
-
// Every tab of the app, the way the platform's merged report reads it
|
|
111
|
-
// missing items.
|
|
111
|
+
// Every tab of the app, the way the platform's merged report reads it.
|
|
112
112
|
const siblings = (deps.sessions.list?.() ?? [])
|
|
113
113
|
.filter((info) => info.sessionId !== tab.id && sameApp(info.projectId, tab.projectId))
|
|
114
114
|
.flatMap((info) => {
|
|
@@ -117,47 +117,23 @@ function appTabsOf(deps, sessionId) {
|
|
|
117
117
|
});
|
|
118
118
|
return { tab, siblings };
|
|
119
119
|
}
|
|
120
|
-
/** The daemon's own reading of the gate for this tab's app, uncounted. */
|
|
121
|
-
function localGateRefusal(deps, sessionId) {
|
|
122
|
-
const app = appTabsOf(deps, sessionId);
|
|
123
|
-
if (app === undefined)
|
|
124
|
-
return undefined;
|
|
125
|
-
const { tab } = app;
|
|
126
|
-
const siblings = app.siblings.map((live) => ({
|
|
127
|
-
id: live.id,
|
|
128
|
-
url: live.url,
|
|
129
|
-
projectId: live.projectId,
|
|
130
|
-
channels: live.channels,
|
|
131
|
-
sourceMapping: live.sourceMapping,
|
|
132
|
-
}));
|
|
133
|
-
const coverage = instrumentationOf(tab, siblings);
|
|
134
|
-
const gate = coverage.harnessGate;
|
|
135
|
-
if (gate.unlocked || gate.reason === undefined)
|
|
136
|
-
return undefined;
|
|
137
|
-
const text = coverage.prompt === undefined
|
|
138
|
-
? gate.reason
|
|
139
|
-
: `${gate.reason}\n\n${MSG_GATE_PROMPT_LEAD}\n${coverage.prompt}`;
|
|
140
|
-
return { text, percent: gate.percent };
|
|
141
|
-
}
|
|
142
120
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* the
|
|
147
|
-
* case the daemon's sentence names what this tab can fix.
|
|
121
|
+
* Why a Harness drive must not start on this tab, or undefined when it may. Only a page and daemon
|
|
122
|
+
* from different builds refuse here. The setup score never does: the Harness runs at any
|
|
123
|
+
* instrumentation, so an app works out of the box. A tab that cannot be resolved is not refused
|
|
124
|
+
* here: the drive itself answers for a missing tab.
|
|
148
125
|
*/
|
|
149
|
-
export async function
|
|
150
|
-
// What the app's pages carry decides, not what an act happened to reach: ask them first.
|
|
126
|
+
export async function harnessStartRefusal(deps, sessionId) {
|
|
151
127
|
const app = appTabsOf(deps, sessionId);
|
|
152
|
-
//
|
|
128
|
+
// A page and daemon from different builds answer every step `unknown`: a drive spends its credits
|
|
129
|
+
// and proves nothing. The handshake already knows, so say it before anything is spent.
|
|
130
|
+
const skew = app?.tab.versionSkew;
|
|
131
|
+
if (skew !== undefined && 0 < skew.length)
|
|
132
|
+
return refusal(`${MSG_SKEW_LEAD} ${skew}`, HarnessRunReason.VERSION_SKEW);
|
|
133
|
+
// Learned something: the platform hears it before the drive, so its coverage reading is current.
|
|
153
134
|
if (app !== undefined && (await probeMarkers([app.tab, ...app.siblings])))
|
|
154
135
|
await reportAppsNow().catch(() => undefined);
|
|
155
|
-
|
|
156
|
-
return undefined;
|
|
157
|
-
const platform = await fetchPlatformConfig(env, fetchConfig);
|
|
158
|
-
if (true === platform?.gate?.unlocked)
|
|
159
|
-
return undefined;
|
|
160
|
-
return coverageRefusal(deps, sessionId);
|
|
136
|
+
return undefined;
|
|
161
137
|
}
|
|
162
138
|
/** Two tabs are one app when both name the same project. A tab that names none stands alone. */
|
|
163
139
|
const sameApp = (a, b) => a !== undefined && a === b;
|
|
@@ -191,27 +167,22 @@ export async function refusedByPlatform(env, options) {
|
|
|
191
167
|
return undefined;
|
|
192
168
|
// No platform, no Harness: it runs there, on the workspace's credits.
|
|
193
169
|
if (serverOptionsFromEnv(env) === undefined)
|
|
194
|
-
return MSG_NO_HARNESS_KEY;
|
|
170
|
+
return refusal(MSG_NO_HARNESS_KEY, HarnessRunReason.NOT_LINKED);
|
|
195
171
|
const config = await platformConfig(env, options);
|
|
196
172
|
// It needs a confirmed yes, not the absence of a no. The platform also checks on every turn.
|
|
197
173
|
if (config === undefined)
|
|
198
|
-
return MSG_HARNESS_UNCONFIRMED;
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
const gate = config.gate;
|
|
202
|
-
if (false === gate?.unlocked && gate.reason !== undefined)
|
|
203
|
-
return gate.prompt === undefined
|
|
204
|
-
? gate.reason
|
|
205
|
-
: `${gate.reason}\n\n${MSG_GATE_PROMPT_LEAD}\n${gate.prompt}`;
|
|
174
|
+
return refusal(MSG_HARNESS_UNCONFIRMED, HarnessRunReason.PLATFORM_UNREACHABLE);
|
|
175
|
+
// An older platform may still send `harnessUnlocked: false`. It is not read: no setup score
|
|
176
|
+
// refuses a drive.
|
|
206
177
|
if (!config.harnessEnabled)
|
|
207
|
-
return MSG_HARNESS_DISABLED;
|
|
178
|
+
return refusal(MSG_HARNESS_DISABLED, HarnessRunReason.HARNESS_OFF);
|
|
208
179
|
// Before entitlement: no credits left is why most workspaces are not entitled, said as the HUD says it.
|
|
209
180
|
if (config.credits !== undefined && creditsSpent(config.credits))
|
|
210
|
-
return creditsUsedLine(config.credits,
|
|
181
|
+
return refusal(creditsUsedLine(config.credits,
|
|
211
182
|
// The platform's own page; built from the API origin only for a platform that names none.
|
|
212
|
-
config.planUrl ?? planUrl(config.platformUrl ?? cloudUrlFrom(env) ?? ''));
|
|
183
|
+
config.planUrl ?? planUrl(config.platformUrl ?? cloudUrlFrom(env) ?? '')), HarnessRunReason.NO_CREDITS);
|
|
213
184
|
if (!config.harnessEntitled)
|
|
214
|
-
return MSG_HARNESS_UNCLAIMED;
|
|
185
|
+
return refusal(MSG_HARNESS_UNCLAIMED, HarnessRunReason.NOT_ENTITLED);
|
|
215
186
|
return undefined;
|
|
216
187
|
}
|
|
217
188
|
/**
|
|
@@ -226,10 +197,13 @@ export async function refusedForPlan(env, options) {
|
|
|
226
197
|
return refusedByPlatform(env, options);
|
|
227
198
|
if (await savedPlanDrivesNothing(platform, planId))
|
|
228
199
|
return undefined;
|
|
229
|
-
const
|
|
230
|
-
if (
|
|
231
|
-
await reportPlanBlocked(platform, planId, firstLine(
|
|
232
|
-
return
|
|
200
|
+
const refused = await refusedByPlatform(env, options);
|
|
201
|
+
if (refused !== undefined)
|
|
202
|
+
await reportPlanBlocked(platform, planId, firstLine(refused.text));
|
|
203
|
+
return refused;
|
|
204
|
+
}
|
|
205
|
+
function refusal(text, reason) {
|
|
206
|
+
return { text, reason };
|
|
233
207
|
}
|
|
234
208
|
/** The sentence a refusal leads with, without the prompt that follows it. */
|
|
235
209
|
export const firstLine = (text) => text.split('\n')[0] ?? text;
|
|
@@ -20,6 +20,8 @@ export declare function laneSeed(deps: ToolDeps, sessionId: string | undefined,
|
|
|
20
20
|
* nothing to plan from, so the caller drives the app with no plan, as before.
|
|
21
21
|
*/
|
|
22
22
|
export declare function exploreScript(deps: ToolDeps, env: Record<string, string | undefined>, options: ExploreOptions, before: ReadonlySet<string>): Promise<ExploreResult | undefined>;
|
|
23
|
+
/** What the project still owes, in its own words: the user's recent request, then open intents. */
|
|
24
|
+
export declare function memoryGoals(deps: ToolDeps, sessionId?: string): Promise<string[]>;
|
|
23
25
|
/**
|
|
24
26
|
* The run's goal verdict: false if any drive missed its goal, true if all judged ones reached it.
|
|
25
27
|
* Every journey passed is the page's answer, already graded at each journey's end: a driver's own
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* the HUD and redrawn as each part starts and ends.
|
|
8
8
|
*/
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
|
-
import { join } from 'node:path';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
11
|
import { ReticleCommand, ReticleTool, ScriptStatus, asRecord, } from '@reticlehq/core';
|
|
12
12
|
import { JourneyBy, PromptContextSchema, checkScript, } from '@reticlehq/core/artifacts';
|
|
13
13
|
import { runScript, } from '../../features/harness/script/script-run.js';
|
|
@@ -17,6 +17,7 @@ import { runHarness, StopReason, } from '../../features/harness/harness.js';
|
|
|
17
17
|
import { reticleDirPaths } from '../../memory/project/dir/reticle-dir.js';
|
|
18
18
|
import { harnessRunId, noteHarnessDisparity, noteHarnessGoal, noteHarnessSpan, } from '../../judgement/runs/drive-run.js';
|
|
19
19
|
import { openSessionIntents } from '../../memory/intent/open-intents.js';
|
|
20
|
+
import { sharesRequests } from '../../memory/intent/record-request.js';
|
|
20
21
|
import { sessionRoot, sessionTarget } from '../../memory/project/session-root.js';
|
|
21
22
|
import { leasableAppUrl, sessionUrlOf } from '../../language/flows/flow-tools.js';
|
|
22
23
|
import { acquireLeasedSession, suiteFixtureSeed } from './lease-tools.js';
|
|
@@ -180,7 +181,7 @@ async function runPlan(deps, env, options, before, planned) {
|
|
|
180
181
|
let off = false;
|
|
181
182
|
const poll = setInterval(() => {
|
|
182
183
|
void refusedByPlatform(env, options).then((refusal) => {
|
|
183
|
-
if (MSG_HARNESS_DISABLED === refusal)
|
|
184
|
+
if (MSG_HARNESS_DISABLED === refusal?.text)
|
|
184
185
|
off = true;
|
|
185
186
|
});
|
|
186
187
|
}, STOP_POLL_MS);
|
|
@@ -198,7 +199,7 @@ async function runPlan(deps, env, options, before, planned) {
|
|
|
198
199
|
// A replay-only plan started without the model's gates; a fallback is the model, so it asks now.
|
|
199
200
|
fallbackRefused: async () => {
|
|
200
201
|
const refusal = await refusedByPlatform(env, options);
|
|
201
|
-
return refusal === undefined ? undefined : firstLine(refusal);
|
|
202
|
+
return refusal === undefined ? undefined : firstLine(refusal.text);
|
|
202
203
|
},
|
|
203
204
|
...(true === options.confirmDangerous ? { confirmDangerous: true } : {}),
|
|
204
205
|
lease: async () => {
|
|
@@ -435,13 +436,17 @@ function scriptTexts(script) {
|
|
|
435
436
|
];
|
|
436
437
|
}
|
|
437
438
|
/** What the project still owes, in its own words: the user's recent request, then open intents. */
|
|
438
|
-
async function memoryGoals(deps, sessionId) {
|
|
439
|
+
export async function memoryGoals(deps, sessionId) {
|
|
439
440
|
const goals = [];
|
|
440
441
|
try {
|
|
441
|
-
const
|
|
442
|
+
const root = sessionRoot(deps, sessionId);
|
|
443
|
+
const parsed = PromptContextSchema.safeParse(JSON.parse(await deps.fs.readFile(reticleDirPaths(root).request)));
|
|
442
444
|
const at = parsed.success ? parsed.data.at : undefined;
|
|
443
445
|
const request = parsed.success ? parsed.data.request : undefined;
|
|
444
|
-
|
|
446
|
+
// The request goes to the platform only when a run would carry it there too: captured shared,
|
|
447
|
+
// and the project has not said `"shareRequests": false` since.
|
|
448
|
+
const shared = parsed.success && true === parsed.data.shared && sharesRequests(dirname(root), root);
|
|
449
|
+
if (shared && request !== undefined && at !== undefined && deps.now() - at < REQUEST_FRESH_MS) {
|
|
445
450
|
goals.push(request);
|
|
446
451
|
}
|
|
447
452
|
}
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* agent can reach.
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
12
11
|
import { AppRuntime, ConsequenceKind, NetInitiator, PredicateKind, ReticleTool, } from '@reticlehq/core';
|
|
13
12
|
import { TOOLS } from './tools.js';
|
|
14
13
|
import { runTool } from './invoke-tool.js';
|
|
@@ -98,8 +97,8 @@ const INJECTED_PARAMS = new Set(['sessionId']);
|
|
|
98
97
|
* wedge, it would manufacture one.
|
|
99
98
|
*/
|
|
100
99
|
const TOOL_TIMEOUT_MS = 300_000;
|
|
101
|
-
/** What the MCP SDK passes
|
|
102
|
-
const MCP_SCHEMA_OPTIONS = {
|
|
100
|
+
/** What the MCP SDK passes zod's own converter, restated so the two surfaces cannot drift apart. */
|
|
101
|
+
const MCP_SCHEMA_OPTIONS = { target: 'draft-7', io: 'input' };
|
|
103
102
|
/** Convert one tool's zod shape into the JSON Schema the model wire wants. */
|
|
104
103
|
function toHarnessTool(tool) {
|
|
105
104
|
const asked = Object.fromEntries(Object.entries(tool.inputSchema).filter(([name]) => !INJECTED_PARAMS.has(name)));
|
|
@@ -115,7 +114,7 @@ function toHarnessTool(tool) {
|
|
|
115
114
|
* argument that decides whether a drive proves anything. Definitions and refs are what every
|
|
116
115
|
* agent driving Reticle over MCP already reads.
|
|
117
116
|
*/
|
|
118
|
-
inputSchema:
|
|
117
|
+
inputSchema: z.toJSONSchema(z.object(asked), MCP_SCHEMA_OPTIONS),
|
|
119
118
|
};
|
|
120
119
|
}
|
|
121
120
|
/**
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import { type NoticeFold } from './agent/notices.js';
|
|
2
2
|
import type { ToolCall, ToolDef, ToolDeps } from './tool-kit.js';
|
|
3
|
-
export declare const SESSION_BOUND_TOOLS: ReadonlySet<string>;
|
|
4
|
-
/**
|
|
5
|
-
* Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
|
|
6
|
-
* disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
|
|
7
|
-
* exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
|
|
8
|
-
* `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
|
|
9
|
-
*/
|
|
10
|
-
export declare const SESSION_EXEMPT_TOOLS: ReadonlySet<string>;
|
|
11
3
|
export declare function runTool<Ext>(tool: ToolDef<Ext>, deps: ToolDeps<Ext>, given: Record<string, unknown>, call?: ToolCall): Promise<unknown>;
|
|
12
4
|
/** Advisories that become once-per-session notice lines. See agent/notices.ts. */
|
|
13
5
|
export declare const NOTICE_FOLD: NoticeFold;
|