@reticlehq/server 2.0.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/LICENSE +105 -0
- package/README.md +17 -0
- package/dist/bridge-security.d.ts +23 -0
- package/dist/bridge-security.d.ts.map +1 -0
- package/dist/bridge-security.js +44 -0
- package/dist/bridge-security.js.map +1 -0
- package/dist/bridge.d.ts +42 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +281 -0
- package/dist/bridge.js.map +1 -0
- package/dist/bridge.test-harness.d.ts +42 -0
- package/dist/bridge.test-harness.d.ts.map +1 -0
- package/dist/bridge.test-harness.js +192 -0
- package/dist/bridge.test-harness.js.map +1 -0
- package/dist/cli-launch.d.ts +53 -0
- package/dist/cli-launch.d.ts.map +1 -0
- package/dist/cli-launch.js +109 -0
- package/dist/cli-launch.js.map +1 -0
- package/dist/cli-parse.d.ts +74 -0
- package/dist/cli-parse.d.ts.map +1 -0
- package/dist/cli-parse.js +321 -0
- package/dist/cli-parse.js.map +1 -0
- package/dist/cli-port.d.ts +26 -0
- package/dist/cli-port.d.ts.map +1 -0
- package/dist/cli-port.js +57 -0
- package/dist/cli-port.js.map +1 -0
- package/dist/cli-verify.d.ts +46 -0
- package/dist/cli-verify.d.ts.map +1 -0
- package/dist/cli-verify.js +181 -0
- package/dist/cli-verify.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +337 -0
- package/dist/cli.js.map +1 -0
- package/dist/cloud/cloud-sync.d.ts +50 -0
- package/dist/cloud/cloud-sync.d.ts.map +1 -0
- package/dist/cloud/cloud-sync.js +47 -0
- package/dist/cloud/cloud-sync.js.map +1 -0
- package/dist/crawl/crawl-tools.d.ts +8 -0
- package/dist/crawl/crawl-tools.d.ts.map +1 -0
- package/dist/crawl/crawl-tools.js +61 -0
- package/dist/crawl/crawl-tools.js.map +1 -0
- package/dist/crawl/crawl.d.ts +45 -0
- package/dist/crawl/crawl.d.ts.map +1 -0
- package/dist/crawl/crawl.js +106 -0
- package/dist/crawl/crawl.js.map +1 -0
- package/dist/daemon-resilience.d.ts +17 -0
- package/dist/daemon-resilience.d.ts.map +1 -0
- package/dist/daemon-resilience.js +23 -0
- package/dist/daemon-resilience.js.map +1 -0
- package/dist/daemon.d.ts +26 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +122 -0
- package/dist/daemon.js.map +1 -0
- package/dist/domain/domain-model.d.ts +64 -0
- package/dist/domain/domain-model.d.ts.map +1 -0
- package/dist/domain/domain-model.js +127 -0
- package/dist/domain/domain-model.js.map +1 -0
- package/dist/domain/domain-tools.d.ts +9 -0
- package/dist/domain/domain-tools.d.ts.map +1 -0
- package/dist/domain/domain-tools.js +66 -0
- package/dist/domain/domain-tools.js.map +1 -0
- package/dist/domain/flow-risk.d.ts +34 -0
- package/dist/domain/flow-risk.d.ts.map +1 -0
- package/dist/domain/flow-risk.js +81 -0
- package/dist/domain/flow-risk.js.map +1 -0
- package/dist/ee/audit-log.d.ts +15 -0
- package/dist/ee/audit-log.d.ts.map +1 -0
- package/dist/ee/audit-log.js +12 -0
- package/dist/ee/audit-log.js.map +1 -0
- package/dist/events/event-filters.d.ts +65 -0
- package/dist/events/event-filters.d.ts.map +1 -0
- package/dist/events/event-filters.js +98 -0
- package/dist/events/event-filters.js.map +1 -0
- package/dist/events/predicate-eval.d.ts +91 -0
- package/dist/events/predicate-eval.d.ts.map +1 -0
- package/dist/events/predicate-eval.js +299 -0
- package/dist/events/predicate-eval.js.map +1 -0
- package/dist/events/predicate.d.ts +19 -0
- package/dist/events/predicate.d.ts.map +1 -0
- package/dist/events/predicate.js +188 -0
- package/dist/events/predicate.js.map +1 -0
- package/dist/events/reaction.d.ts +34 -0
- package/dist/events/reaction.d.ts.map +1 -0
- package/dist/events/reaction.js +60 -0
- package/dist/events/reaction.js.map +1 -0
- package/dist/events/ring-buffer.d.ts +32 -0
- package/dist/events/ring-buffer.d.ts.map +1 -0
- package/dist/events/ring-buffer.js +75 -0
- package/dist/events/ring-buffer.js.map +1 -0
- package/dist/flows/annotate-tools.d.ts +16 -0
- package/dist/flows/annotate-tools.d.ts.map +1 -0
- package/dist/flows/annotate-tools.js +136 -0
- package/dist/flows/annotate-tools.js.map +1 -0
- package/dist/flows/annotate.d.ts +22 -0
- package/dist/flows/annotate.d.ts.map +1 -0
- package/dist/flows/annotate.js +134 -0
- package/dist/flows/annotate.js.map +1 -0
- package/dist/flows/annotation-store.d.ts +23 -0
- package/dist/flows/annotation-store.d.ts.map +1 -0
- package/dist/flows/annotation-store.js +51 -0
- package/dist/flows/annotation-store.js.map +1 -0
- package/dist/flows/decision.d.ts +13 -0
- package/dist/flows/decision.d.ts.map +1 -0
- package/dist/flows/decision.js +111 -0
- package/dist/flows/decision.js.map +1 -0
- package/dist/flows/flow-classify.d.ts +52 -0
- package/dist/flows/flow-classify.d.ts.map +1 -0
- package/dist/flows/flow-classify.js +99 -0
- package/dist/flows/flow-classify.js.map +1 -0
- package/dist/flows/flow-replay-run.d.ts +15 -0
- package/dist/flows/flow-replay-run.d.ts.map +1 -0
- package/dist/flows/flow-replay-run.js +120 -0
- package/dist/flows/flow-replay-run.js.map +1 -0
- package/dist/flows/flow-replay.d.ts +49 -0
- package/dist/flows/flow-replay.d.ts.map +1 -0
- package/dist/flows/flow-replay.js +391 -0
- package/dist/flows/flow-replay.js.map +1 -0
- package/dist/flows/flow-report.d.ts +23 -0
- package/dist/flows/flow-report.d.ts.map +1 -0
- package/dist/flows/flow-report.js +106 -0
- package/dist/flows/flow-report.js.map +1 -0
- package/dist/flows/flow-scope.d.ts +25 -0
- package/dist/flows/flow-scope.d.ts.map +1 -0
- package/dist/flows/flow-scope.js +32 -0
- package/dist/flows/flow-scope.js.map +1 -0
- package/dist/flows/flow-success.d.ts +33 -0
- package/dist/flows/flow-success.d.ts.map +1 -0
- package/dist/flows/flow-success.js +131 -0
- package/dist/flows/flow-success.js.map +1 -0
- package/dist/flows/flow-tools.d.ts +4 -0
- package/dist/flows/flow-tools.d.ts.map +1 -0
- package/dist/flows/flow-tools.js +460 -0
- package/dist/flows/flow-tools.js.map +1 -0
- package/dist/flows/flows.d.ts +86 -0
- package/dist/flows/flows.d.ts.map +1 -0
- package/dist/flows/flows.js +319 -0
- package/dist/flows/flows.js.map +1 -0
- package/dist/flows/heal.d.ts +43 -0
- package/dist/flows/heal.d.ts.map +1 -0
- package/dist/flows/heal.js +98 -0
- package/dist/flows/heal.js.map +1 -0
- package/dist/flows/recordings.d.ts +46 -0
- package/dist/flows/recordings.d.ts.map +1 -0
- package/dist/flows/recordings.js +43 -0
- package/dist/flows/recordings.js.map +1 -0
- package/dist/flows/replay.d.ts +23 -0
- package/dist/flows/replay.d.ts.map +1 -0
- package/dist/flows/replay.js +160 -0
- package/dist/flows/replay.js.map +1 -0
- package/dist/http-server.d.ts +39 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +145 -0
- package/dist/http-server.js.map +1 -0
- package/dist/idle-shutdown.d.ts +34 -0
- package/dist/idle-shutdown.d.ts.map +1 -0
- package/dist/idle-shutdown.js +68 -0
- package/dist/idle-shutdown.js.map +1 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/init/cursor.d.ts +25 -0
- package/dist/init/cursor.d.ts.map +1 -0
- package/dist/init/cursor.js +49 -0
- package/dist/init/cursor.js.map +1 -0
- package/dist/init/detect.d.ts +49 -0
- package/dist/init/detect.d.ts.map +1 -0
- package/dist/init/detect.js +84 -0
- package/dist/init/detect.js.map +1 -0
- package/dist/init/mcp.d.ts +40 -0
- package/dist/init/mcp.d.ts.map +1 -0
- package/dist/init/mcp.js +55 -0
- package/dist/init/mcp.js.map +1 -0
- package/dist/init/node-io.d.ts +8 -0
- package/dist/init/node-io.d.ts.map +1 -0
- package/dist/init/node-io.js +57 -0
- package/dist/init/node-io.js.map +1 -0
- package/dist/init/plan.d.ts +72 -0
- package/dist/init/plan.d.ts.map +1 -0
- package/dist/init/plan.js +280 -0
- package/dist/init/plan.js.map +1 -0
- package/dist/init/project-id.d.ts +17 -0
- package/dist/init/project-id.d.ts.map +1 -0
- package/dist/init/project-id.js +38 -0
- package/dist/init/project-id.js.map +1 -0
- package/dist/init/run.d.ts +42 -0
- package/dist/init/run.d.ts.map +1 -0
- package/dist/init/run.js +171 -0
- package/dist/init/run.js.map +1 -0
- package/dist/init/snippets.d.ts +33 -0
- package/dist/init/snippets.d.ts.map +1 -0
- package/dist/init/snippets.js +117 -0
- package/dist/init/snippets.js.map +1 -0
- package/dist/init/vite-config.d.ts +25 -0
- package/dist/init/vite-config.d.ts.map +1 -0
- package/dist/init/vite-config.js +45 -0
- package/dist/init/vite-config.js.map +1 -0
- package/dist/input/network-mock-tools.d.ts +3 -0
- package/dist/input/network-mock-tools.d.ts.map +1 -0
- package/dist/input/network-mock-tools.js +94 -0
- package/dist/input/network-mock-tools.js.map +1 -0
- package/dist/input/network-mock.d.ts +55 -0
- package/dist/input/network-mock.d.ts.map +1 -0
- package/dist/input/network-mock.js +62 -0
- package/dist/input/network-mock.js.map +1 -0
- package/dist/input/real-input.d.ts +174 -0
- package/dist/input/real-input.d.ts.map +1 -0
- package/dist/input/real-input.js +289 -0
- package/dist/input/real-input.js.map +1 -0
- package/dist/input/scroll-find.d.ts +41 -0
- package/dist/input/scroll-find.d.ts.map +1 -0
- package/dist/input/scroll-find.js +59 -0
- package/dist/input/scroll-find.js.map +1 -0
- package/dist/input/scroll-tools.d.ts +8 -0
- package/dist/input/scroll-tools.d.ts.map +1 -0
- package/dist/input/scroll-tools.js +68 -0
- package/dist/input/scroll-tools.js.map +1 -0
- package/dist/input/viewport-tools.d.ts +3 -0
- package/dist/input/viewport-tools.d.ts.map +1 -0
- package/dist/input/viewport-tools.js +65 -0
- package/dist/input/viewport-tools.js.map +1 -0
- package/dist/license/license.d.ts +108 -0
- package/dist/license/license.d.ts.map +1 -0
- package/dist/license/license.js +203 -0
- package/dist/license/license.js.map +1 -0
- package/dist/log.d.ts +6 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +9 -0
- package/dist/log.js.map +1 -0
- package/dist/mcp-proxy.d.ts +16 -0
- package/dist/mcp-proxy.d.ts.map +1 -0
- package/dist/mcp-proxy.js +168 -0
- package/dist/mcp-proxy.js.map +1 -0
- package/dist/mcp.d.ts +14 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +101 -0
- package/dist/mcp.js.map +1 -0
- package/dist/pairing-token.d.ts +28 -0
- package/dist/pairing-token.d.ts.map +1 -0
- package/dist/pairing-token.js +62 -0
- package/dist/pairing-token.js.map +1 -0
- package/dist/pool/browser-pool.d.ts +90 -0
- package/dist/pool/browser-pool.d.ts.map +1 -0
- package/dist/pool/browser-pool.js +221 -0
- package/dist/pool/browser-pool.js.map +1 -0
- package/dist/pool/lease-reaper.d.ts +16 -0
- package/dist/pool/lease-reaper.d.ts.map +1 -0
- package/dist/pool/lease-reaper.js +41 -0
- package/dist/pool/lease-reaper.js.map +1 -0
- package/dist/pool/playwright-launcher.d.ts +19 -0
- package/dist/pool/playwright-launcher.d.ts.map +1 -0
- package/dist/pool/playwright-launcher.js +51 -0
- package/dist/pool/playwright-launcher.js.map +1 -0
- package/dist/project/baselines.d.ts +22 -0
- package/dist/project/baselines.d.ts.map +1 -0
- package/dist/project/baselines.js +45 -0
- package/dist/project/baselines.js.map +1 -0
- package/dist/project/fs-port.d.ts +27 -0
- package/dist/project/fs-port.d.ts.map +1 -0
- package/dist/project/fs-port.js +32 -0
- package/dist/project/fs-port.js.map +1 -0
- package/dist/project/project-store.d.ts +32 -0
- package/dist/project/project-store.d.ts.map +1 -0
- package/dist/project/project-store.js +127 -0
- package/dist/project/project-store.js.map +1 -0
- package/dist/project/project-tools.d.ts +9 -0
- package/dist/project/project-tools.d.ts.map +1 -0
- package/dist/project/project-tools.js +118 -0
- package/dist/project/project-tools.js.map +1 -0
- package/dist/project/reticle-dir.d.ts +61 -0
- package/dist/project/reticle-dir.d.ts.map +1 -0
- package/dist/project/reticle-dir.js +144 -0
- package/dist/project/reticle-dir.js.map +1 -0
- package/dist/runs/build-verification-run.d.ts +30 -0
- package/dist/runs/build-verification-run.d.ts.map +1 -0
- package/dist/runs/build-verification-run.js +71 -0
- package/dist/runs/build-verification-run.js.map +1 -0
- package/dist/runs/profile-redact.d.ts +16 -0
- package/dist/runs/profile-redact.d.ts.map +1 -0
- package/dist/runs/profile-redact.js +32 -0
- package/dist/runs/profile-redact.js.map +1 -0
- package/dist/runs/render-report.d.ts +9 -0
- package/dist/runs/render-report.d.ts.map +1 -0
- package/dist/runs/render-report.js +70 -0
- package/dist/runs/render-report.js.map +1 -0
- package/dist/runs/repair-prompt.d.ts +15 -0
- package/dist/runs/repair-prompt.d.ts.map +1 -0
- package/dist/runs/repair-prompt.js +59 -0
- package/dist/runs/repair-prompt.js.map +1 -0
- package/dist/runs/replay-mapping.d.ts +12 -0
- package/dist/runs/replay-mapping.d.ts.map +1 -0
- package/dist/runs/replay-mapping.js +35 -0
- package/dist/runs/replay-mapping.js.map +1 -0
- package/dist/runs/reticle-runner.d.ts +48 -0
- package/dist/runs/reticle-runner.d.ts.map +1 -0
- package/dist/runs/reticle-runner.js +56 -0
- package/dist/runs/reticle-runner.js.map +1 -0
- package/dist/runs/risk-classify.d.ts +27 -0
- package/dist/runs/risk-classify.d.ts.map +1 -0
- package/dist/runs/risk-classify.js +76 -0
- package/dist/runs/risk-classify.js.map +1 -0
- package/dist/runs/run-store.d.ts +40 -0
- package/dist/runs/run-store.d.ts.map +1 -0
- package/dist/runs/run-store.js +118 -0
- package/dist/runs/run-store.js.map +1 -0
- package/dist/runs/run-tools.d.ts +10 -0
- package/dist/runs/run-tools.d.ts.map +1 -0
- package/dist/runs/run-tools.js +69 -0
- package/dist/runs/run-tools.js.map +1 -0
- package/dist/runs/runner-port.d.ts +14 -0
- package/dist/runs/runner-port.d.ts.map +1 -0
- package/dist/runs/runner-port.js +23 -0
- package/dist/runs/runner-port.js.map +1 -0
- package/dist/runs/verify-http.d.ts +34 -0
- package/dist/runs/verify-http.d.ts.map +1 -0
- package/dist/runs/verify-http.js +102 -0
- package/dist/runs/verify-http.js.map +1 -0
- package/dist/runs/verify-server.d.ts +26 -0
- package/dist/runs/verify-server.d.ts.map +1 -0
- package/dist/runs/verify-server.js +99 -0
- package/dist/runs/verify-server.js.map +1 -0
- package/dist/server-version.d.ts +3 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +5 -0
- package/dist/server-version.js.map +1 -0
- package/dist/session/control-envelope.d.ts +49 -0
- package/dist/session/control-envelope.d.ts.map +1 -0
- package/dist/session/control-envelope.js +44 -0
- package/dist/session/control-envelope.js.map +1 -0
- package/dist/session/live-control-tools.d.ts +16 -0
- package/dist/session/live-control-tools.d.ts.map +1 -0
- package/dist/session/live-control-tools.js +204 -0
- package/dist/session/live-control-tools.js.map +1 -0
- package/dist/session/output-budget.d.ts +41 -0
- package/dist/session/output-budget.d.ts.map +1 -0
- package/dist/session/output-budget.js +54 -0
- package/dist/session/output-budget.js.map +1 -0
- package/dist/session/presenter-args.d.ts +8 -0
- package/dist/session/presenter-args.d.ts.map +1 -0
- package/dist/session/presenter-args.js +15 -0
- package/dist/session/presenter-args.js.map +1 -0
- package/dist/session/review-store.d.ts +40 -0
- package/dist/session/review-store.d.ts.map +1 -0
- package/dist/session/review-store.js +61 -0
- package/dist/session/review-store.js.map +1 -0
- package/dist/session/session-health.d.ts +22 -0
- package/dist/session/session-health.d.ts.map +1 -0
- package/dist/session/session-health.js +26 -0
- package/dist/session/session-health.js.map +1 -0
- package/dist/session/session-manager.d.ts +43 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +155 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/session-readiness.d.ts +35 -0
- package/dist/session/session-readiness.d.ts.map +1 -0
- package/dist/session/session-readiness.js +32 -0
- package/dist/session/session-readiness.js.map +1 -0
- package/dist/session/session-reaper.d.ts +37 -0
- package/dist/session/session-reaper.d.ts.map +1 -0
- package/dist/session/session-reaper.js +94 -0
- package/dist/session/session-reaper.js.map +1 -0
- package/dist/session/session-recommendation.d.ts +18 -0
- package/dist/session/session-recommendation.d.ts.map +1 -0
- package/dist/session/session-recommendation.js +14 -0
- package/dist/session/session-recommendation.js.map +1 -0
- package/dist/session/session-tools.d.ts +9 -0
- package/dist/session/session-tools.d.ts.map +1 -0
- package/dist/session/session-tools.js +43 -0
- package/dist/session/session-tools.js.map +1 -0
- package/dist/session/session.d.ts +166 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +408 -0
- package/dist/session/session.js.map +1 -0
- package/dist/session/state-select.d.ts +8 -0
- package/dist/session/state-select.d.ts.map +1 -0
- package/dist/session/state-select.js +8 -0
- package/dist/session/state-select.js.map +1 -0
- package/dist/token-auth.d.ts +24 -0
- package/dist/token-auth.d.ts.map +1 -0
- package/dist/token-auth.js +71 -0
- package/dist/token-auth.js.map +1 -0
- package/dist/tools/act-tools.d.ts +3 -0
- package/dist/tools/act-tools.d.ts.map +1 -0
- package/dist/tools/act-tools.js +327 -0
- package/dist/tools/act-tools.js.map +1 -0
- package/dist/tools/act-view.d.ts +19 -0
- package/dist/tools/act-view.d.ts.map +1 -0
- package/dist/tools/act-view.js +46 -0
- package/dist/tools/act-view.js.map +1 -0
- package/dist/tools/assert-grade.d.ts +21 -0
- package/dist/tools/assert-grade.d.ts.map +1 -0
- package/dist/tools/assert-grade.js +52 -0
- package/dist/tools/assert-grade.js.map +1 -0
- package/dist/tools/browser-tools.d.ts +3 -0
- package/dist/tools/browser-tools.d.ts.map +1 -0
- package/dist/tools/browser-tools.js +52 -0
- package/dist/tools/browser-tools.js.map +1 -0
- package/dist/tools/contract-tools.d.ts +8 -0
- package/dist/tools/contract-tools.d.ts.map +1 -0
- package/dist/tools/contract-tools.js +62 -0
- package/dist/tools/contract-tools.js.map +1 -0
- package/dist/tools/dynamic-tools.d.ts +7 -0
- package/dist/tools/dynamic-tools.d.ts.map +1 -0
- package/dist/tools/dynamic-tools.js +103 -0
- package/dist/tools/dynamic-tools.js.map +1 -0
- package/dist/tools/error-recovery.d.ts +31 -0
- package/dist/tools/error-recovery.d.ts.map +1 -0
- package/dist/tools/error-recovery.js +52 -0
- package/dist/tools/error-recovery.js.map +1 -0
- package/dist/tools/invoke-tool.d.ts +23 -0
- package/dist/tools/invoke-tool.d.ts.map +1 -0
- package/dist/tools/invoke-tool.js +99 -0
- package/dist/tools/invoke-tool.js.map +1 -0
- package/dist/tools/lease-tools.d.ts +31 -0
- package/dist/tools/lease-tools.d.ts.map +1 -0
- package/dist/tools/lease-tools.js +164 -0
- package/dist/tools/lease-tools.js.map +1 -0
- package/dist/tools/observe-tools.d.ts +3 -0
- package/dist/tools/observe-tools.d.ts.map +1 -0
- package/dist/tools/observe-tools.js +259 -0
- package/dist/tools/observe-tools.js.map +1 -0
- package/dist/tools/profiles.d.ts +33 -0
- package/dist/tools/profiles.d.ts.map +1 -0
- package/dist/tools/profiles.js +105 -0
- package/dist/tools/profiles.js.map +1 -0
- package/dist/tools/query-paginate.d.ts +15 -0
- package/dist/tools/query-paginate.d.ts.map +1 -0
- package/dist/tools/query-paginate.js +31 -0
- package/dist/tools/query-paginate.js.map +1 -0
- package/dist/tools/read-tools.d.ts +3 -0
- package/dist/tools/read-tools.d.ts.map +1 -0
- package/dist/tools/read-tools.js +329 -0
- package/dist/tools/read-tools.js.map +1 -0
- package/dist/tools/snapshot-delta.d.ts +59 -0
- package/dist/tools/snapshot-delta.d.ts.map +1 -0
- package/dist/tools/snapshot-delta.js +0 -0
- package/dist/tools/snapshot-delta.js.map +1 -0
- package/dist/tools/tool-invoker.d.ts +15 -0
- package/dist/tools/tool-invoker.d.ts.map +1 -0
- package/dist/tools/tool-invoker.js +20 -0
- package/dist/tools/tool-invoker.js.map +1 -0
- package/dist/tools/tool-kit.d.ts +60 -0
- package/dist/tools/tool-kit.d.ts.map +1 -0
- package/dist/tools/tool-kit.js +33 -0
- package/dist/tools/tool-kit.js.map +1 -0
- package/dist/tools/tool-names.d.ts +89 -0
- package/dist/tools/tool-names.d.ts.map +1 -0
- package/dist/tools/tool-names.js +88 -0
- package/dist/tools/tool-names.js.map +1 -0
- package/dist/tools/tools-helpers.d.ts +12 -0
- package/dist/tools/tools-helpers.d.ts.map +1 -0
- package/dist/tools/tools-helpers.js +22 -0
- package/dist/tools/tools-helpers.js.map +1 -0
- package/dist/tools/tools.d.ts +4 -0
- package/dist/tools/tools.d.ts.map +1 -0
- package/dist/tools/tools.js +268 -0
- package/dist/tools/tools.js.map +1 -0
- package/dist/update/update-checker.d.ts +20 -0
- package/dist/update/update-checker.d.ts.map +1 -0
- package/dist/update/update-checker.js +94 -0
- package/dist/update/update-checker.js.map +1 -0
- package/dist/update/update-tools.d.ts +3 -0
- package/dist/update/update-tools.d.ts.map +1 -0
- package/dist/update/update-tools.js +94 -0
- package/dist/update/update-tools.js.map +1 -0
- package/dist/update/updater.d.ts +31 -0
- package/dist/update/updater.d.ts.map +1 -0
- package/dist/update/updater.js +120 -0
- package/dist/update/updater.js.map +1 -0
- package/dist/visual/visual-diff.d.ts +46 -0
- package/dist/visual/visual-diff.d.ts.map +1 -0
- package/dist/visual/visual-diff.js +100 -0
- package/dist/visual/visual-diff.js.map +1 -0
- package/dist/visual/visual-store.d.ts +22 -0
- package/dist/visual/visual-store.d.ts.map +1 -0
- package/dist/visual/visual-store.js +60 -0
- package/dist/visual/visual-store.js.map +1 -0
- package/dist/visual/visual-tools.d.ts +9 -0
- package/dist/visual/visual-tools.d.ts.map +1 -0
- package/dist/visual/visual-tools.js +182 -0
- package/dist/visual/visual-tools.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { AnchorKind, ReplayStatus, } from '@reticlehq/core';
|
|
2
|
+
import { classifyFlowAssertions } from './flow-classify.js';
|
|
3
|
+
/**
|
|
4
|
+
* Turn a replay result into the autonomy DECISION envelope — the judgement a human reviewer used to
|
|
5
|
+
* make, expressed so a coding agent can act on it without one. Pure: no IO, no clock.
|
|
6
|
+
*
|
|
7
|
+
* pass → intent held; next action is none (or "add a consequence oracle" if the flow asserts nothing).
|
|
8
|
+
* drift → a locator/anchor missed; point at WHERE (file:line from the source anchor) + a rebind hint.
|
|
9
|
+
* fail → an action ran but its consequence/success oracle didn't fire (green-but-wrong) — check the handler.
|
|
10
|
+
*/
|
|
11
|
+
/** The first step that drifted or failed (drift takes precedence as the legible cause). */
|
|
12
|
+
function failingStep(steps) {
|
|
13
|
+
return steps.find((s) => s.drift !== undefined) ?? steps.find((s) => !s.ok);
|
|
14
|
+
}
|
|
15
|
+
/** `file:line` for a step, preferring the recorded component anchor's source, else the live page. */
|
|
16
|
+
function whereInSource(step, flow) {
|
|
17
|
+
const anchor = flow?.steps[step.step]?.anchor;
|
|
18
|
+
if (anchor?.kind === AnchorKind.COMPONENT && anchor.source !== undefined) {
|
|
19
|
+
return `${anchor.source.file}:${anchor.source.line}`;
|
|
20
|
+
}
|
|
21
|
+
return step.page;
|
|
22
|
+
}
|
|
23
|
+
export function buildDecision(result, flow) {
|
|
24
|
+
const { name, status, steps } = result;
|
|
25
|
+
if (status === ReplayStatus.OK) {
|
|
26
|
+
// Green — but is it green-for-the-right-reason? A flow that asserts no consequence can pass while
|
|
27
|
+
// broken, so the honest next action is to add one.
|
|
28
|
+
const grade = flow !== undefined ? classifyFlowAssertions(flow) : undefined;
|
|
29
|
+
const verifiesOutcome = grade?.hasConsequenceAssertion === true;
|
|
30
|
+
const intent = flow?.intent;
|
|
31
|
+
return {
|
|
32
|
+
verdict: 'pass',
|
|
33
|
+
summary: intent !== undefined
|
|
34
|
+
? `"${name}" passed — intent "${intent}" ${verifiesOutcome ? 'verified' : 'NOT asserted'}.`
|
|
35
|
+
: `"${name}" passed (${steps.length} steps).`,
|
|
36
|
+
nextAction: verifiesOutcome
|
|
37
|
+
? 'none — the flow held and its consequence was observed.'
|
|
38
|
+
: 'add a consequence assertion (assert-signal / success-state) so this flow can fail when the feature breaks.',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const step = failingStep(steps);
|
|
42
|
+
const where = step !== undefined ? whereInSource(step, flow) : undefined;
|
|
43
|
+
if (status === ReplayStatus.DRIFT && step?.drift !== undefined) {
|
|
44
|
+
const { drift } = step;
|
|
45
|
+
const fix = drift.nearest !== null && drift.ambiguous !== true
|
|
46
|
+
? `rebind the anchor to "${drift.nearest}" (closest survivor)`
|
|
47
|
+
: drift.nearest !== null
|
|
48
|
+
? `candidates exist (e.g. "${drift.nearest}") but are ambiguous — choose deliberately`
|
|
49
|
+
: undefined;
|
|
50
|
+
return {
|
|
51
|
+
verdict: 'drift',
|
|
52
|
+
summary: `"${name}" drifted at step ${step.step} (${step.anchor}).`,
|
|
53
|
+
whatChanged: drift.reason,
|
|
54
|
+
...(where !== undefined ? { whereInSource: where } : {}),
|
|
55
|
+
...(fix !== undefined ? { suggestedFix: fix } : {}),
|
|
56
|
+
nextAction: fix !== undefined
|
|
57
|
+
? `${fix}, or update the flow if the change was intended.`
|
|
58
|
+
: `inspect ${where ?? 'the step'} — the anchored element is gone; rebind or update the flow.`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// status error: an action failed, or the success oracle was not satisfied (green-but-wrong).
|
|
62
|
+
const message = result.error?.message ?? step?.error ?? 'the flow failed';
|
|
63
|
+
const isSuccessOracle = step?.tool === 'success';
|
|
64
|
+
return {
|
|
65
|
+
verdict: 'fail',
|
|
66
|
+
summary: `"${name}" failed${step !== undefined ? ` at step ${step.step} (${step.anchor})` : ''}.`,
|
|
67
|
+
whatChanged: message,
|
|
68
|
+
...(where !== undefined ? { whereInSource: where } : {}),
|
|
69
|
+
nextAction: isSuccessOracle
|
|
70
|
+
? 'the steps ran but the business outcome never fired — check the handler/effect behind the action, not the locator.'
|
|
71
|
+
: 'the action could not complete — check the element state and the handler at the step above.',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Map a replay status to the suite verdict's three-state outcome. */
|
|
75
|
+
function suiteVerdictOf(status) {
|
|
76
|
+
if (status === ReplayStatus.OK)
|
|
77
|
+
return 'pass';
|
|
78
|
+
return status === ReplayStatus.DRIFT ? 'drift' : 'fail';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Aggregate per-flow replays into one suite verdict — the autonomous loop's consolidated answer
|
|
82
|
+
* after a build: did anything break, and what's the prioritized fix list. Pure: pass the already
|
|
83
|
+
* decision-annotated replay results + their flows. Passing flows are counted; only failures carry
|
|
84
|
+
* detail (token-cheap), each with the actionable decision so the agent fixes without re-querying.
|
|
85
|
+
*/
|
|
86
|
+
export function buildSuiteVerdict(runs) {
|
|
87
|
+
const failures = [];
|
|
88
|
+
let passed = 0;
|
|
89
|
+
for (const { replay, flow } of runs) {
|
|
90
|
+
if (replay.status === ReplayStatus.OK) {
|
|
91
|
+
passed += 1;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const decision = replay.decision ?? buildDecision(replay, flow);
|
|
95
|
+
const row = { flow: replay.name, verdict: suiteVerdictOf(replay.status) };
|
|
96
|
+
if (decision.whatChanged !== undefined)
|
|
97
|
+
row.whatChanged = decision.whatChanged;
|
|
98
|
+
if (decision.whereInSource !== undefined)
|
|
99
|
+
row.whereInSource = decision.whereInSource;
|
|
100
|
+
row.nextAction = decision.nextAction;
|
|
101
|
+
failures.push(row);
|
|
102
|
+
}
|
|
103
|
+
const total = runs.length;
|
|
104
|
+
const failed = failures.length;
|
|
105
|
+
const status = failed === 0 ? 'pass' : 'fail';
|
|
106
|
+
const summary = failed === 0
|
|
107
|
+
? `all ${total} flow${total === 1 ? '' : 's'} pass`
|
|
108
|
+
: `${passed}/${total} flows pass — ${failed} need attention: ${failures.map((f) => f.flow).join(', ')}`;
|
|
109
|
+
return { status, total, passed, failed, summary, failures };
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=decision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/flows/decision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify whether a flow asserts an observable CONSEQUENCE or is "assertion-free" / presence-only.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists (grounded in real testing behavior):
|
|
5
|
+
* - Martin Fowler, *Assertion-Free Testing*: teams hit 100% coverage with tests that "weren't any
|
|
6
|
+
* assertions" — green, but verifying nothing.
|
|
7
|
+
* - Kent C. Dodds, *Make Your Test Fail*: a test that doesn't fail when you break the code gives
|
|
8
|
+
* false security.
|
|
9
|
+
* - Self-healing vendors (mabl, qate.ai) admit a locator healed to the WRONG element makes a test
|
|
10
|
+
* pass green while a real regression ships — but only if the test merely checks presence.
|
|
11
|
+
* - AI agents agree with human pass/fail only ~68% of the time (arXiv 2510.02418), so the flow
|
|
12
|
+
* itself must carry a real oracle, not rely on the agent eyeballing success.
|
|
13
|
+
*
|
|
14
|
+
* For a flow, an FlowExpect can assert a `signal` (app emitted an event), a `net` call, or just an
|
|
15
|
+
* `element` presence. signal/net are OBSERVABLE CONSEQUENCES — they can't be satisfied by a wrong
|
|
16
|
+
* element. element-only is WEAK — a healed-but-wrong locator can still satisfy it. A flow with no
|
|
17
|
+
* expect on any step and no success end-condition asserts nothing at all.
|
|
18
|
+
*
|
|
19
|
+
* Pure: no IO, no clock.
|
|
20
|
+
*/
|
|
21
|
+
import type { FlowFile } from '@reticlehq/core';
|
|
22
|
+
export declare const FlowAssertionGrade: {
|
|
23
|
+
/** At least one step (or the success end-condition) asserts a signal/network consequence. */
|
|
24
|
+
readonly ASSERTED: "asserted";
|
|
25
|
+
/** Only element-presence checks — a healed-but-wrong locator could still pass. */
|
|
26
|
+
readonly PRESENCE_ONLY: "presence-only";
|
|
27
|
+
/** Performs actions but asserts nothing observable — passes even if the feature is broken. */
|
|
28
|
+
readonly ASSERTION_FREE: "assertion-free";
|
|
29
|
+
};
|
|
30
|
+
export type FlowAssertionGrade = (typeof FlowAssertionGrade)[keyof typeof FlowAssertionGrade];
|
|
31
|
+
export interface FlowAssertionClassification {
|
|
32
|
+
grade: FlowAssertionGrade;
|
|
33
|
+
/** True when at least one signal/net assertion exists (step-level or success). */
|
|
34
|
+
hasConsequenceAssertion: boolean;
|
|
35
|
+
totalSteps: number;
|
|
36
|
+
consequenceSteps: number;
|
|
37
|
+
weakSteps: number;
|
|
38
|
+
successIsConsequence: boolean;
|
|
39
|
+
/** The flow's declared business goal, if any (the intent annotation). */
|
|
40
|
+
intent?: string;
|
|
41
|
+
/**
|
|
42
|
+
* True only when the flow BOTH declares a business intent AND asserts an observable business
|
|
43
|
+
* OUTCOME (a consequence — signal/net). This is the "intent + outcome oracle": a flow earns
|
|
44
|
+
* `intentVerified` when it can actually fail if its declared goal stops being met. A flow with an
|
|
45
|
+
* intent but only presence-only checks is the dangerous case — it claims a goal it cannot verify.
|
|
46
|
+
*/
|
|
47
|
+
intentVerified: boolean;
|
|
48
|
+
/** Present for presence-only / assertion-free flows: how to make the flow a real test. */
|
|
49
|
+
warning?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare function classifyFlowAssertions(flow: FlowFile): FlowAssertionClassification;
|
|
52
|
+
//# sourceMappingURL=flow-classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-classify.d.ts","sourceRoot":"","sources":["../../src/flows/flow-classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAc,QAAQ,EAAY,MAAM,iBAAiB,CAAC;AAEtE,eAAO,MAAM,kBAAkB;IAC7B,6FAA6F;;IAE7F,kFAAkF;;IAElF,8FAA8F;;CAEtF,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,kFAAkF;IAClF,uBAAuB,EAAE,OAAO,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAqCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,2BAA2B,CA0ClF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify whether a flow asserts an observable CONSEQUENCE or is "assertion-free" / presence-only.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists (grounded in real testing behavior):
|
|
5
|
+
* - Martin Fowler, *Assertion-Free Testing*: teams hit 100% coverage with tests that "weren't any
|
|
6
|
+
* assertions" — green, but verifying nothing.
|
|
7
|
+
* - Kent C. Dodds, *Make Your Test Fail*: a test that doesn't fail when you break the code gives
|
|
8
|
+
* false security.
|
|
9
|
+
* - Self-healing vendors (mabl, qate.ai) admit a locator healed to the WRONG element makes a test
|
|
10
|
+
* pass green while a real regression ships — but only if the test merely checks presence.
|
|
11
|
+
* - AI agents agree with human pass/fail only ~68% of the time (arXiv 2510.02418), so the flow
|
|
12
|
+
* itself must carry a real oracle, not rely on the agent eyeballing success.
|
|
13
|
+
*
|
|
14
|
+
* For a flow, an FlowExpect can assert a `signal` (app emitted an event), a `net` call, or just an
|
|
15
|
+
* `element` presence. signal/net are OBSERVABLE CONSEQUENCES — they can't be satisfied by a wrong
|
|
16
|
+
* element. element-only is WEAK — a healed-but-wrong locator can still satisfy it. A flow with no
|
|
17
|
+
* expect on any step and no success end-condition asserts nothing at all.
|
|
18
|
+
*
|
|
19
|
+
* Pure: no IO, no clock.
|
|
20
|
+
*/
|
|
21
|
+
export const FlowAssertionGrade = {
|
|
22
|
+
/** At least one step (or the success end-condition) asserts a signal/network consequence. */
|
|
23
|
+
ASSERTED: 'asserted',
|
|
24
|
+
/** Only element-presence checks — a healed-but-wrong locator could still pass. */
|
|
25
|
+
PRESENCE_ONLY: 'presence-only',
|
|
26
|
+
/** Performs actions but asserts nothing observable — passes even if the feature is broken. */
|
|
27
|
+
ASSERTION_FREE: 'assertion-free',
|
|
28
|
+
};
|
|
29
|
+
const ASSERTION_FREE_WARNING = 'This flow performs actions but asserts no observable consequence — it will pass even if the feature is broken. Add a consequence assertion with reticle_annotate (assert-signal / assert-net) or a success-state.';
|
|
30
|
+
const PRESENCE_ONLY_WARNING = 'This flow only checks element presence, not an observable consequence (signal/network). A locator healed to the wrong element can still pass it. Add a consequence assertion (assert-signal / assert-net / success-state).';
|
|
31
|
+
const INTENT_WITHOUT_OUTCOME_WARNING = 'This flow declares a business intent but asserts no observable outcome (signal/network) — it claims to verify a goal it cannot actually check. Add a success-state consequence so the flow fails when the goal stops being met.';
|
|
32
|
+
/** signal, net, or state present → the expect verifies a consequence a wrong element cannot fake. */
|
|
33
|
+
function expectIsConsequence(e) {
|
|
34
|
+
return (e !== undefined && (e.signal !== undefined || e.net !== undefined || e.state !== undefined));
|
|
35
|
+
}
|
|
36
|
+
/** element-only (no signal/net/state) → presence check, weak. */
|
|
37
|
+
function expectIsWeak(e) {
|
|
38
|
+
return (e !== undefined &&
|
|
39
|
+
e.element !== undefined &&
|
|
40
|
+
e.signal === undefined &&
|
|
41
|
+
e.net === undefined &&
|
|
42
|
+
e.state === undefined);
|
|
43
|
+
}
|
|
44
|
+
/** Walk steps + act_sequence sub-steps so an expect on either level is counted. */
|
|
45
|
+
function flattenSteps(steps) {
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const s of steps) {
|
|
48
|
+
out.push(s);
|
|
49
|
+
if (s.steps !== undefined)
|
|
50
|
+
out.push(...flattenSteps(s.steps));
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
export function classifyFlowAssertions(flow) {
|
|
55
|
+
const all = flattenSteps(flow.steps);
|
|
56
|
+
let consequenceSteps = 0;
|
|
57
|
+
let weakSteps = 0;
|
|
58
|
+
for (const s of all) {
|
|
59
|
+
if (expectIsConsequence(s.expect))
|
|
60
|
+
consequenceSteps++;
|
|
61
|
+
else if (expectIsWeak(s.expect))
|
|
62
|
+
weakSteps++;
|
|
63
|
+
}
|
|
64
|
+
const successIsConsequence = expectIsConsequence(flow.success);
|
|
65
|
+
const successIsWeak = expectIsWeak(flow.success);
|
|
66
|
+
const hasConsequenceAssertion = consequenceSteps > 0 || successIsConsequence;
|
|
67
|
+
const hasAnyAssertion = hasConsequenceAssertion || weakSteps > 0 || successIsWeak;
|
|
68
|
+
const intent = flow.intent;
|
|
69
|
+
const intentVerified = intent !== undefined && hasConsequenceAssertion;
|
|
70
|
+
let grade;
|
|
71
|
+
let warning;
|
|
72
|
+
if (hasConsequenceAssertion) {
|
|
73
|
+
grade = FlowAssertionGrade.ASSERTED;
|
|
74
|
+
}
|
|
75
|
+
else if (hasAnyAssertion) {
|
|
76
|
+
grade = FlowAssertionGrade.PRESENCE_ONLY;
|
|
77
|
+
warning = PRESENCE_ONLY_WARNING;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
grade = FlowAssertionGrade.ASSERTION_FREE;
|
|
81
|
+
warning = ASSERTION_FREE_WARNING;
|
|
82
|
+
}
|
|
83
|
+
// A declared-but-unverifiable business goal is the sharper failure: surface it over the generic
|
|
84
|
+
// assertion warning, since the flow actively claims to check something it cannot.
|
|
85
|
+
if (intent !== undefined && !hasConsequenceAssertion)
|
|
86
|
+
warning = INTENT_WITHOUT_OUTCOME_WARNING;
|
|
87
|
+
return {
|
|
88
|
+
grade,
|
|
89
|
+
hasConsequenceAssertion,
|
|
90
|
+
totalSteps: all.length,
|
|
91
|
+
consequenceSteps,
|
|
92
|
+
weakSteps,
|
|
93
|
+
successIsConsequence,
|
|
94
|
+
...(intent !== undefined ? { intent } : {}),
|
|
95
|
+
intentVerified,
|
|
96
|
+
...(warning !== undefined ? { warning } : {}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=flow-classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-classify.js","sourceRoot":"","sources":["../../src/flows/flow-classify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FlowErrorCode, type FlowReplayResult, type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
import type { ToolDeps } from '../tools/tools.js';
|
|
3
|
+
export declare function latestRecordedFlow(events: ReticleEvent[]): {
|
|
4
|
+
name: string;
|
|
5
|
+
flow: import('@reticlehq/core').FlowFile;
|
|
6
|
+
} | undefined;
|
|
7
|
+
/** Map a structured FlowErrorCode to a legible one-line message for the agent. */
|
|
8
|
+
export declare function flowErrorMessage(code: FlowErrorCode): string;
|
|
9
|
+
/**
|
|
10
|
+
* Replay one named flow end to end: load → re-resolve+run each step → assert the success oracle →
|
|
11
|
+
* status + decision. Shared by reticle_flow_replay (single flow) and reticle_flow_verify (whole suite) so
|
|
12
|
+
* both produce identical FlowReplayResults. Every exit path records a run to project.json.
|
|
13
|
+
*/
|
|
14
|
+
export declare function replayNamedFlow(deps: ToolDeps, args: Record<string, unknown>): Promise<FlowReplayResult>;
|
|
15
|
+
//# sourceMappingURL=flow-replay-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-replay-run.d.ts","sourceRoot":"","sources":["../../src/flows/flow-replay-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EAKb,KAAK,gBAAgB,EAErB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EAAE,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,iBAAiB,EAAE,QAAQ,CAAA;CAAE,GAAG,SAAS,CAQxE;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAW5D;AA+BD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAyE3B"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { EventType, FLOW_SIGNAL_TIMEOUT_MS, FlowErrorCode, RecordedFlowSchema, ReplayStatus, RunKind, RunStatus, } from '@reticlehq/core';
|
|
2
|
+
import { asString } from '../tools/tools-helpers.js';
|
|
3
|
+
import { replayFlow } from './flow-replay.js';
|
|
4
|
+
import { assertSuccess, dynamicTestids, successLabel, SUCCESS_STEP_TOOL } from './flow-success.js';
|
|
5
|
+
import { buildDecision } from './decision.js';
|
|
6
|
+
import { waitForPredicate } from '../events/predicate.js';
|
|
7
|
+
export function latestRecordedFlow(events) {
|
|
8
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
9
|
+
const event = events[i];
|
|
10
|
+
if (event?.type !== EventType.FLOW_RECORDED)
|
|
11
|
+
continue;
|
|
12
|
+
const parsed = RecordedFlowSchema.safeParse(event.data);
|
|
13
|
+
if (parsed.success)
|
|
14
|
+
return { name: parsed.data.name, flow: parsed.data.flow };
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
/** Map a structured FlowErrorCode to a legible one-line message for the agent. */
|
|
19
|
+
export function flowErrorMessage(code) {
|
|
20
|
+
switch (code) {
|
|
21
|
+
case FlowErrorCode.INVALID_NAME:
|
|
22
|
+
return 'invalid flow name — use a single safe segment (letters/digits/-/_), no path separators';
|
|
23
|
+
case FlowErrorCode.NOT_FOUND:
|
|
24
|
+
return 'no such flow on disk — run reticle_flow_list to see saved flows';
|
|
25
|
+
case FlowErrorCode.PARSE_FAILED:
|
|
26
|
+
return 'flow file is malformed — fix or regenerate it with reticle_flow_save';
|
|
27
|
+
case FlowErrorCode.NO_RECORDING:
|
|
28
|
+
return 'no compiled recording by that name — record one (reticle_record_start/stop) first';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Map the wire ReplayStatus onto the persisted RunStatus (ok→pass). */
|
|
32
|
+
function replayToRunStatus(status) {
|
|
33
|
+
switch (status) {
|
|
34
|
+
case ReplayStatus.OK:
|
|
35
|
+
return RunStatus.PASS;
|
|
36
|
+
case ReplayStatus.DRIFT:
|
|
37
|
+
return RunStatus.DRIFT;
|
|
38
|
+
case ReplayStatus.ERROR:
|
|
39
|
+
return RunStatus.ERROR;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Append a flow-replay outcome to .reticle/project.json (never throws into replay). */
|
|
43
|
+
async function recordReplayRun(deps, name, status, driftSteps, durationMs) {
|
|
44
|
+
await deps.project.recordRun({
|
|
45
|
+
kind: RunKind.FLOW_REPLAY,
|
|
46
|
+
name,
|
|
47
|
+
status: replayToRunStatus(status),
|
|
48
|
+
evidence: { driftSteps },
|
|
49
|
+
durationMs,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Replay one named flow end to end: load → re-resolve+run each step → assert the success oracle →
|
|
54
|
+
* status + decision. Shared by reticle_flow_replay (single flow) and reticle_flow_verify (whole suite) so
|
|
55
|
+
* both produce identical FlowReplayResults. Every exit path records a run to project.json.
|
|
56
|
+
*/
|
|
57
|
+
export async function replayNamedFlow(deps, args) {
|
|
58
|
+
const startedAt = deps.now();
|
|
59
|
+
const name = asString(args['flowName']) ?? '';
|
|
60
|
+
// Resolve within the connecting app's scope so a shared daemon replays THIS project's flow, not a
|
|
61
|
+
// same-named flow from another app. Safe-resolve: a missing session degrades to the global store,
|
|
62
|
+
// and the load-then-session order (unchanged) still surfaces a not-found before a no-session error.
|
|
63
|
+
let projectId;
|
|
64
|
+
try {
|
|
65
|
+
projectId = deps.sessions.resolve(asString(args['sessionId'])).projectId;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
projectId = undefined;
|
|
69
|
+
}
|
|
70
|
+
const loaded = await deps.flows.load(name, projectId);
|
|
71
|
+
if (!loaded.ok) {
|
|
72
|
+
await recordReplayRun(deps, name, ReplayStatus.ERROR, 0, deps.now() - startedAt);
|
|
73
|
+
return {
|
|
74
|
+
name,
|
|
75
|
+
status: ReplayStatus.ERROR,
|
|
76
|
+
steps: [],
|
|
77
|
+
error: { code: loaded.code, message: flowErrorMessage(loaded.code) },
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const session = deps.sessions.resolve(asString(args['sessionId']));
|
|
81
|
+
// Floor the success oracle at the start of THIS replay so a stale signal from a prior run
|
|
82
|
+
// in the same session can't fake a pass.
|
|
83
|
+
const replayFloor = session.elapsed();
|
|
84
|
+
const steps = await replayFlow(session, loaded.value, waitForPredicate, FLOW_SIGNAL_TIMEOUT_MS, args['confirmDangerous'] === true);
|
|
85
|
+
// "green means intent satisfied": when every step ran clean, assert the flow's success
|
|
86
|
+
// end-condition as a real consequence. A signal/net success that never fires FAILS the replay
|
|
87
|
+
// even though all locators resolved — the regression a healed-but-wrong locator ships green.
|
|
88
|
+
const stepsClean = steps.length > 0 && steps.every((s) => s.ok && s.drift === undefined);
|
|
89
|
+
if (stepsClean && loaded.value.success !== undefined) {
|
|
90
|
+
const verdict = await assertSuccess(session, loaded.value.success, dynamicTestids(loaded.value), waitForPredicate, FLOW_SIGNAL_TIMEOUT_MS, replayFloor);
|
|
91
|
+
const row = {
|
|
92
|
+
step: steps.length,
|
|
93
|
+
tool: SUCCESS_STEP_TOOL,
|
|
94
|
+
anchor: successLabel(loaded.value.success),
|
|
95
|
+
ok: verdict.pass,
|
|
96
|
+
...(verdict.pass ? {} : { error: verdict.failureReason ?? 'flow.success not satisfied' }),
|
|
97
|
+
};
|
|
98
|
+
steps.push(row);
|
|
99
|
+
}
|
|
100
|
+
const driftSteps = steps.filter((s) => s.drift !== undefined).length;
|
|
101
|
+
const allOk = steps.every((s) => s.ok);
|
|
102
|
+
const status = driftSteps > 0 ? ReplayStatus.DRIFT : allOk ? ReplayStatus.OK : ReplayStatus.ERROR;
|
|
103
|
+
await recordReplayRun(deps, name, status, driftSteps, deps.now() - startedAt);
|
|
104
|
+
const failed = steps.find((step) => !step.ok && step.drift === undefined);
|
|
105
|
+
if (failed !== undefined) {
|
|
106
|
+
const errored = {
|
|
107
|
+
name,
|
|
108
|
+
status,
|
|
109
|
+
steps,
|
|
110
|
+
error: { code: ReplayStatus.ERROR, message: failed.error ?? 'flow action failed' },
|
|
111
|
+
};
|
|
112
|
+
errored.decision = buildDecision(errored, loaded.value);
|
|
113
|
+
return errored;
|
|
114
|
+
}
|
|
115
|
+
const result = { name, status, steps };
|
|
116
|
+
if (status !== ReplayStatus.OK)
|
|
117
|
+
result.decision = buildDecision(result, loaded.value);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=flow-replay-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-replay-run.js","sourceRoot":"","sources":["../../src/flows/flow-replay-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type CommandResult, type FlowFile, type FlowStepResult, type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
import type { EvalResult, Predicate } from '../events/predicate.js';
|
|
3
|
+
/**
|
|
4
|
+
* The session surface flow-replay needs: QUERY to re-resolve a testid anchor against the live
|
|
5
|
+
* DOM, ACT to run the step, and the event/onEvent pair so a signal anchor can wait on a predicate
|
|
6
|
+
* (via the injected waitForPredicate). Mirrors PredicateSession so the same fake drives both.
|
|
7
|
+
*/
|
|
8
|
+
export interface FlowReplaySession {
|
|
9
|
+
command(name: string, args?: Record<string, unknown>): Promise<CommandResult>;
|
|
10
|
+
eventsSince(cursor: number): ReticleEvent[];
|
|
11
|
+
onEvent(listener: (event: ReticleEvent) => void): () => void;
|
|
12
|
+
/** Buffer clock (ms since connect) — required by the predicate engine's `settled` check. */
|
|
13
|
+
elapsed(): number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The injected predicate-waiter (the real waitForPredicate) — reused, never reimplemented.
|
|
17
|
+
* `since` is the event-time floor (default 0 = whole buffer): pass the cursor captured before a
|
|
18
|
+
* replay so the success oracle can't be satisfied by a stale signal from a prior replay/run.
|
|
19
|
+
*/
|
|
20
|
+
export type WaitForSignal = (session: FlowReplaySession, predicate: Predicate, timeoutMs: number, since?: number) => Promise<EvalResult>;
|
|
21
|
+
/**
|
|
22
|
+
* A single ASCII-ish edit distance (case-insensitive). Small inputs (testids), so O(n*m) is fine.
|
|
23
|
+
* Exported so the heal proposal layer derives its confidence from the SAME distance used to
|
|
24
|
+
* pick `nearest` — no second, divergent heuristic enters the trust boundary.
|
|
25
|
+
*/
|
|
26
|
+
export declare function editDistance(a: string, b: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* The closest present testid to a missing one, by case-insensitive edit distance, ties broken
|
|
29
|
+
* by shortest length then lexically. Returns null only when nothing is present — so a drift
|
|
30
|
+
* record always names a fix when one exists ("whose fault is it": here is the closest survivor).
|
|
31
|
+
*/
|
|
32
|
+
export declare function nearestTestid(missing: string, present: string[]): string | null;
|
|
33
|
+
/** Injected sleeper so tests drive replay with a no-op clock; production waits on a real timer. */
|
|
34
|
+
type Sleep = (ms: number) => Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* True when ≥2 present testids tie at the minimum edit distance to the missing one — `nearest` is
|
|
37
|
+
* then an arbitrary lexical-tiebreak pick, so auto-healing would be a coin-flip between candidates.
|
|
38
|
+
* Such a drift is surfaced (with a nearest) but never auto-healed.
|
|
39
|
+
*/
|
|
40
|
+
export declare function nearestIsAmbiguous(missing: string, present: string[]): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Replay a loaded flow by RE-RESOLVING every step's semantic anchor against the live DOM — never
|
|
43
|
+
* a stale ref. A testid anchor is re-found by reticle_query; a signal anchor waits on a predicate.
|
|
44
|
+
* On the first anchor MISS the step carries legible drift and replay STOPS, returning the partial
|
|
45
|
+
* results. This is the "whose fault is it" contract, not a blind "command failed".
|
|
46
|
+
*/
|
|
47
|
+
export declare function replayFlow(session: FlowReplaySession, flow: FlowFile, waitForSignal: WaitForSignal, signalTimeoutMs: number, confirmDangerous?: boolean, sleep?: Sleep): Promise<FlowStepResult[]>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=flow-replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-replay.d.ts","sourceRoot":"","sources":["../../src/flows/flow-replay.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EAIlB,KAAK,QAAQ,EAEb,KAAK,cAAc,EACnB,KAAK,YAAY,EAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIpE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9E,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IAC5C,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC7D,4FAA4F;IAC5F,OAAO,IAAI,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,KACX,OAAO,CAAC,UAAU,CAAC,CAAC;AAEzB;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBzD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAkB/E;AAYD,mGAAmG;AACnG,KAAK,KAAK,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AA4B3C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAc9E;AA8QD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,QAAQ,EACd,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,MAAM,EACvB,gBAAgB,UAAQ,EACxB,KAAK,GAAE,KAAiB,GACvB,OAAO,CAAC,cAAc,EAAE,CAAC,CAgD3B"}
|