@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,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated file contents and copy-paste snippets for `reticle init`. Kept as named constants/builders
|
|
3
|
+
* so the runner never inlines free strings.
|
|
4
|
+
*/
|
|
5
|
+
import { RETICLE_DEFAULT_PORT, RETICLE_WS_PATH } from '@reticlehq/core';
|
|
6
|
+
/**
|
|
7
|
+
* The connect() argument literal: a non-default port adds a `url`, and a projectId is always passed
|
|
8
|
+
* (so the app is identifiable across port changes). Empty string only when neither applies.
|
|
9
|
+
*/
|
|
10
|
+
function connectArg(port, projectId) {
|
|
11
|
+
const parts = [];
|
|
12
|
+
if (port !== undefined && port !== RETICLE_DEFAULT_PORT) {
|
|
13
|
+
parts.push(`url: 'ws://localhost:${String(port)}${RETICLE_WS_PATH}'`);
|
|
14
|
+
}
|
|
15
|
+
if (projectId !== undefined && projectId.length > 0)
|
|
16
|
+
parts.push(`projectId: '${projectId}'`);
|
|
17
|
+
return parts.length > 0 ? `{ ${parts.join(', ')} }` : '';
|
|
18
|
+
}
|
|
19
|
+
/** The Vite-config snippet printed when we can't safely auto-patch the config. */
|
|
20
|
+
export function viteManual(port) {
|
|
21
|
+
const call = port === undefined ? 'reticle()' : `reticle({ port: ${String(port)} })`;
|
|
22
|
+
return `Add the Reticle plugin to your Vite config:
|
|
23
|
+
|
|
24
|
+
import { reticle } from '@reticlehq/vite-plugin';
|
|
25
|
+
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
plugins: [react(), ${call}],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
The plugin only applies during \`vite\` (dev) — it is dropped from \`vite build\`.`;
|
|
31
|
+
}
|
|
32
|
+
/** Next.js config wrap — always printed (we never auto-rewrite next.config). */
|
|
33
|
+
export function nextConfigManual(configFile) {
|
|
34
|
+
return `Wrap your ${configFile} export with withReticle (keeps SWC, dev-only):
|
|
35
|
+
|
|
36
|
+
import { withReticle } from '@reticlehq/next';
|
|
37
|
+
|
|
38
|
+
export default withReticle(nextConfig);`;
|
|
39
|
+
}
|
|
40
|
+
/** The dev-only client component that connects Reticle after hydration. */
|
|
41
|
+
export function nextReticleDevFile(port, projectId) {
|
|
42
|
+
return `'use client';
|
|
43
|
+
import { useEffect } from 'react';
|
|
44
|
+
|
|
45
|
+
/** Dev-only: connect Reticle + install the React adapter, after hydration. */
|
|
46
|
+
export function ReticleDev() {
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (process.env.NODE_ENV !== 'development') return;
|
|
49
|
+
void import('@reticlehq/react').then(({ reticle, install }) => {
|
|
50
|
+
install();
|
|
51
|
+
reticle.connect(${connectArg(port, projectId)});
|
|
52
|
+
});
|
|
53
|
+
}, []);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
/** Mount instruction for the root layout. */
|
|
59
|
+
export const NEXT_LAYOUT_MANUAL = `Mount <ReticleDev /> in your root layout (app/layout.tsx), dev-only:
|
|
60
|
+
|
|
61
|
+
import { ReticleDev } from './reticle-dev';
|
|
62
|
+
// inside <body>:
|
|
63
|
+
{process.env.NODE_ENV === 'development' ? <ReticleDev /> : null}`;
|
|
64
|
+
/**
|
|
65
|
+
* Manual connect guidance for projects without a Vite/Next plugin. Most such projects still use a
|
|
66
|
+
* BUNDLER (CRA, webpack, Parcel, Vue/Svelte CLIs) — for those, the connect goes in the entry MODULE,
|
|
67
|
+
* where a bare `@reticlehq/react` import resolves. A bare import in a plain index.html does NOT resolve in
|
|
68
|
+
* the browser, so we never tell a bundled app to do that (the old advice silently failed for CRA).
|
|
69
|
+
*/
|
|
70
|
+
export function htmlManual(port, projectId) {
|
|
71
|
+
const arg = connectArg(port, projectId);
|
|
72
|
+
return `No Vite/Next plugin detected — wire the dev-only connect by hand. Pick the form for your setup:
|
|
73
|
+
|
|
74
|
+
• Bundled app (Create React App, webpack, Parcel, Vue/Svelte CLI, etc.) — add to your ENTRY module
|
|
75
|
+
(e.g. src/index.js or src/main.js), where '@reticlehq/react' resolves through your bundler:
|
|
76
|
+
|
|
77
|
+
if (location.hostname === 'localhost') {
|
|
78
|
+
const { reticle, install } = await import('@reticlehq/react');
|
|
79
|
+
install();
|
|
80
|
+
reticle.connect(${arg});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
• Plain static HTML with no build step — the browser can't resolve the bare '@reticlehq/react' import, so
|
|
84
|
+
bundle the SDK once (e.g. \`npx esbuild\`) and point a dev-only <script type="module"> at the output,
|
|
85
|
+
or serve the page through a dev server (Vite) that resolves bare imports.`;
|
|
86
|
+
}
|
|
87
|
+
export const NEXT_RETICLE_DEV_PATH = 'app/reticle-dev.tsx';
|
|
88
|
+
export const SVELTEKIT_HOOKS_PATH = 'src/hooks.client.ts';
|
|
89
|
+
/**
|
|
90
|
+
* Dev-only client hook that connects Reticle in a SvelteKit app. SvelteKit renders through app.html and
|
|
91
|
+
* never triggers Vite's index.html injection (verified), so the standard plugin can't auto-connect —
|
|
92
|
+
* a client hook is the reliable path. SvelteKit runs src/hooks.client.ts on the client at startup.
|
|
93
|
+
*/
|
|
94
|
+
export function svelteKitHooksFile(port, projectId) {
|
|
95
|
+
return `// Dev-only: connect Reticle on the client. SvelteKit renders via app.html, so the Vite-plugin
|
|
96
|
+
// index.html injection doesn't fire — connect from this client hook instead.
|
|
97
|
+
if (import.meta.env.DEV) {
|
|
98
|
+
void import('@reticlehq/react').then(({ reticle, install }) => {
|
|
99
|
+
install();
|
|
100
|
+
reticle.connect(${connectArg(port, projectId)});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Root-level project config for Reticle. Written by `reticle init`; read by `reticle mcp` for the port
|
|
107
|
+
* and by tooling for the stable projectId (the app's identity across port changes).
|
|
108
|
+
*/
|
|
109
|
+
export function reticleConfigContent(framework, port, projectId) {
|
|
110
|
+
const fields = { framework };
|
|
111
|
+
if (projectId !== undefined && projectId.length > 0)
|
|
112
|
+
fields['projectId'] = projectId;
|
|
113
|
+
if (port !== undefined && port !== RETICLE_DEFAULT_PORT)
|
|
114
|
+
fields['port'] = port;
|
|
115
|
+
return `${JSON.stringify(fields, null, 2)}\n`;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=snippets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippets.js","sourceRoot":"","sources":["../../src/init/snippets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAExE;;;GAGG;AACH,SAAS,UAAU,CAAC,IAAwB,EAAE,SAAkB;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,GAAG,CAAC,CAAC;IAC7F,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,UAAU,CAAC,IAAwB;IACjD,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;IACrF,OAAO;;;;;yBAKgB,IAAI;;;mFAGsD,CAAC;AACpF,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,aAAa,UAAU;;;;0CAIU,CAAC;AAC3C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAAC,IAAwB,EAAE,SAAkB;IAC7E,OAAO;;;;;;;;;wBASe,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;;;;;CAKlD,CAAC;AACF,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;mEAIiC,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAwB,EAAE,SAAkB;IACrE,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO;;;;;;;;0BAQiB,GAAG;;;;;8EAKiD,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAwB,EAAE,SAAkB;IAC7E,OAAO;;;;;sBAKa,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;;;CAGhD,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,IAAwB,EACxB,SAAkB;IAElB,MAAM,MAAM,GAA4B,EAAE,SAAS,EAAE,CAAC;IACtD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;IACrF,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,oBAAoB;QAAE,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC/E,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, conservative patcher for a Vite config: add the `@reticlehq/vite-plugin` import and drop
|
|
3
|
+
* `reticle()` into the `plugins` array. Only handles the obvious, common shape — anything ambiguous
|
|
4
|
+
* bails to a `manual` result so we never half-edit a build config (a broken config is worse than a
|
|
5
|
+
* documented manual step).
|
|
6
|
+
*/
|
|
7
|
+
export declare const VITE_IMPORT = "import { reticle } from '@reticlehq/vite-plugin';";
|
|
8
|
+
export declare const VitePatchKind: {
|
|
9
|
+
readonly APPLY: "apply";
|
|
10
|
+
readonly ALREADY: "already";
|
|
11
|
+
readonly MANUAL: "manual";
|
|
12
|
+
};
|
|
13
|
+
export type VitePatchKind = (typeof VitePatchKind)[keyof typeof VitePatchKind];
|
|
14
|
+
type VitePatch = {
|
|
15
|
+
kind: typeof VitePatchKind.APPLY;
|
|
16
|
+
code: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: typeof VitePatchKind.ALREADY;
|
|
19
|
+
} | {
|
|
20
|
+
kind: typeof VitePatchKind.MANUAL;
|
|
21
|
+
reason: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function patchViteConfig(source: string, port?: number): VitePatch;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=vite-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../../src/init/vite-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,WAAW,sDAAsD,CAAC;AAY/E,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAE/E,KAAK,SAAS,GACV;IAAE,IAAI,EAAE,OAAO,aAAa,CAAC,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,OAAO,aAAa,CAAC,OAAO,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,OAAO,aAAa,CAAC,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAmB1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAQxE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, conservative patcher for a Vite config: add the `@reticlehq/vite-plugin` import and drop
|
|
3
|
+
* `reticle()` into the `plugins` array. Only handles the obvious, common shape — anything ambiguous
|
|
4
|
+
* bails to a `manual` result so we never half-edit a build config (a broken config is worse than a
|
|
5
|
+
* documented manual step).
|
|
6
|
+
*/
|
|
7
|
+
export const VITE_IMPORT = "import { reticle } from '@reticlehq/vite-plugin';";
|
|
8
|
+
const RETICLE_MARKER = '@reticlehq/vite-plugin';
|
|
9
|
+
/** The `reticle(...)` call — carries the bridge port so the injected connect() targets it. */
|
|
10
|
+
function reticlePluginCall(port) {
|
|
11
|
+
return port === undefined ? 'reticle()' : `reticle({ port: ${String(port)} })`;
|
|
12
|
+
}
|
|
13
|
+
/** Matches the start of a `plugins: [` array literal. */
|
|
14
|
+
const PLUGINS_ARRAY = /plugins\s*:\s*\[/;
|
|
15
|
+
/** Matches an ES import statement (used to place our import after the last one). */
|
|
16
|
+
const IMPORT_LINE = /^import\s.+from\s+['"][^'"]+['"];?\s*$/gm;
|
|
17
|
+
export const VitePatchKind = {
|
|
18
|
+
APPLY: 'apply',
|
|
19
|
+
ALREADY: 'already',
|
|
20
|
+
MANUAL: 'manual',
|
|
21
|
+
};
|
|
22
|
+
const NO_PLUGINS_REASON = "couldn't find a `plugins: [...]` array to extend";
|
|
23
|
+
function insertImport(source) {
|
|
24
|
+
const matches = [...source.matchAll(IMPORT_LINE)];
|
|
25
|
+
const last = matches[matches.length - 1];
|
|
26
|
+
if (last?.index === undefined) {
|
|
27
|
+
return `${VITE_IMPORT}\n${source}`;
|
|
28
|
+
}
|
|
29
|
+
const end = last.index + last[0].length;
|
|
30
|
+
return `${source.slice(0, end)}\n${VITE_IMPORT}${source.slice(end)}`;
|
|
31
|
+
}
|
|
32
|
+
function insertPlugin(source, port) {
|
|
33
|
+
// Insert right after the opening `[` of the plugins array.
|
|
34
|
+
return source.replace(PLUGINS_ARRAY, (match) => `${match}${reticlePluginCall(port)}, `);
|
|
35
|
+
}
|
|
36
|
+
export function patchViteConfig(source, port) {
|
|
37
|
+
if (source.includes(RETICLE_MARKER)) {
|
|
38
|
+
return { kind: VitePatchKind.ALREADY };
|
|
39
|
+
}
|
|
40
|
+
if (!PLUGINS_ARRAY.test(source)) {
|
|
41
|
+
return { kind: VitePatchKind.MANUAL, reason: NO_PLUGINS_REASON };
|
|
42
|
+
}
|
|
43
|
+
return { kind: VitePatchKind.APPLY, code: insertImport(insertPlugin(source, port)) };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=vite-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../../src/init/vite-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,mDAAmD,CAAC;AAC/E,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAEhD,8FAA8F;AAC9F,SAAS,iBAAiB,CAAC,IAAwB;IACjD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACjF,CAAC;AACD,yDAAyD;AACzD,MAAM,aAAa,GAAG,kBAAkB,CAAC;AACzC,oFAAoF;AACpF,MAAM,WAAW,GAAG,0CAA0C,CAAC;AAE/D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;CACR,CAAC;AAQX,MAAM,iBAAiB,GAAG,kDAAkD,CAAC;AAE7E,SAAS,YAAY,CAAC,MAAc;IAClC,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,IAAI,IAAI,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,GAAG,WAAW,KAAK,MAAM,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AACvE,CAAC;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,IAAwB;IAC5D,2DAA2D;IAC3D,OAAO,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,IAAa;IAC3D,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-mock-tools.d.ts","sourceRoot":"","sources":["../../src/input/network-mock-tools.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AAyD3D,eAAO,MAAM,kBAAkB,EAAE,OAAO,EAsCvC,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { VISUAL_NO_PROVIDER_RECOMMENDATION, VisualReason } from '@reticlehq/core';
|
|
3
|
+
import { ReticleTool } from '../tools/tool-names.js';
|
|
4
|
+
import { asString } from '../tools/tools-helpers.js';
|
|
5
|
+
const sessionIdShape = {
|
|
6
|
+
sessionId: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe('Active session ID from reticle_sessions. Omit when only one browser session is open.'),
|
|
10
|
+
};
|
|
11
|
+
function mockProvider(deps) {
|
|
12
|
+
const p = deps.realInput;
|
|
13
|
+
return p !== undefined && typeof p.setMocks === 'function' ? p : undefined;
|
|
14
|
+
}
|
|
15
|
+
const ruleShape = z.object({
|
|
16
|
+
urlContains: z
|
|
17
|
+
.string()
|
|
18
|
+
.min(1)
|
|
19
|
+
.describe('Substring the request URL must contain, e.g. "/api/pay".'),
|
|
20
|
+
method: z.string().optional().describe('Optional method filter (GET/POST/…), case-insensitive.'),
|
|
21
|
+
status: z.number().int().optional().describe('Fulfill with this HTTP status (default 200).'),
|
|
22
|
+
body: z.string().optional().describe('Response body to fulfill with.'),
|
|
23
|
+
contentType: z.string().optional().describe('Response content type (default application/json).'),
|
|
24
|
+
delayMs: z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('Delay (ms) before fulfilling — simulate a slow API.'),
|
|
29
|
+
abort: z
|
|
30
|
+
.boolean()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe('Simulate a network failure (offline) instead of a response.'),
|
|
33
|
+
});
|
|
34
|
+
/** Narrow the validated tool args into MockRule[], omitting undefined keys (exactOptionalPropertyTypes). */
|
|
35
|
+
function toRules(value) {
|
|
36
|
+
const parsed = z.array(ruleShape).safeParse(value);
|
|
37
|
+
if (!parsed.success)
|
|
38
|
+
return [];
|
|
39
|
+
return parsed.data.map((r) => {
|
|
40
|
+
const rule = { urlContains: r.urlContains };
|
|
41
|
+
if (r.method !== undefined)
|
|
42
|
+
rule.method = r.method;
|
|
43
|
+
if (r.status !== undefined)
|
|
44
|
+
rule.status = r.status;
|
|
45
|
+
if (r.body !== undefined)
|
|
46
|
+
rule.body = r.body;
|
|
47
|
+
if (r.contentType !== undefined)
|
|
48
|
+
rule.contentType = r.contentType;
|
|
49
|
+
if (r.delayMs !== undefined)
|
|
50
|
+
rule.delayMs = r.delayMs;
|
|
51
|
+
if (r.abort !== undefined)
|
|
52
|
+
rule.abort = r.abort;
|
|
53
|
+
return rule;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
export const NETWORK_MOCK_TOOLS = [
|
|
57
|
+
{
|
|
58
|
+
name: ReticleTool.NETWORK_MOCK,
|
|
59
|
+
description: 'Stub or intercept network requests on the DRIVEN page (needs `reticle drive`): return a 500, ' +
|
|
60
|
+
'force offline (abort), or delay a response — so you can deterministically test error and edge ' +
|
|
61
|
+
'states without touching the backend ("verify the app handles a failed payment"). Pass `mocks` ' +
|
|
62
|
+
'(first matching rule wins); pass an empty array or `clear: true` to turn mocking off.',
|
|
63
|
+
inputSchema: {
|
|
64
|
+
mocks: z.array(ruleShape).optional().describe('Interception rules; omit/empty to clear.'),
|
|
65
|
+
clear: z.boolean().optional().describe('Clear all active mocks (same as mocks: []).'),
|
|
66
|
+
...sessionIdShape,
|
|
67
|
+
},
|
|
68
|
+
outputSchema: {
|
|
69
|
+
applied: z.boolean(),
|
|
70
|
+
count: z.number(),
|
|
71
|
+
ok: z.boolean().optional(),
|
|
72
|
+
reason: z.string().optional(),
|
|
73
|
+
recommendation: z.string().optional(),
|
|
74
|
+
},
|
|
75
|
+
handler: async (deps, args) => {
|
|
76
|
+
const provider = mockProvider(deps);
|
|
77
|
+
if (provider === undefined) {
|
|
78
|
+
// Mocking needs a browser Reticle drives; a synthetic in-page session can't intercept the network.
|
|
79
|
+
return {
|
|
80
|
+
applied: false,
|
|
81
|
+
count: 0,
|
|
82
|
+
ok: false,
|
|
83
|
+
reason: VisualReason.NO_PROVIDER,
|
|
84
|
+
recommendation: VISUAL_NO_PROVIDER_RECOMMENDATION,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const session = deps.sessions.resolve(asString(args['sessionId']));
|
|
88
|
+
const rules = args['clear'] === true ? [] : toRules(args['mocks']);
|
|
89
|
+
const applied = await provider.setMocks(session.url, rules);
|
|
90
|
+
return { applied, count: applied ? rules.length : 0 };
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
//# sourceMappingURL=network-mock-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-mock-tools.js","sourceRoot":"","sources":["../../src/input/network-mock-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Page, Route } from 'playwright';
|
|
2
|
+
/**
|
|
3
|
+
* CDP network mock/intercept for `reticle drive`. Lets an agent or dev deterministically test error and
|
|
4
|
+
* edge states — a 500 on checkout, an offline payment, a slow API — without touching the backend.
|
|
5
|
+
* "Verify the app handles a failed payment" becomes one declared rule.
|
|
6
|
+
*
|
|
7
|
+
* Two layers, split for testability:
|
|
8
|
+
* - matchMock(): PURE. Given the active rules and a request's url/method, decide the outcome
|
|
9
|
+
* (fulfill | abort | continue). Unit-tested directly.
|
|
10
|
+
* - installNetworkMocks(): the Playwright wiring. Registers a single catch-all page.route handler
|
|
11
|
+
* that consults matchMock and fulfills/aborts/continues. Driven in tests with a fake Page + Route.
|
|
12
|
+
*/
|
|
13
|
+
/** One interception rule. First matching rule (in order) wins for a request. */
|
|
14
|
+
export interface MockRule {
|
|
15
|
+
/** Substring the request URL must contain to match (e.g. "/api/pay"). */
|
|
16
|
+
urlContains: string;
|
|
17
|
+
/** Optional method filter (GET/POST/…); case-insensitive. Omit to match any method. */
|
|
18
|
+
method?: string;
|
|
19
|
+
/** Fulfill the request with this HTTP status (default 200). Ignored when `abort` is set. */
|
|
20
|
+
status?: number;
|
|
21
|
+
/** Response body to fulfill with. */
|
|
22
|
+
body?: string;
|
|
23
|
+
/** Response content type (default application/json). */
|
|
24
|
+
contentType?: string;
|
|
25
|
+
/** Delay (ms) before fulfilling — simulate a slow endpoint. */
|
|
26
|
+
delayMs?: number;
|
|
27
|
+
/** Simulate a network failure (offline / connection refused) instead of a response. */
|
|
28
|
+
abort?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** What to do with a request after matching: fulfill a canned response, abort it, or let it through. */
|
|
31
|
+
interface MockOutcome {
|
|
32
|
+
kind: 'fulfill' | 'abort' | 'continue';
|
|
33
|
+
status?: number;
|
|
34
|
+
body?: string;
|
|
35
|
+
contentType?: string;
|
|
36
|
+
delayMs?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Decide the outcome for a request from the active rules. Pure: no IO, no clock. The first rule
|
|
40
|
+
* whose url-substring (and optional method) matches wins; no match → continue (let it hit the network).
|
|
41
|
+
*/
|
|
42
|
+
export declare function matchMock(rules: MockRule[], req: {
|
|
43
|
+
url: string;
|
|
44
|
+
method: string;
|
|
45
|
+
}): MockOutcome;
|
|
46
|
+
/** Apply a matched outcome to a Playwright Route. Exported so the route handler is testable in isolation. */
|
|
47
|
+
export declare function applyOutcome(route: Route, outcome: MockOutcome, sleep: (ms: number) => Promise<void>): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Install (or replace) the network-mock handler on a driven page. Clears any prior Reticle route first,
|
|
50
|
+
* so calling with a new rule set is idempotent and calling with [] turns mocking off. The handler
|
|
51
|
+
* consults matchMock per request and fulfills/aborts/continues accordingly.
|
|
52
|
+
*/
|
|
53
|
+
export declare function installNetworkMocks(page: Page, rules: MockRule[], sleep?: (ms: number) => Promise<void>): Promise<void>;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=network-mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-mock.d.ts","sourceRoot":"","sources":["../../src/input/network-mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;GAUG;AAEH,gFAAgF;AAChF,MAAM,WAAW,QAAQ;IACvB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wGAAwG;AACxG,UAAU,WAAW;IACnB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAgB9F;AAED,6GAA6G;AAC7G,wBAAsB,YAAY,CAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACnC,OAAO,CAAC,IAAI,CAAC,CAef;AAID;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,QAAQ,EAAE,EACjB,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAa,GAC/C,OAAO,CAAC,IAAI,CAAC,CAQf"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const DEFAULT_STATUS = 200;
|
|
2
|
+
const DEFAULT_CONTENT_TYPE = 'application/json';
|
|
3
|
+
/**
|
|
4
|
+
* Decide the outcome for a request from the active rules. Pure: no IO, no clock. The first rule
|
|
5
|
+
* whose url-substring (and optional method) matches wins; no match → continue (let it hit the network).
|
|
6
|
+
*/
|
|
7
|
+
export function matchMock(rules, req) {
|
|
8
|
+
for (const rule of rules) {
|
|
9
|
+
if (!req.url.includes(rule.urlContains))
|
|
10
|
+
continue;
|
|
11
|
+
if (rule.method !== undefined && rule.method.toUpperCase() !== req.method.toUpperCase())
|
|
12
|
+
continue;
|
|
13
|
+
if (rule.abort === true)
|
|
14
|
+
return { kind: 'abort' };
|
|
15
|
+
const outcome = {
|
|
16
|
+
kind: 'fulfill',
|
|
17
|
+
status: rule.status ?? DEFAULT_STATUS,
|
|
18
|
+
contentType: rule.contentType ?? DEFAULT_CONTENT_TYPE,
|
|
19
|
+
};
|
|
20
|
+
if (rule.body !== undefined)
|
|
21
|
+
outcome.body = rule.body;
|
|
22
|
+
if (rule.delayMs !== undefined)
|
|
23
|
+
outcome.delayMs = rule.delayMs;
|
|
24
|
+
return outcome;
|
|
25
|
+
}
|
|
26
|
+
return { kind: 'continue' };
|
|
27
|
+
}
|
|
28
|
+
/** Apply a matched outcome to a Playwright Route. Exported so the route handler is testable in isolation. */
|
|
29
|
+
export async function applyOutcome(route, outcome, sleep) {
|
|
30
|
+
if (outcome.kind === 'continue') {
|
|
31
|
+
await route.continue();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (outcome.kind === 'abort') {
|
|
35
|
+
await route.abort('failed');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (outcome.delayMs !== undefined && outcome.delayMs > 0)
|
|
39
|
+
await sleep(outcome.delayMs);
|
|
40
|
+
await route.fulfill({
|
|
41
|
+
status: outcome.status ?? DEFAULT_STATUS,
|
|
42
|
+
contentType: outcome.contentType ?? DEFAULT_CONTENT_TYPE,
|
|
43
|
+
body: outcome.body ?? '',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const realSleep = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
47
|
+
/**
|
|
48
|
+
* Install (or replace) the network-mock handler on a driven page. Clears any prior Reticle route first,
|
|
49
|
+
* so calling with a new rule set is idempotent and calling with [] turns mocking off. The handler
|
|
50
|
+
* consults matchMock per request and fulfills/aborts/continues accordingly.
|
|
51
|
+
*/
|
|
52
|
+
export async function installNetworkMocks(page, rules, sleep = realSleep) {
|
|
53
|
+
await page.unroute('**/*').catch(() => undefined);
|
|
54
|
+
if (rules.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
await page.route('**/*', (route) => {
|
|
57
|
+
const req = route.request();
|
|
58
|
+
const outcome = matchMock(rules, { url: req.url(), method: req.method() });
|
|
59
|
+
void applyOutcome(route, outcome, sleep);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=network-mock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-mock.js","sourceRoot":"","sources":["../../src/input/network-mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional CDP/Playwright real-input mode.
|
|
3
|
+
*
|
|
4
|
+
* Synthetic `dispatchEvent` cannot drive native hover/pointer state (an onMouseEnter never
|
|
5
|
+
* fires, hit-testing never runs). When a CDP endpoint is configured, this module connects a
|
|
6
|
+
* Playwright `Browser` over CDP and drives REAL pointer/keyboard input against the element box
|
|
7
|
+
* the SDK resolves (viewport CSS px from getBoundingClientRect).
|
|
8
|
+
*
|
|
9
|
+
* Node-only. Playwright is loaded via DYNAMIC `import('playwright')` so non-CDP users never
|
|
10
|
+
* pay for it; the type-only import is elided by `tsc`, so the build stays green without it.
|
|
11
|
+
*/
|
|
12
|
+
import type { Browser, Page } from 'playwright';
|
|
13
|
+
import { DriveErrorCode } from '@reticlehq/core';
|
|
14
|
+
import { type MockRule } from './network-mock.js';
|
|
15
|
+
/** Viewport CSS-px box as returned by the INSPECT command (getBoundingClientRect). */
|
|
16
|
+
export interface ElementBox {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
}
|
|
22
|
+
/** Args forwarded from reticle_act (fill value, type text, drag drop-target box). */
|
|
23
|
+
export interface RealInputArgs {
|
|
24
|
+
value?: string;
|
|
25
|
+
text?: string;
|
|
26
|
+
/** For drag: the resolved box of the drop-target ref (toRef). */
|
|
27
|
+
toBox?: ElementBox;
|
|
28
|
+
steps?: number;
|
|
29
|
+
}
|
|
30
|
+
interface RealInputResult {
|
|
31
|
+
/** True if a native gesture was actually driven. */
|
|
32
|
+
performed: boolean;
|
|
33
|
+
/** Center used, for diagnostics/tests. */
|
|
34
|
+
center: {
|
|
35
|
+
cx: number;
|
|
36
|
+
cy: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Options for a page screenshot — full-page scroll capture and/or a clip box. */
|
|
40
|
+
export interface ScreenshotOpts {
|
|
41
|
+
fullPage?: boolean;
|
|
42
|
+
/** Restrict the capture to one element/region (viewport CSS px). */
|
|
43
|
+
clip?: ElementBox;
|
|
44
|
+
}
|
|
45
|
+
/** The capability surface reticle_act depends on. A FAKE implementing this is injected in tests. */
|
|
46
|
+
export interface RealInputProvider {
|
|
47
|
+
/** Whether a Playwright Page currently matches this SDK session URL. */
|
|
48
|
+
isAvailableFor(sessionUrl: string): Promise<boolean>;
|
|
49
|
+
/** Drive a native gesture for `action` at the element `box`. */
|
|
50
|
+
perform(sessionUrl: string, action: string, box: ElementBox, args: RealInputArgs): Promise<RealInputResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Capture a PNG of the correlated page, or undefined if no page matches. Optional
|
|
53
|
+
* so the visual layer stays opt-in — a provider that cannot screenshot simply omits it.
|
|
54
|
+
*/
|
|
55
|
+
screenshot?(sessionUrl: string, opts: ScreenshotOpts): Promise<Uint8Array | undefined>;
|
|
56
|
+
/**
|
|
57
|
+
* Install (or replace, or with [] clear) network-mock rules on the correlated page — stub a 500,
|
|
58
|
+
* force offline, delay a response — for deterministic error/edge-state testing. Returns true when
|
|
59
|
+
* a page matched and the rules were applied, false when no driven page matches this session.
|
|
60
|
+
* Optional: a provider with no owned browser simply omits it.
|
|
61
|
+
*/
|
|
62
|
+
setMocks?(sessionUrl: string, rules: MockRule[]): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Pin the correlated page's viewport to fixed pixel dimensions so a screenshot baseline is
|
|
65
|
+
* reproducible across machines (the missing piece of CI-stable visual regression, alongside masks
|
|
66
|
+
* and the frozen clock). Returns true when a page matched, false otherwise. Optional.
|
|
67
|
+
*/
|
|
68
|
+
setViewport?(sessionUrl: string, size: {
|
|
69
|
+
width: number;
|
|
70
|
+
height: number;
|
|
71
|
+
}): Promise<boolean>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Optional lifecycle a provider that OWNS a browser implements (`reticle drive`). The
|
|
75
|
+
* reticle_act routing still depends only on `RealInputProvider`; the server uses these to boot/tear-down.
|
|
76
|
+
*/
|
|
77
|
+
export interface OwnedRealInputProvider extends RealInputProvider {
|
|
78
|
+
/** Launch + navigate the owned browser. Must reject (never hang) on failure. */
|
|
79
|
+
navigate(): Promise<void>;
|
|
80
|
+
/** Close the owned browser. Idempotent. */
|
|
81
|
+
dispose(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
/** Structured, code-tagged failure so callers branch on cause, not message text. */
|
|
84
|
+
export declare class DriveError extends Error {
|
|
85
|
+
readonly code: DriveErrorCode;
|
|
86
|
+
constructor(code: DriveErrorCode, message: string);
|
|
87
|
+
}
|
|
88
|
+
/** Center of a viewport box in CSS px. Pure — unit-tested directly. */
|
|
89
|
+
export declare function boxCenter(box: ElementBox): {
|
|
90
|
+
cx: number;
|
|
91
|
+
cy: number;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Which actions are driven by native pointer input. fill/type stay synthetic unless a
|
|
95
|
+
* provider explicitly runs them.
|
|
96
|
+
*/
|
|
97
|
+
export declare function isPointerAction(action: string): boolean;
|
|
98
|
+
type SleepFn = (ms: number) => Promise<void>;
|
|
99
|
+
type ConnectFn = (url: string) => Promise<Browser>;
|
|
100
|
+
/**
|
|
101
|
+
* Shared gesture executor: drive a native gesture on an already-resolved Page. Used by both the
|
|
102
|
+
* CDP-attached and the launched (drive) providers so the pointer logic lives in one place.
|
|
103
|
+
*/
|
|
104
|
+
export declare function performGesture(page: Page, action: string, box: ElementBox, args: RealInputArgs, sleep: SleepFn): Promise<RealInputResult>;
|
|
105
|
+
/**
|
|
106
|
+
* Capture a PNG from a Playwright page. Shared by the CDP + launched providers so the
|
|
107
|
+
* screenshot path lives in one place (mirrors performGesture). Returns the raw PNG bytes.
|
|
108
|
+
*/
|
|
109
|
+
export declare function capturePage(page: Page, opts: ScreenshotOpts): Promise<Uint8Array>;
|
|
110
|
+
interface CdpProviderOptions {
|
|
111
|
+
cdpUrl: string;
|
|
112
|
+
/** Injected so the settle delay is deterministic in tests; defaults to a real Node timer. */
|
|
113
|
+
sleep?: SleepFn;
|
|
114
|
+
/** Injected connector so unit tests can stub Playwright without import(). */
|
|
115
|
+
connect?: ConnectFn;
|
|
116
|
+
}
|
|
117
|
+
/** CDP-backed real-input provider. Lazily connects on first availability check / perform. */
|
|
118
|
+
export declare class CdpRealInputProvider implements RealInputProvider {
|
|
119
|
+
#private;
|
|
120
|
+
constructor(options: CdpProviderOptions);
|
|
121
|
+
isAvailableFor(sessionUrl: string): Promise<boolean>;
|
|
122
|
+
perform(sessionUrl: string, action: string, box: ElementBox, args: RealInputArgs): Promise<RealInputResult>;
|
|
123
|
+
/** PNG of the correlated page, or undefined if none matches. */
|
|
124
|
+
screenshot(sessionUrl: string, opts: ScreenshotOpts): Promise<Uint8Array | undefined>;
|
|
125
|
+
/** Apply network-mock rules to the correlated page; false when no driven page matches. */
|
|
126
|
+
setMocks(sessionUrl: string, rules: MockRule[]): Promise<boolean>;
|
|
127
|
+
/** Pin the correlated page's viewport to fixed dimensions; false when no driven page matches. */
|
|
128
|
+
setViewport(sessionUrl: string, size: {
|
|
129
|
+
width: number;
|
|
130
|
+
height: number;
|
|
131
|
+
}): Promise<boolean>;
|
|
132
|
+
/** Best-effort cleanup; idempotent. */
|
|
133
|
+
dispose(): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
/** Injected launcher so unit tests stub Playwright without import(). */
|
|
136
|
+
export type LaunchFn = (headless: boolean) => Promise<Browser>;
|
|
137
|
+
/**
|
|
138
|
+
* Force a driven page's already-loaded SDK to connect to our loopback bridge with a pairing token,
|
|
139
|
+
* overriding the app's own (often localhost-only) reticle.connect() — so a hosted preview verifies with
|
|
140
|
+
* no app redeploy. connect() is a no-op once connected, so re-invoking it is safe.
|
|
141
|
+
*/
|
|
142
|
+
export interface InjectConnectOptions {
|
|
143
|
+
token: string;
|
|
144
|
+
url: string;
|
|
145
|
+
}
|
|
146
|
+
export interface LaunchedProviderOptions {
|
|
147
|
+
driveUrl: string;
|
|
148
|
+
headless: boolean;
|
|
149
|
+
/** Injected so the settle delay is deterministic in tests; defaults to a real Node timer. */
|
|
150
|
+
sleep?: SleepFn;
|
|
151
|
+
/** Injected launcher so unit tests can stub Playwright; defaults to dynamic import('playwright'). */
|
|
152
|
+
launch?: LaunchFn;
|
|
153
|
+
/** When set, re-invoke the page's reticle.connect() with these after load (drive-a-hosted-preview). */
|
|
154
|
+
injectConnect?: InjectConnectOptions;
|
|
155
|
+
/** Path to a Playwright storageState JSON (cookies/localStorage) — starts the page authenticated. */
|
|
156
|
+
storageState?: string;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Launches and OWNS a Playwright Chromium, navigates it to `driveUrl`, then drives native
|
|
160
|
+
* input on that page. Headless-capable so @reticlehq/test / CI can run hover/drag unattended.
|
|
161
|
+
*/
|
|
162
|
+
export declare class LaunchedRealInputProvider implements OwnedRealInputProvider {
|
|
163
|
+
#private;
|
|
164
|
+
constructor(options: LaunchedProviderOptions);
|
|
165
|
+
navigate(): Promise<void>;
|
|
166
|
+
isAvailableFor(sessionUrl: string): Promise<boolean>;
|
|
167
|
+
perform(_sessionUrl: string, action: string, box: ElementBox, args: RealInputArgs): Promise<RealInputResult>;
|
|
168
|
+
/** PNG of the owned page, or undefined before navigate / after dispose. */
|
|
169
|
+
screenshot(_sessionUrl: string, opts: ScreenshotOpts): Promise<Uint8Array | undefined>;
|
|
170
|
+
/** Close the owned browser once. Idempotent and safe before navigate. */
|
|
171
|
+
dispose(): Promise<void>;
|
|
172
|
+
}
|
|
173
|
+
export {};
|
|
174
|
+
//# sourceMappingURL=real-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"real-input.d.ts","sourceRoot":"","sources":["../../src/input/real-input.ts"],"names":[],"mappings":"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"}
|