@reticlehq/server 2.11.0 → 2.13.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 +93 -111
- package/dist/bridge/auth-failure-reason.d.ts +6 -2
- package/dist/bridge/auth-failure-reason.js +15 -8
- package/dist/bridge/bridge.d.ts +18 -14
- package/dist/bridge/bridge.js +248 -165
- package/dist/bridge/bridge.test-harness.d.ts +2 -0
- package/dist/bridge/bridge.test-harness.js +8 -1
- package/dist/bridge/pairing-token.d.ts +5 -0
- package/dist/bridge/pairing-token.js +28 -0
- package/dist/bridge/protocol-skew.d.ts +37 -0
- package/dist/bridge/protocol-skew.js +45 -0
- package/dist/capsule/capsule-store.d.ts +8 -7
- package/dist/capsule/capsule-store.js +1 -1
- package/dist/capsule/causal-summary.d.ts +2 -2
- package/dist/capsule/causal-summary.js +7 -2
- package/dist/chromium-launch-options.d.ts +28 -0
- package/dist/chromium-launch-options.js +29 -0
- package/dist/cli/cli-doctor.js +39 -1
- package/dist/cli/cli-flow-commands.d.ts +3 -1
- package/dist/cli/cli-flow-commands.js +34 -4
- package/dist/cli/cli-kill.d.ts +2 -1
- package/dist/cli/cli-launch.d.ts +11 -1
- package/dist/cli/cli-launch.js +59 -10
- package/dist/cli/cli-parse.d.ts +17 -1
- package/dist/cli/cli-parse.js +238 -12
- package/dist/cli/cli-update-commands.js +20 -1
- package/dist/cli/cli-verify.d.ts +2 -1
- package/dist/cli/cli-verify.js +5 -4
- package/dist/cli/cloud-cli.js +428 -253
- package/dist/cli/cloud-keystore.d.ts +37 -0
- package/dist/cli/cloud-keystore.js +97 -0
- package/dist/cli/cloud-kit.d.ts +37 -0
- package/dist/cli/cloud-kit.js +121 -0
- package/dist/cli/cloud-login.d.ts +17 -0
- package/dist/cli/cloud-login.js +183 -0
- package/dist/cli/cloud-session.d.ts +48 -0
- package/dist/cli/cloud-session.js +53 -0
- package/dist/cli/config-discovery.d.ts +2 -1
- package/dist/cli/config-discovery.js +1 -0
- package/dist/cli/daemon-start-options.d.ts +32 -0
- package/dist/cli/daemon-start-options.js +38 -0
- package/dist/cli/device-flow.d.ts +76 -0
- package/dist/cli/device-flow.js +56 -0
- package/dist/cli/doctor-rows.d.ts +12 -1
- package/dist/cli/doctor-rows.js +12 -1
- package/dist/cli/drive-attach.d.ts +13 -0
- package/dist/cli/drive-attach.js +18 -0
- package/dist/cli/drive-command.js +7 -3
- package/dist/cli/gate-exit.d.ts +21 -0
- package/dist/cli/gate-exit.js +21 -0
- package/dist/cli/gate-hook-message.d.ts +33 -0
- package/dist/cli/gate-hook-message.js +46 -0
- package/dist/cli/mcp-command.d.ts +25 -0
- package/dist/cli/mcp-command.js +174 -0
- package/dist/cli/project-name.d.ts +30 -0
- package/dist/cli/project-name.js +44 -0
- package/dist/cli/sibling-ports.d.ts +37 -0
- package/dist/cli/sibling-ports.js +56 -0
- package/dist/cli/status-next-action.d.ts +14 -0
- package/dist/cli/status-next-action.js +4 -4
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +167 -186
- package/dist/cloud/cloud-config.d.ts +24 -2
- package/dist/cloud/cloud-config.js +64 -5
- package/dist/cloud/cloud-sync.d.ts +16 -5
- package/dist/cloud/cloud-sync.js +64 -1
- package/dist/cloud/sync-cycle.d.ts +110 -0
- package/dist/cloud/sync-cycle.js +270 -0
- package/dist/cloud/sync-daemon.d.ts +69 -0
- package/dist/cloud/sync-daemon.js +260 -0
- package/dist/cloud/sync-disk.d.ts +9 -0
- package/dist/cloud/sync-disk.js +191 -0
- package/dist/cloud/sync-hash.d.ts +2 -0
- package/dist/cloud/sync-hash.js +35 -0
- package/dist/crawl/crawl-tools.js +5 -3
- package/dist/crawl/crawl.d.ts +12 -13
- package/dist/crawl/crawl.js +25 -3
- package/dist/daemon/daemon-resolve.d.ts +122 -0
- package/dist/daemon/daemon-resolve.js +187 -0
- package/dist/daemon/dev-servers.d.ts +15 -0
- package/dist/daemon/dev-servers.js +68 -0
- package/dist/daemon/free-port.d.ts +29 -0
- package/dist/daemon/free-port.js +55 -0
- package/dist/daemon/heartbeat.d.ts +0 -4
- package/dist/daemon/heartbeat.js +2 -2
- package/dist/daemon/wake-decision.d.ts +32 -0
- package/dist/daemon/wake-decision.js +38 -0
- package/dist/dev/stale-issue-guard.d.ts +0 -2
- package/dist/dev/stale-issue-guard.js +1 -1
- package/dist/domain/domain-tools.js +2 -2
- package/dist/events/contradictions.d.ts +59 -0
- package/dist/events/contradictions.js +253 -27
- package/dist/events/declared.d.ts +17 -0
- package/dist/events/declared.js +43 -1
- package/dist/events/echo-mismatch.js +65 -1
- package/dist/events/event-filters.d.ts +8 -0
- package/dist/events/event-filters.js +19 -2
- package/dist/events/observed-in-window.d.ts +12 -0
- package/dist/events/observed-in-window.js +17 -0
- package/dist/events/predicate-asks.d.ts +13 -0
- package/dist/events/predicate-asks.js +22 -0
- package/dist/events/predicate-eval.js +117 -27
- package/dist/events/predicate-parse.d.ts +0 -6
- package/dist/events/predicate-parse.js +43 -3
- package/dist/events/predicate-precheck.d.ts +8 -0
- package/dist/events/predicate-precheck.js +41 -0
- package/dist/events/predicate-route.d.ts +14 -0
- package/dist/events/predicate-route.js +36 -8
- package/dist/events/predicate-schema.d.ts +44 -0
- package/dist/events/predicate-schema.js +126 -23
- package/dist/events/predicate.d.ts +20 -0
- package/dist/events/predicate.js +77 -6
- package/dist/events/split-text-miss.d.ts +30 -0
- package/dist/events/split-text-miss.js +44 -0
- package/dist/flows/coverage.d.ts +0 -8
- package/dist/flows/coverage.js +1 -1
- package/dist/flows/decision.d.ts +5 -1
- package/dist/flows/decision.js +33 -7
- package/dist/flows/flake.d.ts +6 -8
- package/dist/flows/flake.js +1 -1
- package/dist/flows/flow-intent.d.ts +52 -0
- package/dist/flows/flow-intent.js +123 -0
- package/dist/flows/flow-memory-consult.d.ts +55 -0
- package/dist/flows/flow-memory-consult.js +38 -0
- package/dist/flows/flow-replay-run.d.ts +18 -7
- package/dist/flows/flow-replay-run.js +263 -23
- package/dist/flows/flow-replay.js +11 -2
- package/dist/flows/flow-step-runners.d.ts +8 -0
- package/dist/flows/flow-step-runners.js +8 -2
- package/dist/flows/flow-store-for-session.d.ts +31 -0
- package/dist/flows/flow-store-for-session.js +33 -0
- package/dist/flows/flow-success.js +15 -3
- package/dist/flows/flow-tools.js +87 -33
- package/dist/flows/flows.d.ts +14 -1
- package/dist/flows/flows.js +502 -24
- package/dist/flows/heal-run.js +5 -2
- package/dist/flows/predicate-to-expect.d.ts +17 -12
- package/dist/flows/predicate-to-expect.js +36 -15
- package/dist/flows/recordings.d.ts +13 -1
- package/dist/flows/recordings.js +17 -2
- package/dist/flows/replay.d.ts +22 -2
- package/dist/flows/replay.js +28 -2
- package/dist/flows/server-verify.js +16 -2
- package/dist/flows/verify-change-tools.js +9 -3
- package/dist/honesty/blind-spots.d.ts +51 -15
- package/dist/honesty/blind-spots.js +64 -4
- package/dist/honesty/feature-capture.d.ts +150 -0
- package/dist/honesty/feature-capture.js +233 -0
- package/dist/honesty/honesty.d.ts +24 -0
- package/dist/honesty/honesty.js +25 -1
- package/dist/honesty/instrumentation-gaps.d.ts +39 -6
- package/dist/honesty/instrumentation-gaps.js +88 -5
- package/dist/honesty/tool-hit-rate.d.ts +86 -0
- package/dist/honesty/tool-hit-rate.js +90 -0
- package/dist/honesty/undeclared-change.d.ts +51 -0
- package/dist/honesty/undeclared-change.js +56 -0
- package/dist/honesty/verified.d.ts +16 -0
- package/dist/honesty/verified.js +84 -5
- package/dist/http-server.d.ts +0 -1
- package/dist/http-server.js +13 -1
- package/dist/hunt/hunt-report.d.ts +0 -2
- package/dist/hunt/hunt-report.js +1 -1
- package/dist/impact/impact-recorder.d.ts +31 -8
- package/dist/impact/impact-recorder.js +104 -21
- package/dist/impact/impact-store.d.ts +13 -4
- package/dist/impact/impact-store.js +44 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.js +113 -7
- package/dist/init/agent-rules.d.ts +30 -6
- package/dist/init/agent-rules.js +54 -13
- package/dist/init/astro-patch.d.ts +16 -0
- package/dist/init/astro-patch.js +28 -0
- package/dist/init/capabilities.d.ts +4 -3
- package/dist/init/capabilities.js +23 -3
- package/dist/init/closing-hint.d.ts +36 -0
- package/dist/init/closing-hint.js +120 -0
- package/dist/init/confirm.d.ts +27 -28
- package/dist/init/confirm.js +51 -11
- package/dist/init/cra.d.ts +34 -5
- package/dist/init/cra.js +96 -25
- package/dist/init/csp-check.js +17 -2
- package/dist/init/csp-doctor.d.ts +8 -1
- package/dist/init/csp-doctor.js +8 -3
- package/dist/init/dev-script.d.ts +50 -0
- package/dist/init/dev-script.js +66 -0
- package/dist/init/format-generated.d.ts +18 -0
- package/dist/init/format-generated.js +39 -0
- package/dist/init/install-hint.d.ts +9 -0
- package/dist/init/install-hint.js +29 -0
- package/dist/init/mcp-clients.d.ts +7 -0
- package/dist/init/mcp-clients.js +7 -0
- package/dist/init/mcp.d.ts +17 -6
- package/dist/init/mcp.js +27 -11
- package/dist/init/node-io.js +11 -1
- package/dist/init/plan-framework.d.ts +0 -5
- package/dist/init/plan-framework.js +147 -37
- package/dist/init/plan.d.ts +30 -37
- package/dist/init/plan.js +50 -60
- package/dist/init/preflight.d.ts +28 -0
- package/dist/init/preflight.js +38 -0
- package/dist/init/refresh-rules.d.ts +39 -0
- package/dist/init/refresh-rules.js +51 -0
- package/dist/init/run.d.ts +32 -35
- package/dist/init/run.js +151 -202
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/snippets.js +90 -31
- package/dist/init/vite-config.d.ts +1 -1
- package/dist/init/vite-config.js +39 -25
- package/dist/init/workspace-apps.d.ts +17 -10
- package/dist/init/workspace-apps.js +110 -0
- package/dist/input/network-mock-tools.js +3 -6
- package/dist/input/real-input.d.ts +2 -0
- package/dist/input/real-input.js +28 -7
- package/dist/input/scroll-find.d.ts +7 -4
- package/dist/input/scroll-find.js +63 -25
- package/dist/input/scroll-tools.js +4 -6
- package/dist/input/viewport-tools.js +5 -4
- package/dist/intent/inline-intent.d.ts +37 -0
- package/dist/intent/inline-intent.js +193 -0
- package/dist/intent/intent-shard-store.d.ts +72 -0
- package/dist/intent/intent-shard-store.js +203 -0
- package/dist/intent/intent-shard.d.ts +411 -0
- package/dist/intent/intent-shard.js +176 -0
- package/dist/intent/intent-store.d.ts +49 -0
- package/dist/intent/intent-store.js +133 -0
- package/dist/intent/intent-subject.d.ts +45 -0
- package/dist/intent/intent-subject.js +177 -0
- package/dist/intent/intent-tools.d.ts +2 -0
- package/dist/intent/intent-tools.js +143 -0
- package/dist/intent/open-intents.d.ts +42 -0
- package/dist/intent/open-intents.js +40 -0
- package/dist/journal/envelope.d.ts +26 -26
- package/dist/journal/journal-recorder.d.ts +23 -0
- package/dist/journal/journal-recorder.js +35 -0
- package/dist/license/license-env.d.ts +29 -0
- package/dist/license/license-env.js +148 -0
- package/dist/loopback-agent.d.ts +31 -0
- package/dist/loopback-agent.js +57 -0
- package/dist/mcp/attach-memory.d.ts +83 -0
- package/dist/mcp/attach-memory.js +185 -0
- package/dist/mcp/client-identity.d.ts +31 -0
- package/dist/mcp/client-identity.js +51 -0
- package/dist/mcp/mcp-post-transport.d.ts +26 -0
- package/dist/mcp/mcp-post-transport.js +109 -0
- package/dist/mcp/mcp-proxy.d.ts +2 -8
- package/dist/mcp/mcp-proxy.js +64 -62
- package/dist/mcp/mcp.d.ts +2 -0
- package/dist/mcp/mcp.js +52 -24
- package/dist/mcp/proxy-backoff.d.ts +11 -0
- package/dist/mcp/proxy-backoff.js +13 -0
- package/dist/mcp/proxy-daemon-probe.d.ts +1 -0
- package/dist/mcp/proxy-daemon-probe.js +7 -1
- package/dist/mcp/proxy-handshake.d.ts +23 -0
- package/dist/mcp/proxy-handshake.js +31 -0
- package/dist/mcp/server-instructions.js +45 -3
- package/dist/mcp/tool-catalog-cache.d.ts +16 -0
- package/dist/mcp/tool-catalog-cache.js +22 -0
- package/dist/memory/memory-tools.d.ts +2 -0
- package/dist/memory/memory-tools.js +82 -0
- package/dist/memory/project-memory.d.ts +34 -0
- package/dist/memory/project-memory.js +96 -0
- package/dist/oracles/flow-instrument-gaps.d.ts +4 -4
- package/dist/oracles/flow-instrument-gaps.js +4 -5
- package/dist/oracles/propose-consequences.js +12 -3
- package/dist/oracles/self-instrument.d.ts +9 -9
- package/dist/oracles/self-instrument.js +19 -13
- package/dist/pool/browser-pool.d.ts +75 -5
- package/dist/pool/browser-pool.js +144 -5
- package/dist/pool/playwright-launcher.js +12 -1
- package/dist/project/fs-port.d.ts +3 -0
- package/dist/project/fs-port.js +3 -2
- package/dist/project/memory-fs.js +6 -1
- package/dist/project/project-tools.js +6 -35
- package/dist/project/reticle-dir.d.ts +17 -2
- package/dist/project/reticle-dir.js +22 -4
- package/dist/runs/context-tools.d.ts +2 -0
- package/dist/runs/context-tools.js +89 -0
- package/dist/runs/run-context.d.ts +40 -0
- package/dist/runs/run-context.js +158 -0
- package/dist/runs/run-diff.d.ts +2 -1
- package/dist/runs/run-store.d.ts +10 -0
- package/dist/runs/run-store.js +10 -0
- package/dist/runs/verification-sync.d.ts +0 -11
- package/dist/runs/verification-sync.js +24 -3
- package/dist/runs/verify-server.d.ts +8 -1
- package/dist/runs/verify-server.js +14 -2
- package/dist/session/command-timeout.d.ts +5 -2
- package/dist/session/command-timeout.js +5 -4
- package/dist/session/dev-server-probe.d.ts +0 -8
- package/dist/session/dev-server-probe.js +1 -1
- package/dist/session/last-act.d.ts +7 -1
- package/dist/session/last-act.js +2 -2
- package/dist/session/lease-visibility.d.ts +67 -0
- package/dist/session/lease-visibility.js +76 -0
- package/dist/session/live-control-tools.js +1 -42
- package/dist/session/no-session-diagnosis.d.ts +33 -0
- package/dist/session/no-session-diagnosis.js +82 -24
- package/dist/session/no-session-next-action.d.ts +12 -0
- package/dist/session/no-session-next-action.js +77 -6
- package/dist/session/no-session-watch.d.ts +18 -6
- package/dist/session/no-session-watch.js +125 -75
- package/dist/session/output-budget.js +4 -1
- package/dist/session/pending-commands.d.ts +11 -1
- package/dist/session/pending-commands.js +12 -2
- package/dist/session/resolve-within.d.ts +34 -0
- package/dist/session/resolve-within.js +53 -0
- package/dist/session/session-health.d.ts +9 -0
- package/dist/session/session-health.js +23 -0
- package/dist/session/session-info.d.ts +18 -0
- package/dist/session/session-info.js +11 -0
- package/dist/session/session-manager.d.ts +14 -0
- package/dist/session/session-manager.js +111 -4
- package/dist/session/session-mirror.d.ts +16 -0
- package/dist/session/session-mirror.js +22 -0
- package/dist/session/session-recommendation.d.ts +19 -5
- package/dist/session/session-recommendation.js +25 -9
- package/dist/session/session-successor.d.ts +37 -0
- package/dist/session/session-successor.js +113 -0
- package/dist/session/session-tools.js +2 -2
- package/dist/session/session.d.ts +53 -3
- package/dist/session/session.js +162 -9
- package/dist/session/wall-clock.d.ts +12 -0
- package/dist/session/wall-clock.js +14 -0
- package/dist/setup/agent-configs.d.ts +96 -0
- package/dist/setup/agent-configs.js +333 -0
- package/dist/setup/agent-io.d.ts +9 -0
- package/dist/setup/agent-io.js +16 -0
- package/dist/setup/agent-writer.d.ts +51 -0
- package/dist/setup/agent-writer.js +115 -0
- package/dist/setup/approval-migration.d.ts +47 -0
- package/dist/setup/approval-migration.js +68 -0
- package/dist/setup/auto-approve.d.ts +85 -0
- package/dist/setup/auto-approve.js +150 -0
- package/dist/setup/bridge-port.d.ts +15 -0
- package/dist/setup/bridge-port.js +24 -0
- package/dist/setup/desktop-shape.d.ts +57 -0
- package/dist/setup/desktop-shape.js +63 -0
- package/dist/setup/dev-server-wait.d.ts +60 -0
- package/dist/setup/dev-server-wait.js +65 -0
- package/dist/setup/drive-agent.d.ts +71 -0
- package/dist/setup/drive-agent.js +171 -0
- package/dist/setup/drive-plan.d.ts +68 -0
- package/dist/setup/drive-plan.js +130 -0
- package/dist/setup/ensure-daemon.d.ts +29 -0
- package/dist/setup/ensure-daemon.js +58 -0
- package/dist/setup/init-runtime.d.ts +47 -0
- package/dist/setup/init-runtime.js +160 -0
- package/dist/setup/interrupt.d.ts +25 -0
- package/dist/setup/interrupt.js +40 -0
- package/dist/setup/license-key.d.ts +39 -0
- package/dist/setup/license-key.js +72 -0
- package/dist/setup/listeners.d.ts +37 -0
- package/dist/setup/listeners.js +85 -0
- package/dist/setup/node-effects.d.ts +60 -0
- package/dist/setup/node-effects.js +210 -0
- package/dist/setup/page-probe.d.ts +39 -0
- package/dist/setup/page-probe.js +49 -0
- package/dist/setup/relaunch.d.ts +36 -0
- package/dist/setup/relaunch.js +57 -0
- package/dist/setup/remaining-steps.d.ts +19 -0
- package/dist/setup/remaining-steps.js +31 -0
- package/dist/setup/run-setup.d.ts +99 -0
- package/dist/setup/run-setup.js +187 -0
- package/dist/setup/session-pick.d.ts +47 -0
- package/dist/setup/session-pick.js +51 -0
- package/dist/setup/setup-command.d.ts +45 -0
- package/dist/setup/setup-command.js +199 -0
- package/dist/setup/setup-options.d.ts +74 -0
- package/dist/setup/setup-options.js +67 -0
- package/dist/setup/transcripts.d.ts +16 -0
- package/dist/setup/transcripts.js +43 -0
- package/dist/status-payload.d.ts +14 -1
- package/dist/status-payload.js +23 -1
- package/dist/telemetry/automation-hint.d.ts +2 -1
- package/dist/telemetry/daemon-telemetry.d.ts +8 -1
- package/dist/telemetry/daemon-telemetry.js +52 -5
- package/dist/telemetry/error-class.js +1 -1
- package/dist/telemetry/feedback-context.d.ts +9 -1
- package/dist/telemetry/feedback-context.js +60 -29
- package/dist/telemetry/feedback-local.d.ts +15 -0
- package/dist/telemetry/feedback-local.js +56 -0
- package/dist/telemetry/feedback-outbox.d.ts +2 -1
- package/dist/telemetry/feedback.d.ts +11 -0
- package/dist/telemetry/feedback.js +19 -6
- package/dist/telemetry/init-telemetry.d.ts +2 -0
- package/dist/telemetry/init-telemetry.js +2 -0
- package/dist/telemetry/install-source.d.ts +14 -0
- package/dist/telemetry/install-source.js +30 -0
- package/dist/telemetry/license-activation.d.ts +7 -1
- package/dist/telemetry/license-activation.js +9 -5
- package/dist/telemetry/mcp-connection.js +7 -0
- package/dist/telemetry/project-profile.d.ts +12 -9
- package/dist/telemetry/project-profile.js +12 -7
- package/dist/telemetry/proxy-telemetry.d.ts +3 -0
- package/dist/telemetry/proxy-telemetry.js +21 -0
- package/dist/telemetry/run-telemetry.d.ts +0 -2
- package/dist/telemetry/run-telemetry.js +1 -1
- package/dist/telemetry/session-metrics.d.ts +12 -0
- package/dist/telemetry/session-metrics.js +35 -1
- package/dist/telemetry/telemetry.js +17 -2
- package/dist/telemetry/tool-refused.d.ts +3 -1
- package/dist/telemetry/tool-refused.js +34 -2
- package/dist/telemetry/verification-of.js +2 -2
- package/dist/tools/act-capsule.d.ts +10 -0
- package/dist/tools/act-capsule.js +8 -2
- package/dist/tools/act-danger.d.ts +2 -1
- package/dist/tools/act-danger.js +11 -3
- package/dist/tools/act-observation.d.ts +41 -0
- package/dist/tools/act-observation.js +36 -0
- package/dist/tools/act-preflight.d.ts +20 -0
- package/dist/tools/act-preflight.js +98 -0
- package/dist/tools/act-sequence-retry.d.ts +45 -0
- package/dist/tools/act-sequence-retry.js +58 -0
- package/dist/tools/act-sequence-tool.d.ts +13 -0
- package/dist/tools/act-sequence-tool.js +135 -0
- package/dist/tools/act-target.d.ts +14 -0
- package/dist/tools/act-target.js +47 -0
- package/dist/tools/act-tools.d.ts +21 -1
- package/dist/tools/act-tools.js +196 -204
- package/dist/tools/assert-source.d.ts +22 -0
- package/dist/tools/assert-source.js +53 -0
- package/dist/tools/assert-verdict.d.ts +20 -3
- package/dist/tools/assert-verdict.js +58 -20
- package/dist/tools/browser-tools.js +6 -22
- package/dist/tools/complete-snapshot.d.ts +48 -0
- package/dist/tools/complete-snapshot.js +75 -0
- package/dist/tools/coverage-tools.d.ts +10 -1
- package/dist/tools/coverage-tools.js +123 -69
- package/dist/tools/dynamic-tools.js +53 -13
- package/dist/tools/error-recovery.d.ts +25 -14
- package/dist/tools/error-recovery.js +78 -9
- package/dist/tools/feedback-tools.d.ts +1 -1
- package/dist/tools/feedback-tools.js +2 -2
- package/dist/tools/invoke-tool.js +121 -11
- package/dist/tools/lease-hint.d.ts +10 -0
- package/dist/tools/lease-hint.js +53 -4
- package/dist/tools/lease-tools.d.ts +35 -5
- package/dist/tools/lease-tools.js +191 -13
- package/dist/tools/merged-name-redirect.d.ts +13 -0
- package/dist/tools/merged-name-redirect.js +22 -0
- package/dist/tools/navigate-arrival.d.ts +0 -2
- package/dist/tools/navigate-arrival.js +1 -1
- package/dist/tools/numeric-bounds.d.ts +100 -0
- package/dist/tools/numeric-bounds.js +125 -0
- package/dist/tools/observe-tools.js +109 -65
- package/dist/tools/read-tools.js +31 -8
- package/dist/tools/real-input-attempt.d.ts +32 -0
- package/dist/tools/real-input-attempt.js +212 -2
- package/dist/tools/reconcile-tools.js +22 -8
- package/dist/tools/resolve-target.d.ts +0 -7
- package/dist/tools/sdk-marker-probe.d.ts +29 -0
- package/dist/tools/sdk-marker-probe.js +57 -0
- package/dist/tools/snapshot-delta.d.ts +1 -1
- package/dist/tools/tool-kit.d.ts +24 -0
- package/dist/tools/tool-kit.js +21 -0
- package/dist/tools/tool-names.d.ts +5 -0
- package/dist/tools/tool-names.js +5 -0
- package/dist/tools/tool-surface.d.ts +85 -6
- package/dist/tools/tool-surface.js +122 -2
- package/dist/tools/tools-helpers.d.ts +19 -0
- package/dist/tools/tools-helpers.js +46 -0
- package/dist/tools/tools.d.ts +2 -0
- package/dist/tools/tools.js +78 -12
- package/dist/tools/unadvertised-help.js +4 -4
- package/dist/tools/verify-next-baton.d.ts +53 -0
- package/dist/tools/verify-next-baton.js +52 -0
- package/dist/update/reticle-deps.d.ts +9 -0
- package/dist/update/reticle-deps.js +27 -0
- package/dist/update/sdk-sync.d.ts +1 -2
- package/dist/update/sdk-sync.js +1 -21
- package/dist/update/update-nudge.d.ts +25 -10
- package/dist/update/update-nudge.js +32 -3
- package/dist/update/updater.d.ts +1 -1
- package/dist/version/peer-announce.js +4 -2
- package/dist/version/sdk-fix.d.ts +47 -0
- package/dist/version/sdk-fix.js +127 -0
- package/dist/version/version-nudge.d.ts +14 -0
- package/dist/version/version-nudge.js +21 -0
- package/dist/version/version-skew.d.ts +38 -3
- package/dist/version/version-skew.js +83 -7
- package/dist/visual/visual-store.d.ts +6 -6
- package/dist/visual/visual-store.js +18 -16
- package/dist/visual/visual-tools.js +57 -12
- package/docs/README.md +2 -1
- package/docs/cli/cloud.mdx +1 -1
- package/docs/cli/doctor.mdx +2 -0
- package/docs/cli/serve.mdx +4 -2
- package/docs/cli/verify.mdx +4 -5
- package/docs/cli.mdx +7 -3
- package/docs/desktop.mdx +1 -1
- package/docs/docs.json +2 -2
- package/docs/gates.md +1 -1
- package/docs/getting-started.md +19 -3
- package/docs/index.mdx +9 -6
- package/docs/install-agentic.mdx +38 -12
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/server.mdx +1 -1
- package/docs/packages.mdx +8 -6
- package/docs/platform-integration.md +17 -0
- package/docs/predicates.mdx +8 -0
- package/docs/reticle-manual.md +106 -0
- package/docs/skill-file.mdx +3 -3
- package/docs/telemetry-contract.md +108 -4
- package/docs/tools-act-sequence.mdx +16 -0
- package/docs/tools-tools-and-run.mdx +2 -4
- package/docs/troubleshooting.mdx +9 -0
- package/docs/usage.md +4 -3
- package/package.json +4 -3
- package/dist/init/cursor.d.ts +0 -24
- package/dist/init/cursor.js +0 -80
- package/dist/session/session-readiness.d.ts +0 -34
- package/dist/session/session-readiness.js +0 -36
package/dist/tools/act-tools.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { normalizeQueryArgs } from './query-shape.js';
|
|
2
|
-
import { resolveTargetRef } from './resolve-target.js';
|
|
3
|
-
/**
|
|
4
|
-
* Action tools — reticle_act, reticle_act_sequence, reticle_act_and_wait. Split out of tools.ts to keep
|
|
5
|
-
* that file under the line cap and assembled back into the tool list there via ...ACT_TOOLS; the
|
|
6
|
-
* native-input attempt itself lives in real-input-attempt.ts for the same reason.
|
|
7
|
-
*/
|
|
8
1
|
import { z } from 'zod';
|
|
9
2
|
import { aliasParam } from './alias-args.js';
|
|
10
|
-
import {
|
|
3
|
+
import { resolveSessionWithin } from '../session/resolve-within.js';
|
|
4
|
+
import { WALL_CLOCK } from '../session/wall-clock.js';
|
|
5
|
+
import { ACT_SEQUENCE_TOOL } from './act-sequence-tool.js';
|
|
6
|
+
import { timeoutMsSchema } from './numeric-bounds.js';
|
|
7
|
+
import { captureAct } from '../flows/replay.js';
|
|
11
8
|
import { ActionType, ActionWarning, CaptureLoss, DEFAULT_ASSERT_TIMEOUT_MS, InputMode, ReticleCommand, Verified, VerifiedReason, PredicateKind, } from '@reticlehq/core';
|
|
12
|
-
import { assertNativeInputSupported } from './act-danger.js';
|
|
13
9
|
import { leanActResult, mutatedWithin } from './act-view.js';
|
|
14
10
|
import { ReticleTool } from './tool-names.js';
|
|
15
11
|
import { buildReactionReport, summarizeReaction } from '../events/reaction.js';
|
|
@@ -18,28 +14,70 @@ import { causalSummary } from '../capsule/causal-summary.js';
|
|
|
18
14
|
import { findContradictions } from '../events/contradictions.js';
|
|
19
15
|
import { gapsForAction } from '../honesty/instrumentation-gaps.js';
|
|
20
16
|
import { noteSessionGaps } from '../honesty/gap-ledger.js';
|
|
17
|
+
import { isChangeUndeclared } from '../honesty/undeclared-change.js';
|
|
18
|
+
import { intentDebt, openSessionIntents } from '../intent/open-intents.js';
|
|
19
|
+
import { dischargeInlineIntent, inlineVerdictId, linkInlineIntent, } from '../intent/inline-intent.js';
|
|
21
20
|
import { declaresState } from '../events/predicate-asks.js';
|
|
22
21
|
import { isStateUnwatched } from '../honesty/blind-spots.js';
|
|
23
22
|
import { inFlightRequestLabels, repeatedRequestLabels, waitForInFlight, } from './settle-in-flight.js';
|
|
24
23
|
import { waitForReaction } from './react-grace.js';
|
|
25
24
|
import { decideVerified } from '../honesty/verified.js';
|
|
26
|
-
import {
|
|
25
|
+
import { honestyForVerdict } from '../honesty/honesty.js';
|
|
26
|
+
import { declaredExpectations, declaresBodyIndependentChannel } from '../events/declared.js';
|
|
27
27
|
import { readsDomState } from '../honesty/already-true.js';
|
|
28
28
|
import { describeWaitTarget } from '../honesty/unsettled.js';
|
|
29
29
|
import { saveFailedAssertCapsule } from './act-capsule.js';
|
|
30
30
|
import { buildDivergenceCapsule } from '../capsule/capsule.js';
|
|
31
31
|
import { predicateToExpectedLinks } from '../capsule/predicate-to-links.js';
|
|
32
32
|
import { buildHonestyBlock } from '../honesty/honesty.js';
|
|
33
|
-
import { buildCoverageStatement, blindSpotsFromState, transportGapNote, Coverage, impeachesCapture, } from '../honesty/blind-spots.js';
|
|
33
|
+
import { absenceBlindSpotNote, buildCoverageStatement, blindSpotsFromState, transportGapNote, Coverage, impeachesCapture, } from '../honesty/blind-spots.js';
|
|
34
34
|
import { hasAcceptedWrite } from '../honesty/accepted-write.js';
|
|
35
35
|
import { unreadWriteLabels } from '../honesty/unread-outcome.js';
|
|
36
36
|
import { evaluatePredicate, waitForPredicate, provenExpectedLinks, PredicateSchema, } from '../events/predicate.js';
|
|
37
37
|
import { healthEnvelope, refuseIfThrottled } from '../session/session-health.js';
|
|
38
38
|
import { pausedShortCircuit, pausedOutputShape, withControl, PAUSED_NO_VERDICT, } from '../session/control-envelope.js';
|
|
39
39
|
import { asString, asNumber, asRecord, sourceOf } from './tools-helpers.js';
|
|
40
|
-
import {
|
|
40
|
+
import { dispatchAct, preflightAct } from './act-preflight.js';
|
|
41
|
+
import { followLostObservation } from './act-observation.js';
|
|
42
|
+
import { intentArg, sessionIdShape } from './tool-kit.js';
|
|
41
43
|
import { asActionType, gradeOf } from './act-helpers.js';
|
|
42
|
-
import {
|
|
44
|
+
import { resolveActTarget } from './act-target.js';
|
|
45
|
+
import { tryRealInput, rewriteUploadArgs, HOVER_NEEDS_POINTER_MSG } from './real-input-attempt.js';
|
|
46
|
+
/**
|
|
47
|
+
* Single dispatch point for every ACT and ACT_SEQUENCE command.
|
|
48
|
+
*
|
|
49
|
+
* This is the seam the reviewer asked for: instead of wiring rewriteUploadArgs at three separate
|
|
50
|
+
* call sites (reticle_act, reticle_act_and_wait, reticle_act_sequence) we intercept once here,
|
|
51
|
+
* which also covers flow-replay, crawl, and any future dispatch site that goes through this helper.
|
|
52
|
+
*
|
|
53
|
+
* captureAct is called AFTER this, so the flow-recording captures the pre-rewrite args (the path
|
|
54
|
+
* the agent actually wrote) rather than the base64 blob — replay would otherwise send 750 KiB of
|
|
55
|
+
* base64 to the browser as if it were an inline content call.
|
|
56
|
+
*/
|
|
57
|
+
export async function actCommand(deps, session, actArgs, timeoutMs) {
|
|
58
|
+
const rewritten = await rewriteUploadArgs(deps, 'string' === typeof actArgs['action'] ? actArgs['action'] : '', asRecord(actArgs['args']));
|
|
59
|
+
// Sequence and act_and_wait dispatch through here without the ACT handler's tryRealInput.
|
|
60
|
+
// A synthetic hover reports dispatched/settled while CSS :hover never applies — drive a real
|
|
61
|
+
// pointer when one is available, otherwise refuse rather than lie.
|
|
62
|
+
if (ActionType.HOVER === actArgs['action']) {
|
|
63
|
+
const ref = asString(actArgs['ref']);
|
|
64
|
+
if (ref === undefined)
|
|
65
|
+
throw new Error(HOVER_NEEDS_POINTER_MSG);
|
|
66
|
+
const real = await tryRealInput(deps, session, ref, ActionType.HOVER, actArgs);
|
|
67
|
+
if (real.result === undefined)
|
|
68
|
+
throw new Error(HOVER_NEEDS_POINTER_MSG);
|
|
69
|
+
return {
|
|
70
|
+
kind: 'command_result',
|
|
71
|
+
id: 'hover',
|
|
72
|
+
ok: true,
|
|
73
|
+
result: { dispatched: true, settled: real.settled, ...asRecord(real.result) },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const bridgeArgs = { ...actArgs, args: rewritten };
|
|
77
|
+
return timeoutMs !== undefined
|
|
78
|
+
? session.command(ReticleCommand.ACT, bridgeArgs, timeoutMs)
|
|
79
|
+
: session.command(ReticleCommand.ACT, bridgeArgs);
|
|
80
|
+
}
|
|
43
81
|
/**
|
|
44
82
|
* Narrow the wire's `action` to a real ActionType, or undefined.
|
|
45
83
|
*
|
|
@@ -60,41 +98,7 @@ import { tryRealInput } from './real-input-attempt.js';
|
|
|
60
98
|
*/
|
|
61
99
|
const ACTION_TYPE_VALUES = Object.values(ActionType);
|
|
62
100
|
const ACTION_TYPE_LIST = ACTION_TYPE_VALUES.join(' | ');
|
|
63
|
-
const actionTypeEnum = z.enum(ACTION_TYPE_VALUES);
|
|
64
|
-
/**
|
|
65
|
-
* Resolve an action's element: an explicit `ref`, or a `target` query resolved in the SAME call.
|
|
66
|
-
*
|
|
67
|
-
* Requiring a ref meant every verification paid a `reticle_query` turn first just to learn one
|
|
68
|
-
* string, and the advertised tool surface is re-sent on every turn — measured on the wire, a
|
|
69
|
-
* two-turn verification spent 10,756 of 11,235 tokens on schema and 479 on the actual answers. The
|
|
70
|
-
* lookup still happens; it just stops costing a round trip through the model.
|
|
71
|
-
*
|
|
72
|
-
* `ref` wins when both are given, because it is the more specific instruction and silently
|
|
73
|
-
* preferring the query would act on something the caller did not name.
|
|
74
|
-
*/
|
|
75
|
-
async function resolveActTarget(session, args) {
|
|
76
|
-
const ref = asString(args['ref']);
|
|
77
|
-
if (ref !== undefined && ref.length > 0)
|
|
78
|
-
return { kind: 'ref', ref };
|
|
79
|
-
const target = args['target'];
|
|
80
|
-
if (target === undefined) {
|
|
81
|
-
return {
|
|
82
|
-
kind: 'error',
|
|
83
|
-
message: 'pass `ref` (from reticle_query/reticle_snapshot) or `target` (e.g. { testid } or { role, name }).',
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
const q = normalizeQueryArgs(asRecord(target));
|
|
87
|
-
const out = await session.command(ReticleCommand.QUERY, {
|
|
88
|
-
by: q['by'],
|
|
89
|
-
value: q['value'],
|
|
90
|
-
name: q['name'],
|
|
91
|
-
scope: q['scope'],
|
|
92
|
-
});
|
|
93
|
-
if (!out.ok)
|
|
94
|
-
return { kind: 'error', message: out.error ?? 'target query failed' };
|
|
95
|
-
const elements = asRecord(out.result)['elements'];
|
|
96
|
-
return resolveTargetRef(Array.isArray(elements) ? elements : []);
|
|
97
|
-
}
|
|
101
|
+
export const actionTypeEnum = z.enum(ACTION_TYPE_VALUES);
|
|
98
102
|
export const ACT_TOOLS = [
|
|
99
103
|
{
|
|
100
104
|
name: ReticleTool.ACT,
|
|
@@ -113,7 +117,7 @@ export const ACT_TOOLS = [
|
|
|
113
117
|
args: z
|
|
114
118
|
.record(z.unknown())
|
|
115
119
|
.optional()
|
|
116
|
-
.describe('Action-specific arguments: { value } for fill/select, { text } for type/press (the key NAME, e.g. Escape or Tab), { modifiers: ["Meta","Shift"] } for a press shortcut (Meta/Control/Shift/Alt — a Cmd+K), { toRef } for drag (the ref to drop ON — without it the drag lands nowhere), { native: true } to force a trusted native click, { holdMs: N } to keep the pointer DOWN for N ms (hold-to-confirm controls; effect.heldMs reports what was achieved), { confirmDangerous: true } to allow a potentially destructive control — a permission gate, NOT a duration.'),
|
|
120
|
+
.describe('Action-specific arguments: { value } for fill/select, { text } for type/press (the key NAME, e.g. Escape or Tab), { modifiers: ["Meta","Shift"] } for a press shortcut (Meta/Control/Shift/Alt — a Cmd+K), { toRef } for drag (the ref to drop ON — without it the drag lands nowhere), { native: true } to force a trusted native click, { holdMs: N } to keep the pointer DOWN for N ms (hold-to-confirm controls; effect.heldMs reports what was achieved), { confirmDangerous: true } to allow a potentially destructive control — a permission gate, NOT a duration. For upload: { path } is a path on disk (absolute or relative to the project root; the daemon reads the file and delivers real bytes to the file picker — this is the way to verify document-ingestion flows); or { name, content?, type? } to supply inline bytes directly.'),
|
|
117
121
|
refuseWhenThrottled: z
|
|
118
122
|
.boolean()
|
|
119
123
|
.optional()
|
|
@@ -179,7 +183,7 @@ export const ACT_TOOLS = [
|
|
|
179
183
|
settledOutcome = real.settled ?? undefined;
|
|
180
184
|
// Native input reports no synthetic effect block, so nothing measured in-target: undefined
|
|
181
185
|
// (the weaker empty-window test), never a fabricated zero.
|
|
182
|
-
session.lastAct.markActed(since, action, undefined);
|
|
186
|
+
session.lastAct.markActed(since, action, undefined, asString(args['ref']));
|
|
183
187
|
return withControl(session, {
|
|
184
188
|
since,
|
|
185
189
|
inputMode: InputMode.REAL,
|
|
@@ -190,7 +194,9 @@ export const ACT_TOOLS = [
|
|
|
190
194
|
...healthEnvelope(session),
|
|
191
195
|
});
|
|
192
196
|
}
|
|
193
|
-
|
|
197
|
+
// actCommand is the single interception point: it rewrites upload+path args to real bytes
|
|
198
|
+
// before any ACT command crosses the bridge, covering this call site and all others.
|
|
199
|
+
const result = await actCommand(deps, session, {
|
|
194
200
|
ref: targetRef.ref,
|
|
195
201
|
action: args['action'],
|
|
196
202
|
args: args['args'] ?? {},
|
|
@@ -205,7 +211,7 @@ export const ACT_TOOLS = [
|
|
|
205
211
|
// Keep what only this call measured, so the observe that judges this window can ask whether
|
|
206
212
|
// anything happened INSIDE the target — the one fact that separates a dead control from a
|
|
207
213
|
// page that was merely busy with something else.
|
|
208
|
-
session.lastAct.markActed(since, action, mutatedWithin(r));
|
|
214
|
+
session.lastAct.markActed(since, action, mutatedWithin(r), asString(args['ref']));
|
|
209
215
|
return withControl(session, {
|
|
210
216
|
since,
|
|
211
217
|
inputMode: InputMode.SYNTHETIC,
|
|
@@ -225,127 +231,6 @@ export const ACT_TOOLS = [
|
|
|
225
231
|
}
|
|
226
232
|
},
|
|
227
233
|
},
|
|
228
|
-
{
|
|
229
|
-
name: ReticleTool.ACT_SEQUENCE,
|
|
230
|
-
// The example is required for a core tool, and this one carries weight: the measured loop it
|
|
231
|
-
// replaces is literally a login form driven as three separate reticle_act calls (98 clicks and
|
|
232
|
-
// 21 fills inside looping sessions, 2026-08-10/11). Showing fill -> fill -> click is showing the
|
|
233
|
-
// exact shape an agent otherwise spends three round trips on.
|
|
234
|
-
example: {
|
|
235
|
-
steps: [
|
|
236
|
-
{ ref: 'e12', action: 'fill', args: { value: 'a@b.com' } },
|
|
237
|
-
{ ref: 'e13', action: 'fill', args: { value: 'hunter2' } },
|
|
238
|
-
{ ref: 'e14', action: 'click' },
|
|
239
|
-
],
|
|
240
|
-
},
|
|
241
|
-
description: 'Run multiple actions in order (fill -> fill -> submit) in ONE round-trip. Prefer this over repeating reticle_act for a multi-step journey, then assert its consequence once. Returns per-step effects[] (see reticle_act).',
|
|
242
|
-
inputSchema: {
|
|
243
|
-
steps: z
|
|
244
|
-
.array(z.record(z.unknown()))
|
|
245
|
-
.describe('Ordered list of { ref, action, args? } objects. Each step is equivalent to one reticle_act call; put confirmDangerous:true in a destructive step args object.'),
|
|
246
|
-
timeout_ms: z
|
|
247
|
-
.number()
|
|
248
|
-
.optional()
|
|
249
|
-
.describe('Per-step timeout in milliseconds. Default: 8000. Each step gets this budget independently.'),
|
|
250
|
-
...sessionIdShape,
|
|
251
|
-
},
|
|
252
|
-
outputSchema: {
|
|
253
|
-
since: z.number(),
|
|
254
|
-
dispatched: z.boolean(),
|
|
255
|
-
completed: z.number(),
|
|
256
|
-
stalled_at: z.number().optional(),
|
|
257
|
-
steps: z.array(z.record(z.unknown())).optional(),
|
|
258
|
-
result: z.unknown().optional(),
|
|
259
|
-
session: z
|
|
260
|
-
.object({ lastSeenMs: z.number(), throttled: z.boolean(), focused: z.boolean() })
|
|
261
|
-
.optional(),
|
|
262
|
-
// Short-circuits to pausedShortCircuit while paused — declare its fields (drained-once guidance).
|
|
263
|
-
...pausedOutputShape,
|
|
264
|
-
},
|
|
265
|
-
handler: async (deps, args) => {
|
|
266
|
-
const session = deps.sessions.resolve(asString(args['sessionId']));
|
|
267
|
-
const paused = pausedShortCircuit(session);
|
|
268
|
-
if (paused !== undefined)
|
|
269
|
-
return paused;
|
|
270
|
-
const since = session.elapsed();
|
|
271
|
-
session.beginAction(ReticleTool.ACT_SEQUENCE, asRecord(args));
|
|
272
|
-
try {
|
|
273
|
-
const inputSteps = Array.isArray(args['steps']) ? args['steps'] : [];
|
|
274
|
-
const perStepTimeout = 'number' === typeof args['timeout_ms'] ? args['timeout_ms'] : 8000;
|
|
275
|
-
const stepResults = [];
|
|
276
|
-
let stalledAt;
|
|
277
|
-
// DIVERGENCE: live sends N individual ACT commands (for per-step timeout + progress);
|
|
278
|
-
// replay sends one batched ACT_SEQUENCE command (flows/replay.ts:294). A bug in either is
|
|
279
|
-
// invisible from the other — cover both when changing sequence semantics.
|
|
280
|
-
for (let i = 0; i < inputSteps.length; i++) {
|
|
281
|
-
const step = asRecord(inputSteps[i]);
|
|
282
|
-
try {
|
|
283
|
-
const result = await session.command(ReticleCommand.ACT, { ref: step['ref'], action: step['action'], args: step['args'] ?? {} }, perStepTimeout);
|
|
284
|
-
if (!result.ok) {
|
|
285
|
-
stalledAt = i;
|
|
286
|
-
stepResults.push({
|
|
287
|
-
ref: step['ref'],
|
|
288
|
-
action: step['action'],
|
|
289
|
-
dispatched: false,
|
|
290
|
-
error: result.error ?? 'step failed',
|
|
291
|
-
});
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
const r = asRecord(result.result);
|
|
295
|
-
const stepResult = {
|
|
296
|
-
ref: r['ref'] ?? step['ref'],
|
|
297
|
-
action: r['action'] ?? step['action'],
|
|
298
|
-
dispatched: r['dispatched'] ?? true,
|
|
299
|
-
settled: r['settled'] ?? null,
|
|
300
|
-
settleReason: r['settleReason'] ?? null,
|
|
301
|
-
};
|
|
302
|
-
if (r['testid'] !== undefined)
|
|
303
|
-
stepResult['testid'] = r['testid'];
|
|
304
|
-
if (r['component'] !== undefined)
|
|
305
|
-
stepResult['component'] = r['component'];
|
|
306
|
-
if (r['role'] !== undefined)
|
|
307
|
-
stepResult['role'] = r['role'];
|
|
308
|
-
if (r['name'] !== undefined)
|
|
309
|
-
stepResult['name'] = r['name'];
|
|
310
|
-
if (r['source'] !== undefined)
|
|
311
|
-
stepResult['source'] = r['source'];
|
|
312
|
-
if (r['warning'] !== undefined)
|
|
313
|
-
stepResult['warning'] = r['warning'];
|
|
314
|
-
stepResults.push(stepResult);
|
|
315
|
-
}
|
|
316
|
-
catch (err) {
|
|
317
|
-
stalledAt = i;
|
|
318
|
-
stepResults.push({
|
|
319
|
-
ref: step['ref'],
|
|
320
|
-
action: step['action'],
|
|
321
|
-
dispatched: null,
|
|
322
|
-
timedOut: true,
|
|
323
|
-
error: err instanceof Error ? err.message : 'step timed out',
|
|
324
|
-
});
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
const completed = stalledAt ?? inputSteps.length;
|
|
329
|
-
if (completed > 0) {
|
|
330
|
-
session.lastAct.markActed(since, undefined, undefined);
|
|
331
|
-
}
|
|
332
|
-
if (deps.recordings.active().length > 0 && stalledAt === undefined) {
|
|
333
|
-
deps.recordings.capture(compileSequenceStep(args, { count: inputSteps.length, steps: stepResults }));
|
|
334
|
-
}
|
|
335
|
-
return withControl(session, {
|
|
336
|
-
since,
|
|
337
|
-
dispatched: completed > 0,
|
|
338
|
-
completed,
|
|
339
|
-
...(stalledAt !== undefined ? { stalled_at: stalledAt } : {}),
|
|
340
|
-
steps: stepResults,
|
|
341
|
-
...healthEnvelope(session),
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
finally {
|
|
345
|
-
session.finishAction();
|
|
346
|
-
}
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
234
|
{
|
|
350
235
|
name: ReticleTool.ACT_AND_WAIT,
|
|
351
236
|
example: {
|
|
@@ -372,17 +257,17 @@ export const ACT_TOOLS = [
|
|
|
372
257
|
args: z
|
|
373
258
|
.record(z.unknown())
|
|
374
259
|
.optional()
|
|
375
|
-
.describe('Action-specific arguments: { value } for fill/select, { text } for type/press (the key NAME, e.g. Escape or Tab), { modifiers: ["Meta","Shift"] } for a press shortcut (Meta/Control/Shift/Alt), { toRef } for drag (the ref to drop ON — without it the drag lands nowhere), { confirmDangerous: true } for a potentially destructive control.'),
|
|
260
|
+
.describe('Action-specific arguments: { value } for fill/select, { text } for type/press (the key NAME, e.g. Escape or Tab), { modifiers: ["Meta","Shift"] } for a press shortcut (Meta/Control/Shift/Alt), { toRef } for drag (the ref to drop ON — without it the drag lands nowhere), { confirmDangerous: true } for a potentially destructive control. For upload: { path } is a path on disk (absolute or relative to project root; daemon reads real bytes) or { name, content?, type? } for inline bytes.'),
|
|
376
261
|
predicate: PredicateSchema.optional().describe('Alias for `until` (the name reticle_assert / reticle_wait_for use).'),
|
|
377
262
|
until: PredicateSchema.optional().describe('Predicate to wait for after the action completes (same shape as reticle_assert). OMIT to wait for the page to SETTLE — network + DOM idle — the deterministic default instead of a sleep. To assert a consequence AND settle, allOf them: { kind: "allOf", predicates: [<your predicate>, { kind: "settled" }] }.'),
|
|
378
|
-
timeout_ms:
|
|
379
|
-
.number()
|
|
263
|
+
timeout_ms: timeoutMsSchema
|
|
380
264
|
.optional()
|
|
381
265
|
.describe('Maximum wait time in milliseconds. 0 = evaluate once without waiting. Default: 4000.'),
|
|
382
266
|
refuseWhenThrottled: z
|
|
383
267
|
.boolean()
|
|
384
268
|
.optional()
|
|
385
269
|
.describe('Throw if the tab is throttled. Default: false.'),
|
|
270
|
+
intent: intentArg,
|
|
386
271
|
...sessionIdShape,
|
|
387
272
|
},
|
|
388
273
|
outputSchema: {
|
|
@@ -397,6 +282,10 @@ export const ACT_TOOLS = [
|
|
|
397
282
|
.boolean()
|
|
398
283
|
.optional()
|
|
399
284
|
.describe('The tab disconnected mid-wait, so this was never observed — the verdict is UNKNOWN, not a failure of the app.'),
|
|
285
|
+
inconclusive: z
|
|
286
|
+
.string()
|
|
287
|
+
.optional()
|
|
288
|
+
.describe('The wait could not be graded as a product failure — e.g. the tab is throttled and may never have rendered. The verdict is UNKNOWN, not "the UI is absent".'),
|
|
400
289
|
// The STRUCTURED cause — observed / expected / assertion — is what the repair literature ranks
|
|
401
290
|
// above the prose failureReason (structured feedback beat narrative by 10.5pp) and above a bare
|
|
402
291
|
// pointer. `verdict` is `await waitForPredicate(...)`, whose EvalResult carries these on a
|
|
@@ -446,6 +335,10 @@ export const ACT_TOOLS = [
|
|
|
446
335
|
since: z
|
|
447
336
|
.number()
|
|
448
337
|
.describe('Cursor for this act — pass to reticle_observe/reticle_assert for the full timeline.'),
|
|
338
|
+
sessionId: z
|
|
339
|
+
.string()
|
|
340
|
+
.optional()
|
|
341
|
+
.describe('The session that answered, when a full-document navigation replaced the one that was acted on. Absent when the original session survived.'),
|
|
449
342
|
session: z
|
|
450
343
|
.object({ lastSeenMs: z.number(), throttled: z.boolean(), focused: z.boolean() })
|
|
451
344
|
.optional(),
|
|
@@ -453,7 +346,12 @@ export const ACT_TOOLS = [
|
|
|
453
346
|
...pausedOutputShape,
|
|
454
347
|
},
|
|
455
348
|
handler: async (deps, args) => {
|
|
456
|
-
|
|
349
|
+
// Spend the caller's budget waiting for the APP too, not only for the consequence. This tool
|
|
350
|
+
// is the one an agent reaches for straight after `init` and a dev-server restart, which is
|
|
351
|
+
// exactly when there is no session yet and one is seconds away. See resolve-within.
|
|
352
|
+
let session = await resolveSessionWithin(deps.sessions, asString(args['sessionId']), asNumber(args['timeout_ms']) ?? DEFAULT_ASSERT_TIMEOUT_MS, WALL_CLOCK);
|
|
353
|
+
const acted = session;
|
|
354
|
+
const actedSessionId = session.id;
|
|
457
355
|
// Live-control: refuse to drive the page (no act, no predicate eval) while paused.
|
|
458
356
|
//
|
|
459
357
|
// A VERDICT rides out with the refusal. This is the one tool here that promises `verified`,
|
|
@@ -472,20 +370,28 @@ export const ACT_TOOLS = [
|
|
|
472
370
|
? parsePredicate(withUntil['until'])
|
|
473
371
|
: { kind: PredicateKind.SETTLED };
|
|
474
372
|
const timeout = asNumber(args['timeout_ms']) ?? DEFAULT_ASSERT_TIMEOUT_MS;
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
|
|
373
|
+
// An intent declared here lands in the ledger BEFORE the verdict is drawn, which is what makes
|
|
374
|
+
// the undeclared-change gap silent on THIS verdict rather than the next one: it reads the
|
|
375
|
+
// ledger below and finds something open. The discharge comes after that read.
|
|
376
|
+
const intentId = await linkInlineIntent(deps, asString(args['sessionId']), asString(args['intent']), PredicateKind.SETTLED === until.kind ? undefined : until);
|
|
377
|
+
// Everything refusable without touching the page — see act-preflight.ts.
|
|
378
|
+
preflightAct(asRecord(args['args']), until);
|
|
478
379
|
// Resolve `target` to a ref BEFORE the action window opens, so the lookup is not attributed to
|
|
479
380
|
// the act and cannot be mistaken for something the action caused.
|
|
480
381
|
const resolved = await resolveActTarget(session, args);
|
|
481
382
|
if ('error' === resolved.kind)
|
|
482
383
|
throw new Error(resolved.message);
|
|
483
|
-
|
|
384
|
+
let since = session.elapsed();
|
|
385
|
+
const actedSince = since;
|
|
484
386
|
// The cursor + effect are marked after the act dispatches (below) — a refused act leaves none.
|
|
485
387
|
// The attribution window stays open across the settle wait below, so post-dispatch async events
|
|
486
388
|
// (the whole point of act_and_wait) attribute to this action. finishAction fires after the wait.
|
|
487
389
|
session.beginAction(ReticleTool.ACT_AND_WAIT, asRecord(args));
|
|
488
390
|
let settledOutcome;
|
|
391
|
+
// The verdict, written into the action record so a LATER turn can read what this one proved.
|
|
392
|
+
// A verdict that lives only in the response lives only in the agent's context window, which is
|
|
393
|
+
// exactly the copy a compaction destroys — see runs/run-context.ts.
|
|
394
|
+
let verdictEffect;
|
|
489
395
|
// Was the declared consequence ALREADY TRUE? Only asked for predicates that read live DOM
|
|
490
396
|
// state — event-based ones are floored at this act's cursor and cannot be satisfied by the
|
|
491
397
|
// past, so they need no pre-check and pay nothing. One extra query, on the path where a green
|
|
@@ -494,22 +400,48 @@ export const ACT_TOOLS = [
|
|
|
494
400
|
? (await evaluatePredicate(session, until, since, false)).pass
|
|
495
401
|
: false;
|
|
496
402
|
try {
|
|
497
|
-
|
|
403
|
+
// actCommand is the single interception point for upload+path rewrite.
|
|
404
|
+
//
|
|
405
|
+
// A replacement can land BETWEEN resolving the target and dispatching, and the tool used to
|
|
406
|
+
// throw that transport fact at the agent verbatim: no verdict at all, from the layer whose
|
|
407
|
+
// whole job is to answer in verdicts, worded as though the app were at fault. `dispatchAct`
|
|
408
|
+
// returns null instead (see act-preflight.ts for why a write is never re-sent), and the
|
|
409
|
+
// successor block below then asks whether the consequence held on the NEW document — a
|
|
410
|
+
// green if it did, an honest observation_lost if it did not.
|
|
411
|
+
const actResult = await dispatchAct(() => actCommand(deps, session, {
|
|
498
412
|
ref: resolved.ref,
|
|
499
413
|
action: args['action'],
|
|
500
414
|
args: args['args'] ?? {},
|
|
501
|
-
});
|
|
502
|
-
if (
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
415
|
+
}));
|
|
416
|
+
if (actResult !== null) {
|
|
417
|
+
if (!actResult.ok)
|
|
418
|
+
throw new Error(actResult.error ?? 'act failed');
|
|
419
|
+
captureAct(deps.recordings, args, actResult.result);
|
|
420
|
+
// Dispatched — now this act owns the cursor and the effect. Marking its OWN measurement
|
|
421
|
+
// also stops the spread below from inheriting an earlier reticle_act's action and
|
|
422
|
+
// mutation count.
|
|
423
|
+
session.lastAct.markActed(since, asString(args['action']), mutatedWithin(asRecord(actResult.result)), asString(args['ref']));
|
|
424
|
+
}
|
|
508
425
|
// Honesty: floor the predicate at this act's cursor so a stale buffered event can't satisfy it.
|
|
509
426
|
const predicateStarted = session.elapsed();
|
|
510
|
-
|
|
511
|
-
?
|
|
512
|
-
:
|
|
427
|
+
let verdict = null === actResult
|
|
428
|
+
? { pass: false, observationLost: true }
|
|
429
|
+
: timeout > 0
|
|
430
|
+
? await waitForPredicate(session, until, timeout, since)
|
|
431
|
+
: await evaluatePredicate(session, until, since);
|
|
432
|
+
// The SDK may have gone away mid-act — see act-observation.ts.
|
|
433
|
+
const followed = await followLostObservation({
|
|
434
|
+
sessions: deps.sessions,
|
|
435
|
+
session,
|
|
436
|
+
verdict,
|
|
437
|
+
timeout,
|
|
438
|
+
predicateStarted,
|
|
439
|
+
reevaluate: (next, budget) => waitForPredicate(next, until, budget, 0),
|
|
440
|
+
});
|
|
441
|
+
if (followed.followed)
|
|
442
|
+
since = 0;
|
|
443
|
+
session = followed.session;
|
|
444
|
+
verdict = followed.verdict;
|
|
513
445
|
// The predicate resolves the INSTANT it holds, which on an optimistically-navigating app is
|
|
514
446
|
// while the write is still in flight — so the verdict was taken over a window the app had not
|
|
515
447
|
// finished, and came back `unknown / unsettled` asking the CALLER to re-check. A login that
|
|
@@ -539,7 +471,7 @@ export const ACT_TOOLS = [
|
|
|
539
471
|
// moved after it — and short enough that a genuinely dropped response is still reported.
|
|
540
472
|
await waitForReaction(session, since, spent(), sleep);
|
|
541
473
|
}
|
|
542
|
-
const r = asRecord(actResult
|
|
474
|
+
const r = asRecord(actResult?.result);
|
|
543
475
|
if ('boolean' === typeof r['settled'])
|
|
544
476
|
settledOutcome = r['settled'];
|
|
545
477
|
// Where the acted element is written. Captured at act time alongside the anchor, so it is
|
|
@@ -547,7 +479,8 @@ export const ACT_TOOLS = [
|
|
|
547
479
|
const actedSource = sourceOf(r['source']);
|
|
548
480
|
// Remembered on the session so a LATER assertion can name a file even when its failure has no
|
|
549
481
|
// element to point at — a signal that never fired, a request that was never made.
|
|
550
|
-
|
|
482
|
+
const actedSourceLabel = actedSource === undefined ? undefined : `${actedSource.file}:${String(actedSource.line)}`;
|
|
483
|
+
session.lastAct.markSource(actedSourceLabel);
|
|
551
484
|
const windowEvents = session.eventsSince(since);
|
|
552
485
|
const trace = summarizeReaction(buildReactionReport(windowEvents, session.elapsed() - since));
|
|
553
486
|
// The bounded Tier-1 causal summary — net/console/state/storage diffs the trace's counts miss.
|
|
@@ -565,8 +498,9 @@ export const ACT_TOOLS = [
|
|
|
565
498
|
// stronger than this block. Grade from the strongest asserted consequence; integrity from evictions.
|
|
566
499
|
// Coverage: cross-origin frames / other blind spots the SDK reported during this window mean the
|
|
567
500
|
// verdict didn't see everything — say so, never imply full coverage.
|
|
568
|
-
const spots = blindSpotsFromState(session.blindSpots());
|
|
501
|
+
const spots = blindSpotsFromState(session.blindSpots(), session.runtime);
|
|
569
502
|
const coverage = buildCoverageStatement(spots);
|
|
503
|
+
const absenceBlindSpot = absenceBlindSpotNote(until, spots);
|
|
570
504
|
// Nothing subscribed ⇒ the state channel is dark, and the summary must say so rather than
|
|
571
505
|
// report an empty diff list that reads like a fact about the app. See CausalSummary.
|
|
572
506
|
const stateUnwatched = isStateUnwatched(spots);
|
|
@@ -590,8 +524,11 @@ export const ACT_TOOLS = [
|
|
|
590
524
|
...(gapNote === undefined ? [] : [CaptureLoss.TRANSPORT_GAP]),
|
|
591
525
|
...(impeaching.note === undefined ? [] : [CaptureLoss.BLIND_SPOT]),
|
|
592
526
|
];
|
|
527
|
+
// Named because the discharge below records the same grade the verdict reports, rather than a
|
|
528
|
+
// second reading of the same evidence that could drift from it.
|
|
529
|
+
const grade = gradeOf(gradedLinks);
|
|
593
530
|
const honesty = buildHonestyBlock({
|
|
594
|
-
grade
|
|
531
|
+
grade,
|
|
595
532
|
attribution: 'window',
|
|
596
533
|
// Did the buffer lose scarce evidence FROM THIS WINDOW — not "did it evict anything while
|
|
597
534
|
// the action ran", which was the previous rule and which is true on essentially every live
|
|
@@ -601,6 +538,7 @@ export const ACT_TOOLS = [
|
|
|
601
538
|
// evictions that happened outside the window they impeached.
|
|
602
539
|
truncated: bufferLost,
|
|
603
540
|
coveragePartial: Coverage.PARTIAL === coverage.coverage,
|
|
541
|
+
...(coverage.note === undefined ? {} : { coverageNote: coverage.note }),
|
|
604
542
|
// Settlement no longer vetoes a declared consequence that held, so the fact is carried
|
|
605
543
|
// here instead of only in the verdict it used to decide. Omitted when never measured.
|
|
606
544
|
...(settledOutcome === undefined ? {} : { settled: settledOutcome }),
|
|
@@ -613,7 +551,11 @@ export const ACT_TOOLS = [
|
|
|
613
551
|
capsule,
|
|
614
552
|
links,
|
|
615
553
|
args,
|
|
616
|
-
|
|
554
|
+
// The session actually driven — after any navigation follow — so the capsule is filed
|
|
555
|
+
// against the codebase that produced the failure, not wherever the daemon stands.
|
|
556
|
+
root: session.artifactRoot,
|
|
557
|
+
// No dispatch result to capture when the transport was displaced mid-write.
|
|
558
|
+
actResult: actResult ?? {},
|
|
617
559
|
...(actedSource === undefined ? {} : { actedSource }),
|
|
618
560
|
});
|
|
619
561
|
// Pass the action: an EMPTY window then reads as "the target does not react" rather than as a
|
|
@@ -644,6 +586,9 @@ export const ACT_TOOLS = [
|
|
|
644
586
|
// not evidence the destination rendered either — `alreadyTrue` decides that, once.
|
|
645
587
|
renderProved: verdict.pass && !alreadyTrue && declared.rendersContent,
|
|
646
588
|
...session.lastAct.effect(),
|
|
589
|
+
currentDocumentId: session.currentDocumentId,
|
|
590
|
+
currentEditEpoch: session.currentEditEpoch,
|
|
591
|
+
appOrigin: session.url,
|
|
647
592
|
});
|
|
648
593
|
// The single field an agent reads. Everything below it is the evidence it was derived from;
|
|
649
594
|
// this is the only one that has to be interpreted, and now it interprets itself.
|
|
@@ -656,6 +601,9 @@ export const ACT_TOOLS = [
|
|
|
656
601
|
// overriding it — see `declaredConsequence`. An explicit `{ kind: "settled" }` is not a
|
|
657
602
|
// declaration about the app's behaviour, it IS the idle wait, so it does not count.
|
|
658
603
|
declaredConsequence: until.kind !== PredicateKind.SETTLED,
|
|
604
|
+
// A body-independent declaration that held is a channel the unread payload does not own.
|
|
605
|
+
// Omit when false: a net-only `until` must still hit `outcome_unread`.
|
|
606
|
+
...(declaresBodyIndependentChannel(until) ? { independentOfBody: true } : {}),
|
|
659
607
|
...(alreadyTrue ? { alreadyTrue } : {}),
|
|
660
608
|
// An assertion nobody could evaluate must not be reported as one the app failed.
|
|
661
609
|
...(verdict.inconclusive === undefined ? {} : { inconclusive: verdict.inconclusive }),
|
|
@@ -663,6 +611,7 @@ export const ACT_TOOLS = [
|
|
|
663
611
|
// the measured false red: a reload mid-wait, graded assertion_failed at the clicked
|
|
664
612
|
// component's own file and line.
|
|
665
613
|
...(true === verdict.observationLost ? { observationLost: true } : {}),
|
|
614
|
+
...(absenceBlindSpot === undefined ? {} : { absenceBlindSpot }),
|
|
666
615
|
honesty,
|
|
667
616
|
contradictions,
|
|
668
617
|
...(outcomePending ? { outcomePending } : {}),
|
|
@@ -683,32 +632,72 @@ export const ACT_TOOLS = [
|
|
|
683
632
|
// Computed once: the verdict block reports it, and the instrumentation gaps are a second
|
|
684
633
|
// reading of the same evidence rather than a new observation.
|
|
685
634
|
const actionSummary = causalSummary(windowEvents, { stateUnwatched });
|
|
635
|
+
// Asked of every verdict drawn after an observed edit, not once per edit — see
|
|
636
|
+
// isChangeUndeclared for why repeating it is disclosure rather than nagging.
|
|
637
|
+
// Read ONCE and used twice: `changeUndeclared` asks whether the ledger is empty, and the
|
|
638
|
+
// undischarged-intent gap asks how much it still holds. Two reads would be two chances for
|
|
639
|
+
// them to disagree about the same file.
|
|
640
|
+
const openIntents = await openSessionIntents(deps, asString(args['sessionId']));
|
|
641
|
+
const changeUndeclared = await isChangeUndeclared(session.currentEditEpoch, () => Promise.resolve(openIntents));
|
|
686
642
|
const gaps = gapsForAction({
|
|
687
643
|
pass: verdict.pass,
|
|
688
644
|
proved: decision.verifiedReason === VerifiedReason.PROVED,
|
|
689
|
-
|
|
645
|
+
changeUndeclared,
|
|
646
|
+
source: actedSourceLabel,
|
|
690
647
|
ref: asString(args['ref']),
|
|
691
648
|
stateAsked: declaresState(until),
|
|
692
649
|
stateUnwatched,
|
|
650
|
+
// What the app DECLARED, so an under-instrumented one is told without having to be asked.
|
|
651
|
+
hasCapabilities: session.hasCapabilities,
|
|
652
|
+
// What the run still owes. A green that leaves this above zero is not the same as done.
|
|
653
|
+
// MINUS the one this verdict is about to discharge.
|
|
654
|
+
//
|
|
655
|
+
// The discharge happens below, after the gaps are built, so a straight `openIntents.length`
|
|
656
|
+
// counts the intent this very call proves. Measured live on the first drive: an inline
|
|
657
|
+
// intent was declared, asserted and PROVED by the same verdict, and the result still said
|
|
658
|
+
// "1 declared intent(s) are still unproved" while the ledger recorded it `proved`. A gap
|
|
659
|
+
// that fires on the one path doing everything right is noise, and noise is what gets
|
|
660
|
+
// filtered out — taking the honest gaps with it.
|
|
661
|
+
...intentDebt(openIntents, intentId !== undefined && Verified.YES === decision.verified ? intentId : undefined, deps.now()),
|
|
693
662
|
domMutated: (session.lastAct.effect().mutatedWithin ?? 0) > 0,
|
|
694
663
|
signalsFired: actionSummary.signals.length,
|
|
695
664
|
routeChanged: actionSummary.route !== undefined,
|
|
696
665
|
routeSignalFired: actionSummary.signals.some((name) => name.startsWith('route')),
|
|
697
666
|
});
|
|
667
|
+
// The verdict IS the proof attempt, so a green one discharges the intent it was drawn for.
|
|
668
|
+
// Only a green: a red proved nothing, and `dischargeIntent` refuses an unbound intent anyway,
|
|
669
|
+
// so a bare settle leaves it open rather than collecting a proof nothing earned. The id is
|
|
670
|
+
// checked here rather than only inside the helper so a caller that declared no intent touches
|
|
671
|
+
// nothing at all, not even the clock.
|
|
672
|
+
if (intentId !== undefined && Verified.YES === decision.verified) {
|
|
673
|
+
await dischargeInlineIntent(deps, asString(args['sessionId']), intentId, {
|
|
674
|
+
verdictId: inlineVerdictId(ReticleTool.ACT_AND_WAIT, deps.now()),
|
|
675
|
+
grade,
|
|
676
|
+
at: deps.now(),
|
|
677
|
+
},
|
|
678
|
+
// Where the acted element is written, so the record can name a file somebody would open
|
|
679
|
+
// to change the thing it describes.
|
|
680
|
+
actedSourceLabel);
|
|
681
|
+
}
|
|
682
|
+
verdictEffect = {
|
|
683
|
+
claim: describeWaitTarget(until),
|
|
684
|
+
verified: decision.verified,
|
|
685
|
+
...(actedSourceLabel === undefined ? {} : { source: actedSourceLabel }),
|
|
686
|
+
};
|
|
698
687
|
// Recorded on the session, so a later "am I done?" can answer with what is STILL missing
|
|
699
688
|
// rather than with everything that was ever missing. An empty list closes a gap, which is
|
|
700
689
|
// why it is noted rather than skipped.
|
|
701
690
|
noteSessionGaps(session, gaps);
|
|
702
691
|
return withControl(session, {
|
|
703
692
|
...decision,
|
|
704
|
-
effect
|
|
693
|
+
// An unobserved act has no effect to report, and inventing an empty one would read as
|
|
694
|
+
// "the page did nothing" — a claim about the app, from a call that never saw it.
|
|
695
|
+
...(null === actResult ? {} : { effect: leanActResult(actResult.result) }),
|
|
705
696
|
verdict,
|
|
706
697
|
// Promoted out of `effect` on red only. On green nobody needs it and it is noise; on red it
|
|
707
698
|
// is the first thing the agent wants, and burying a file:line inside the effect block is
|
|
708
699
|
// most of the way to not reporting it at all.
|
|
709
|
-
...(verdict.pass ||
|
|
710
|
-
? {}
|
|
711
|
-
: { source: `${actedSource.file}:${String(actedSource.line)}` }),
|
|
700
|
+
...(verdict.pass || actedSourceLabel === undefined ? {} : { source: actedSourceLabel }),
|
|
712
701
|
trace,
|
|
713
702
|
...(capsuleSaved === undefined ? {} : { capsuleSaved }),
|
|
714
703
|
// The window cannot say whether anything was WATCHING state — that is a level fact the
|
|
@@ -727,15 +716,18 @@ export const ACT_TOOLS = [
|
|
|
727
716
|
// agent cannot miss it by not asking. Omitted entirely when clean, so a healthy action
|
|
728
717
|
// pays nothing.
|
|
729
718
|
...(contradictions.length > 0 ? { contradictions } : {}),
|
|
730
|
-
honesty,
|
|
719
|
+
honesty: honestyForVerdict(String(decision.verified), honesty),
|
|
731
720
|
...(capsule === undefined ? {} : { capsule }),
|
|
732
721
|
since,
|
|
722
|
+
...(session.id === actedSessionId ? {} : { sessionId: session.id }),
|
|
733
723
|
...healthEnvelope(session),
|
|
734
724
|
});
|
|
735
725
|
}
|
|
736
726
|
finally {
|
|
737
|
-
|
|
727
|
+
acted.finishAction(verdictEffect, settledOutcome, true === settledOutcome ? acted.elapsed() - actedSince : undefined);
|
|
738
728
|
}
|
|
739
729
|
},
|
|
740
730
|
},
|
|
731
|
+
// Split into its own module for size; still shipped as one of the acting tools.
|
|
732
|
+
ACT_SEQUENCE_TOOL,
|
|
741
733
|
];
|