@reticlehq/server 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +30 -28
- package/dist/command/cli/adhoc-suite.d.ts +19 -0
- package/dist/command/cli/adhoc-suite.js +88 -0
- package/dist/command/cli/adhoc-verdict.d.ts +23 -2
- package/dist/command/cli/adhoc-verdict.js +18 -10
- package/dist/command/cli/auth/device-flow.d.ts +2 -2
- package/dist/command/cli/cli-doctor.js +37 -5
- package/dist/command/cli/cli-flow-commands.d.ts +2 -1
- package/dist/command/cli/cli-kill.js +1 -1
- package/dist/command/cli/cli-parse-grammar.d.ts +7 -0
- package/dist/command/cli/cli-parse-grammar.js +7 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -5
- package/dist/command/cli/cli-parse-verify.js +86 -13
- package/dist/command/cli/cli-parse.d.ts +8 -1
- package/dist/command/cli/cli-parse.js +38 -7
- package/dist/command/cli/cli-verify.d.ts +59 -0
- package/dist/command/cli/cli-verify.js +131 -19
- package/dist/command/cli/cloud-cli.js +7 -6
- package/dist/command/cli/cloud-kit.d.ts +0 -2
- package/dist/command/cli/cloud-kit.js +3 -7
- package/dist/command/cli/config/config-discovery.d.ts +12 -0
- package/dist/command/cli/config/config-discovery.js +19 -0
- package/dist/command/cli/doctor/doctor-rows.d.ts +12 -0
- package/dist/command/cli/doctor/doctor-rows.js +12 -0
- package/dist/command/cli/doctor/doctor-sessions-line.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +1 -1
- package/dist/command/cli/launch/cli-launch.d.ts +3 -23
- package/dist/command/cli/launch/cli-launch.js +29 -70
- package/dist/command/cli/lifecycle/daemon-lifecycle.d.ts +33 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +198 -0
- package/dist/command/cli/mcp-command.js +5 -3
- package/dist/command/cli/ports/resolve/cli-port.d.ts +15 -1
- package/dist/command/cli/ports/resolve/cli-port.js +50 -2
- package/dist/command/cli/report-command.d.ts +16 -0
- package/dist/command/cli/report-command.js +97 -0
- package/dist/command/cli/status/status-lines.d.ts +28 -0
- package/dist/command/cli/status/status-lines.js +117 -0
- package/dist/command/cli.d.ts +1 -1
- package/dist/command/cli.js +29 -177
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +32 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +93 -0
- package/dist/command/daemon/binding/loopback-reach.d.ts +42 -0
- package/dist/command/daemon/binding/loopback-reach.js +63 -0
- package/dist/command/daemon/binding/port-presence.d.ts +1 -1
- package/dist/command/daemon/daemon-resilience.d.ts +13 -1
- package/dist/command/daemon/daemon-resilience.js +12 -1
- package/dist/command/daemon/daemon.d.ts +2 -11
- package/dist/command/daemon/daemon.js +8 -11
- package/dist/command/daemon/idle-shutdown.d.ts +2 -1
- package/dist/command/daemon/lifetime/heartbeat.d.ts +8 -0
- package/dist/command/daemon/lifetime/heartbeat.js +10 -0
- package/dist/command/daemon/lifetime/log-cap.d.ts +68 -0
- package/dist/command/daemon/lifetime/log-cap.js +115 -0
- package/dist/command/setup/agent-notice-memory.d.ts +16 -0
- package/dist/command/setup/agent-notice-memory.js +65 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +1 -0
- package/dist/command/setup/bringup/dev-server-wait.js +16 -0
- package/dist/command/setup/bringup/ensure-daemon.js +1 -1
- package/dist/command/setup/init/init-host.js +8 -0
- package/dist/command/setup/init/init-runtime.js +13 -1
- package/dist/command/setup/node-effects.js +1 -1
- package/dist/command/setup/probe/page-probe.js +9 -2
- package/dist/command/setup/run-setup.d.ts +25 -7
- package/dist/command/setup/run-setup.js +51 -9
- package/dist/command/setup/setup-command.js +31 -3
- package/dist/command/setup/terminal/confirm.js +2 -1
- package/dist/command/update/updater.d.ts +27 -0
- package/dist/command/update/updater.js +35 -2
- package/dist/features/crawl/crawl-tools.js +3 -1
- package/dist/features/crawl/crawl.d.ts +2 -0
- package/dist/features/crawl/crawl.js +3 -1
- package/dist/features/harness/drive-report.d.ts +73 -0
- package/dist/features/harness/drive-report.js +196 -0
- package/dist/features/harness/driver.js +29 -8
- package/dist/features/harness/drivers.d.ts +19 -0
- package/dist/features/harness/drivers.js +19 -0
- package/dist/features/harness/fill-values.d.ts +67 -0
- package/dist/features/harness/fill-values.js +153 -0
- package/dist/features/harness/jev-driver.d.ts +188 -0
- package/dist/features/harness/jev-driver.js +661 -0
- package/dist/features/harness/openai-driver.d.ts +46 -0
- package/dist/features/harness/openai-driver.js +197 -0
- package/dist/features/harness/platform-config.d.ts +62 -0
- package/dist/features/harness/platform-config.js +97 -0
- package/dist/features/visual/visual-tools.js +26 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +80 -130
- package/dist/judgement/capsule/capsule-store.d.ts +31 -2
- package/dist/judgement/capsule/capsule-store.js +58 -6
- package/dist/judgement/capsule/capsule.js +5 -0
- package/dist/judgement/capsule/causal-summary.d.ts +13 -1
- package/dist/judgement/capsule/causal-summary.js +7 -0
- package/dist/judgement/domain/domain-model.js +38 -9
- package/dist/judgement/domain/domain-tools.js +4 -2
- package/dist/judgement/outcome/assertion-integrity.d.ts +3 -3
- package/dist/judgement/phenomena/phenomena.d.ts +2 -1
- package/dist/judgement/runs/artifact/gap-report.d.ts +17 -0
- package/dist/judgement/runs/artifact/gap-report.js +46 -0
- package/dist/judgement/runs/artifact/gap-summary.d.ts +58 -0
- package/dist/judgement/runs/artifact/gap-summary.js +85 -0
- package/dist/judgement/runs/artifact/render-report.js +4 -1
- package/dist/judgement/runs/artifact/to-artifact.d.ts +7 -2
- package/dist/judgement/runs/artifact/to-artifact.js +1 -1
- package/dist/judgement/runs/context-tools.js +21 -3
- package/dist/judgement/runs/drive-run.js +7 -2
- package/dist/judgement/runs/verification-sync.d.ts +2 -2
- package/dist/judgement/runs/verification-sync.js +9 -2
- package/dist/language/flows/affected-tools.js +6 -3
- package/dist/language/flows/annotate-notes/annotate.d.ts +0 -15
- package/dist/language/flows/annotate-notes/annotate.js +66 -18
- package/dist/language/flows/flow-anchor.d.ts +12 -0
- package/dist/language/flows/flow-anchor.js +20 -0
- package/dist/language/flows/flow-expect-grammar.d.ts +2 -2
- package/dist/language/flows/flow-expect-grammar.js +92 -11
- package/dist/language/flows/flow-intent.js +1 -1
- package/dist/language/flows/flow-learning.d.ts +3 -0
- package/dist/language/flows/flow-learning.js +39 -8
- package/dist/language/flows/flow-replay-run.d.ts +55 -10
- package/dist/language/flows/flow-replay-run.js +217 -58
- package/dist/language/flows/flow-replay-types.d.ts +9 -0
- package/dist/language/flows/flow-replay.d.ts +29 -11
- package/dist/language/flows/flow-replay.js +221 -203
- package/dist/language/flows/flow-result.d.ts +18 -1
- package/dist/language/flows/flow-result.js +18 -2
- package/dist/language/flows/flow-step-runners.d.ts +26 -10
- package/dist/language/flows/flow-step-runners.js +20 -4
- package/dist/language/flows/flow-store-for-session.d.ts +2 -1
- package/dist/language/flows/flow-success.d.ts +21 -6
- package/dist/language/flows/flow-success.js +50 -138
- package/dist/language/flows/flow-tools.js +8 -4
- package/dist/language/flows/flows.d.ts +15 -10
- package/dist/language/flows/flows.js +17 -4
- package/dist/language/flows/heal.d.ts +9 -1
- package/dist/language/flows/heal.js +24 -2
- package/dist/language/flows/learned-sources.d.ts +21 -0
- package/dist/language/flows/learned-sources.js +84 -0
- package/dist/language/flows/narrow-write.d.ts +4 -4
- package/dist/language/flows/recording/recording-backtrack.d.ts +0 -7
- package/dist/language/flows/recording/recording-backtrack.js +1 -1
- package/dist/language/flows/recording/replay-halt.d.ts +2 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +2 -2
- package/dist/language/flows/replay.js +13 -9
- package/dist/language/flows/stores/annotation-store.d.ts +5 -5
- package/dist/language/flows/stores/assertion-tiers-store.js +2 -3
- package/dist/language/flows/stores/flake-store.js +2 -3
- package/dist/language/flows/suite/coverage.d.ts +1 -1
- package/dist/language/flows/suite/parallel-suite.d.ts +2 -1
- package/dist/language/flows/suite-selection.d.ts +15 -1
- package/dist/language/flows/suite-selection.js +1 -1
- package/dist/language/flows/verify-change-tools.js +21 -4
- package/dist/memory/cloud/account-state.d.ts +1 -1
- package/dist/memory/cloud/account-state.js +5 -4
- package/dist/memory/cloud/cloud-config.d.ts +9 -0
- package/dist/memory/cloud/cloud-config.js +9 -0
- package/dist/memory/cloud/cloud-sync.d.ts +7 -4
- package/dist/memory/cloud/cloud-sync.js +11 -6
- package/dist/memory/cloud/harness-config.d.ts +12 -0
- package/dist/memory/cloud/harness-config.js +58 -0
- package/dist/memory/cloud/harness-offer.d.ts +44 -0
- package/dist/memory/cloud/harness-offer.js +146 -0
- package/dist/memory/cloud/harness-switch.d.ts +11 -0
- package/dist/memory/cloud/harness-switch.js +53 -0
- package/dist/memory/cloud/sync-cycle.d.ts +12 -0
- package/dist/memory/cloud/sync-cycle.js +29 -4
- package/dist/memory/cloud/sync-daemon.d.ts +35 -2
- package/dist/memory/cloud/sync-daemon.js +45 -0
- package/dist/memory/cloud/sync-disk.js +11 -6
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +2 -1
- package/dist/memory/impact/impact-store.d.ts +5 -0
- package/dist/memory/impact/impact-store.js +25 -0
- package/dist/memory/intent/inline-intent.js +8 -3
- package/dist/memory/intent/intent-shard-store.d.ts +33 -47
- package/dist/memory/intent/intent-shard-store.js +253 -141
- package/dist/memory/intent/intent-shard.d.ts +22 -23
- package/dist/memory/intent/intent-shard.js +1 -1
- package/dist/memory/intent/intent-store.d.ts +13 -8
- package/dist/memory/intent/intent-store.js +46 -90
- package/dist/memory/intent/intent-tools.js +34 -23
- package/dist/memory/journal/ambient-store.js +2 -3
- package/dist/memory/journal/attach-journal.d.ts +11 -0
- package/dist/memory/journal/attach-journal.js +1 -1
- package/dist/memory/journal/deviation-report.js +4 -1
- package/dist/memory/journal/deviation-service.js +10 -2
- package/dist/memory/journal/drive-flow.d.ts +2 -2
- package/dist/memory/journal/drive-flow.js +21 -12
- package/dist/memory/journal/envelope-store.js +2 -3
- package/dist/memory/journal/journal-query.d.ts +35 -1
- package/dist/memory/journal/journal-query.js +46 -0
- package/dist/memory/journal/journal-recorder.d.ts +71 -2
- package/dist/memory/journal/journal-recorder.js +45 -7
- package/dist/memory/journal/on-disk/retain-policy.d.ts +34 -0
- package/dist/memory/journal/on-disk/retain-policy.js +44 -0
- package/dist/memory/journal/on-disk/retention.d.ts +91 -2
- package/dist/memory/journal/on-disk/retention.js +181 -11
- package/dist/memory/journal/on-disk/startup-maintenance.d.ts +42 -0
- package/dist/memory/journal/on-disk/startup-maintenance.js +14 -0
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +0 -2
- package/dist/memory/journal/on-disk/workspace-gitignore.js +6 -38
- package/dist/memory/journal/on-disk/workspace-tiers.d.ts +52 -0
- package/dist/memory/journal/on-disk/workspace-tiers.js +88 -0
- package/dist/memory/journal/route-template.d.ts +22 -0
- package/dist/memory/journal/route-template.js +44 -0
- package/dist/memory/journal/self-observation.d.ts +3 -0
- package/dist/memory/journal/self-observation.js +67 -0
- package/dist/memory/journal/session-end.d.ts +17 -4
- package/dist/memory/journal/session-end.js +85 -7
- package/dist/memory/journal/session-journal.d.ts +122 -5
- package/dist/memory/journal/session-journal.js +489 -32
- package/dist/memory/project/artifact-root-resolver.d.ts +3 -0
- package/dist/memory/project/artifact-root-resolver.js +89 -0
- package/dist/memory/project/artifact-root.d.ts +39 -2
- package/dist/memory/project/artifact-root.js +58 -1
- package/dist/memory/project/baselines.d.ts +1 -1
- package/dist/memory/project/dir/fill-value-store.d.ts +32 -0
- package/dist/memory/project/dir/fill-value-store.js +88 -0
- package/dist/memory/project/dir/reticle-dir.d.ts +15 -5
- package/dist/memory/project/dir/reticle-dir.js +11 -0
- package/dist/memory/project/fs/fs-port.d.ts +22 -1
- package/dist/memory/project/fs/fs-port.js +72 -5
- package/dist/memory/project/fs/write-atomic.d.ts +26 -0
- package/dist/memory/project/fs/write-atomic.js +48 -0
- package/dist/memory/project/learned-routes.d.ts +16 -2
- package/dist/memory/project/learned-routes.js +26 -10
- package/dist/memory/project/project-for-root.d.ts +30 -0
- package/dist/memory/project/project-for-root.js +43 -0
- package/dist/memory/project/project-tools.js +10 -5
- package/dist/memory/project/session-root.d.ts +35 -6
- package/dist/memory/project/session-root.js +70 -8
- package/dist/memory/recall/prior/connection-memory.d.ts +6 -0
- package/dist/memory/recall/prior/connection-memory.js +8 -0
- package/dist/memory/recall/registered-projects.d.ts +2 -1
- package/dist/portal/bridge/auth-failure-reason.d.ts +9 -0
- package/dist/portal/bridge/auth-failure-reason.js +20 -3
- package/dist/portal/bridge/bridge.d.ts +6 -1
- package/dist/portal/bridge/bridge.js +36 -2
- package/dist/portal/input/real-input.js +2 -1
- package/dist/portal/pool/browser-pool.d.ts +10 -0
- package/dist/portal/pool/browser-pool.js +10 -0
- package/dist/portal/pool/playwright-launcher.js +1 -0
- package/dist/portal/pool/pool-contract.d.ts +2 -0
- package/dist/portal/pool/storage-seed.d.ts +2 -1
- package/dist/portal/pool/zero-install.d.ts +27 -0
- package/dist/portal/pool/zero-install.js +54 -0
- package/dist/portal/realm/web-realm.js +6 -0
- package/dist/portal/session/dev-server/dev-server-probe.d.ts +2 -1
- package/dist/portal/session/dev-server/served-document.d.ts +21 -0
- package/dist/portal/session/dev-server/served-document.js +57 -0
- package/dist/portal/session/facts/background-traffic.d.ts +9 -0
- package/dist/portal/session/facts/background-traffic.js +25 -0
- package/dist/portal/session/facts/session-replaced.d.ts +19 -0
- package/dist/portal/session/facts/session-replaced.js +22 -0
- package/dist/portal/session/live-control-tools.js +48 -3
- package/dist/portal/session/no-session-diagnosis.d.ts +1 -0
- package/dist/portal/session/no-session-diagnosis.js +67 -60
- package/dist/portal/session/no-session-next-action.js +3 -2
- package/dist/portal/session/no-session-watch.js +14 -10
- package/dist/portal/session/presence/attachment-history.d.ts +13 -2
- package/dist/portal/session/rebind.d.ts +18 -0
- package/dist/portal/session/rebind.js +38 -0
- package/dist/portal/session/session-health.d.ts +61 -0
- package/dist/portal/session/session-health.js +40 -1
- package/dist/portal/session/session-info.d.ts +6 -0
- package/dist/portal/session/session-manager.d.ts +13 -0
- package/dist/portal/session/session-manager.js +42 -3
- package/dist/portal/session/session-successor.d.ts +11 -0
- package/dist/portal/session/session-successor.js +14 -1
- package/dist/portal/session/session-verdict-facts.d.ts +28 -0
- package/dist/portal/session/session-verdict-facts.js +15 -0
- package/dist/portal/session/session.d.ts +26 -10
- package/dist/portal/session/session.js +48 -49
- package/dist/status-payload.d.ts +12 -1
- package/dist/status-payload.js +4 -1
- package/dist/surface/http-server.js +3 -5
- package/dist/surface/mcp/faults/mcp-outage.d.ts +2 -1
- package/dist/surface/mcp/faults/mcp-outage.js +20 -4
- package/dist/surface/mcp/mcp-proxy.d.ts +10 -1
- package/dist/surface/mcp/mcp-proxy.js +23 -12
- package/dist/surface/mcp/mcp.d.ts +10 -1
- package/dist/surface/mcp/mcp.js +59 -29
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +15 -2
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +22 -5
- package/dist/surface/mcp/proxy/proxy-log.d.ts +5 -11
- package/dist/surface/mcp/proxy/proxy-log.js +7 -22
- package/dist/surface/mcp/proxy-idle-exit.d.ts +2 -1
- package/dist/surface/mcp/server-instructions.js +12 -1
- package/dist/surface/tools/act/act-preflight.js +6 -1
- package/dist/surface/tools/act/already-true.d.ts +40 -0
- package/dist/surface/tools/act/already-true.js +36 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +6 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +13 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -0
- package/dist/surface/tools/act/settle-in-flight.d.ts +6 -2
- package/dist/surface/tools/act/settle-in-flight.js +29 -6
- package/dist/surface/tools/act-capsule.js +49 -8
- package/dist/surface/tools/act-tools.js +25 -24
- package/dist/surface/tools/args/numeric-bounds.d.ts +15 -2
- package/dist/surface/tools/args/numeric-bounds.js +30 -3
- package/dist/surface/tools/assert/assert-grade.js +14 -2
- package/dist/surface/tools/assert/assert-verdict.js +74 -21
- package/dist/surface/tools/browser-tools.js +4 -3
- package/dist/surface/tools/coverage-tools.js +5 -2
- package/dist/surface/tools/dynamic-tools.js +43 -46
- package/dist/surface/tools/error-recovery.d.ts +6 -0
- package/dist/surface/tools/error-recovery.js +15 -0
- package/dist/surface/tools/explore-tools.js +80 -7
- package/dist/surface/tools/feedback-tools.d.ts +2 -1
- package/dist/surface/tools/feedback-tools.js +50 -3
- package/dist/surface/tools/first-sentence.d.ts +24 -0
- package/dist/surface/tools/first-sentence.js +0 -0
- package/dist/surface/tools/harness-explore.d.ts +125 -1
- package/dist/surface/tools/harness-explore.js +401 -15
- package/dist/surface/tools/harness-plan.d.ts +76 -0
- package/dist/surface/tools/harness-plan.js +156 -0
- package/dist/surface/tools/harness-toolset.js +12 -1
- package/dist/surface/tools/invoke-tool.js +82 -9
- package/dist/surface/tools/lease-hint.d.ts +8 -0
- package/dist/surface/tools/lease-hint.js +10 -0
- package/dist/surface/tools/lease-tools.d.ts +16 -28
- package/dist/surface/tools/lease-tools.js +53 -5
- package/dist/surface/tools/lineage-tools.js +1 -1
- package/dist/surface/tools/live-call-text.d.ts +6 -0
- package/dist/surface/tools/live-call-text.js +36 -2
- package/dist/surface/tools/observe-tools.js +69 -15
- package/dist/surface/tools/read/query-windowed.d.ts +1 -1
- package/dist/surface/tools/read/query-windowed.js +1 -1
- package/dist/surface/tools/read-tools.js +1 -2
- package/dist/surface/tools/real-input-attempt.d.ts +0 -5
- package/dist/surface/tools/real-input-attempt.js +1 -1
- package/dist/surface/tools/tool-kit.d.ts +23 -3
- package/dist/surface/tools/tool-kit.js +6 -1
- package/dist/surface/tools/tool-surface.js +17 -5
- package/dist/surface/tools/tools-helpers.d.ts +8 -7
- package/dist/surface/tools/tools-helpers.js +11 -13
- package/dist/surface/tools/tools.js +70 -30
- package/dist/telemetry/bug-found.js +32 -2
- package/dist/telemetry/feedback-context.js +3 -3
- package/dist/telemetry/feedback-local.d.ts +1 -0
- package/dist/telemetry/feedback-local.js +1 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/harness-drive.d.ts +6 -0
- package/dist/telemetry/harness-drive.js +39 -0
- package/dist/telemetry/hud-metrics.d.ts +32 -0
- package/dist/telemetry/hud-metrics.js +95 -0
- package/dist/telemetry/mcp-connection.d.ts +14 -1
- package/dist/telemetry/mcp-connection.js +17 -2
- package/dist/telemetry/onboarding-firsts.d.ts +30 -1
- package/dist/telemetry/onboarding-firsts.js +54 -12
- package/dist/telemetry/session-metrics.d.ts +5 -0
- package/dist/telemetry/session-metrics.js +15 -1
- package/dist/telemetry/verification-of.js +31 -3
- package/dist/wire-journal.d.ts +31 -0
- package/dist/wire-journal.js +100 -0
- package/docs/README.md +1 -0
- package/docs/agent-cheatsheet.md +7 -3
- package/docs/autodrive.md +42 -2
- package/docs/benchmarks.md +1 -1
- package/docs/capabilities.mdx +1 -1
- package/docs/cli/cloud.mdx +11 -9
- package/docs/cli/doctor.mdx +1 -0
- package/docs/cli/init.mdx +1 -0
- package/docs/cli/report.mdx +44 -0
- package/docs/cli/status.mdx +35 -20
- package/docs/cli.mdx +8 -18
- package/docs/desktop.mdx +1 -1
- package/docs/faq.mdx +1 -1
- package/docs/flows.md +11 -0
- package/docs/frameworks.mdx +113 -1
- package/docs/install-agentic.mdx +36 -0
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages.mdx +1 -1
- package/docs/predicates.mdx +144 -4
- package/docs/system-map.md +6 -4
- package/docs/telemetry.md +2 -1
- package/docs/token-efficiency.md +2 -2
- package/docs/tools/overview.mdx +1 -1
- package/docs/tools/query.mdx +10 -10
- package/docs/troubleshooting.mdx +8 -2
- package/docs/usage.md +2 -2
- package/docs/what-is-recorded.md +62 -0
- package/package.json +5 -5
- package/dist/judgement/outcome/predicate-to-expect.d.ts +0 -44
- package/dist/judgement/outcome/predicate-to-expect.js +0 -148
|
@@ -123,12 +123,37 @@ export function liveCallText(text, advertised) {
|
|
|
123
123
|
continue;
|
|
124
124
|
out = out.replace(pattern, instead);
|
|
125
125
|
}
|
|
126
|
-
|
|
126
|
+
/**
|
|
127
|
+
* A sentence explaining where a name WENT keeps that name, even though it is unreachable.
|
|
128
|
+
*
|
|
129
|
+
* These messages open with their own subject — "reticle_act_sequence was merged into reticle_act",
|
|
130
|
+
* "reticle_refresh no longer exists" — and the rewrite is precisely a rule for replacing
|
|
131
|
+
* unreachable names, so it replaced the subject too. Asking about `reticle_act_sequence` answered
|
|
132
|
+
* "reticle_act no longer exists", which is false: `reticle_act` is a tool, and the one thing the
|
|
133
|
+
* reader needed to know was which name had moved.
|
|
134
|
+
*
|
|
135
|
+
* Only the leading token, and only in front of those two phrases. Every other mention in the same
|
|
136
|
+
* sentence — including the tool to call INSTEAD — is still rewritten, which is the whole job.
|
|
137
|
+
*/
|
|
138
|
+
const explainsItsSubject = /^(reticle_[a-z_]+)(?= (?:was merged into|no longer exists))/.exec(out);
|
|
139
|
+
const subject = explainsItsSubject?.[1];
|
|
140
|
+
return out.replace(TOOL_TOKEN, (name, offset) => {
|
|
141
|
+
if (name === subject && 0 === offset)
|
|
142
|
+
return name;
|
|
127
143
|
if (advertised.has(name))
|
|
128
144
|
return name;
|
|
129
145
|
return replacementFor(name, advertised) ?? name;
|
|
130
146
|
});
|
|
131
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Keys whose STRING value names a thing rather than advising a call.
|
|
150
|
+
*
|
|
151
|
+
* `name` is what the caller asked about and has to match their question against; `tool` is the
|
|
152
|
+
* already-resolved answer to "call this instead", so redirecting it a second time can only move it
|
|
153
|
+
* away from the answer. Deliberately two names and not a pattern: every other string in a result is
|
|
154
|
+
* prose, and prose is exactly what the rewrite is for.
|
|
155
|
+
*/
|
|
156
|
+
const IDENTITY_KEYS = new Set(['name', 'tool']);
|
|
132
157
|
/**
|
|
133
158
|
* The same rewrite, applied to a result's STRING VALUES instead of to its encoded form.
|
|
134
159
|
*
|
|
@@ -140,6 +165,12 @@ export function liveCallText(text, advertised) {
|
|
|
140
165
|
* was corrected and the result became unreadable, which is a worse trade than the advice was worth.
|
|
141
166
|
*
|
|
142
167
|
* Values, not keys: a key is a contract with the caller and nothing in a key is advice.
|
|
168
|
+
*
|
|
169
|
+
* And not every value is advice either. A field that carries a tool's IDENTITY is an answer to
|
|
170
|
+
* "which one", not a suggestion about what to call — rewriting it destroys the thing the caller
|
|
171
|
+
* asked for. `reticle_tools { names: ["reticle_act_sequence"] }` sets `name` to the name it was
|
|
172
|
+
* asked about, and this rewrote it to `reticle_act`, so a batch query came back with entries the
|
|
173
|
+
* caller could no longer match to their questions. See `IDENTITY_KEYS`.
|
|
143
174
|
*/
|
|
144
175
|
export function liveCallValues(value, advertised) {
|
|
145
176
|
if ('string' === typeof value)
|
|
@@ -149,7 +180,10 @@ export function liveCallValues(value, advertised) {
|
|
|
149
180
|
if (null !== value && 'object' === typeof value) {
|
|
150
181
|
const out = {};
|
|
151
182
|
for (const [key, each] of Object.entries(value)) {
|
|
152
|
-
out[key] =
|
|
183
|
+
out[key] =
|
|
184
|
+
IDENTITY_KEYS.has(key) && 'string' === typeof each
|
|
185
|
+
? each
|
|
186
|
+
: liveCallValues(each, advertised);
|
|
153
187
|
}
|
|
154
188
|
return out;
|
|
155
189
|
}
|
|
@@ -7,7 +7,7 @@ import { z } from 'zod';
|
|
|
7
7
|
import { aliasParam } from './args/alias-args.js';
|
|
8
8
|
import { CONSOLE_ATTACH_NOTE, CONSOLE_LEVELS, ReticleCommand, DEFAULT_ASSERT_TIMEOUT_MS, PredicateKind, Verified, } from '@reticlehq/core';
|
|
9
9
|
import { ReticleTool } from '@reticlehq/core';
|
|
10
|
-
import { countSchema, cursorSchema, httpStatusSchema, timeoutMsSchema, windowMsSchema, } from './args/numeric-bounds.js';
|
|
10
|
+
import { countSchema, cursorSchema, httpStatusSchema, timeoutMsSchema, waitForTimeoutMsSchema, resumeAfter, MAX_BLOCKING_WAIT_MS, windowMsSchema, } from './args/numeric-bounds.js';
|
|
11
11
|
import { buildReactionReport } from '@reticlehq/engine/question/reaction.js';
|
|
12
12
|
import { findContradictions } from '@reticlehq/engine/disagreement/contradictions.js';
|
|
13
13
|
import { evaluatePredicate, waitForPredicate, PredicateSchema, } from '@reticlehq/engine/question/predicate/predicate.js';
|
|
@@ -16,9 +16,10 @@ import { WALL_CLOCK } from '../../portal/session/timing/wall-clock.js';
|
|
|
16
16
|
import { parsePredicate } from '@reticlehq/engine/question/predicate/predicate-parse.js';
|
|
17
17
|
import { matchNet, matchConsole, isConsoleEvent, eventMatchesFilters, netEmptyHint, consoleEmptyHint, reconcileNet, projectNetCall, projectConsoleLog, withoutUrlRaw, } from '@reticlehq/engine/window/event-filters.js';
|
|
18
18
|
import { applyEventBudget, costHint, withSizeCost, DEFAULT_OBSERVE_EVENT_LIMIT, DEFAULT_QUERY_LIMIT, } from '../../portal/session/output-budget.js';
|
|
19
|
-
import { annotateStarvedFailure, healthEnvelope, bufferEnvelope, } from '../../portal/session/session-health.js';
|
|
19
|
+
import { annotateStarvedFailure, currentOf, healthEnvelope, bufferEnvelope, } from '../../portal/session/session-health.js';
|
|
20
20
|
import { assertsDerivedIpcStatus, DERIVED_IPC_STATUS_ADVICE, isPresenceOnlyAssertion, PRESENCE_ONLY_ADVICE, } from './assert/assert-grade.js';
|
|
21
21
|
import { assertVerdict } from './assert/assert-verdict.js';
|
|
22
|
+
import { followLostObservation } from './act/act-observation.js';
|
|
22
23
|
import { withGapNovelty } from './gap-novelty.js';
|
|
23
24
|
import { assertionSource } from './assert/assert-source.js';
|
|
24
25
|
import { isChangeUndeclared } from '@reticlehq/engine/evidence/undeclared-change.js';
|
|
@@ -171,6 +172,7 @@ export const OBSERVE_TOOLS = [
|
|
|
171
172
|
currentDocumentId: session.currentDocumentId,
|
|
172
173
|
currentEditEpoch: session.currentEditEpoch,
|
|
173
174
|
appOrigin: session.url,
|
|
175
|
+
background: session.background,
|
|
174
176
|
...(judgingTheAct ? { ...session.lastAct.effect(), actionSince: actCursor } : {}),
|
|
175
177
|
});
|
|
176
178
|
// carry session health — a throttled tab means the observed timeline may be incomplete.
|
|
@@ -192,15 +194,19 @@ export const OBSERVE_TOOLS = [
|
|
|
192
194
|
predicate: PredicateSchema.optional().describe('Predicate to wait for: { signal }, { net }, { element }, { kind: "net", ok: false } (assert on the OUTCOME — the honest field for IPC, which has no status code), { kind: "state", store, path, equals } (assert a registered store\'s value directly — the source of truth no DOM read can reach; equals takes a literal or { $gte | $contains | $length } pattern), { kind: "settled", quietMs } (deterministic network + DOM idle — prefer this over a fixed sleep), or a combination via allOf/anyOf.'),
|
|
193
195
|
// Same concept, the neighbouring tool's name. See alias-args.ts.
|
|
194
196
|
until: PredicateSchema.optional().describe("Alias for `predicate` (act_and_wait's name)."),
|
|
195
|
-
timeout_ms:
|
|
197
|
+
timeout_ms: waitForTimeoutMsSchema
|
|
196
198
|
.optional()
|
|
197
|
-
.describe(
|
|
199
|
+
.describe(`Maximum wait in milliseconds. Default: 4000, up to 600000. One call waits at most ${String(MAX_BLOCKING_WAIT_MS)} ms, because your MCP client aborts a longer request; past that it returns resume_ms, and you call again with timeout_ms: resume_ms and the same since to keep waiting.`),
|
|
198
200
|
since: cursorSchema
|
|
199
201
|
.optional()
|
|
200
202
|
.describe('Cursor from a prior reticle_act — scopes the wait to events after that act.'),
|
|
201
203
|
...sessionIdShape,
|
|
202
204
|
},
|
|
203
205
|
outputSchema: {
|
|
206
|
+
resume_ms: z
|
|
207
|
+
.number()
|
|
208
|
+
.optional()
|
|
209
|
+
.describe('Present when this call stopped at the per-call limit before the predicate was seen. Call again with timeout_ms set to this, the same predicate and the same since, to keep waiting.'),
|
|
204
210
|
pass: z.boolean(),
|
|
205
211
|
evidence: z.unknown().optional(),
|
|
206
212
|
failureReason: z.string().optional(),
|
|
@@ -208,6 +214,10 @@ export const OBSERVE_TOOLS = [
|
|
|
208
214
|
.boolean()
|
|
209
215
|
.optional()
|
|
210
216
|
.describe('The tab disconnected mid-wait, so this was never observed — the verdict is UNKNOWN, not a failure of the app.'),
|
|
217
|
+
sessionId: z
|
|
218
|
+
.string()
|
|
219
|
+
.optional()
|
|
220
|
+
.describe('The session that answered, when a full-document navigation replaced the one this was asked of. Absent when the original session survived.'),
|
|
211
221
|
inconclusive: z
|
|
212
222
|
.string()
|
|
213
223
|
.optional()
|
|
@@ -234,9 +244,11 @@ export const OBSERVE_TOOLS = [
|
|
|
234
244
|
.describe('Where the code behind this verdict lives, as `file:line`. For an element/text assertion it is the matched element itself; for a FAILING signal/net/state assertion — which has no element to point at — it is the control last acted on, where the handler that should have fired lives. OMITTED when neither is known: this tool never borrows an unrelated location.'),
|
|
235
245
|
},
|
|
236
246
|
handler: async (deps, args) => {
|
|
237
|
-
const
|
|
247
|
+
const requestedMs = asNumber(args['timeout_ms']) ?? DEFAULT_ASSERT_TIMEOUT_MS;
|
|
248
|
+
// One call never blocks past what the client allows; the rest comes back as resume_ms.
|
|
249
|
+
const waitBudget = Math.min(requestedMs, MAX_BLOCKING_WAIT_MS);
|
|
238
250
|
// Spend the budget waiting for the APP as well as for the predicate. See resolve-within.
|
|
239
|
-
|
|
251
|
+
let session = await resolveSessionWithin(deps.sessions, asString(args['sessionId']), waitBudget, WALL_CLOCK);
|
|
240
252
|
// `until` is act_and_wait's name for this — see alias-args.ts.
|
|
241
253
|
const predicate = parsePredicate(aliasParam(args, 'predicate', ['until'])['predicate']);
|
|
242
254
|
// Refused up front rather than waited out: a body clause this session cannot answer would
|
|
@@ -245,8 +257,22 @@ export const OBSERVE_TOOLS = [
|
|
|
245
257
|
if (bodyRefusal !== undefined)
|
|
246
258
|
throw new Error(bodyRefusal);
|
|
247
259
|
// Honesty: explicit since wins; else default to the last act's cursor; else the whole buffer.
|
|
248
|
-
|
|
249
|
-
|
|
260
|
+
let since = asNumber(args['since']) ?? session.lastAct.cursor() ?? 0;
|
|
261
|
+
// See the note on the assert handler below: a wait cut off by a full-document navigation is
|
|
262
|
+
// followed to the document that took over, rather than graded as a lost observation there.
|
|
263
|
+
const predicateStarted = session.elapsed();
|
|
264
|
+
const followed = await followLostObservation({
|
|
265
|
+
sessions: deps.sessions,
|
|
266
|
+
session,
|
|
267
|
+
verdict: await waitForPredicate(session, predicate, waitBudget, since),
|
|
268
|
+
timeout: waitBudget,
|
|
269
|
+
predicateStarted,
|
|
270
|
+
reevaluate: (next, budget) => waitForPredicate(next, predicate, budget, 0),
|
|
271
|
+
});
|
|
272
|
+
if (followed.followed)
|
|
273
|
+
since = 0;
|
|
274
|
+
session = followed.session;
|
|
275
|
+
const verdict = followed.verdict;
|
|
250
276
|
// match reticle_assert — wrap with control + session health (throttle matters most while blocking)
|
|
251
277
|
// and the buffer envelope, so a verdict reached over an evicted window says so.
|
|
252
278
|
return withControl(session, {
|
|
@@ -255,6 +281,8 @@ export const OBSERVE_TOOLS = [
|
|
|
255
281
|
// `lastActSourceOnFailure` — an assert used to be blamed on the previous act's file:line.
|
|
256
282
|
...annotateStarvedFailure(session, verdict),
|
|
257
283
|
...assertionSource(session, predicate, verdict),
|
|
284
|
+
...(followed.followed ? { sessionId: session.id } : {}),
|
|
285
|
+
...((resume) => (resume === undefined ? {} : { resume_ms: resume }))(resumeAfter(requestedMs, waitBudget, verdict)),
|
|
258
286
|
...healthEnvelope(session),
|
|
259
287
|
...bufferEnvelope(session),
|
|
260
288
|
});
|
|
@@ -271,7 +299,7 @@ export const OBSERVE_TOOLS = [
|
|
|
271
299
|
// is the most common thing an agent wants to assert. A field report reached us from an agent
|
|
272
300
|
// that guessed `urlContains` on route (net's spelling) and got unrecognized_keys.
|
|
273
301
|
'Predicate to evaluate. Kinds: { signal, name|dataMatches|count } ' +
|
|
274
|
-
'{ net, urlContains|method|status|count|bodyContains|requestBodyContains|requestBodyMatches } ' +
|
|
302
|
+
'{ net, urlContains|method|status|count|bodyMatches|bodyContains|requestBodyContains|requestBodyMatches } ' +
|
|
275
303
|
'{ state, path|equals } { route, pathname (exact) | contains (path+query+hash) } ' +
|
|
276
304
|
'{ element, testid|role|text } { text } { console, level|contains|absent } { animation, name } ' +
|
|
277
305
|
'{ settled } — combine with { allOf | anyOf | not }. Prefer a signal/net/state consequence ' +
|
|
@@ -294,6 +322,10 @@ export const OBSERVE_TOOLS = [
|
|
|
294
322
|
.boolean()
|
|
295
323
|
.optional()
|
|
296
324
|
.describe('The tab disconnected mid-wait, so this was never observed — the verdict is UNKNOWN, not a failure of the app.'),
|
|
325
|
+
sessionId: z
|
|
326
|
+
.string()
|
|
327
|
+
.optional()
|
|
328
|
+
.describe('The session that answered, when a full-document navigation replaced the one this was asked of. Absent when the original session survived.'),
|
|
297
329
|
inconclusive: z
|
|
298
330
|
.string()
|
|
299
331
|
.optional()
|
|
@@ -338,7 +370,7 @@ export const OBSERVE_TOOLS = [
|
|
|
338
370
|
handler: async (deps, args) => {
|
|
339
371
|
const timeout = asNumber(args['timeout_ms']) ?? 0;
|
|
340
372
|
// Spend the budget waiting for the APP as well as for the predicate. See resolve-within.
|
|
341
|
-
|
|
373
|
+
let session = await resolveSessionWithin(deps.sessions, asString(args['sessionId']), timeout, WALL_CLOCK);
|
|
342
374
|
// `until` is act_and_wait's name for this — see alias-args.ts.
|
|
343
375
|
const predicate = parsePredicate(aliasParam(args, 'predicate', ['until'])['predicate']);
|
|
344
376
|
// Refused up front rather than waited out: a body clause this session cannot answer would
|
|
@@ -347,13 +379,34 @@ export const OBSERVE_TOOLS = [
|
|
|
347
379
|
if (bodyRefusal !== undefined)
|
|
348
380
|
throw new Error(bodyRefusal);
|
|
349
381
|
// Honesty: explicit since wins; else default to the last act's cursor; else the whole buffer.
|
|
350
|
-
|
|
382
|
+
let since = asNumber(args['since']) ?? session.lastAct.cursor() ?? 0;
|
|
351
383
|
// Declared BEFORE the verdict, so the undeclared-change read below finds it open and stays
|
|
352
384
|
// quiet on THIS verdict rather than on the next one. Discharged after that read.
|
|
353
385
|
const intentId = await linkInlineIntent(deps, asString(args['sessionId']), asString(args['intent']), PredicateKind.SETTLED === predicate.kind ? undefined : predicate);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
386
|
+
// A full-document navigation tears the in-page SDK down mid-wait, and the predicate finishes
|
|
387
|
+
// `observationLost` against a channel that no longer exists. `act_and_wait` has followed the
|
|
388
|
+
// document that took over since the MPA drive was fixed; this path did not, so an assertion
|
|
389
|
+
// straddling a navigation came back "Reticle could not tell" while the answer was sitting on
|
|
390
|
+
// the successor — reported four times from the field, every one of them proving `yes` on the
|
|
391
|
+
// UNCHANGED predicate after a manual reconnect. Re-asking is not fabricating: the consequence
|
|
392
|
+
// is evaluated on a live document, and where there is no unique successor to follow,
|
|
393
|
+
// `followLostObservation` refuses to guess and the honest lost verdict stands.
|
|
394
|
+
const predicateStarted = session.elapsed();
|
|
395
|
+
const followed = await followLostObservation({
|
|
396
|
+
sessions: deps.sessions,
|
|
397
|
+
session,
|
|
398
|
+
verdict: timeout > 0
|
|
399
|
+
? await waitForPredicate(session, predicate, timeout, since)
|
|
400
|
+
: await evaluatePredicate(session, predicate, since),
|
|
401
|
+
timeout,
|
|
402
|
+
predicateStarted,
|
|
403
|
+
reevaluate: (next, budget) => waitForPredicate(next, predicate, budget, 0),
|
|
404
|
+
});
|
|
405
|
+
// The successor's buffer is its own: the departed session's cursor means nothing there.
|
|
406
|
+
if (followed.followed)
|
|
407
|
+
since = 0;
|
|
408
|
+
session = followed.session;
|
|
409
|
+
const verdict = followed.verdict;
|
|
357
410
|
// A GREEN presence-only assertion is the dangerous case (a wrong element can fake it) — nudge
|
|
358
411
|
// toward a consequence. Never on a failing verdict (moot) or when a signal/net is asserted.
|
|
359
412
|
// Two nudges, both only on a GREEN verdict (a failing one is moot): a presence-only assertion
|
|
@@ -396,6 +449,7 @@ export const OBSERVE_TOOLS = [
|
|
|
396
449
|
return withControl(session, {
|
|
397
450
|
...decision,
|
|
398
451
|
...annotateStarvedFailure(session, verdict),
|
|
452
|
+
...(followed.followed ? { sessionId: session.id } : {}),
|
|
399
453
|
...(contradictions.length > 0 ? { contradictions } : {}),
|
|
400
454
|
// What the app did not tell Reticle, on the same rule the act path uses.
|
|
401
455
|
// Remedy once per session, facts every time. Applied HERE rather than inside
|
|
@@ -408,7 +462,7 @@ export const OBSERVE_TOOLS = [
|
|
|
408
462
|
...coverage,
|
|
409
463
|
// The SAME pointer the journal keeps, not a second lookup — one verdict, one file:line.
|
|
410
464
|
...(verdictEffect.source === undefined ? {} : { source: verdictEffect.source }),
|
|
411
|
-
...healthEnvelope(session),
|
|
465
|
+
...healthEnvelope(currentOf(deps.sessions, session)),
|
|
412
466
|
...bufferEnvelope(session),
|
|
413
467
|
});
|
|
414
468
|
},
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* is not advertised on the default surface, so the agent that needed it could not see it and had no
|
|
12
12
|
* way to learn it existed. A capability reachable only by already knowing about it is not reachable.
|
|
13
13
|
*
|
|
14
|
-
* The SCROLLING half lives in `portal/input/
|
|
14
|
+
* The SCROLLING half lives in `portal/input/scroll-find.ts`, because it drives the page and this
|
|
15
15
|
* directory must not reach into `input/` — doing so completed a mutual pair, and two directories
|
|
16
16
|
* that need each other cannot be read, moved or tested apart. Shaping an answer and scrolling a list
|
|
17
17
|
* are different jobs anyway; the guard made that visible before it was a habit.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* is not advertised on the default surface, so the agent that needed it could not see it and had no
|
|
12
12
|
* way to learn it existed. A capability reachable only by already knowing about it is not reachable.
|
|
13
13
|
*
|
|
14
|
-
* The SCROLLING half lives in `portal/input/
|
|
14
|
+
* The SCROLLING half lives in `portal/input/scroll-find.ts`, because it drives the page and this
|
|
15
15
|
* directory must not reach into `input/` — doing so completed a mutual pair, and two directories
|
|
16
16
|
* that need each other cannot be read, moved or tested apart. Shaping an answer and scrolling a list
|
|
17
17
|
* are different jobs anyway; the guard made that visible before it was a habit.
|
|
@@ -14,8 +14,7 @@ import { diffLines } from '../../memory/project/baselines.js';
|
|
|
14
14
|
import { selectPath, capDepth, projectComponentState } from '../../portal/session/state-select.js';
|
|
15
15
|
import { costHint } from '../../portal/session/output-budget.js';
|
|
16
16
|
import { buildReactionReport, summarizeReaction } from '@reticlehq/engine/question/reaction.js';
|
|
17
|
-
import { asNumber, asString } from '@reticlehq/core';
|
|
18
|
-
import { parseInteractive } from './tools-helpers.js';
|
|
17
|
+
import { asNumber, asString, parseInteractive } from '@reticlehq/core';
|
|
19
18
|
import { sessionIdShape, commandOrThrow, snapshotTree } from './tool-kit.js';
|
|
20
19
|
import { bufferEnvelope } from '../../portal/session/session-health.js';
|
|
21
20
|
import { routeOfUrl } from '@reticlehq/engine/question/predicate/predicate-route.js';
|
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
import { ActionType, InputModeReason } from '@reticlehq/core';
|
|
23
23
|
import type { Session } from '../../portal/session/session.js';
|
|
24
24
|
import { type ToolDeps } from './tool-kit.js';
|
|
25
|
-
/**
|
|
26
|
-
* Expand a leading `~` against the caller's home directory. Absolute and relative paths pass
|
|
27
|
-
* through unchanged. `home` is injected so unit tests do not depend on the machine's real home.
|
|
28
|
-
*/
|
|
29
|
-
export declare function expandUserPath(rawPath: string, home: string): string;
|
|
30
25
|
/**
|
|
31
26
|
* If the action is `upload` AND the inner args carry `path`, read the file from disk and rewrite
|
|
32
27
|
* the args to `{ content, name, type, __base64: true }` before the ACT command reaches the browser.
|
|
@@ -99,7 +99,7 @@ const UPLOAD_MAX_BYTES = Math.floor((TRANSPORT_LIMITS.MAX_MESSAGE_BYTES / (4 / 3
|
|
|
99
99
|
* Expand a leading `~` against the caller's home directory. Absolute and relative paths pass
|
|
100
100
|
* through unchanged. `home` is injected so unit tests do not depend on the machine's real home.
|
|
101
101
|
*/
|
|
102
|
-
|
|
102
|
+
function expandUserPath(rawPath, home) {
|
|
103
103
|
if ('~' === rawPath)
|
|
104
104
|
return home;
|
|
105
105
|
if (rawPath.startsWith('~/') || rawPath.startsWith('~\\'))
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* without a circular import — `tools.ts` assembles the groups and re-exports `ToolDef`/`ToolDeps`.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import { ReticleCommand } from '@reticlehq/core';
|
|
8
|
+
import { type ProjectId, ReticleCommand } from '@reticlehq/core';
|
|
9
9
|
import type { SessionManager } from '../../portal/session/session-manager.js';
|
|
10
10
|
import type { RealInputProvider } from '../../portal/input/real-input.js';
|
|
11
11
|
import type { BaselineStore } from '../../memory/project/baselines.js';
|
|
@@ -33,6 +33,21 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
33
33
|
recordings: RecordingStore;
|
|
34
34
|
/** on-disk anchored-flow store (.reticle/flows/). */
|
|
35
35
|
flows: FlowStore;
|
|
36
|
+
/**
|
|
37
|
+
* The credential this machine already holds for the linked project, if it is linked.
|
|
38
|
+
*
|
|
39
|
+
* INJECTED rather than read here. `reticle link` files a project-scoped key in
|
|
40
|
+
* `~/.reticle/credentials.json`, and the harness needs it so that somebody who has signed in and
|
|
41
|
+
* linked is not also asked to export a key by hand. Resolving it inside the tool surface would
|
|
42
|
+
* make `tools` reach into `memory/cloud`, which the directory guard refused — and it was right
|
|
43
|
+
* to: this is a port, and the daemon already resolves exactly this for cloud sync.
|
|
44
|
+
*
|
|
45
|
+
* Absent ⇒ nothing is linked, or the caller is an embedder with no filesystem. Never an error.
|
|
46
|
+
*/
|
|
47
|
+
linkedCloud?: () => Promise<{
|
|
48
|
+
url: string;
|
|
49
|
+
apiKey: string;
|
|
50
|
+
} | null>;
|
|
36
51
|
/** structured annotations accumulating for the live recording. */
|
|
37
52
|
annotations: AnnotationStore;
|
|
38
53
|
/**
|
|
@@ -65,7 +80,7 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
65
80
|
* embedding this engine may not have a filesystem to search. Absent ⇒ `reticleRoot`, which is
|
|
66
81
|
* exactly today's behaviour.
|
|
67
82
|
*/
|
|
68
|
-
artifactRootFor?: (projectId:
|
|
83
|
+
artifactRootFor?: (projectId: ProjectId | undefined) => ArtifactRoot;
|
|
69
84
|
/**
|
|
70
85
|
* A verification run just landed — wake cloud sync instead of waiting for its next tick.
|
|
71
86
|
*
|
|
@@ -85,7 +100,7 @@ export interface ToolDeps<Ext = unknown> {
|
|
|
85
100
|
* test construction of ToolDeps predates it. Absence means "cannot tell", which must never be
|
|
86
101
|
* treated as a mismatch.
|
|
87
102
|
*/
|
|
88
|
-
projectId?:
|
|
103
|
+
projectId?: ProjectId;
|
|
89
104
|
/** injected clock for the contract's generatedAt stamp. */
|
|
90
105
|
now: () => number;
|
|
91
106
|
/**
|
|
@@ -207,6 +222,11 @@ export declare const EnvelopeKey: {
|
|
|
207
222
|
readonly VERIFY_NEXT: "verify_next";
|
|
208
223
|
/** The contextual "tell us what just went wrong" invitation. Same story, same release. */
|
|
209
224
|
readonly FEEDBACK_INVITE: "feedback_invite";
|
|
225
|
+
/**
|
|
226
|
+
* The same moment, for the HUMAN: a call with the founder, or an email through `identify`. The
|
|
227
|
+
* agent is told to offer it and never to book or submit anything itself.
|
|
228
|
+
*/
|
|
229
|
+
readonly TALK_TO_US: "talk_to_us";
|
|
210
230
|
/** SDK/daemon version skew — often the one fact that explains everything else in the session. */
|
|
211
231
|
readonly VERSION_SKEW: "version_skew";
|
|
212
232
|
/** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
|
|
@@ -28,7 +28,7 @@ export const intentArg = z
|
|
|
28
28
|
'BAD: "P1 step 5", "drive 2 of 2", "same as before the fix", "the board renders cleanly" — these name a session, ' +
|
|
29
29
|
'a step number or nothing checkable, and the person reading them later has none of that context. ' +
|
|
30
30
|
'This is shared memory: it is pooled per project and later agents read it back to avoid re-deriving what you just established. ' +
|
|
31
|
-
'Recorded in .reticle/intent
|
|
31
|
+
'Recorded in .reticle/intent/, the same ledger reticle_intent writes, and marked proved by this verdict if it passes.');
|
|
32
32
|
export const sessionIdShape = {
|
|
33
33
|
sessionId: z
|
|
34
34
|
.string()
|
|
@@ -75,6 +75,11 @@ export const EnvelopeKey = {
|
|
|
75
75
|
VERIFY_NEXT: 'verify_next',
|
|
76
76
|
/** The contextual "tell us what just went wrong" invitation. Same story, same release. */
|
|
77
77
|
FEEDBACK_INVITE: 'feedback_invite',
|
|
78
|
+
/**
|
|
79
|
+
* The same moment, for the HUMAN: a call with the founder, or an email through `identify`. The
|
|
80
|
+
* agent is told to offer it and never to book or submit anything itself.
|
|
81
|
+
*/
|
|
82
|
+
TALK_TO_US: 'talk_to_us',
|
|
78
83
|
/** SDK/daemon version skew — often the one fact that explains everything else in the session. */
|
|
79
84
|
VERSION_SKEW: 'version_skew',
|
|
80
85
|
/** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
|
|
@@ -395,11 +395,23 @@ export function describeToolSurface(active, requested) {
|
|
|
395
395
|
export function defaultAdvertisedNames() {
|
|
396
396
|
const surface = resolveToolSurface();
|
|
397
397
|
const names = [...filterToolNames(surface)];
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
398
|
+
/*
|
|
399
|
+
* Both meta tools, on every surface, because that is what the MCP actually advertises.
|
|
400
|
+
*
|
|
401
|
+
* This used to withhold `reticle_run` from the merged surface, reasoning that "naming a hatch
|
|
402
|
+
* that is not there is the same defect one level in". The reasoning is sound and the premise was
|
|
403
|
+
* false: `buildDynamicTools` returns `[reticle_tools, reticle_run]` unconditionally and
|
|
404
|
+
* `advertisedTools` appends both to every surface, so the hatch has always been there. Measured
|
|
405
|
+
* against a live daemon on the default surface: `reticle_run` is advertised, and
|
|
406
|
+
* `reticle_run { tool: "reticle_lease" }` reaches `reticle_lease`.
|
|
407
|
+
*
|
|
408
|
+
* Two functions answering one question, and this was the one the MCP never called. It is read by
|
|
409
|
+
* `server-instructions`, which gates "Everything else is one hop: reticle_tools lists it,
|
|
410
|
+
* reticle_run calls it" on this list - so agents were told the hatch was absent from a surface
|
|
411
|
+
* carrying it, and six recovery messages were later rewritten to match the lie.
|
|
412
|
+
* `advertised-names-are-real.test.ts` now pins this to `advertisedTools` itself.
|
|
413
|
+
*/
|
|
414
|
+
return [...names, ReticleTool.TOOLS, ReticleTool.RUN];
|
|
403
415
|
}
|
|
404
416
|
/** The advertised NAME set for a surface, without needing the tool table. */
|
|
405
417
|
function filterToolNames(surface) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/** Small pure helpers shared by the MCP tool handlers. */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The argument a call names a tab with.
|
|
4
|
+
*
|
|
5
|
+
* A named constant because dispatch now WRITES this key as well as reading it — see `runTool`,
|
|
6
|
+
* which pins the session it resolved into the args the handler is given — and a key spelled at both
|
|
7
|
+
* ends of that can drift without anything saying so.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SESSION_ID_ARG = "sessionId";
|
|
8
10
|
/**
|
|
9
11
|
* The session this call is aimed at: a top-level `sessionId`, or the same key on sequence steps.
|
|
10
12
|
*
|
|
@@ -36,4 +38,3 @@ export declare function sourceOf(value: unknown): {
|
|
|
36
38
|
line: number;
|
|
37
39
|
column?: number;
|
|
38
40
|
} | undefined;
|
|
39
|
-
export {};
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { asRecord, asString } from '@reticlehq/core';
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return items;
|
|
12
|
-
}
|
|
2
|
+
/** Small pure helpers shared by the MCP tool handlers. */
|
|
3
|
+
/**
|
|
4
|
+
* The argument a call names a tab with.
|
|
5
|
+
*
|
|
6
|
+
* A named constant because dispatch now WRITES this key as well as reading it — see `runTool`,
|
|
7
|
+
* which pins the session it resolved into the args the handler is given — and a key spelled at both
|
|
8
|
+
* ends of that can drift without anything saying so.
|
|
9
|
+
*/
|
|
10
|
+
export const SESSION_ID_ARG = 'sessionId';
|
|
13
11
|
/**
|
|
14
12
|
* The session this call is aimed at: a top-level `sessionId`, or the same key on sequence steps.
|
|
15
13
|
*
|
|
@@ -21,7 +19,7 @@ export function parseInteractive(tree) {
|
|
|
21
19
|
* Mixed step ids refuse rather than pick: two named tabs is a guess we will not make.
|
|
22
20
|
*/
|
|
23
21
|
export function sessionIdFromArgs(args) {
|
|
24
|
-
const top = asString(args[
|
|
22
|
+
const top = asString(args[SESSION_ID_ARG]);
|
|
25
23
|
if (top !== undefined)
|
|
26
24
|
return top;
|
|
27
25
|
const steps = args['steps'];
|
|
@@ -29,7 +27,7 @@ export function sessionIdFromArgs(args) {
|
|
|
29
27
|
return undefined;
|
|
30
28
|
let found;
|
|
31
29
|
for (const raw of steps) {
|
|
32
|
-
const id = asString(asRecord(raw)[
|
|
30
|
+
const id = asString(asRecord(raw)[SESSION_ID_ARG]);
|
|
33
31
|
if (id === undefined)
|
|
34
32
|
continue;
|
|
35
33
|
if (found !== undefined && found !== id) {
|