@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
package/dist/cloud-cli.d.ts
CHANGED
package/dist/cloud-cli.js
CHANGED
|
@@ -102,7 +102,15 @@ const api = async (method, url, token, body) => {
|
|
|
102
102
|
init.body = JSON.stringify(body);
|
|
103
103
|
const res = await fetch(url, init);
|
|
104
104
|
const text = await res.text();
|
|
105
|
-
|
|
105
|
+
let json = null;
|
|
106
|
+
if (text.length > 0) {
|
|
107
|
+
try {
|
|
108
|
+
json = JSON.parse(text);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
throw new Error(`expected JSON from ${method} ${url} but got: ${text.slice(0, 120)}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
106
114
|
if (!res.ok) {
|
|
107
115
|
const parsed = z.object({ error: z.object({ message: z.string() }) }).safeParse(json);
|
|
108
116
|
throw new Error(parsed.success ? parsed.data.error.message : `${res.status} ${res.statusText}`);
|
|
@@ -504,4 +512,3 @@ export const runCloudCommand = async (argv) => {
|
|
|
504
512
|
return 1;
|
|
505
513
|
}
|
|
506
514
|
};
|
|
507
|
-
//# sourceMappingURL=cloud-cli.js.map
|
|
@@ -11,7 +11,7 @@ const nodeSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
11
11
|
export const CRAWL_TOOLS = [
|
|
12
12
|
{
|
|
13
13
|
name: ReticleTool.CRAWL,
|
|
14
|
-
description: 'Autonomously click every reachable interactive control (bounded by maxSteps, default 25) and report anomalies WITHOUT a script: console errors, failed requests
|
|
14
|
+
description: 'Autonomously click every reachable interactive control (bounded by maxSteps, default 25) and report anomalies WITHOUT a script. Two classes: single-channel faults (console errors, failed requests ≥400, DEAD controls that dispatched but did nothing) and CONTRADICTIONS — two channels disagreeing about the same click, e.g. the UI advanced while its write failed, a success signal fired over a failed request, a write succeeded and nothing changed, the same write fired twice, or the UI moved on over an in-flight request. Contradictions are the false greens a human cannot see, because a human watches one channel (the screen) and it looks correct. DESTRUCTIVE — it really clicks (may navigate/mutate state); use reticle_explore first for a non-destructive list. Returns { interactiveFound, stepsRun, anomalies[{kind,ref,desc,detail}], counts, visited, truncated }.',
|
|
15
15
|
inputSchema: {
|
|
16
16
|
maxSteps: z.number().optional().describe('Maximum number of controls to click. Default: 25.'),
|
|
17
17
|
settleMs: z
|
|
@@ -70,4 +70,3 @@ export const CRAWL_TOOLS = [
|
|
|
70
70
|
},
|
|
71
71
|
},
|
|
72
72
|
];
|
|
73
|
-
//# sourceMappingURL=crawl-tools.js.map
|
package/dist/crawl/crawl.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CrawlAnomalyKind, type CommandResult, type ReticleEvent } from '@reticlehq/core';
|
|
1
|
+
import { CrawlAnomalyKind, ContradictionKind, type CommandResult, type ReticleEvent } from '@reticlehq/core';
|
|
2
2
|
/** The slice of Session the crawler needs — so tests inject a fake without a live browser. */
|
|
3
3
|
export interface CrawlSession {
|
|
4
4
|
command(name: string, args?: Record<string, unknown>): Promise<CommandResult>;
|
|
@@ -16,7 +16,13 @@ export interface CrawlSession {
|
|
|
16
16
|
}
|
|
17
17
|
type CrawlSleep = (ms: number) => Promise<void>;
|
|
18
18
|
export interface CrawlAnomaly {
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* A single-channel fault (something bad in one stream) or a CONTRADICTION (two channels
|
|
21
|
+
* disagreeing about the same click). The second kind is why an autonomous crawl is worth more
|
|
22
|
+
* than a human clicking the same buttons: a person sees only the screen, so a UI that advanced
|
|
23
|
+
* while its write failed looks like success to them and always will.
|
|
24
|
+
*/
|
|
25
|
+
kind: CrawlAnomalyKind | ContradictionKind;
|
|
20
26
|
/** The control that triggered it. */
|
|
21
27
|
ref: string;
|
|
22
28
|
desc: string;
|
|
@@ -41,6 +47,7 @@ export interface CrawlReport {
|
|
|
41
47
|
consoleErrors: number;
|
|
42
48
|
failedRequests: number;
|
|
43
49
|
deadControls: number;
|
|
50
|
+
contradictions: number;
|
|
44
51
|
};
|
|
45
52
|
/** Descriptions of the controls actually clicked. */
|
|
46
53
|
visited: string[];
|
|
@@ -62,6 +69,13 @@ export interface CrawlOptions {
|
|
|
62
69
|
* orchestration over a CrawlSession: no browser/Node imports, fully unit-testable with a fake.
|
|
63
70
|
* Single-pass by design (no re-discovery) so it always terminates and never explodes on navigation.
|
|
64
71
|
*/
|
|
72
|
+
/**
|
|
73
|
+
* Controls whose correct behaviour IS to do nothing when clicked.
|
|
74
|
+
*
|
|
75
|
+
* Read off the same descriptor the crawler already has, so no extra round trip: `[disabled]` is inert
|
|
76
|
+
* by definition, an already `[checked]` radio/checkbox is idempotent, and clicking a text field
|
|
77
|
+
* focuses it rather than changing anything.
|
|
78
|
+
*/
|
|
79
|
+
export declare function legitimatelyInert(desc: string): boolean;
|
|
65
80
|
export declare function crawl(session: CrawlSession, opts: CrawlOptions, sleep: CrawlSleep): Promise<CrawlReport>;
|
|
66
81
|
export {};
|
|
67
|
-
//# sourceMappingURL=crawl.d.ts.map
|
package/dist/crawl/crawl.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ActionType, CRAWL_DEFAULTS, CrawlAnomalyKind, DANGEROUS_ACTION_CONFIRM_ARG, EventType, ReticleCommand, } from '@reticlehq/core';
|
|
1
|
+
import { ActionType, CRAWL_DEFAULTS, CrawlAnomalyKind, ContradictionKind, DANGEROUS_ACTION_CONFIRM_ARG, EventType, ReticleCommand, } from '@reticlehq/core';
|
|
2
2
|
import { parseInteractive, asRecord, asNumber, asString, sourceOf, } from '../tools/tools-helpers.js';
|
|
3
3
|
import { ReticleTool } from '../tools/tool-names.js';
|
|
4
|
+
import { findContradictions } from '../events/contradictions.js';
|
|
4
5
|
/** Said out loud when the page was larger than one snapshot, so a clean sweep cannot mean "all clear". */
|
|
5
6
|
export const CAPPED_SNAPSHOT_NOTE = 'the page exceeded one snapshot, so controls past the cap were never seen — interactiveFound is a floor, not a total; re-run with a narrower `scope` to cover the rest';
|
|
6
7
|
/** Any buffer event that proves the app reacted to a click (vs a dead/no-op control). */
|
|
@@ -33,6 +34,20 @@ function failedRequests(events, floor) {
|
|
|
33
34
|
* orchestration over a CrawlSession: no browser/Node imports, fully unit-testable with a fake.
|
|
34
35
|
* Single-pass by design (no re-discovery) so it always terminates and never explodes on navigation.
|
|
35
36
|
*/
|
|
37
|
+
/**
|
|
38
|
+
* Controls whose correct behaviour IS to do nothing when clicked.
|
|
39
|
+
*
|
|
40
|
+
* Read off the same descriptor the crawler already has, so no extra round trip: `[disabled]` is inert
|
|
41
|
+
* by definition, an already `[checked]` radio/checkbox is idempotent, and clicking a text field
|
|
42
|
+
* focuses it rather than changing anything.
|
|
43
|
+
*/
|
|
44
|
+
export function legitimatelyInert(desc) {
|
|
45
|
+
if (desc.includes('[disabled]'))
|
|
46
|
+
return true;
|
|
47
|
+
if (desc.includes('[checked]'))
|
|
48
|
+
return true;
|
|
49
|
+
return /\b(textbox|searchbox|combobox|spinbutton)\b/.test(desc);
|
|
50
|
+
}
|
|
36
51
|
export async function crawl(session, opts, sleep) {
|
|
37
52
|
const maxSteps = opts.maxSteps ?? CRAWL_DEFAULTS.MAX_STEPS;
|
|
38
53
|
const settleMs = opts.settleMs ?? CRAWL_DEFAULTS.SETTLE_MS;
|
|
@@ -50,7 +65,7 @@ export async function crawl(session, opts, sleep) {
|
|
|
50
65
|
const coverageCapped = snapshot.truncated === true;
|
|
51
66
|
const anomalies = [];
|
|
52
67
|
const visited = [];
|
|
53
|
-
const counts = { consoleErrors: 0, failedRequests: 0, deadControls: 0 };
|
|
68
|
+
const counts = { consoleErrors: 0, failedRequests: 0, deadControls: 0, contradictions: 0 };
|
|
54
69
|
const seen = new Set();
|
|
55
70
|
let stepsRun = 0;
|
|
56
71
|
for (const item of items) {
|
|
@@ -107,9 +122,34 @@ export async function crawl(session, opts, sleep) {
|
|
|
107
122
|
...source,
|
|
108
123
|
});
|
|
109
124
|
}
|
|
125
|
+
// CONTRADICTIONS: the channels disagree about what this click did. Reported per control, so a
|
|
126
|
+
// crawl of an unknown app surfaces its false greens without anyone knowing where to look.
|
|
127
|
+
for (const c of findContradictions(events)) {
|
|
128
|
+
counts.contradictions += 1;
|
|
129
|
+
anomalies.push({
|
|
130
|
+
kind: c.kind,
|
|
131
|
+
ref: item.ref,
|
|
132
|
+
desc: item.desc,
|
|
133
|
+
detail: `${c.claim}, but ${c.counter} — ${c.detail}`,
|
|
134
|
+
...source,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
110
137
|
// DEAD: the click dispatched but the app produced no activity and no error to explain it.
|
|
138
|
+
//
|
|
139
|
+
// Unless the control is SUPPOSED to be inert. Measured on a shipments console: every one of the
|
|
140
|
+
// crawler's three anomalies was a control behaving correctly — a `[disabled]` button, an already
|
|
141
|
+
// `[checked]` radio, and a text input (a click focuses it; mutating would be the surprise). An
|
|
142
|
+
// anomaly list that is 100% false on a real app is worse than no anomaly list, because the agent
|
|
143
|
+
// spends its budget disproving it and learns to skip the field.
|
|
144
|
+
//
|
|
145
|
+
// Deliberately NOT fixed by counting focus as activity: focus moving is not the app reacting, and
|
|
146
|
+
// treating it as such would make a genuinely dead button that takes focus look alive — trading
|
|
147
|
+
// noise for the false negative this check exists to catch.
|
|
111
148
|
const dispatched = asRecord(act.result)['dispatched'] !== false && act.ok;
|
|
112
|
-
if (dispatched &&
|
|
149
|
+
if (dispatched &&
|
|
150
|
+
errs.length === 0 &&
|
|
151
|
+
!events.some(isActivity) &&
|
|
152
|
+
!legitimatelyInert(item.desc)) {
|
|
113
153
|
counts.deadControls += 1;
|
|
114
154
|
anomalies.push({
|
|
115
155
|
kind: CrawlAnomalyKind.DEAD_CONTROL,
|
|
@@ -133,4 +173,3 @@ export async function crawl(session, opts, sleep) {
|
|
|
133
173
|
...(coverageCapped ? { coverageNote: CAPPED_SNAPSHOT_NOTE } : {}),
|
|
134
174
|
};
|
|
135
175
|
}
|
|
136
|
-
//# sourceMappingURL=crawl.js.map
|
|
@@ -12,6 +12,11 @@ export interface ProcessLike {
|
|
|
12
12
|
on(event: string, listener: (arg: unknown) => void): unknown;
|
|
13
13
|
}
|
|
14
14
|
type LogFn = (event: string, data: Record<string, unknown>) => void;
|
|
15
|
+
/** The two ways a failure reaches the top of the process. Named so the analytics can tell them apart. */
|
|
16
|
+
export declare const CrashKind: {
|
|
17
|
+
readonly UNHANDLED_REJECTION: "unhandled_rejection";
|
|
18
|
+
readonly UNCAUGHT_EXCEPTION: "uncaught_exception";
|
|
19
|
+
};
|
|
20
|
+
export type CrashKind = (typeof CrashKind)[keyof typeof CrashKind];
|
|
15
21
|
export declare function installDaemonResilience(proc: ProcessLike, log: LogFn, onFatal: () => void): void;
|
|
16
22
|
export {};
|
|
17
|
-
//# sourceMappingURL=daemon-resilience.d.ts.map
|
|
@@ -8,16 +8,78 @@
|
|
|
8
8
|
* per Node's guidance, so LOG a clear reason and exit cleanly; the next `reticle mcp` respawns a fresh
|
|
9
9
|
* daemon, which beats crashing silently or limping along corrupt.
|
|
10
10
|
*/
|
|
11
|
+
import { TelemetryActor, TelemetryEventKind } from '@reticlehq/core';
|
|
12
|
+
import { errorSkeleton, errorTypeOf, fingerprintCrash, MAX_REPORTED_FRAMES, reticleFrames, } from './telemetry/error-fingerprint.js';
|
|
13
|
+
import { getSessionMetrics } from './telemetry/session-metrics.js';
|
|
14
|
+
import { machineSnapshot } from './telemetry/machine-snapshot.js';
|
|
15
|
+
import { getTelemetry } from './telemetry/telemetry.js';
|
|
11
16
|
function describe(value) {
|
|
12
17
|
return value instanceof Error ? value.message : String(value);
|
|
13
18
|
}
|
|
19
|
+
/** The two ways a failure reaches the top of the process. Named so the analytics can tell them apart. */
|
|
20
|
+
export const CrashKind = {
|
|
21
|
+
UNHANDLED_REJECTION: 'unhandled_rejection',
|
|
22
|
+
UNCAUGHT_EXCEPTION: 'uncaught_exception',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Report a crash with enough detail to actually diagnose it.
|
|
26
|
+
*
|
|
27
|
+
* This is the only place in the product that learns about a crash at all. An uncaught exception in a
|
|
28
|
+
* long-running daemon takes down every agent attached to it, and the only other record is a line in a
|
|
29
|
+
* local log nobody sends us.
|
|
30
|
+
*
|
|
31
|
+
* The first version sent a hash and nothing else, which made crashes rankable and undiagnosable — you
|
|
32
|
+
* could see that forty machines hit `a3f2c1d8e9b0` and had no way to learn what that was. So it now
|
|
33
|
+
* carries the four things an RCA needs: WHERE (our own frames, with function names and line numbers),
|
|
34
|
+
* WHAT (the message with every variable part stripped), WHEN (the tool in flight), and WHY-ish (the
|
|
35
|
+
* agent's approach run before it). All of it is our code and our vocabulary; the user's stack frames,
|
|
36
|
+
* their paths, and the contents of their message are removed before any of it is built.
|
|
37
|
+
*
|
|
38
|
+
* Best-effort and wrapped: reporting a crash must never be the reason a crash gets worse.
|
|
39
|
+
*/
|
|
40
|
+
function reportCrash(kind, value) {
|
|
41
|
+
try {
|
|
42
|
+
const errorType = errorTypeOf(value);
|
|
43
|
+
const stack = value instanceof Error ? (value.stack ?? '') : '';
|
|
44
|
+
const message = describe(value);
|
|
45
|
+
const { breadcrumb, inFlight } = getSessionMetrics().trail;
|
|
46
|
+
const machine = machineSnapshot();
|
|
47
|
+
void getTelemetry().emit(TelemetryEventKind.RUNTIME_CRASHED, {
|
|
48
|
+
// A crash is ALWAYS reached through something the agent asked for — the daemon does nothing on
|
|
49
|
+
// its own — so attributing it to the agent is accurate rather than a guess.
|
|
50
|
+
actor: TelemetryActor.AGENT,
|
|
51
|
+
crash: {
|
|
52
|
+
kind,
|
|
53
|
+
errorType,
|
|
54
|
+
fingerprint: fingerprintCrash(errorType, stack, message),
|
|
55
|
+
// The skeleton, not the message: every quoted string, path, URL, id and number is replaced
|
|
56
|
+
// by `*` first. This is what makes the fingerprint mean something to a human reading a chart.
|
|
57
|
+
message: errorSkeleton(message).slice(0, 300),
|
|
58
|
+
// Our own frames, our own published code. The file, the line, and the function — which is the
|
|
59
|
+
// whole of "where did it break". Frames from the user's app never survive this.
|
|
60
|
+
frames: reticleFrames(stack).slice(0, MAX_REPORTED_FRAMES),
|
|
61
|
+
...(inFlight !== undefined ? { tool: inFlight } : {}),
|
|
62
|
+
...(breadcrumb.length > 0 ? { breadcrumb } : {}),
|
|
63
|
+
// Crashes cluster hard by runtime version and architecture, and we were recording neither.
|
|
64
|
+
nodeVersion: process.versions.node,
|
|
65
|
+
arch: process.arch,
|
|
66
|
+
// "Out of memory" and "our bug" look identical in a stack trace. This is what tells them apart.
|
|
67
|
+
...(machine !== undefined ? { machine } : {}),
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* a crash report must never be the reason a crash gets worse */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
14
75
|
export function installDaemonResilience(proc, log, onFatal) {
|
|
15
76
|
proc.on('unhandledRejection', (reason) => {
|
|
16
77
|
log('reticle_daemon_unhandled_rejection', { reason: describe(reason) });
|
|
78
|
+
reportCrash(CrashKind.UNHANDLED_REJECTION, reason);
|
|
17
79
|
});
|
|
18
80
|
proc.on('uncaughtException', (err) => {
|
|
19
81
|
log('reticle_daemon_uncaught_exception', { error: describe(err) });
|
|
82
|
+
reportCrash(CrashKind.UNCAUGHT_EXCEPTION, err);
|
|
20
83
|
onFatal();
|
|
21
84
|
});
|
|
22
85
|
}
|
|
23
|
-
//# sourceMappingURL=daemon-resilience.js.map
|
package/dist/daemon.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function logPath(port: number): string;
|
|
2
|
-
export declare function readPid(port: number): number | null;
|
|
2
|
+
export declare function readPid(port: number, home?: string): number | null;
|
|
3
3
|
export declare function isAlive(pid: number): boolean;
|
|
4
4
|
export declare function writePid(port: number): void;
|
|
5
5
|
/**
|
|
@@ -41,10 +41,30 @@ export declare function discoverDaemonPort(): number | null;
|
|
|
41
41
|
* ~/.reticle and the process.kill(pid,0) liveness probe).
|
|
42
42
|
*/
|
|
43
43
|
export declare function reclaimStaleDaemons(home?: string, pidAlive?: (pid: number) => boolean): number[];
|
|
44
|
+
/** The minimal shape of a spawned child that spawnDaemon uses. */
|
|
45
|
+
export interface SpawnedChild {
|
|
46
|
+
readonly pid?: number | undefined;
|
|
47
|
+
on(event: string, handler: (...args: unknown[]) => void): unknown;
|
|
48
|
+
unref(): void;
|
|
49
|
+
}
|
|
50
|
+
/** Injectable deps for spawnDaemon — the testability seam. Defaults to the real implementations. */
|
|
51
|
+
export interface SpawnDaemonDeps {
|
|
52
|
+
readonly home: string;
|
|
53
|
+
openFile(path: string, flags: string): number;
|
|
54
|
+
closeFile(fd: number): void;
|
|
55
|
+
spawnChild(command: string, args: readonly string[], options: {
|
|
56
|
+
detached: boolean;
|
|
57
|
+
stdio: readonly ('ignore' | number)[];
|
|
58
|
+
}): SpawnedChild;
|
|
59
|
+
pidAlive(pid: number): boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare function defaultSpawnDaemonDeps(): SpawnDaemonDeps;
|
|
44
62
|
/**
|
|
45
63
|
* Spawn the reticle daemon as a detached background process, redirecting output to the log file.
|
|
46
64
|
* Writes the PID file from the parent before returning so callers can call isRunning
|
|
47
65
|
* immediately without a race window.
|
|
66
|
+
*
|
|
67
|
+
* `deps` is injectable for testing (default: real fs/spawn against ~/.reticle). The same seam
|
|
68
|
+
* pattern as reclaimStaleDaemons(home, pidAlive).
|
|
48
69
|
*/
|
|
49
|
-
export declare function spawnDaemon(nodeExec: string, scriptPath: string, args: string[], port: number): boolean;
|
|
50
|
-
//# sourceMappingURL=daemon.d.ts.map
|
|
70
|
+
export declare function spawnDaemon(nodeExec: string, scriptPath: string, args: string[], port: number, deps?: SpawnDaemonDeps): boolean;
|
package/dist/daemon.js
CHANGED
|
@@ -4,8 +4,8 @@ import { mkdirSync, readFileSync, writeFileSync, existsSync, unlinkSync, openSyn
|
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
5
|
import { daemonRegistryFileName, daemonRegistryPort, DaemonRegistryEntrySchema, pickDaemonPort, } from '@reticlehq/core';
|
|
6
6
|
const RETICLE_HOME = join(homedir(), '.reticle');
|
|
7
|
-
function pidPath(port) {
|
|
8
|
-
return join(
|
|
7
|
+
function pidPath(port, home = RETICLE_HOME) {
|
|
8
|
+
return join(home, `daemon-${port}.pid`);
|
|
9
9
|
}
|
|
10
10
|
function registryPath(port) {
|
|
11
11
|
return join(RETICLE_HOME, daemonRegistryFileName(port));
|
|
@@ -13,8 +13,8 @@ function registryPath(port) {
|
|
|
13
13
|
export function logPath(port) {
|
|
14
14
|
return join(RETICLE_HOME, `daemon-${port}.log`);
|
|
15
15
|
}
|
|
16
|
-
export function readPid(port) {
|
|
17
|
-
const path = pidPath(port);
|
|
16
|
+
export function readPid(port, home = RETICLE_HOME) {
|
|
17
|
+
const path = pidPath(port, home);
|
|
18
18
|
if (!existsSync(path))
|
|
19
19
|
return null;
|
|
20
20
|
const n = parseInt(readFileSync(path, 'utf8').trim(), 10);
|
|
@@ -180,28 +180,41 @@ export function reclaimStaleDaemons(home = RETICLE_HOME, pidAlive = isAlive) {
|
|
|
180
180
|
}
|
|
181
181
|
return reclaimed;
|
|
182
182
|
}
|
|
183
|
+
export function defaultSpawnDaemonDeps() {
|
|
184
|
+
return {
|
|
185
|
+
home: RETICLE_HOME,
|
|
186
|
+
openFile: openSync,
|
|
187
|
+
closeFile: closeSync,
|
|
188
|
+
spawnChild: (command, args, options) => spawn(command, [...args], { detached: options.detached, stdio: [...options.stdio] }),
|
|
189
|
+
pidAlive: isAlive,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
183
192
|
/**
|
|
184
193
|
* Spawn the reticle daemon as a detached background process, redirecting output to the log file.
|
|
185
194
|
* Writes the PID file from the parent before returning so callers can call isRunning
|
|
186
195
|
* immediately without a race window.
|
|
196
|
+
*
|
|
197
|
+
* `deps` is injectable for testing (default: real fs/spawn against ~/.reticle). The same seam
|
|
198
|
+
* pattern as reclaimStaleDaemons(home, pidAlive).
|
|
187
199
|
*/
|
|
188
|
-
export function spawnDaemon(nodeExec, scriptPath, args, port) {
|
|
189
|
-
mkdirSync(
|
|
190
|
-
const
|
|
200
|
+
export function spawnDaemon(nodeExec, scriptPath, args, port, deps = defaultSpawnDaemonDeps()) {
|
|
201
|
+
mkdirSync(deps.home, { recursive: true });
|
|
202
|
+
const pidFilePath = join(deps.home, `daemon-${port}.pid`);
|
|
203
|
+
const logFilePath = join(deps.home, `daemon-${port}.log`);
|
|
191
204
|
// O_EXCL spawn-lock: only the FIRST racer to create the pidfile spawns. A concurrent second gets
|
|
192
205
|
// EEXIST — if a LIVE daemon owns the port it skips (no duplicate detached daemon, no clobbered pid);
|
|
193
206
|
// a stale pidfile from a crashed daemon is reclaimed. Returns false when it did not spawn.
|
|
194
207
|
let lockFd;
|
|
195
208
|
try {
|
|
196
|
-
lockFd =
|
|
209
|
+
lockFd = deps.openFile(pidFilePath, 'wx');
|
|
197
210
|
}
|
|
198
211
|
catch {
|
|
199
|
-
const existing = readPid(port);
|
|
200
|
-
if (existing !== null &&
|
|
212
|
+
const existing = readPid(port, deps.home);
|
|
213
|
+
if (existing !== null && deps.pidAlive(existing))
|
|
201
214
|
return false;
|
|
202
215
|
try {
|
|
203
|
-
unlinkSync(
|
|
204
|
-
lockFd =
|
|
216
|
+
unlinkSync(pidFilePath);
|
|
217
|
+
lockFd = deps.openFile(pidFilePath, 'wx');
|
|
205
218
|
}
|
|
206
219
|
catch {
|
|
207
220
|
return false; // lost a concurrent reclaim race
|
|
@@ -209,13 +222,13 @@ export function spawnDaemon(nodeExec, scriptPath, args, port) {
|
|
|
209
222
|
}
|
|
210
223
|
let logFd;
|
|
211
224
|
try {
|
|
212
|
-
logFd =
|
|
225
|
+
logFd = deps.openFile(logFilePath, 'a');
|
|
213
226
|
}
|
|
214
227
|
catch {
|
|
215
228
|
// Log path unwritable (permissions, disk full). Clean up the lock so we don't leave a ghost.
|
|
216
|
-
|
|
229
|
+
deps.closeFile(lockFd);
|
|
217
230
|
try {
|
|
218
|
-
unlinkSync(
|
|
231
|
+
unlinkSync(pidFilePath);
|
|
219
232
|
}
|
|
220
233
|
catch {
|
|
221
234
|
// racing another reclaimer — fine
|
|
@@ -224,17 +237,17 @@ export function spawnDaemon(nodeExec, scriptPath, args, port) {
|
|
|
224
237
|
}
|
|
225
238
|
let child;
|
|
226
239
|
try {
|
|
227
|
-
child =
|
|
240
|
+
child = deps.spawnChild(nodeExec, [scriptPath, ...args], {
|
|
228
241
|
detached: true,
|
|
229
242
|
stdio: ['ignore', logFd, logFd],
|
|
230
243
|
});
|
|
231
244
|
}
|
|
232
245
|
catch {
|
|
233
246
|
// spawn can throw synchronously on some platforms (e.g. ENOMEM, invalid args).
|
|
234
|
-
|
|
235
|
-
|
|
247
|
+
deps.closeFile(logFd);
|
|
248
|
+
deps.closeFile(lockFd);
|
|
236
249
|
try {
|
|
237
|
-
unlinkSync(
|
|
250
|
+
unlinkSync(pidFilePath);
|
|
238
251
|
}
|
|
239
252
|
catch {
|
|
240
253
|
// racing another reclaimer — fine
|
|
@@ -242,7 +255,7 @@ export function spawnDaemon(nodeExec, scriptPath, args, port) {
|
|
|
242
255
|
return false;
|
|
243
256
|
}
|
|
244
257
|
// The parent's copy of logFd is no longer needed — spawn duplicated it into the child.
|
|
245
|
-
|
|
258
|
+
deps.closeFile(logFd);
|
|
246
259
|
// Suppress the async ENOENT/EACCES that fires when the executable is missing or unexecutable.
|
|
247
260
|
// The failure is already detected synchronously via `child.pid === undefined`; without this
|
|
248
261
|
// handler the error propagates as an uncaught exception and crashes the parent process.
|
|
@@ -250,9 +263,9 @@ export function spawnDaemon(nodeExec, scriptPath, args, port) {
|
|
|
250
263
|
if (child.pid === undefined) {
|
|
251
264
|
// Spawn failed silently (resource exhaustion, invalid executable on some platforms). The pidfile
|
|
252
265
|
// is empty — clean it up so discovery doesn't see a ghost, and report failure honestly.
|
|
253
|
-
|
|
266
|
+
deps.closeFile(lockFd);
|
|
254
267
|
try {
|
|
255
|
-
unlinkSync(
|
|
268
|
+
unlinkSync(pidFilePath);
|
|
256
269
|
}
|
|
257
270
|
catch {
|
|
258
271
|
// racing another reclaimer — fine
|
|
@@ -260,8 +273,7 @@ export function spawnDaemon(nodeExec, scriptPath, args, port) {
|
|
|
260
273
|
return false;
|
|
261
274
|
}
|
|
262
275
|
writeFileSync(lockFd, String(child.pid), 'utf8');
|
|
263
|
-
|
|
276
|
+
deps.closeFile(lockFd);
|
|
264
277
|
child.unref();
|
|
265
278
|
return true;
|
|
266
279
|
}
|
|
267
|
-
//# sourceMappingURL=daemon.js.map
|
|
@@ -108,7 +108,7 @@ export function buildDomainModel(flows, contract, runs = []) {
|
|
|
108
108
|
}
|
|
109
109
|
function buildSummary(flowCount, coverage, gaps, topRisk) {
|
|
110
110
|
if (flowCount === 0) {
|
|
111
|
-
return 'No saved flows yet — record the critical journeys (
|
|
111
|
+
return 'No saved flows yet — record the critical journeys (reticle_record{action:"start"}) so the agent learns the app.';
|
|
112
112
|
}
|
|
113
113
|
const parts = [
|
|
114
114
|
`${String(flowCount)} flow${flowCount === 1 ? '' : 's'}: ${String(coverage.asserted)} asserted, ${String(coverage.presenceOnly)} presence-only, ${String(coverage.assertionFree)} assertion-free`,
|
|
@@ -124,4 +124,3 @@ function buildSummary(flowCount, coverage, gaps, topRisk) {
|
|
|
124
124
|
}
|
|
125
125
|
return parts.join('. ') + '.';
|
|
126
126
|
}
|
|
127
|
-
//# sourceMappingURL=domain-model.js.map
|
|
@@ -1,9 +1,2 @@
|
|
|
1
1
|
import type { ToolDef } from '../tools/tools.js';
|
|
2
|
-
/**
|
|
3
|
-
* reticle_domain — the "learn the app before testing it" tool. Synthesizes every saved flow + the
|
|
4
|
-
* registered capabilities into a compact domain model: the journeys, what each asserts, and the
|
|
5
|
-
* GAPS (declared signals/testids no flow verifies). An agent reads this once instead of crawling
|
|
6
|
-
* the whole app or reading all the source — and it points straight at untested intent.
|
|
7
|
-
*/
|
|
8
2
|
export declare const DOMAIN_TOOLS: ToolDef[];
|
|
9
|
-
//# sourceMappingURL=domain-tools.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { asNumber } from '../tools/tools-helpers.js';
|
|
2
3
|
import { ReticleTool } from '../tools/tool-names.js';
|
|
3
4
|
import { readContract } from '../project/reticle-dir.js';
|
|
4
5
|
import { buildDomainModel } from './domain-model.js';
|
|
@@ -10,11 +11,18 @@ import { instrumentationGapsForFlows } from '../oracles/flow-instrument-gaps.js'
|
|
|
10
11
|
* GAPS (declared signals/testids no flow verifies). An agent reads this once instead of crawling
|
|
11
12
|
* the whole app or reading all the source — and it points straight at untested intent.
|
|
12
13
|
*/
|
|
14
|
+
/** Flows detailed when the caller does not ask for a specific count. */
|
|
15
|
+
const DEFAULT_FLOW_DETAIL_LIMIT = 25;
|
|
13
16
|
export const DOMAIN_TOOLS = [
|
|
14
17
|
{
|
|
15
18
|
name: ReticleTool.DOMAIN,
|
|
16
19
|
description: 'Read the app domain model BEFORE testing: every saved flow with its assertion grade, the consequence that MUST hold for it (mustHold = what it actually tests), the anchors/signals it exercises, plus GAPS — declared signals/testids that NO flow asserts (untested intent), and flows that assert no observable consequence. Use this to decide what to test and where the real risk is, instead of crawling the whole app. Reads .reticle/flows/ + .reticle/contract.json (no browser needed).',
|
|
17
|
-
inputSchema: {
|
|
20
|
+
inputSchema: {
|
|
21
|
+
limit: z
|
|
22
|
+
.number()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Most-recent N flows to detail. Defaults to 25 — the per-flow list grows with every saved flow (measured at ~11KB / ~2,700 tokens at 22 flows) and a large project would spend most of an agent context on flows it is not asking about. `flowCount` is always the true total, and the gaps/coverage summary is computed over ALL flows regardless, so capping the detail never changes the analysis.'),
|
|
25
|
+
},
|
|
18
26
|
outputSchema: {
|
|
19
27
|
flowCount: z.number(),
|
|
20
28
|
flows: z.array(z.object({
|
|
@@ -35,6 +43,10 @@ export const DOMAIN_TOOLS = [
|
|
|
35
43
|
signals: z.array(z.string()),
|
|
36
44
|
stores: z.array(z.string()),
|
|
37
45
|
}),
|
|
46
|
+
flowsTruncated: z
|
|
47
|
+
.number()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('How many flows were omitted from `flows` by `limit`. Absent means the listing is complete. gaps/coverage always cover every flow.'),
|
|
38
50
|
coverage: z.object({
|
|
39
51
|
asserted: z.number(),
|
|
40
52
|
presenceOnly: z.number(),
|
|
@@ -54,7 +66,7 @@ export const DOMAIN_TOOLS = [
|
|
|
54
66
|
.optional()
|
|
55
67
|
.describe('Ready-to-apply instrumentation proposals for gaps that have a source location — { file, line, insert, rationale }. Apply, re-verify, and the app’s observability compounds.'),
|
|
56
68
|
},
|
|
57
|
-
handler: async (deps) => {
|
|
69
|
+
handler: async (deps, args) => {
|
|
58
70
|
const names = await deps.flows.list();
|
|
59
71
|
const flows = [];
|
|
60
72
|
for (const name of names) {
|
|
@@ -69,8 +81,13 @@ export const DOMAIN_TOOLS = [
|
|
|
69
81
|
// Self-instrumentation: turn located gaps (unasserted flows with a source stamp) into apply-ready diffs.
|
|
70
82
|
const stepsByName = new Map(flows.map((f) => [f.name, f.steps]));
|
|
71
83
|
const instrumentation = proposeInstrumentation(instrumentationGapsForFlows(model.gaps.unassertedFlows, stepsByName));
|
|
72
|
-
|
|
84
|
+
// The per-flow detail is capped; `flowCount`, `gaps` and `coverage` are computed over every
|
|
85
|
+
// flow, so the ANALYSIS is never truncated — only the listing an agent reads past is.
|
|
86
|
+
const cap = asNumber(args['limit']) ?? DEFAULT_FLOW_DETAIL_LIMIT;
|
|
87
|
+
const capped = model.flows.length > cap
|
|
88
|
+
? { ...model, flows: model.flows.slice(-cap), flowsTruncated: model.flows.length - cap }
|
|
89
|
+
: model;
|
|
90
|
+
return instrumentation.length > 0 ? { ...capped, instrumentation } : capped;
|
|
73
91
|
},
|
|
74
92
|
},
|
|
75
93
|
];
|
|
76
|
-
//# sourceMappingURL=domain-tools.js.map
|
package/dist/domain/flow-risk.js
CHANGED
package/dist/ee/audit-log.d.ts
CHANGED
|
@@ -12,4 +12,3 @@ interface AuditEvent {
|
|
|
12
12
|
/** Record an audit event — gated. Throws EnterpriseLicenseError in production without a valid license. */
|
|
13
13
|
export declare function recordAuditEvent(event: AuditEvent, ctx: GateContext): AuditEvent;
|
|
14
14
|
export {};
|
|
15
|
-
//# sourceMappingURL=audit-log.d.ts.map
|
package/dist/ee/audit-log.js
CHANGED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
import type { Contradiction } from './contradictions.js';
|
|
3
|
+
/** Contradictions for 2xx responses whose bodies report failure. One per offending call. */
|
|
4
|
+
export declare function findBodyFailures(events: readonly ReticleEvent[]): Contradiction[];
|