@reticlehq/server 2.2.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bridge-security.d.ts +0 -1
- package/dist/bridge-security.js +0 -1
- package/dist/bridge.d.ts +0 -1
- package/dist/bridge.js +102 -12
- package/dist/bridge.test-harness.d.ts +5 -1
- package/dist/bridge.test-harness.js +12 -1
- package/dist/capsule/capsule-store.d.ts +2 -3
- package/dist/capsule/capsule-store.js +0 -1
- package/dist/capsule/capsule.d.ts +0 -1
- package/dist/capsule/capsule.js +0 -1
- package/dist/capsule/causal-summary.d.ts +21 -1
- package/dist/capsule/causal-summary.js +20 -2
- package/dist/capsule/divergence.d.ts +0 -1
- package/dist/capsule/divergence.js +0 -1
- package/dist/capsule/minimize.d.ts +0 -1
- package/dist/capsule/minimize.js +0 -1
- package/dist/capsule/predicate-to-links.d.ts +0 -1
- package/dist/capsule/predicate-to-links.js +0 -1
- package/dist/cli-doctor.d.ts +6 -0
- package/dist/cli-doctor.js +60 -0
- package/dist/cli-flow-commands.d.ts +0 -1
- package/dist/cli-flow-commands.js +0 -1
- package/dist/cli-launch.d.ts +0 -1
- package/dist/cli-launch.js +7 -3
- package/dist/cli-parse.d.ts +47 -3
- package/dist/cli-parse.js +147 -13
- package/dist/cli-port.d.ts +3 -1
- package/dist/cli-port.js +21 -1
- package/dist/cli-verify.d.ts +0 -1
- package/dist/cli-verify.js +1 -2
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +88 -69
- package/dist/cloud/cloud-config.d.ts +0 -1
- package/dist/cloud/cloud-config.js +0 -1
- package/dist/cloud/cloud-sync.d.ts +4 -5
- package/dist/cloud/cloud-sync.js +0 -1
- package/dist/cloud-cli.d.ts +0 -1
- package/dist/cloud-cli.js +9 -2
- package/dist/crawl/crawl-tools.d.ts +0 -1
- package/dist/crawl/crawl-tools.js +1 -2
- package/dist/crawl/crawl.d.ts +17 -3
- package/dist/crawl/crawl.js +43 -4
- package/dist/daemon-resilience.d.ts +6 -1
- package/dist/daemon-resilience.js +63 -1
- package/dist/daemon.d.ts +23 -3
- package/dist/daemon.js +36 -24
- package/dist/domain/domain-model.d.ts +0 -1
- package/dist/domain/domain-model.js +1 -2
- package/dist/domain/domain-tools.d.ts +0 -7
- package/dist/domain/domain-tools.js +21 -4
- package/dist/domain/flow-risk.d.ts +0 -1
- package/dist/domain/flow-risk.js +0 -1
- package/dist/ee/audit-log.d.ts +0 -1
- package/dist/ee/audit-log.js +0 -1
- package/dist/events/body-failures.d.ts +4 -0
- package/dist/events/body-failures.js +113 -0
- package/dist/events/contradictions.d.ts +53 -0
- package/dist/events/contradictions.js +282 -0
- package/dist/events/echo-mismatch.d.ts +4 -0
- package/dist/events/echo-mismatch.js +138 -0
- package/dist/events/event-filters.d.ts +17 -3
- package/dist/events/event-filters.js +13 -3
- package/dist/events/json-salvage.d.ts +32 -0
- package/dist/events/json-salvage.js +96 -0
- package/dist/events/predicate-eval.d.ts +2 -1
- package/dist/events/predicate-eval.js +56 -9
- package/dist/events/predicate.d.ts +0 -1
- package/dist/events/predicate.js +56 -2
- package/dist/events/reaction.d.ts +0 -1
- package/dist/events/reaction.js +0 -1
- package/dist/events/reconcile.d.ts +39 -0
- package/dist/events/reconcile.js +211 -0
- package/dist/events/ring-buffer.d.ts +0 -1
- package/dist/events/ring-buffer.js +0 -1
- package/dist/events/stale-response.d.ts +4 -0
- package/dist/events/stale-response.js +139 -0
- package/dist/events/unit-mismatch.d.ts +16 -0
- package/dist/events/unit-mismatch.js +167 -0
- package/dist/flows/affected-tools.d.ts +18 -0
- package/dist/flows/affected-tools.js +52 -0
- package/dist/flows/affected.d.ts +0 -1
- package/dist/flows/affected.js +0 -1
- package/dist/flows/annotate-tools.d.ts +0 -1
- package/dist/flows/annotate-tools.js +21 -3
- package/dist/flows/annotate.d.ts +0 -1
- package/dist/flows/annotate.js +0 -1
- package/dist/flows/annotation-store.d.ts +0 -1
- package/dist/flows/annotation-store.js +0 -1
- package/dist/flows/assertion-integrity.d.ts +0 -1
- package/dist/flows/assertion-integrity.js +0 -1
- package/dist/flows/assertion-tiers-store.d.ts +0 -1
- package/dist/flows/assertion-tiers-store.js +0 -1
- package/dist/flows/buddy-status.d.ts +0 -1
- package/dist/flows/buddy-status.js +0 -1
- package/dist/flows/coverage.d.ts +0 -1
- package/dist/flows/coverage.js +0 -1
- package/dist/flows/decision.d.ts +0 -7
- package/dist/flows/decision.js +47 -7
- package/dist/flows/flake-store.d.ts +0 -1
- package/dist/flows/flake-store.js +0 -1
- package/dist/flows/flake.d.ts +0 -1
- package/dist/flows/flake.js +0 -1
- package/dist/flows/flow-classify.d.ts +0 -1
- package/dist/flows/flow-classify.js +0 -1
- package/dist/flows/flow-replay-run.d.ts +0 -1
- package/dist/flows/flow-replay-run.js +2 -3
- package/dist/flows/flow-replay.d.ts +20 -4
- package/dist/flows/flow-replay.js +9 -43
- package/dist/flows/flow-report.d.ts +0 -1
- package/dist/flows/flow-report.js +0 -1
- package/dist/flows/flow-scope.d.ts +0 -1
- package/dist/flows/flow-scope.js +0 -1
- package/dist/flows/flow-sources.d.ts +0 -1
- package/dist/flows/flow-sources.js +0 -1
- package/dist/flows/flow-step-runners.d.ts +23 -0
- package/dist/flows/flow-step-runners.js +102 -0
- package/dist/flows/flow-success.d.ts +0 -1
- package/dist/flows/flow-success.js +0 -1
- package/dist/flows/flow-tools.d.ts +0 -1
- package/dist/flows/flow-tools.js +44 -14
- package/dist/flows/flows.d.ts +6 -2
- package/dist/flows/flows.js +15 -2
- package/dist/flows/gate.d.ts +0 -1
- package/dist/flows/gate.js +0 -1
- package/dist/flows/git-changed.d.ts +0 -1
- package/dist/flows/git-changed.js +0 -1
- package/dist/flows/heal-run.d.ts +0 -1
- package/dist/flows/heal-run.js +0 -1
- package/dist/flows/heal.d.ts +0 -1
- package/dist/flows/heal.js +0 -1
- package/dist/flows/parallel-suite.d.ts +0 -1
- package/dist/flows/parallel-suite.js +0 -1
- package/dist/flows/recordings.d.ts +0 -1
- package/dist/flows/recordings.js +0 -1
- package/dist/flows/replay.d.ts +0 -1
- package/dist/flows/replay.js +71 -4
- package/dist/flows/server-verify.d.ts +0 -1
- package/dist/flows/server-verify.js +0 -1
- package/dist/flows/verify-change-tools.d.ts +2 -0
- package/dist/flows/verify-change-tools.js +187 -0
- package/dist/flows/watch-batcher.d.ts +0 -1
- package/dist/flows/watch-batcher.js +0 -1
- package/dist/honesty/accepted-write.d.ts +14 -0
- package/dist/honesty/accepted-write.js +17 -0
- package/dist/honesty/blind-spots.d.ts +18 -1
- package/dist/honesty/blind-spots.js +47 -5
- package/dist/honesty/honesty.d.ts +0 -1
- package/dist/honesty/honesty.js +0 -1
- package/dist/honesty/uncaptured-bodies.d.ts +19 -0
- package/dist/honesty/uncaptured-bodies.js +30 -0
- package/dist/honesty/unread-outcome.d.ts +2 -0
- package/dist/honesty/unread-outcome.js +50 -0
- package/dist/honesty/verified.d.ts +40 -0
- package/dist/honesty/verified.js +86 -0
- package/dist/http-server.d.ts +0 -1
- package/dist/http-server.js +5 -1
- package/dist/hunt/hunt-report.d.ts +50 -0
- package/dist/hunt/hunt-report.js +84 -0
- package/dist/idle-shutdown.d.ts +0 -1
- package/dist/idle-shutdown.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/init/agent-rules.d.ts +0 -1
- package/dist/init/agent-rules.js +4 -2
- package/dist/init/capabilities.d.ts +17 -0
- package/dist/init/capabilities.js +51 -0
- package/dist/init/cursor.d.ts +0 -1
- package/dist/init/cursor.js +0 -1
- package/dist/init/desktop-doctor.d.ts +40 -0
- package/dist/init/desktop-doctor.js +198 -0
- package/dist/init/detect.d.ts +25 -1
- package/dist/init/detect.js +65 -4
- package/dist/init/mcp.d.ts +0 -1
- package/dist/init/mcp.js +0 -1
- package/dist/init/next-patch.d.ts +41 -0
- package/dist/init/next-patch.js +106 -0
- package/dist/init/node-io.d.ts +0 -1
- package/dist/init/node-io.js +25 -1
- package/dist/init/patch-kind.d.ts +20 -0
- package/dist/init/patch-kind.js +10 -0
- package/dist/init/plan-framework.d.ts +35 -0
- package/dist/init/plan-framework.js +217 -0
- package/dist/init/plan.d.ts +55 -4
- package/dist/init/plan.js +130 -112
- package/dist/init/project-id.d.ts +0 -1
- package/dist/init/project-id.js +0 -1
- package/dist/init/run.d.ts +17 -1
- package/dist/init/run.js +237 -18
- package/dist/init/slash-command.d.ts +18 -0
- package/dist/init/slash-command.js +52 -0
- package/dist/init/snippets.d.ts +48 -3
- package/dist/init/snippets.js +156 -6
- package/dist/init/vite-config.d.ts +4 -11
- package/dist/init/vite-config.js +15 -8
- package/dist/input/driven-redaction.d.ts +15 -0
- package/dist/input/driven-redaction.js +76 -0
- package/dist/input/network-detail.d.ts +9 -4
- package/dist/input/network-detail.js +35 -16
- package/dist/input/network-mock-tools.d.ts +0 -1
- package/dist/input/network-mock-tools.js +3 -4
- package/dist/input/network-mock.d.ts +0 -1
- package/dist/input/network-mock.js +0 -1
- package/dist/input/real-input.d.ts +14 -1
- package/dist/input/real-input.js +45 -3
- package/dist/input/scroll-find.d.ts +0 -1
- package/dist/input/scroll-find.js +0 -1
- package/dist/input/scroll-tools.d.ts +0 -1
- package/dist/input/scroll-tools.js +0 -1
- package/dist/input/viewport-tools.d.ts +0 -1
- package/dist/input/viewport-tools.js +3 -4
- package/dist/journal/ambient-store.d.ts +0 -1
- package/dist/journal/ambient-store.js +0 -1
- package/dist/journal/ambient.d.ts +0 -1
- package/dist/journal/ambient.js +0 -1
- package/dist/journal/attach-journal.d.ts +0 -1
- package/dist/journal/attach-journal.js +0 -1
- package/dist/journal/deviation-report.d.ts +0 -1
- package/dist/journal/deviation-report.js +0 -1
- package/dist/journal/deviation-service.d.ts +0 -1
- package/dist/journal/deviation-service.js +0 -1
- package/dist/journal/envelope-store.d.ts +0 -1
- package/dist/journal/envelope-store.js +0 -1
- package/dist/journal/envelope.d.ts +8 -9
- package/dist/journal/envelope.js +0 -1
- package/dist/journal/journal-query.d.ts +0 -1
- package/dist/journal/journal-query.js +0 -1
- package/dist/journal/journal-recorder.d.ts +0 -1
- package/dist/journal/journal-recorder.js +0 -1
- package/dist/journal/retention.d.ts +0 -1
- package/dist/journal/retention.js +0 -1
- package/dist/journal/rollups.d.ts +0 -1
- package/dist/journal/rollups.js +0 -1
- package/dist/journal/session-end.d.ts +0 -1
- package/dist/journal/session-end.js +0 -1
- package/dist/journal/session-journal.d.ts +0 -1
- package/dist/journal/session-journal.js +0 -1
- package/dist/license/license.d.ts +0 -1
- package/dist/license/license.js +0 -1
- package/dist/log.d.ts +0 -1
- package/dist/log.js +0 -1
- package/dist/mcp-proxy.d.ts +35 -4
- package/dist/mcp-proxy.js +174 -28
- package/dist/mcp.d.ts +15 -1
- package/dist/mcp.js +145 -17
- package/dist/oracles/flow-instrument-gaps.d.ts +0 -1
- package/dist/oracles/flow-instrument-gaps.js +0 -1
- package/dist/oracles/propose-consequences.d.ts +0 -1
- package/dist/oracles/propose-consequences.js +0 -1
- package/dist/oracles/self-instrument.d.ts +0 -1
- package/dist/oracles/self-instrument.js +0 -1
- package/dist/pairing-token.d.ts +0 -1
- package/dist/pairing-token.js +0 -1
- package/dist/phenomena/phenomena.d.ts +0 -1
- package/dist/phenomena/phenomena.js +0 -1
- package/dist/pool/browser-pool.d.ts +0 -1
- package/dist/pool/browser-pool.js +0 -1
- package/dist/pool/lease-reaper.d.ts +0 -1
- package/dist/pool/lease-reaper.js +0 -1
- package/dist/pool/playwright-launcher.d.ts +0 -1
- package/dist/pool/playwright-launcher.js +10 -2
- package/dist/project/baselines.d.ts +0 -1
- package/dist/project/baselines.js +0 -1
- package/dist/project/file-lock.d.ts +2 -1
- package/dist/project/file-lock.js +12 -2
- package/dist/project/fs-port.d.ts +0 -1
- package/dist/project/fs-port.js +0 -1
- package/dist/project/project-store.d.ts +0 -1
- package/dist/project/project-store.js +0 -1
- package/dist/project/project-tools.d.ts +0 -1
- package/dist/project/project-tools.js +29 -4
- package/dist/project/reticle-dir.d.ts +0 -1
- package/dist/project/reticle-dir.js +0 -1
- package/dist/runs/build-verification-run.d.ts +0 -1
- package/dist/runs/build-verification-run.js +0 -1
- package/dist/runs/profile-redact.d.ts +0 -1
- package/dist/runs/profile-redact.js +0 -1
- package/dist/runs/render-report.d.ts +0 -1
- package/dist/runs/render-report.js +0 -1
- package/dist/runs/repair-prompt.d.ts +0 -1
- package/dist/runs/repair-prompt.js +0 -1
- package/dist/runs/replay-mapping.d.ts +0 -1
- package/dist/runs/replay-mapping.js +0 -1
- package/dist/runs/reticle-runner.d.ts +0 -1
- package/dist/runs/reticle-runner.js +4 -2
- package/dist/runs/risk-classify.d.ts +0 -1
- package/dist/runs/risk-classify.js +0 -1
- package/dist/runs/run-diff.d.ts +0 -1
- package/dist/runs/run-diff.js +0 -1
- package/dist/runs/run-store.d.ts +0 -1
- package/dist/runs/run-store.js +0 -1
- package/dist/runs/run-tools.d.ts +0 -1
- package/dist/runs/run-tools.js +0 -1
- package/dist/runs/runner-port.d.ts +0 -1
- package/dist/runs/runner-port.js +0 -1
- package/dist/runs/verification-sync.d.ts +0 -1
- package/dist/runs/verification-sync.js +0 -1
- package/dist/runs/verify-http.d.ts +0 -1
- package/dist/runs/verify-http.js +0 -1
- package/dist/runs/verify-server.d.ts +0 -1
- package/dist/runs/verify-server.js +0 -1
- package/dist/server-version.d.ts +0 -1
- package/dist/server-version.js +0 -1
- package/dist/session/command-timeout.d.ts +35 -0
- package/dist/session/command-timeout.js +41 -0
- package/dist/session/control-envelope.d.ts +2 -3
- package/dist/session/control-envelope.js +2 -3
- package/dist/session/last-act.d.ts +31 -0
- package/dist/session/last-act.js +24 -0
- package/dist/session/live-control-tools.d.ts +0 -1
- package/dist/session/live-control-tools.js +3 -4
- package/dist/session/live-control.d.ts +0 -1
- package/dist/session/live-control.js +0 -1
- package/dist/session/observed-state.d.ts +12 -2
- package/dist/session/observed-state.js +29 -2
- package/dist/session/output-budget.d.ts +0 -1
- package/dist/session/output-budget.js +0 -1
- package/dist/session/pending-commands.d.ts +12 -0
- package/dist/session/pending-commands.js +36 -0
- package/dist/session/presenter-args.d.ts +0 -1
- package/dist/session/presenter-args.js +0 -1
- package/dist/session/review-store.d.ts +0 -1
- package/dist/session/review-store.js +0 -1
- package/dist/session/session-health.d.ts +26 -2
- package/dist/session/session-health.js +13 -1
- package/dist/session/session-info.d.ts +29 -0
- package/dist/session/session-info.js +1 -0
- package/dist/session/session-lease.d.ts +25 -0
- package/dist/session/session-lease.js +14 -0
- package/dist/session/session-manager.d.ts +7 -19
- package/dist/session/session-manager.js +35 -2
- package/dist/session/session-readiness.d.ts +0 -1
- package/dist/session/session-readiness.js +3 -4
- package/dist/session/session-reaper.d.ts +0 -1
- package/dist/session/session-reaper.js +0 -1
- package/dist/session/session-recommendation.d.ts +0 -1
- package/dist/session/session-recommendation.js +0 -1
- package/dist/session/session-tools.d.ts +0 -1
- package/dist/session/session-tools.js +2 -3
- package/dist/session/session.d.ts +33 -53
- package/dist/session/session.js +102 -66
- package/dist/session/state-select.d.ts +0 -1
- package/dist/session/state-select.js +0 -1
- package/dist/telemetry/argument-shape.d.ts +41 -0
- package/dist/telemetry/argument-shape.js +87 -0
- package/dist/telemetry/bug-found.d.ts +33 -0
- package/dist/telemetry/bug-found.js +95 -0
- package/dist/telemetry/cli-telemetry.d.ts +13 -0
- package/dist/telemetry/cli-telemetry.js +43 -0
- package/dist/telemetry/connect-failure.d.ts +16 -0
- package/dist/telemetry/connect-failure.js +44 -0
- package/dist/telemetry/daemon-telemetry.d.ts +19 -0
- package/dist/telemetry/daemon-telemetry.js +76 -0
- package/dist/telemetry/dev-repo.d.ts +10 -0
- package/dist/telemetry/dev-repo.js +80 -0
- package/dist/telemetry/error-fingerprint.d.ts +24 -0
- package/dist/telemetry/error-fingerprint.js +88 -0
- package/dist/telemetry/feedback-cli.d.ts +31 -0
- package/dist/telemetry/feedback-cli.js +102 -0
- package/dist/telemetry/feedback-context.d.ts +32 -0
- package/dist/telemetry/feedback-context.js +143 -0
- package/dist/telemetry/feedback.d.ts +66 -0
- package/dist/telemetry/feedback.js +175 -0
- package/dist/telemetry/git-facts.d.ts +21 -0
- package/dist/telemetry/git-facts.js +109 -0
- package/dist/telemetry/identify.d.ts +22 -0
- package/dist/telemetry/identify.js +73 -0
- package/dist/telemetry/init-telemetry.d.ts +26 -0
- package/dist/telemetry/init-telemetry.js +33 -0
- package/dist/telemetry/machine-snapshot.d.ts +6 -0
- package/dist/telemetry/machine-snapshot.js +39 -0
- package/dist/telemetry/mcp-connection.d.ts +5 -0
- package/dist/telemetry/mcp-connection.js +44 -0
- package/dist/telemetry/project-profile.d.ts +44 -0
- package/dist/telemetry/project-profile.js +205 -0
- package/dist/telemetry/run-telemetry.d.ts +21 -0
- package/dist/telemetry/run-telemetry.js +62 -0
- package/dist/telemetry/session-metrics.d.ts +103 -0
- package/dist/telemetry/session-metrics.js +329 -0
- package/dist/telemetry/telemetry.d.ts +35 -8
- package/dist/telemetry/telemetry.js +105 -12
- package/dist/token-auth.d.ts +0 -1
- package/dist/token-auth.js +0 -1
- package/dist/tools/act-capsule.d.ts +23 -0
- package/dist/tools/act-capsule.js +47 -0
- package/dist/tools/act-danger.d.ts +7 -0
- package/dist/tools/act-danger.js +44 -0
- package/dist/tools/act-helpers.d.ts +17 -0
- package/dist/tools/act-helpers.js +40 -0
- package/dist/tools/act-tools.d.ts +8 -1
- package/dist/tools/act-tools.js +96 -98
- package/dist/tools/act-view.d.ts +7 -1
- package/dist/tools/act-view.js +13 -1
- package/dist/tools/assert-grade.d.ts +22 -1
- package/dist/tools/assert-grade.js +46 -1
- package/dist/tools/assert-verdict.d.ts +21 -0
- package/dist/tools/assert-verdict.js +62 -0
- package/dist/tools/browser-tools.d.ts +0 -1
- package/dist/tools/browser-tools.js +2 -2
- package/dist/tools/contract-tools.d.ts +0 -1
- package/dist/tools/contract-tools.js +0 -1
- package/dist/tools/coverage-tools.d.ts +9 -0
- package/dist/tools/coverage-tools.js +92 -0
- package/dist/tools/dynamic-tools.d.ts +0 -1
- package/dist/tools/dynamic-tools.js +21 -2
- package/dist/tools/error-recovery.d.ts +18 -2
- package/dist/tools/error-recovery.js +42 -7
- package/dist/tools/feedback-tools.d.ts +24 -0
- package/dist/tools/feedback-tools.js +180 -0
- package/dist/tools/invoke-tool.d.ts +0 -1
- package/dist/tools/invoke-tool.js +115 -5
- package/dist/tools/lease-tools.d.ts +0 -1
- package/dist/tools/lease-tools.js +6 -5
- package/dist/tools/merge-tools.d.ts +0 -1
- package/dist/tools/merge-tools.js +0 -1
- package/dist/tools/observe-tools.d.ts +0 -1
- package/dist/tools/observe-tools.js +91 -39
- package/dist/tools/profiles.d.ts +1 -2
- package/dist/tools/profiles.js +43 -16
- package/dist/tools/query-paginate.d.ts +0 -1
- package/dist/tools/query-paginate.js +0 -1
- package/dist/tools/read-tools.d.ts +0 -1
- package/dist/tools/read-tools.js +14 -8
- package/dist/tools/reconcile-tools.d.ts +2 -0
- package/dist/tools/reconcile-tools.js +111 -0
- package/dist/tools/snapshot-delta.d.ts +0 -1
- package/dist/tools/snapshot-delta.js +0 -0
- package/dist/tools/tool-invoker.d.ts +0 -1
- package/dist/tools/tool-invoker.js +0 -1
- package/dist/tools/tool-kit.d.ts +16 -1
- package/dist/tools/tool-kit.js +8 -2
- package/dist/tools/tool-names.d.ts +6 -1
- package/dist/tools/tool-names.js +6 -1
- package/dist/tools/tools-helpers.d.ts +0 -1
- package/dist/tools/tools-helpers.js +0 -1
- package/dist/tools/tools.d.ts +0 -1
- package/dist/tools/tools.js +24 -4
- package/dist/update/update-checker.d.ts +0 -1
- package/dist/update/update-checker.js +0 -1
- package/dist/update/update-nudge.d.ts +20 -0
- package/dist/update/update-nudge.js +72 -0
- package/dist/update/updater.d.ts +14 -1
- package/dist/update/updater.js +33 -2
- package/dist/visual/visual-diff.d.ts +0 -1
- package/dist/visual/visual-diff.js +0 -1
- package/dist/visual/visual-store.d.ts +0 -1
- package/dist/visual/visual-store.js +0 -1
- package/dist/visual/visual-tools.d.ts +0 -1
- package/dist/visual/visual-tools.js +103 -16
- package/package.json +2 -2
- package/dist/bridge-security.d.ts.map +0 -1
- package/dist/bridge-security.js.map +0 -1
- package/dist/bridge.d.ts.map +0 -1
- package/dist/bridge.js.map +0 -1
- package/dist/bridge.test-harness.d.ts.map +0 -1
- package/dist/bridge.test-harness.js.map +0 -1
- package/dist/capsule/capsule-store.d.ts.map +0 -1
- package/dist/capsule/capsule-store.js.map +0 -1
- package/dist/capsule/capsule.d.ts.map +0 -1
- package/dist/capsule/capsule.js.map +0 -1
- package/dist/capsule/causal-summary.d.ts.map +0 -1
- package/dist/capsule/causal-summary.js.map +0 -1
- package/dist/capsule/divergence.d.ts.map +0 -1
- package/dist/capsule/divergence.js.map +0 -1
- package/dist/capsule/minimize.d.ts.map +0 -1
- package/dist/capsule/minimize.js.map +0 -1
- package/dist/capsule/predicate-to-links.d.ts.map +0 -1
- package/dist/capsule/predicate-to-links.js.map +0 -1
- package/dist/cli-flow-commands.d.ts.map +0 -1
- package/dist/cli-flow-commands.js.map +0 -1
- package/dist/cli-launch.d.ts.map +0 -1
- package/dist/cli-launch.js.map +0 -1
- package/dist/cli-parse.d.ts.map +0 -1
- package/dist/cli-parse.js.map +0 -1
- package/dist/cli-port.d.ts.map +0 -1
- package/dist/cli-port.js.map +0 -1
- package/dist/cli-verify.d.ts.map +0 -1
- package/dist/cli-verify.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cloud/cloud-config.d.ts.map +0 -1
- package/dist/cloud/cloud-config.js.map +0 -1
- package/dist/cloud/cloud-sync.d.ts.map +0 -1
- package/dist/cloud/cloud-sync.js.map +0 -1
- package/dist/cloud-cli.d.ts.map +0 -1
- package/dist/cloud-cli.js.map +0 -1
- package/dist/crawl/crawl-tools.d.ts.map +0 -1
- package/dist/crawl/crawl-tools.js.map +0 -1
- package/dist/crawl/crawl.d.ts.map +0 -1
- package/dist/crawl/crawl.js.map +0 -1
- package/dist/daemon-resilience.d.ts.map +0 -1
- package/dist/daemon-resilience.js.map +0 -1
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js.map +0 -1
- package/dist/domain/domain-model.d.ts.map +0 -1
- package/dist/domain/domain-model.js.map +0 -1
- package/dist/domain/domain-tools.d.ts.map +0 -1
- package/dist/domain/domain-tools.js.map +0 -1
- package/dist/domain/flow-risk.d.ts.map +0 -1
- package/dist/domain/flow-risk.js.map +0 -1
- package/dist/ee/audit-log.d.ts.map +0 -1
- package/dist/ee/audit-log.js.map +0 -1
- package/dist/events/event-filters.d.ts.map +0 -1
- package/dist/events/event-filters.js.map +0 -1
- package/dist/events/predicate-eval.d.ts.map +0 -1
- package/dist/events/predicate-eval.js.map +0 -1
- package/dist/events/predicate.d.ts.map +0 -1
- package/dist/events/predicate.js.map +0 -1
- package/dist/events/reaction.d.ts.map +0 -1
- package/dist/events/reaction.js.map +0 -1
- package/dist/events/ring-buffer.d.ts.map +0 -1
- package/dist/events/ring-buffer.js.map +0 -1
- package/dist/flows/affected.d.ts.map +0 -1
- package/dist/flows/affected.js.map +0 -1
- package/dist/flows/annotate-tools.d.ts.map +0 -1
- package/dist/flows/annotate-tools.js.map +0 -1
- package/dist/flows/annotate.d.ts.map +0 -1
- package/dist/flows/annotate.js.map +0 -1
- package/dist/flows/annotation-store.d.ts.map +0 -1
- package/dist/flows/annotation-store.js.map +0 -1
- package/dist/flows/assertion-integrity.d.ts.map +0 -1
- package/dist/flows/assertion-integrity.js.map +0 -1
- package/dist/flows/assertion-tiers-store.d.ts.map +0 -1
- package/dist/flows/assertion-tiers-store.js.map +0 -1
- package/dist/flows/buddy-status.d.ts.map +0 -1
- package/dist/flows/buddy-status.js.map +0 -1
- package/dist/flows/coverage.d.ts.map +0 -1
- package/dist/flows/coverage.js.map +0 -1
- package/dist/flows/decision.d.ts.map +0 -1
- package/dist/flows/decision.js.map +0 -1
- package/dist/flows/flake-store.d.ts.map +0 -1
- package/dist/flows/flake-store.js.map +0 -1
- package/dist/flows/flake.d.ts.map +0 -1
- package/dist/flows/flake.js.map +0 -1
- package/dist/flows/flow-classify.d.ts.map +0 -1
- package/dist/flows/flow-classify.js.map +0 -1
- package/dist/flows/flow-replay-run.d.ts.map +0 -1
- package/dist/flows/flow-replay-run.js.map +0 -1
- package/dist/flows/flow-replay.d.ts.map +0 -1
- package/dist/flows/flow-replay.js.map +0 -1
- package/dist/flows/flow-report.d.ts.map +0 -1
- package/dist/flows/flow-report.js.map +0 -1
- package/dist/flows/flow-scope.d.ts.map +0 -1
- package/dist/flows/flow-scope.js.map +0 -1
- package/dist/flows/flow-sources.d.ts.map +0 -1
- package/dist/flows/flow-sources.js.map +0 -1
- package/dist/flows/flow-success.d.ts.map +0 -1
- package/dist/flows/flow-success.js.map +0 -1
- package/dist/flows/flow-tools.d.ts.map +0 -1
- package/dist/flows/flow-tools.js.map +0 -1
- package/dist/flows/flows.d.ts.map +0 -1
- package/dist/flows/flows.js.map +0 -1
- package/dist/flows/gate.d.ts.map +0 -1
- package/dist/flows/gate.js.map +0 -1
- package/dist/flows/git-changed.d.ts.map +0 -1
- package/dist/flows/git-changed.js.map +0 -1
- package/dist/flows/heal-run.d.ts.map +0 -1
- package/dist/flows/heal-run.js.map +0 -1
- package/dist/flows/heal.d.ts.map +0 -1
- package/dist/flows/heal.js.map +0 -1
- package/dist/flows/parallel-suite.d.ts.map +0 -1
- package/dist/flows/parallel-suite.js.map +0 -1
- package/dist/flows/recordings.d.ts.map +0 -1
- package/dist/flows/recordings.js.map +0 -1
- package/dist/flows/replay.d.ts.map +0 -1
- package/dist/flows/replay.js.map +0 -1
- package/dist/flows/server-verify.d.ts.map +0 -1
- package/dist/flows/server-verify.js.map +0 -1
- package/dist/flows/watch-batcher.d.ts.map +0 -1
- package/dist/flows/watch-batcher.js.map +0 -1
- package/dist/honesty/blind-spots.d.ts.map +0 -1
- package/dist/honesty/blind-spots.js.map +0 -1
- package/dist/honesty/honesty.d.ts.map +0 -1
- package/dist/honesty/honesty.js.map +0 -1
- package/dist/http-server.d.ts.map +0 -1
- package/dist/http-server.js.map +0 -1
- package/dist/idle-shutdown.d.ts.map +0 -1
- package/dist/idle-shutdown.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init/agent-rules.d.ts.map +0 -1
- package/dist/init/agent-rules.js.map +0 -1
- package/dist/init/cursor.d.ts.map +0 -1
- package/dist/init/cursor.js.map +0 -1
- package/dist/init/detect.d.ts.map +0 -1
- package/dist/init/detect.js.map +0 -1
- package/dist/init/mcp.d.ts.map +0 -1
- package/dist/init/mcp.js.map +0 -1
- package/dist/init/node-io.d.ts.map +0 -1
- package/dist/init/node-io.js.map +0 -1
- package/dist/init/plan.d.ts.map +0 -1
- package/dist/init/plan.js.map +0 -1
- package/dist/init/project-id.d.ts.map +0 -1
- package/dist/init/project-id.js.map +0 -1
- package/dist/init/run.d.ts.map +0 -1
- package/dist/init/run.js.map +0 -1
- package/dist/init/snippets.d.ts.map +0 -1
- package/dist/init/snippets.js.map +0 -1
- package/dist/init/vite-config.d.ts.map +0 -1
- package/dist/init/vite-config.js.map +0 -1
- package/dist/input/network-detail.d.ts.map +0 -1
- package/dist/input/network-detail.js.map +0 -1
- package/dist/input/network-mock-tools.d.ts.map +0 -1
- package/dist/input/network-mock-tools.js.map +0 -1
- package/dist/input/network-mock.d.ts.map +0 -1
- package/dist/input/network-mock.js.map +0 -1
- package/dist/input/real-input.d.ts.map +0 -1
- package/dist/input/real-input.js.map +0 -1
- package/dist/input/scroll-find.d.ts.map +0 -1
- package/dist/input/scroll-find.js.map +0 -1
- package/dist/input/scroll-tools.d.ts.map +0 -1
- package/dist/input/scroll-tools.js.map +0 -1
- package/dist/input/viewport-tools.d.ts.map +0 -1
- package/dist/input/viewport-tools.js.map +0 -1
- package/dist/journal/ambient-store.d.ts.map +0 -1
- package/dist/journal/ambient-store.js.map +0 -1
- package/dist/journal/ambient.d.ts.map +0 -1
- package/dist/journal/ambient.js.map +0 -1
- package/dist/journal/attach-journal.d.ts.map +0 -1
- package/dist/journal/attach-journal.js.map +0 -1
- package/dist/journal/deviation-report.d.ts.map +0 -1
- package/dist/journal/deviation-report.js.map +0 -1
- package/dist/journal/deviation-service.d.ts.map +0 -1
- package/dist/journal/deviation-service.js.map +0 -1
- package/dist/journal/envelope-store.d.ts.map +0 -1
- package/dist/journal/envelope-store.js.map +0 -1
- package/dist/journal/envelope.d.ts.map +0 -1
- package/dist/journal/envelope.js.map +0 -1
- package/dist/journal/journal-query.d.ts.map +0 -1
- package/dist/journal/journal-query.js.map +0 -1
- package/dist/journal/journal-recorder.d.ts.map +0 -1
- package/dist/journal/journal-recorder.js.map +0 -1
- package/dist/journal/retention.d.ts.map +0 -1
- package/dist/journal/retention.js.map +0 -1
- package/dist/journal/rollups.d.ts.map +0 -1
- package/dist/journal/rollups.js.map +0 -1
- package/dist/journal/session-end.d.ts.map +0 -1
- package/dist/journal/session-end.js.map +0 -1
- package/dist/journal/session-journal.d.ts.map +0 -1
- package/dist/journal/session-journal.js.map +0 -1
- package/dist/license/license.d.ts.map +0 -1
- package/dist/license/license.js.map +0 -1
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js.map +0 -1
- package/dist/mcp-proxy.d.ts.map +0 -1
- package/dist/mcp-proxy.js.map +0 -1
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js.map +0 -1
- package/dist/oracles/flow-instrument-gaps.d.ts.map +0 -1
- package/dist/oracles/flow-instrument-gaps.js.map +0 -1
- package/dist/oracles/propose-consequences.d.ts.map +0 -1
- package/dist/oracles/propose-consequences.js.map +0 -1
- package/dist/oracles/self-instrument.d.ts.map +0 -1
- package/dist/oracles/self-instrument.js.map +0 -1
- package/dist/pairing-token.d.ts.map +0 -1
- package/dist/pairing-token.js.map +0 -1
- package/dist/phenomena/phenomena.d.ts.map +0 -1
- package/dist/phenomena/phenomena.js.map +0 -1
- package/dist/pool/browser-pool.d.ts.map +0 -1
- package/dist/pool/browser-pool.js.map +0 -1
- package/dist/pool/lease-reaper.d.ts.map +0 -1
- package/dist/pool/lease-reaper.js.map +0 -1
- package/dist/pool/playwright-launcher.d.ts.map +0 -1
- package/dist/pool/playwright-launcher.js.map +0 -1
- package/dist/project/baselines.d.ts.map +0 -1
- package/dist/project/baselines.js.map +0 -1
- package/dist/project/file-lock.d.ts.map +0 -1
- package/dist/project/file-lock.js.map +0 -1
- package/dist/project/fs-port.d.ts.map +0 -1
- package/dist/project/fs-port.js.map +0 -1
- package/dist/project/project-store.d.ts.map +0 -1
- package/dist/project/project-store.js.map +0 -1
- package/dist/project/project-tools.d.ts.map +0 -1
- package/dist/project/project-tools.js.map +0 -1
- package/dist/project/reticle-dir.d.ts.map +0 -1
- package/dist/project/reticle-dir.js.map +0 -1
- package/dist/runs/build-verification-run.d.ts.map +0 -1
- package/dist/runs/build-verification-run.js.map +0 -1
- package/dist/runs/profile-redact.d.ts.map +0 -1
- package/dist/runs/profile-redact.js.map +0 -1
- package/dist/runs/render-report.d.ts.map +0 -1
- package/dist/runs/render-report.js.map +0 -1
- package/dist/runs/repair-prompt.d.ts.map +0 -1
- package/dist/runs/repair-prompt.js.map +0 -1
- package/dist/runs/replay-mapping.d.ts.map +0 -1
- package/dist/runs/replay-mapping.js.map +0 -1
- package/dist/runs/reticle-runner.d.ts.map +0 -1
- package/dist/runs/reticle-runner.js.map +0 -1
- package/dist/runs/risk-classify.d.ts.map +0 -1
- package/dist/runs/risk-classify.js.map +0 -1
- package/dist/runs/run-diff.d.ts.map +0 -1
- package/dist/runs/run-diff.js.map +0 -1
- package/dist/runs/run-store.d.ts.map +0 -1
- package/dist/runs/run-store.js.map +0 -1
- package/dist/runs/run-tools.d.ts.map +0 -1
- package/dist/runs/run-tools.js.map +0 -1
- package/dist/runs/runner-port.d.ts.map +0 -1
- package/dist/runs/runner-port.js.map +0 -1
- package/dist/runs/verification-sync.d.ts.map +0 -1
- package/dist/runs/verification-sync.js.map +0 -1
- package/dist/runs/verify-http.d.ts.map +0 -1
- package/dist/runs/verify-http.js.map +0 -1
- package/dist/runs/verify-server.d.ts.map +0 -1
- package/dist/runs/verify-server.js.map +0 -1
- package/dist/server-version.d.ts.map +0 -1
- package/dist/server-version.js.map +0 -1
- package/dist/session/control-envelope.d.ts.map +0 -1
- package/dist/session/control-envelope.js.map +0 -1
- package/dist/session/live-control-tools.d.ts.map +0 -1
- package/dist/session/live-control-tools.js.map +0 -1
- package/dist/session/live-control.d.ts.map +0 -1
- package/dist/session/live-control.js.map +0 -1
- package/dist/session/observed-state.d.ts.map +0 -1
- package/dist/session/observed-state.js.map +0 -1
- package/dist/session/output-budget.d.ts.map +0 -1
- package/dist/session/output-budget.js.map +0 -1
- package/dist/session/presenter-args.d.ts.map +0 -1
- package/dist/session/presenter-args.js.map +0 -1
- package/dist/session/review-store.d.ts.map +0 -1
- package/dist/session/review-store.js.map +0 -1
- package/dist/session/session-health.d.ts.map +0 -1
- package/dist/session/session-health.js.map +0 -1
- package/dist/session/session-manager.d.ts.map +0 -1
- package/dist/session/session-manager.js.map +0 -1
- package/dist/session/session-readiness.d.ts.map +0 -1
- package/dist/session/session-readiness.js.map +0 -1
- package/dist/session/session-reaper.d.ts.map +0 -1
- package/dist/session/session-reaper.js.map +0 -1
- package/dist/session/session-recommendation.d.ts.map +0 -1
- package/dist/session/session-recommendation.js.map +0 -1
- package/dist/session/session-tools.d.ts.map +0 -1
- package/dist/session/session-tools.js.map +0 -1
- package/dist/session/session.d.ts.map +0 -1
- package/dist/session/session.js.map +0 -1
- package/dist/session/state-select.d.ts.map +0 -1
- package/dist/session/state-select.js.map +0 -1
- package/dist/telemetry/telemetry.d.ts.map +0 -1
- package/dist/telemetry/telemetry.js.map +0 -1
- package/dist/token-auth.d.ts.map +0 -1
- package/dist/token-auth.js.map +0 -1
- package/dist/tools/act-tools.d.ts.map +0 -1
- package/dist/tools/act-tools.js.map +0 -1
- package/dist/tools/act-view.d.ts.map +0 -1
- package/dist/tools/act-view.js.map +0 -1
- package/dist/tools/assert-grade.d.ts.map +0 -1
- package/dist/tools/assert-grade.js.map +0 -1
- package/dist/tools/browser-tools.d.ts.map +0 -1
- package/dist/tools/browser-tools.js.map +0 -1
- package/dist/tools/contract-tools.d.ts.map +0 -1
- package/dist/tools/contract-tools.js.map +0 -1
- package/dist/tools/dynamic-tools.d.ts.map +0 -1
- package/dist/tools/dynamic-tools.js.map +0 -1
- package/dist/tools/error-recovery.d.ts.map +0 -1
- package/dist/tools/error-recovery.js.map +0 -1
- package/dist/tools/invoke-tool.d.ts.map +0 -1
- package/dist/tools/invoke-tool.js.map +0 -1
- package/dist/tools/lease-tools.d.ts.map +0 -1
- package/dist/tools/lease-tools.js.map +0 -1
- package/dist/tools/merge-tools.d.ts.map +0 -1
- package/dist/tools/merge-tools.js.map +0 -1
- package/dist/tools/observe-tools.d.ts.map +0 -1
- package/dist/tools/observe-tools.js.map +0 -1
- package/dist/tools/profiles.d.ts.map +0 -1
- package/dist/tools/profiles.js.map +0 -1
- package/dist/tools/query-paginate.d.ts.map +0 -1
- package/dist/tools/query-paginate.js.map +0 -1
- package/dist/tools/read-tools.d.ts.map +0 -1
- package/dist/tools/read-tools.js.map +0 -1
- package/dist/tools/snapshot-delta.d.ts.map +0 -1
- package/dist/tools/snapshot-delta.js.map +0 -1
- package/dist/tools/tool-invoker.d.ts.map +0 -1
- package/dist/tools/tool-invoker.js.map +0 -1
- package/dist/tools/tool-kit.d.ts.map +0 -1
- package/dist/tools/tool-kit.js.map +0 -1
- package/dist/tools/tool-names.d.ts.map +0 -1
- package/dist/tools/tool-names.js.map +0 -1
- package/dist/tools/tools-helpers.d.ts.map +0 -1
- package/dist/tools/tools-helpers.js.map +0 -1
- package/dist/tools/tools.d.ts.map +0 -1
- package/dist/tools/tools.js.map +0 -1
- package/dist/update/update-checker.d.ts.map +0 -1
- package/dist/update/update-checker.js.map +0 -1
- package/dist/update/updater.d.ts.map +0 -1
- package/dist/update/updater.js.map +0 -1
- package/dist/visual/visual-diff.d.ts.map +0 -1
- package/dist/visual/visual-diff.js.map +0 -1
- package/dist/visual/visual-store.d.ts.map +0 -1
- package/dist/visual/visual-store.js.map +0 -1
- package/dist/visual/visual-tools.d.ts.map +0 -1
- package/dist/visual/visual-tools.js.map +0 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ActionType, DANGEROUS_ACTION_CONFIRM_ARG, isDangerousActionText } from '@reticlehq/core';
|
|
2
|
+
import { asRecord, asString } from './tools-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Refuse to drive a money-moving or destructive control by accident.
|
|
5
|
+
*
|
|
6
|
+
* A native click is indistinguishable from a user's, so an agent exploring an unfamiliar app can
|
|
7
|
+
* refund a payment or delete an account while "just looking". The guard reads every text surface the
|
|
8
|
+
* control exposes — its name, its text, its value, where it points, and the form it submits — because
|
|
9
|
+
* a button labelled only with an icon still says what it does through its `formAction`.
|
|
10
|
+
*
|
|
11
|
+
* Opt in per action with `args.confirmDangerous: true`. Deliberately a THROW rather than a warning:
|
|
12
|
+
* a caller that has not thought about it must not proceed by ignoring a field.
|
|
13
|
+
*/
|
|
14
|
+
function descriptorText(value) {
|
|
15
|
+
const descriptor = asRecord(value);
|
|
16
|
+
return [
|
|
17
|
+
asString(descriptor['name']) ?? '',
|
|
18
|
+
asString(descriptor['text']) ?? '',
|
|
19
|
+
asString(descriptor['value']) ?? '',
|
|
20
|
+
asString(descriptor['href']) ?? '',
|
|
21
|
+
asString(descriptor['formAction']) ?? '',
|
|
22
|
+
asString(descriptor['formText']) ?? '',
|
|
23
|
+
].join(' ');
|
|
24
|
+
}
|
|
25
|
+
export function assertNotDestructive(action, innerArgs, inspected) {
|
|
26
|
+
if (action !== ActionType.CLICK && action !== ActionType.DBLCLICK)
|
|
27
|
+
return;
|
|
28
|
+
if (innerArgs[DANGEROUS_ACTION_CONFIRM_ARG] === true)
|
|
29
|
+
return;
|
|
30
|
+
if (!isDangerousActionText(descriptorText(inspected)))
|
|
31
|
+
return;
|
|
32
|
+
throw new Error(`potentially destructive native action blocked; retry with args.${DANGEROUS_ACTION_CONFIRM_ARG}=true`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A drag is judged on BOTH ends. Dropping a harmless row onto "Delete" is destructive, and the
|
|
36
|
+
* source alone never says so.
|
|
37
|
+
*/
|
|
38
|
+
export function assertDragNotDestructive(innerArgs, from, to) {
|
|
39
|
+
if (innerArgs[DANGEROUS_ACTION_CONFIRM_ARG] === true)
|
|
40
|
+
return;
|
|
41
|
+
if (!isDangerousActionText(`${descriptorText(from)} ${descriptorText(to)}`))
|
|
42
|
+
return;
|
|
43
|
+
throw new Error(`potentially destructive native action blocked; retry with args.${DANGEROUS_ACTION_CONFIRM_ARG}=true`);
|
|
44
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure coercion + grading helpers behind the act tools.
|
|
3
|
+
*
|
|
4
|
+
* Split out when act-tools.ts crossed the 600-line cap. The seam is that nothing here touches a
|
|
5
|
+
* session, a command, or a tool definition — these are total functions over their arguments, which
|
|
6
|
+
* is why they can be tested without a browser and why they were the right thing to move.
|
|
7
|
+
*/
|
|
8
|
+
import { ActionType } from '@reticlehq/core';
|
|
9
|
+
import type { ElementBox } from '../input/real-input.js';
|
|
10
|
+
import { HonestyGrade } from '../honesty/honesty.js';
|
|
11
|
+
import type { ExpectedLink } from '../capsule/divergence.js';
|
|
12
|
+
/** The strongest consequence grade a set of expected links proves (signal > net > state > presence). */
|
|
13
|
+
export declare function gradeOf(links: readonly ExpectedLink[]): HonestyGrade;
|
|
14
|
+
/** Narrow an INSPECT result's `box` into a positive-area ElementBox (else undefined). */
|
|
15
|
+
export declare function asBox(value: unknown): ElementBox | undefined;
|
|
16
|
+
/** Outcome of a real-input attempt — real success (result set) or synthetic with a reason. */
|
|
17
|
+
export declare function asActionType(value: unknown): ActionType | undefined;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure coercion + grading helpers behind the act tools.
|
|
3
|
+
*
|
|
4
|
+
* Split out when act-tools.ts crossed the 600-line cap. The seam is that nothing here touches a
|
|
5
|
+
* session, a command, or a tool definition — these are total functions over their arguments, which
|
|
6
|
+
* is why they can be tested without a browser and why they were the right thing to move.
|
|
7
|
+
*/
|
|
8
|
+
import { ActionType } from '@reticlehq/core';
|
|
9
|
+
import { HonestyGrade } from '../honesty/honesty.js';
|
|
10
|
+
import { asNumber, asRecord, asString } from './tools-helpers.js';
|
|
11
|
+
/** The strongest consequence grade a set of expected links proves (signal > net > state > presence). */
|
|
12
|
+
export function gradeOf(links) {
|
|
13
|
+
if (links.some((l) => l.kind === 'signal'))
|
|
14
|
+
return HonestyGrade.SIGNAL;
|
|
15
|
+
if (links.some((l) => l.kind === 'net'))
|
|
16
|
+
return HonestyGrade.NET;
|
|
17
|
+
if (links.some((l) => l.kind === 'state'))
|
|
18
|
+
return HonestyGrade.STATE;
|
|
19
|
+
return HonestyGrade.PRESENCE;
|
|
20
|
+
}
|
|
21
|
+
/** Narrow an INSPECT result's `box` into a positive-area ElementBox (else undefined). */
|
|
22
|
+
export function asBox(value) {
|
|
23
|
+
const b = asRecord(asRecord(value)['box']);
|
|
24
|
+
const x = asNumber(b['x']);
|
|
25
|
+
const y = asNumber(b['y']);
|
|
26
|
+
const w = asNumber(b['width']);
|
|
27
|
+
const h = asNumber(b['height']);
|
|
28
|
+
if (x === undefined || y === undefined || w === undefined || h === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
if (w <= 0 || h <= 0)
|
|
31
|
+
return undefined; // zero-area (display:none) ⇒ native click would miss
|
|
32
|
+
return { x, y, width: w, height: h };
|
|
33
|
+
}
|
|
34
|
+
/** Outcome of a real-input attempt — real success (result set) or synthetic with a reason. */
|
|
35
|
+
export function asActionType(value) {
|
|
36
|
+
const raw = asString(value);
|
|
37
|
+
if (raw === undefined)
|
|
38
|
+
return undefined;
|
|
39
|
+
return Object.values(ActionType).includes(raw) ? raw : undefined;
|
|
40
|
+
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { type ToolDef } from './tool-kit.js';
|
|
2
|
+
/**
|
|
3
|
+
* Narrow the wire's `action` to a real ActionType, or undefined.
|
|
4
|
+
*
|
|
5
|
+
* It used to be `asString(args['action']) ?? ''`, so an unknown or missing action became the empty
|
|
6
|
+
* string and travelled on — reaching the browser as a command it could not perform, and reported back
|
|
7
|
+
* as a generic failure rather than "that is not an action". Validate at the boundary, per the project's
|
|
8
|
+
* unknown-plus-narrowing rule, so a typo is rejected where it can still be explained.
|
|
9
|
+
*/
|
|
2
10
|
export declare const ACT_TOOLS: ToolDef[];
|
|
3
|
-
//# sourceMappingURL=act-tools.d.ts.map
|
package/dist/tools/act-tools.js
CHANGED
|
@@ -5,45 +5,28 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { compileActStep, compileSequenceStep } from '../flows/replay.js';
|
|
8
|
-
import { ActionType, ActionWarning,
|
|
8
|
+
import { ActionType, ActionWarning, DEFAULT_ASSERT_TIMEOUT_MS, InputMode, InputModeReason, ReticleCommand, } from '@reticlehq/core';
|
|
9
9
|
import { isPointerAction } from '../input/real-input.js';
|
|
10
|
-
import { leanActResult } from './act-view.js';
|
|
10
|
+
import { leanActResult, mutatedWithin } from './act-view.js';
|
|
11
11
|
import { ReticleTool } from './tool-names.js';
|
|
12
12
|
import { buildReactionReport, summarizeReaction } from '../events/reaction.js';
|
|
13
13
|
import { causalSummary } from '../capsule/causal-summary.js';
|
|
14
|
+
import { findContradictions } from '../events/contradictions.js';
|
|
15
|
+
import { decideVerified } from '../honesty/verified.js';
|
|
16
|
+
import { saveFailedAssertCapsule } from './act-capsule.js';
|
|
14
17
|
import { buildDivergenceCapsule } from '../capsule/capsule.js';
|
|
15
18
|
import { predicateToExpectedLinks } from '../capsule/predicate-to-links.js';
|
|
16
|
-
import {
|
|
17
|
-
import { buildCoverageStatement, blindSpotsFromState } from '../honesty/blind-spots.js';
|
|
18
|
-
import {
|
|
19
|
+
import { buildHonestyBlock } from '../honesty/honesty.js';
|
|
20
|
+
import { buildCoverageStatement, blindSpotsFromState, impeachesCapture, } from '../honesty/blind-spots.js';
|
|
21
|
+
import { hasAcceptedWrite } from '../honesty/accepted-write.js';
|
|
22
|
+
import { hasUnreadWriteOutcome } from '../honesty/unread-outcome.js';
|
|
23
|
+
import { assertDragNotDestructive, assertNotDestructive } from './act-danger.js';
|
|
19
24
|
import { evaluatePredicate, waitForPredicate, provenExpectedLinks, PredicateSchema, } from '../events/predicate.js';
|
|
20
25
|
import { healthEnvelope, refuseIfThrottled } from '../session/session-health.js';
|
|
21
26
|
import { pausedShortCircuit, pausedOutputShape, withControl } from '../session/control-envelope.js';
|
|
22
27
|
import { asString, asNumber, asRecord, sourceOf } from './tools-helpers.js';
|
|
23
28
|
import { sessionIdShape, commandOrThrow } from './tool-kit.js';
|
|
24
|
-
|
|
25
|
-
function gradeOf(links) {
|
|
26
|
-
if (links.some((l) => l.kind === 'signal'))
|
|
27
|
-
return HonestyGrade.SIGNAL;
|
|
28
|
-
if (links.some((l) => l.kind === 'net'))
|
|
29
|
-
return HonestyGrade.NET;
|
|
30
|
-
if (links.some((l) => l.kind === 'state'))
|
|
31
|
-
return HonestyGrade.STATE;
|
|
32
|
-
return HonestyGrade.PRESENCE;
|
|
33
|
-
}
|
|
34
|
-
/** Narrow an INSPECT result's `box` into a positive-area ElementBox (else undefined). */
|
|
35
|
-
function asBox(value) {
|
|
36
|
-
const b = asRecord(asRecord(value)['box']);
|
|
37
|
-
const x = asNumber(b['x']);
|
|
38
|
-
const y = asNumber(b['y']);
|
|
39
|
-
const w = asNumber(b['width']);
|
|
40
|
-
const h = asNumber(b['height']);
|
|
41
|
-
if (x === undefined || y === undefined || w === undefined || h === undefined)
|
|
42
|
-
return undefined;
|
|
43
|
-
if (w <= 0 || h <= 0)
|
|
44
|
-
return undefined; // zero-area (display:none) ⇒ native click would miss
|
|
45
|
-
return { x, y, width: w, height: h };
|
|
46
|
-
}
|
|
29
|
+
import { asActionType, asBox, gradeOf } from './act-helpers.js';
|
|
47
30
|
/** Synthetic outcome with a diagnostic reason (provider configured but native input skipped). */
|
|
48
31
|
function synthetic(reason) {
|
|
49
32
|
return reason === undefined
|
|
@@ -73,23 +56,7 @@ async function tryRealInput(deps, session, ref, action, args) {
|
|
|
73
56
|
if (!(await provider.isAvailableFor(session.url)))
|
|
74
57
|
return synthetic(InputModeReason.PAGE_NOT_CORRELATED);
|
|
75
58
|
const inspected = await commandOrThrow(deps, session.id, ReticleCommand.INSPECT, { ref });
|
|
76
|
-
|
|
77
|
-
const dangerousDescriptorText = (value) => {
|
|
78
|
-
const descriptor = asRecord(value);
|
|
79
|
-
return [
|
|
80
|
-
asString(descriptor['name']) ?? '',
|
|
81
|
-
asString(descriptor['text']) ?? '',
|
|
82
|
-
asString(descriptor['value']) ?? '',
|
|
83
|
-
asString(descriptor['href']) ?? '',
|
|
84
|
-
asString(descriptor['formAction']) ?? '',
|
|
85
|
-
asString(descriptor['formText']) ?? '',
|
|
86
|
-
].join(' ');
|
|
87
|
-
};
|
|
88
|
-
if ((action === ActionType.CLICK || action === ActionType.DBLCLICK) &&
|
|
89
|
-
!confirmed &&
|
|
90
|
-
isDangerousActionText(dangerousDescriptorText(inspected))) {
|
|
91
|
-
throw new Error(`potentially destructive native action blocked; retry with args.${DANGEROUS_ACTION_CONFIRM_ARG}=true`);
|
|
92
|
-
}
|
|
59
|
+
assertNotDestructive(action, inner, inspected);
|
|
93
60
|
const box = asBox(inspected);
|
|
94
61
|
if (box === undefined)
|
|
95
62
|
return synthetic(InputModeReason.ELEMENT_NOT_LOCATABLE);
|
|
@@ -101,10 +68,9 @@ async function tryRealInput(deps, session, ref, action, args) {
|
|
|
101
68
|
const targetInspected = await commandOrThrow(deps, session.id, ReticleCommand.INSPECT, {
|
|
102
69
|
ref: toRef,
|
|
103
70
|
});
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
71
|
+
// A drag is judged on BOTH ends: dropping onto "Trash" is destructive however innocent the
|
|
72
|
+
// thing being dragged looks.
|
|
73
|
+
assertDragNotDestructive(inner, inspected, targetInspected);
|
|
108
74
|
toBox = asBox(targetInspected);
|
|
109
75
|
if (toBox === undefined)
|
|
110
76
|
return synthetic(InputModeReason.DRAG_TARGET_UNRESOLVED);
|
|
@@ -141,18 +107,15 @@ async function tryRealInput(deps, session, ref, action, args) {
|
|
|
141
107
|
* as a generic failure rather than "that is not an action". Validate at the boundary, per the project's
|
|
142
108
|
* unknown-plus-narrowing rule, so a typo is rejected where it can still be explained.
|
|
143
109
|
*/
|
|
144
|
-
function asActionType(value) {
|
|
145
|
-
const raw = asString(value);
|
|
146
|
-
if (raw === undefined)
|
|
147
|
-
return undefined;
|
|
148
|
-
return Object.values(ActionType).includes(raw) ? raw : undefined;
|
|
149
|
-
}
|
|
150
110
|
export const ACT_TOOLS = [
|
|
151
111
|
{
|
|
152
112
|
name: ReticleTool.ACT,
|
|
113
|
+
example: { ref: 'e42', action: 'fill', args: { value: 'hello' } },
|
|
153
114
|
description: 'Execute one action against a ref: click|dblclick|hover|focus|fill|type|clear|select|check|uncheck|submit|press|scrollIntoView. Returns immediately with a `since` cursor — observe the reaction with reticle_observe. Carries effect:{dispatched,targetMatched,visible,enabled,focusMoved,valueChanged,domMutatedWithin,occluded,occludedBy,scrolledIntoView} to tell "action missed" from "app didn\'t react"; dispatched=landed, settled=a real frame flushed, and a settle timeout never fails the tool. Fields at their uninformative default are OMITTED so a clean action collapses to its consequence: an absent dispatched/targetMatched/visible/enabled means true, an absent occluded/scrolledIntoView/valueChanged/defaultPrevented means false, an absent focusMoved/occludedBy means null. occluded=true means the click point is covered by another element (a real user could not click it) — synthetic dispatch still delivered the event; scrolledIntoView=true means an off-viewport target was scrolled in first. inputMode is "real" (native CDP, no synthetic effect block) or "synthetic"; clicks default to the occlusion-honest synthetic path even when CDP is configured — pass args.native:true to force a trusted native click (file pickers, clipboard). inputModeReason explains any real→synthetic choice so it is never silent. Full model (real-input, throttled tabs, `reticle drive`): docs/usage.md §18.',
|
|
154
115
|
inputSchema: {
|
|
155
|
-
ref: z
|
|
116
|
+
ref: z
|
|
117
|
+
.string()
|
|
118
|
+
.describe(`Element ref (e.g. 'e42') from reticle_snapshot/reticle_query — stable until the element leaves the DOM, so no re-snapshot between actions.`),
|
|
156
119
|
action: z
|
|
157
120
|
.string()
|
|
158
121
|
.describe('Action to perform: click | dblclick | hover | focus | fill | type | clear | select | check | uncheck | submit | press | scrollIntoView'),
|
|
@@ -200,7 +163,10 @@ export const ACT_TOOLS = [
|
|
|
200
163
|
return paused;
|
|
201
164
|
refuseIfThrottled(session, args['refuseWhenThrottled']);
|
|
202
165
|
const since = session.elapsed();
|
|
203
|
-
session.
|
|
166
|
+
session.lastAct.markCursor(since); // honesty: wait_for/assert default their floor to this cursor
|
|
167
|
+
// Cleared up front: a throw between here and the result must not leave the PREVIOUS act's
|
|
168
|
+
// measurement standing, which would judge this window with the last one's evidence.
|
|
169
|
+
session.lastAct.markEffect(asString(args['action']), undefined);
|
|
204
170
|
const ref = asString(args['ref']) ?? '';
|
|
205
171
|
// Open the journal's action-attribution window BEFORE dispatching, so it covers the native path
|
|
206
172
|
// too. It used to open only on the synthetic path, and the native path returned above it — so a
|
|
@@ -243,6 +209,10 @@ export const ACT_TOOLS = [
|
|
|
243
209
|
const r = asRecord(result.result);
|
|
244
210
|
if (typeof r['settled'] === 'boolean')
|
|
245
211
|
settledOutcome = r['settled'];
|
|
212
|
+
// Keep what only this call measured, so the observe that judges this window can ask whether
|
|
213
|
+
// anything happened INSIDE the target — the one fact that separates a dead control from a
|
|
214
|
+
// page that was merely busy with something else.
|
|
215
|
+
session.lastAct.markEffect(asString(args['action']), mutatedWithin(r));
|
|
246
216
|
return withControl(session, {
|
|
247
217
|
since,
|
|
248
218
|
inputMode: InputMode.SYNTHETIC,
|
|
@@ -288,7 +258,7 @@ export const ACT_TOOLS = [
|
|
|
288
258
|
if (paused !== undefined)
|
|
289
259
|
return paused;
|
|
290
260
|
const since = session.elapsed();
|
|
291
|
-
session.
|
|
261
|
+
session.lastAct.markCursor(since); // honesty: a later wait_for/assert floors at this cursor
|
|
292
262
|
session.beginAction(ReticleTool.ACT_SEQUENCE, asRecord(args));
|
|
293
263
|
try {
|
|
294
264
|
const result = await session.command(ReticleCommand.ACT_SEQUENCE, { steps: args['steps'] });
|
|
@@ -313,6 +283,7 @@ export const ACT_TOOLS = [
|
|
|
313
283
|
},
|
|
314
284
|
{
|
|
315
285
|
name: ReticleTool.ACT_AND_WAIT,
|
|
286
|
+
example: { ref: 'e42', action: 'click', until: { kind: 'signal', name: 'todos:loaded' } },
|
|
316
287
|
description: 'Act on a ref, then wait for a predicate to hold — one hop for the act->observe->assert loop. ' +
|
|
317
288
|
'Omit `until` to wait for the page to settle (network + DOM idle) — use this instead of a fixed sleep. ' +
|
|
318
289
|
'Returns { effect } (the action result), { verdict } (predicate pass/evidence/near-miss), ' +
|
|
@@ -320,7 +291,9 @@ export const ACT_TOOLS = [
|
|
|
320
291
|
'cursor; pass it to reticle_observe for the full per-event timeline when the counts are not enough). ' +
|
|
321
292
|
'timeout_ms 0 evaluates the predicate once without waiting.',
|
|
322
293
|
inputSchema: {
|
|
323
|
-
ref: z
|
|
294
|
+
ref: z
|
|
295
|
+
.string()
|
|
296
|
+
.describe(`Element ref (e.g. 'e42') from reticle_snapshot/reticle_query — stable until the element leaves the DOM, so no re-snapshot between actions.`),
|
|
324
297
|
action: z
|
|
325
298
|
.string()
|
|
326
299
|
.describe('Action to perform: click | dblclick | hover | focus | fill | type | clear | select | check | uncheck | submit | press | scrollIntoView'),
|
|
@@ -378,6 +351,14 @@ export const ACT_TOOLS = [
|
|
|
378
351
|
.string()
|
|
379
352
|
.optional()
|
|
380
353
|
.describe('Present only on a FAILED verdict when the fail-to-pass capsule was persisted: its id, replayable as a regression flow once the bug goes green.'),
|
|
354
|
+
verified: z
|
|
355
|
+
.string()
|
|
356
|
+
.describe('THE field to gate on: "yes" | "no" | "unknown". Read this first and read `because` for the reason. "unknown" is NOT failure — it means the evidence could not decide (dirty capture, nothing asserted at a real grade, or the page never settled), which calls for a better check rather than a code change. Everything else on this result is the evidence this was derived from.'),
|
|
357
|
+
because: z.string().describe('One sentence naming the deciding evidence behind `verified`.'),
|
|
358
|
+
contradictions: z
|
|
359
|
+
.array(z.unknown())
|
|
360
|
+
.optional()
|
|
361
|
+
.describe('Channels that DISAGREE about this action — the UI advanced while its write failed, a success signal fired over a failed request, a response changed nothing, a duplicate fired, a request never settled. OMITTED when clean. Treat any entry as a finding even when the verdict is green: a passing assertion and a contradicted channel is exactly the false green this exists to catch.'),
|
|
381
362
|
honesty: z
|
|
382
363
|
.unknown()
|
|
383
364
|
.describe('The verdict trust block { grade, attribution, coverage, integrity, envelope? } — a green never looks stronger than this. Gate on grade ≥ net AND integrity.clean. Fields that were not measured are OMITTED rather than reported as zero, so treat an absent `envelope` as "not sampled", never as a failure.'),
|
|
@@ -403,7 +384,12 @@ export const ACT_TOOLS = [
|
|
|
403
384
|
: { kind: 'settled' };
|
|
404
385
|
const timeout = asNumber(args['timeout_ms']) ?? DEFAULT_ASSERT_TIMEOUT_MS;
|
|
405
386
|
const since = session.elapsed();
|
|
406
|
-
|
|
387
|
+
// `dropped` is cumulative for the SESSION, so comparing against a pre-action reading is what
|
|
388
|
+
// asks "did the buffer lose anything while THIS action was observed?" — the question the
|
|
389
|
+
// honesty block means. Reading the raw total pinned every later verdict to `unknown` after a
|
|
390
|
+
// single early eviction (measured on the Next.js demo at dropped:51, windows intact).
|
|
391
|
+
const droppedBefore = session.bufferHealth().dropped;
|
|
392
|
+
session.lastAct.markCursor(since);
|
|
407
393
|
// The attribution window stays open across the settle wait below, so post-dispatch async events
|
|
408
394
|
// (the whole point of act_and_wait) attribute to this action. finishAction fires after the wait.
|
|
409
395
|
session.beginAction(ReticleTool.ACT_AND_WAIT, asRecord(args));
|
|
@@ -428,7 +414,7 @@ export const ACT_TOOLS = [
|
|
|
428
414
|
const actedSource = sourceOf(r['source']);
|
|
429
415
|
// Remembered on the session so a LATER assertion can name a file even when its failure has no
|
|
430
416
|
// element to point at — a signal that never fired, a request that was never made.
|
|
431
|
-
session.
|
|
417
|
+
session.lastAct.markSource(actedSource === undefined ? undefined : `${actedSource.file}:${String(actedSource.line)}`);
|
|
432
418
|
const windowEvents = session.eventsSince(since);
|
|
433
419
|
const trace = summarizeReaction(buildReactionReport(windowEvents, session.elapsed() - since));
|
|
434
420
|
// The bounded Tier-1 causal summary — net/console/state/storage diffs the trace's counts miss.
|
|
@@ -446,48 +432,51 @@ export const ACT_TOOLS = [
|
|
|
446
432
|
// stronger than this block. Grade from the strongest asserted consequence; integrity from evictions.
|
|
447
433
|
// Coverage: cross-origin frames / other blind spots the SDK reported during this window mean the
|
|
448
434
|
// verdict didn't see everything — say so, never imply full coverage.
|
|
449
|
-
const
|
|
435
|
+
const spots = blindSpotsFromState(session.blindSpots());
|
|
436
|
+
const coverage = buildCoverageStatement(spots);
|
|
437
|
+
// Only a spot that IMPEACHES the capture belongs in integrity — see impeachesCapture. A
|
|
438
|
+
// structural boundary (virtualized rows, a cross-origin frame) is reported as coverage and
|
|
439
|
+
// must not downgrade a verdict about what WAS observed.
|
|
440
|
+
const impeaching = buildCoverageStatement(spots.filter((s) => impeachesCapture(s.kind)));
|
|
450
441
|
const honesty = buildHonestyBlock({
|
|
451
442
|
grade: gradeOf(gradedLinks),
|
|
452
443
|
attribution: 'window',
|
|
453
|
-
truncated: session.bufferHealth().dropped >
|
|
444
|
+
truncated: session.bufferHealth().dropped > droppedBefore,
|
|
454
445
|
coveragePartial: coverage.coverage === 'partial',
|
|
455
|
-
...(
|
|
446
|
+
...(impeaching.note === undefined ? {} : { blindSpots: [impeaching.note] }),
|
|
447
|
+
});
|
|
448
|
+
const capsuleSaved = await saveFailedAssertCapsule({
|
|
449
|
+
deps,
|
|
450
|
+
verdict,
|
|
451
|
+
capsule,
|
|
452
|
+
links,
|
|
453
|
+
args,
|
|
454
|
+
actResult,
|
|
455
|
+
...(actedSource === undefined ? {} : { actedSource }),
|
|
456
|
+
});
|
|
457
|
+
// Pass the action: an EMPTY window then reads as "the target does not react" rather than as a
|
|
458
|
+
// clean run — `settled` is satisfied by a page that did nothing, i.e. by a click that missed.
|
|
459
|
+
const acted = asString(args['action']);
|
|
460
|
+
const contradictions = findContradictions(windowEvents, {
|
|
461
|
+
action: acted,
|
|
462
|
+
...session.lastAct.effect(),
|
|
463
|
+
});
|
|
464
|
+
// The single field an agent reads. Everything below it is the evidence it was derived from;
|
|
465
|
+
// this is the only one that has to be interpreted, and now it interprets itself.
|
|
466
|
+
const outcomePending = hasAcceptedWrite(windowEvents);
|
|
467
|
+
const outcomeUnread = hasUnreadWriteOutcome(windowEvents);
|
|
468
|
+
const decision = decideVerified({
|
|
469
|
+
pass: verdict.pass,
|
|
470
|
+
honesty,
|
|
471
|
+
contradictions,
|
|
472
|
+
...(outcomePending ? { outcomePending } : {}),
|
|
473
|
+
...(outcomeUnread ? { outcomeUnread } : {}),
|
|
474
|
+
// `settled` is genuinely optional: a wait that declared no predicate never measured it, and
|
|
475
|
+
// passing `false` there would report "never settled" about something never asked to settle.
|
|
476
|
+
...(settledOutcome === undefined ? {} : { settled: settledOutcome }),
|
|
456
477
|
});
|
|
457
|
-
//: a red assertion is the ONE moment the evidence explaining it is in hand. Persist it as a
|
|
458
|
-
// replayable fail-to-pass capsule so the bug survives the turn — and becomes a regression flow
|
|
459
|
-
// the moment it goes green. Best-effort: capturing evidence must never fail the run that found it.
|
|
460
|
-
let capsuleSaved;
|
|
461
|
-
if (!verdict.pass && capsule !== undefined) {
|
|
462
|
-
const id = capsuleId(deps.now(), asString(args['ref']) ?? 'assert');
|
|
463
|
-
const expectedText = links
|
|
464
|
-
.map((l) => ('name' in l ? `${l.kind} ${l.name}` : l.kind))
|
|
465
|
-
.join(' AND ');
|
|
466
|
-
const saved = await new CapsuleStore(deps.fs, deps.reticleRoot).save({
|
|
467
|
-
version: 1,
|
|
468
|
-
id,
|
|
469
|
-
createdAt: deps.now(),
|
|
470
|
-
origin: 'failed-assert',
|
|
471
|
-
expected: expectedText.length > 0 ? expectedText : 'declared consequence',
|
|
472
|
-
observed: capsule.firstDivergence?.observed ?? verdict.failureReason ?? 'not observed',
|
|
473
|
-
steps: [
|
|
474
|
-
{
|
|
475
|
-
tool: ReticleTool.ACT,
|
|
476
|
-
anchor: {
|
|
477
|
-
kind: AnchorKind.TESTID,
|
|
478
|
-
value: asString(asRecord(actResult.result)['testid']) ?? asString(args['ref']) ?? '',
|
|
479
|
-
// Carried so the saved capsule — which outlives this turn and becomes a regression
|
|
480
|
-
// flow when it goes green — still knows which file the failure came from.
|
|
481
|
-
...(actedSource === undefined ? {} : { source: actedSource }),
|
|
482
|
-
},
|
|
483
|
-
action: (asString(args['action']) ?? ActionType.CLICK),
|
|
484
|
-
},
|
|
485
|
-
],
|
|
486
|
-
});
|
|
487
|
-
if (saved)
|
|
488
|
-
capsuleSaved = id;
|
|
489
|
-
}
|
|
490
478
|
return withControl(session, {
|
|
479
|
+
...decision,
|
|
491
480
|
effect: leanActResult(actResult.result),
|
|
492
481
|
verdict,
|
|
493
482
|
// Promoted out of `effect` on red only. On green nobody needs it and it is noise; on red it
|
|
@@ -499,6 +488,16 @@ export const ACT_TOOLS = [
|
|
|
499
488
|
trace,
|
|
500
489
|
...(capsuleSaved === undefined ? {} : { capsuleSaved }),
|
|
501
490
|
summary: causalSummary(windowEvents),
|
|
491
|
+
// Cross-channel disagreement, reported WITH the action that caused it.
|
|
492
|
+
//
|
|
493
|
+
// This is the one finding here a human structurally cannot make — they watch one channel,
|
|
494
|
+
// the screen, so a UI that advanced while its write failed looks like success to them and
|
|
495
|
+
// always will. It ran only inside reticle_observe, which means it was found only when the
|
|
496
|
+
// agent already suspected something and thought to go looking. That inverts the value: the
|
|
497
|
+
// whole point is catching what NOBODY suspected. It now travels with the action, so an
|
|
498
|
+
// agent cannot miss it by not asking. Omitted entirely when clean, so a healthy action
|
|
499
|
+
// pays nothing.
|
|
500
|
+
...(contradictions.length > 0 ? { contradictions } : {}),
|
|
502
501
|
honesty,
|
|
503
502
|
...(capsule === undefined ? {} : { capsule }),
|
|
504
503
|
since,
|
|
@@ -511,4 +510,3 @@ export const ACT_TOOLS = [
|
|
|
511
510
|
},
|
|
512
511
|
},
|
|
513
512
|
];
|
|
514
|
-
//# sourceMappingURL=act-tools.js.map
|
package/dist/tools/act-view.d.ts
CHANGED
|
@@ -16,4 +16,10 @@
|
|
|
16
16
|
*/
|
|
17
17
|
/** Return a copy of an act command result with its `effect` block leaned. Non-objects pass through. */
|
|
18
18
|
export declare function leanActResult(result: unknown): unknown;
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* DOM mutations the browser counted inside the acted element's own subtree.
|
|
21
|
+
*
|
|
22
|
+
* Nested under `effect` and OMITTED when zero (the lean-result rule drops uninformative defaults), so
|
|
23
|
+
* an absent field means zero rather than "not measured" — which is exactly the case that matters.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mutatedWithin(result: Record<string, unknown>): number | undefined;
|
package/dist/tools/act-view.js
CHANGED
|
@@ -43,4 +43,16 @@ export function leanActResult(result) {
|
|
|
43
43
|
return result;
|
|
44
44
|
return { ...r, effect: leanEffect(effect) };
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
* DOM mutations the browser counted inside the acted element's own subtree.
|
|
48
|
+
*
|
|
49
|
+
* Nested under `effect` and OMITTED when zero (the lean-result rule drops uninformative defaults), so
|
|
50
|
+
* an absent field means zero rather than "not measured" — which is exactly the case that matters.
|
|
51
|
+
*/
|
|
52
|
+
export function mutatedWithin(result) {
|
|
53
|
+
const effect = result['effect'];
|
|
54
|
+
if (typeof effect !== 'object' || effect === null)
|
|
55
|
+
return undefined;
|
|
56
|
+
const value = effect['domMutatedWithin'];
|
|
57
|
+
return typeof value === 'number' ? value : 0;
|
|
58
|
+
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Pure: no IO, no clock.
|
|
12
12
|
*/
|
|
13
|
+
import { HonestyGrade } from '../honesty/honesty.js';
|
|
13
14
|
import type { Predicate } from '../events/predicate.js';
|
|
14
15
|
export declare const PRESENCE_ONLY_ADVICE = "This predicate only checks element/text presence, not an observable consequence. A locator healed to the wrong element (or a stale render) can satisfy it while the feature is broken. Prefer a { signal } or { net } assertion \u2014 or allOf it with one \u2014 so green means the feature actually worked.";
|
|
15
16
|
/**
|
|
@@ -17,5 +18,25 @@ export declare const PRESENCE_ONLY_ADVICE = "This predicate only checks element/
|
|
|
17
18
|
* — the weak pattern worth nudging. A predicate that mixes in a consequence, or that checks something
|
|
18
19
|
* other than presence (route/console/settled), is not flagged.
|
|
19
20
|
*/
|
|
21
|
+
/**
|
|
22
|
+
* Advice for an assertion pinned to a status Reticle derived rather than one a server sent.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DERIVED_IPC_STATUS_ADVICE: string;
|
|
25
|
+
/**
|
|
26
|
+
* Does this predicate pin an IPC call to a status code?
|
|
27
|
+
*
|
|
28
|
+
* The 200/500 on an IPC record is a convenience so `reticle_network { status }` keeps working across
|
|
29
|
+
* runtimes — it is not something any server sent. An assertion built on it is really an assertion
|
|
30
|
+
* about Reticle's encoding, and would silently stop meaning what it meant if that encoding changed.
|
|
31
|
+
* Recognised by the `ipc://` scheme, so a genuine HTTP status is never second-guessed.
|
|
32
|
+
*/
|
|
33
|
+
export declare function assertsDerivedIpcStatus(predicate: Predicate): boolean;
|
|
20
34
|
export declare function isPresenceOnlyAssertion(predicate: Predicate): boolean;
|
|
21
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The tier a predicate actually proves, for the honesty block on a verdict.
|
|
37
|
+
*
|
|
38
|
+
* A signal or a network consequence is evidence the APP produced; a state read is one step removed;
|
|
39
|
+
* presence of an element is the weakest, because a wrong or healed element can satisfy it. The
|
|
40
|
+
* verdict carries this so "it passed" is always qualified by what it passed on.
|
|
41
|
+
*/
|
|
42
|
+
export declare function gradeOfPredicate(predicate: Predicate): HonestyGrade;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* Pure: no IO, no clock.
|
|
12
12
|
*/
|
|
13
13
|
import { isConsequenceKind, isPresenceKind } from '@reticlehq/core';
|
|
14
|
+
import { HonestyGrade } from '../honesty/honesty.js';
|
|
14
15
|
export const PRESENCE_ONLY_ADVICE = 'This predicate only checks element/text presence, not an observable consequence. A locator healed to the wrong element (or a stale render) can satisfy it while the feature is broken. Prefer a { signal } or { net } assertion — or allOf it with one — so green means the feature actually worked.';
|
|
15
16
|
function walk(predicate) {
|
|
16
17
|
if (predicate.kind === 'allOf' || predicate.kind === 'anyOf') {
|
|
@@ -34,8 +35,52 @@ function walk(predicate) {
|
|
|
34
35
|
* — the weak pattern worth nudging. A predicate that mixes in a consequence, or that checks something
|
|
35
36
|
* other than presence (route/console/settled), is not flagged.
|
|
36
37
|
*/
|
|
38
|
+
/**
|
|
39
|
+
* Advice for an assertion pinned to a status Reticle derived rather than one a server sent.
|
|
40
|
+
*/
|
|
41
|
+
export const DERIVED_IPC_STATUS_ADVICE = 'This asserts on a status code Reticle DERIVED — IPC has none. Prefer `{ ok: false }`, which ' +
|
|
42
|
+
'describes what the app did rather than how Reticle encoded it, and cannot drift if that encoding ' +
|
|
43
|
+
'changes. The `error` field carries the message the main process or Rust command actually returned.';
|
|
44
|
+
/**
|
|
45
|
+
* Does this predicate pin an IPC call to a status code?
|
|
46
|
+
*
|
|
47
|
+
* The 200/500 on an IPC record is a convenience so `reticle_network { status }` keeps working across
|
|
48
|
+
* runtimes — it is not something any server sent. An assertion built on it is really an assertion
|
|
49
|
+
* about Reticle's encoding, and would silently stop meaning what it meant if that encoding changed.
|
|
50
|
+
* Recognised by the `ipc://` scheme, so a genuine HTTP status is never second-guessed.
|
|
51
|
+
*/
|
|
52
|
+
export function assertsDerivedIpcStatus(predicate) {
|
|
53
|
+
if (predicate.kind === 'allOf' || predicate.kind === 'anyOf') {
|
|
54
|
+
return predicate.predicates.some(assertsDerivedIpcStatus);
|
|
55
|
+
}
|
|
56
|
+
if (predicate.kind === 'not')
|
|
57
|
+
return assertsDerivedIpcStatus(predicate.predicate);
|
|
58
|
+
if (predicate.kind !== 'net')
|
|
59
|
+
return false;
|
|
60
|
+
return (predicate.status !== undefined &&
|
|
61
|
+
predicate.ok === undefined &&
|
|
62
|
+
(predicate.urlContains ?? '').startsWith('ipc://'));
|
|
63
|
+
}
|
|
37
64
|
export function isPresenceOnlyAssertion(predicate) {
|
|
38
65
|
const kinds = walk(predicate);
|
|
39
66
|
return kinds.presence && !kinds.consequence;
|
|
40
67
|
}
|
|
41
|
-
|
|
68
|
+
/**
|
|
69
|
+
* The tier a predicate actually proves, for the honesty block on a verdict.
|
|
70
|
+
*
|
|
71
|
+
* A signal or a network consequence is evidence the APP produced; a state read is one step removed;
|
|
72
|
+
* presence of an element is the weakest, because a wrong or healed element can satisfy it. The
|
|
73
|
+
* verdict carries this so "it passed" is always qualified by what it passed on.
|
|
74
|
+
*/
|
|
75
|
+
export function gradeOfPredicate(predicate) {
|
|
76
|
+
switch (predicate.kind) {
|
|
77
|
+
case 'signal':
|
|
78
|
+
return HonestyGrade.SIGNAL;
|
|
79
|
+
case 'net':
|
|
80
|
+
return HonestyGrade.NET;
|
|
81
|
+
case 'state':
|
|
82
|
+
return HonestyGrade.STATE;
|
|
83
|
+
default:
|
|
84
|
+
return HonestyGrade.PRESENCE;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Predicate } from '../events/predicate.js';
|
|
2
|
+
import type { Session } from '../session/session.js';
|
|
3
|
+
import { type Contradiction } from '../events/contradictions.js';
|
|
4
|
+
/**
|
|
5
|
+
* The honesty verdict for a plain `reticle_assert`.
|
|
6
|
+
*
|
|
7
|
+
* This is the single field an agent reads, and it was missing from the most-used verdict path.
|
|
8
|
+
* `act_and_wait` has always returned it; `reticle_assert` returned a bare `pass: true`.
|
|
9
|
+
*
|
|
10
|
+
* Measured on a shipments console: a dispatch answered 202 Accepted, the row rendered "dispatched"
|
|
11
|
+
* optimistically, an assert taken right after the click returned `pass: true` with no caveat, and the
|
|
12
|
+
* server reverted the write to "held" 1.2s later. The 202 machinery that exists precisely to report
|
|
13
|
+
* that as `verified: "unknown"` was never reached, because the tool an agent actually calls did not
|
|
14
|
+
* consult it. Asserting a moment earlier — while the POST was still open — is the same story with a
|
|
15
|
+
* different name: `request-never-settled`, also unreported.
|
|
16
|
+
*/
|
|
17
|
+
export declare function assertVerdict(session: Session, predicate: Predicate, pass: boolean, since: number): Promise<{
|
|
18
|
+
decision: Record<string, unknown>;
|
|
19
|
+
contradictions: Contradiction[];
|
|
20
|
+
coverage: Record<string, unknown>;
|
|
21
|
+
}>;
|