devharness 0.8.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 +21 -0
- package/README.md +185 -0
- package/build/atomic-write.d.ts +28 -0
- package/build/atomic-write.d.ts.map +1 -0
- package/build/atomic-write.js +126 -0
- package/build/atomic-write.js.map +1 -0
- package/build/cdp-manager.d.ts +524 -0
- package/build/cdp-manager.d.ts.map +1 -0
- package/build/cdp-manager.js +1828 -0
- package/build/cdp-manager.js.map +1 -0
- package/build/cdp-manager.test.d.ts +6 -0
- package/build/cdp-manager.test.d.ts.map +1 -0
- package/build/cdp-manager.test.js +546 -0
- package/build/cdp-manager.test.js.map +1 -0
- package/build/chrome-launcher.d.ts +400 -0
- package/build/chrome-launcher.d.ts.map +1 -0
- package/build/chrome-launcher.js +1071 -0
- package/build/chrome-launcher.js.map +1 -0
- package/build/chrome-launcher.test.d.ts +11 -0
- package/build/chrome-launcher.test.d.ts.map +1 -0
- package/build/chrome-launcher.test.js +204 -0
- package/build/chrome-launcher.test.js.map +1 -0
- package/build/clickable-cache.d.ts +73 -0
- package/build/clickable-cache.d.ts.map +1 -0
- package/build/clickable-cache.js +90 -0
- package/build/clickable-cache.js.map +1 -0
- package/build/command-recorder.d.ts +401 -0
- package/build/command-recorder.d.ts.map +1 -0
- package/build/command-recorder.js +701 -0
- package/build/command-recorder.js.map +1 -0
- package/build/config.d.ts +390 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +826 -0
- package/build/config.js.map +1 -0
- package/build/config.test.d.ts +2 -0
- package/build/config.test.d.ts.map +1 -0
- package/build/config.test.js +112 -0
- package/build/config.test.js.map +1 -0
- package/build/connection-manager.d.ts +159 -0
- package/build/connection-manager.d.ts.map +1 -0
- package/build/connection-manager.js +432 -0
- package/build/connection-manager.js.map +1 -0
- package/build/connection-manager.test.d.ts +11 -0
- package/build/connection-manager.test.d.ts.map +1 -0
- package/build/connection-manager.test.js +114 -0
- package/build/connection-manager.test.js.map +1 -0
- package/build/console-monitor.d.ts +150 -0
- package/build/console-monitor.d.ts.map +1 -0
- package/build/console-monitor.js +454 -0
- package/build/console-monitor.js.map +1 -0
- package/build/dashboard/bundle.js +1 -0
- package/build/dashboard/dashboard-client.d.ts +42 -0
- package/build/dashboard/dashboard-client.d.ts.map +1 -0
- package/build/dashboard/dashboard-client.js +184 -0
- package/build/dashboard/dashboard-client.js.map +1 -0
- package/build/dashboard/dashboard-hub.d.ts +50 -0
- package/build/dashboard/dashboard-hub.d.ts.map +1 -0
- package/build/dashboard/dashboard-hub.js +654 -0
- package/build/dashboard/dashboard-hub.js.map +1 -0
- package/build/dashboard/hub-lock.d.ts +16 -0
- package/build/dashboard/hub-lock.d.ts.map +1 -0
- package/build/dashboard/hub-lock.js +77 -0
- package/build/dashboard/hub-lock.js.map +1 -0
- package/build/dashboard/index.d.ts +25 -0
- package/build/dashboard/index.d.ts.map +1 -0
- package/build/dashboard/index.js +77 -0
- package/build/dashboard/index.js.map +1 -0
- package/build/dashboard/types.d.ts +83 -0
- package/build/dashboard/types.d.ts.map +1 -0
- package/build/dashboard/types.js +6 -0
- package/build/dashboard/types.js.map +1 -0
- package/build/debug-logger.d.ts +85 -0
- package/build/debug-logger.d.ts.map +1 -0
- package/build/debug-logger.js +195 -0
- package/build/debug-logger.js.map +1 -0
- package/build/debugger-aware-wrapper.d.ts +37 -0
- package/build/debugger-aware-wrapper.d.ts.map +1 -0
- package/build/debugger-aware-wrapper.js +128 -0
- package/build/debugger-aware-wrapper.js.map +1 -0
- package/build/dom-change-monitor.d.ts +92 -0
- package/build/dom-change-monitor.d.ts.map +1 -0
- package/build/dom-change-monitor.js +437 -0
- package/build/dom-change-monitor.js.map +1 -0
- package/build/element-collector.d.ts +16 -0
- package/build/element-collector.d.ts.map +1 -0
- package/build/element-collector.js +207 -0
- package/build/element-collector.js.map +1 -0
- package/build/error-helpers.d.ts +43 -0
- package/build/error-helpers.d.ts.map +1 -0
- package/build/error-helpers.js +143 -0
- package/build/error-helpers.js.map +1 -0
- package/build/formatters/console-formatter.d.ts +160 -0
- package/build/formatters/console-formatter.d.ts.map +1 -0
- package/build/formatters/console-formatter.js +338 -0
- package/build/formatters/console-formatter.js.map +1 -0
- package/build/helpers/parser-plugins.d.ts +44 -0
- package/build/helpers/parser-plugins.d.ts.map +1 -0
- package/build/helpers/parser-plugins.js +102 -0
- package/build/helpers/parser-plugins.js.map +1 -0
- package/build/helpers/paths.d.ts +79 -0
- package/build/helpers/paths.d.ts.map +1 -0
- package/build/helpers/paths.js +168 -0
- package/build/helpers/paths.js.map +1 -0
- package/build/helpers/process-liveness.d.ts +24 -0
- package/build/helpers/process-liveness.d.ts.map +1 -0
- package/build/helpers/process-liveness.js +36 -0
- package/build/helpers/process-liveness.js.map +1 -0
- package/build/helpers/process-liveness.test.d.ts +2 -0
- package/build/helpers/process-liveness.test.d.ts.map +1 -0
- package/build/helpers/process-liveness.test.js +40 -0
- package/build/helpers/process-liveness.test.js.map +1 -0
- package/build/helpers/sequence-tree.d.ts +27 -0
- package/build/helpers/sequence-tree.d.ts.map +1 -0
- package/build/helpers/sequence-tree.js +80 -0
- package/build/helpers/sequence-tree.js.map +1 -0
- package/build/helpers/sequence-tree.test.d.ts +2 -0
- package/build/helpers/sequence-tree.test.d.ts.map +1 -0
- package/build/helpers/sequence-tree.test.js +122 -0
- package/build/helpers/sequence-tree.test.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2007 -0
- package/build/index.js.map +1 -0
- package/build/interaction-recorder.d.ts +214 -0
- package/build/interaction-recorder.d.ts.map +1 -0
- package/build/interaction-recorder.js +2007 -0
- package/build/interaction-recorder.js.map +1 -0
- package/build/issue-tracker.d.ts +107 -0
- package/build/issue-tracker.d.ts.map +1 -0
- package/build/issue-tracker.js +582 -0
- package/build/issue-tracker.js.map +1 -0
- package/build/issue-tracker.test.d.ts +2 -0
- package/build/issue-tracker.test.d.ts.map +1 -0
- package/build/issue-tracker.test.js +88 -0
- package/build/issue-tracker.test.js.map +1 -0
- package/build/launch-chrome-port.test.d.ts +14 -0
- package/build/launch-chrome-port.test.d.ts.map +1 -0
- package/build/launch-chrome-port.test.js +97 -0
- package/build/launch-chrome-port.test.js.map +1 -0
- package/build/log-processor/orchestrator.d.ts +32 -0
- package/build/log-processor/orchestrator.d.ts.map +1 -0
- package/build/log-processor/orchestrator.js +27 -0
- package/build/log-processor/orchestrator.js.map +1 -0
- package/build/logpoint-execution-tracker.d.ts +57 -0
- package/build/logpoint-execution-tracker.d.ts.map +1 -0
- package/build/logpoint-execution-tracker.js +112 -0
- package/build/logpoint-execution-tracker.js.map +1 -0
- package/build/mcp-supervisor.d.ts +3 -0
- package/build/mcp-supervisor.d.ts.map +1 -0
- package/build/mcp-supervisor.js +211 -0
- package/build/mcp-supervisor.js.map +1 -0
- package/build/messages.d.ts +165 -0
- package/build/messages.d.ts.map +1 -0
- package/build/messages.js +574 -0
- package/build/messages.js.map +1 -0
- package/build/network-monitor.d.ts +172 -0
- package/build/network-monitor.d.ts.map +1 -0
- package/build/network-monitor.js +350 -0
- package/build/network-monitor.js.map +1 -0
- package/build/overlays.d.ts +49 -0
- package/build/overlays.d.ts.map +1 -0
- package/build/overlays.js +409 -0
- package/build/overlays.js.map +1 -0
- package/build/persistent-profiles.test.d.ts +15 -0
- package/build/persistent-profiles.test.d.ts.map +1 -0
- package/build/persistent-profiles.test.js +470 -0
- package/build/persistent-profiles.test.js.map +1 -0
- package/build/port-reserver.d.ts +32 -0
- package/build/port-reserver.d.ts.map +1 -0
- package/build/port-reserver.js +118 -0
- package/build/port-reserver.js.map +1 -0
- package/build/puppeteer-manager.d.ts +47 -0
- package/build/puppeteer-manager.d.ts.map +1 -0
- package/build/puppeteer-manager.js +116 -0
- package/build/puppeteer-manager.js.map +1 -0
- package/build/recording-coverage.test.d.ts +12 -0
- package/build/recording-coverage.test.d.ts.map +1 -0
- package/build/recording-coverage.test.js +72 -0
- package/build/recording-coverage.test.js.map +1 -0
- package/build/reference-validator.d.ts +47 -0
- package/build/reference-validator.d.ts.map +1 -0
- package/build/reference-validator.js +86 -0
- package/build/reference-validator.js.map +1 -0
- package/build/reference-validator.test.d.ts +5 -0
- package/build/reference-validator.test.d.ts.map +1 -0
- package/build/reference-validator.test.js +243 -0
- package/build/reference-validator.test.js.map +1 -0
- package/build/replay-cursor.d.ts +27 -0
- package/build/replay-cursor.d.ts.map +1 -0
- package/build/replay-cursor.js +240 -0
- package/build/replay-cursor.js.map +1 -0
- package/build/runners/docker-compose-runner.d.ts +69 -0
- package/build/runners/docker-compose-runner.d.ts.map +1 -0
- package/build/runners/docker-compose-runner.js +438 -0
- package/build/runners/docker-compose-runner.js.map +1 -0
- package/build/runners/docker-runner.d.ts +65 -0
- package/build/runners/docker-runner.d.ts.map +1 -0
- package/build/runners/docker-runner.js +414 -0
- package/build/runners/docker-runner.js.map +1 -0
- package/build/runners/index.d.ts +19 -0
- package/build/runners/index.d.ts.map +1 -0
- package/build/runners/index.js +35 -0
- package/build/runners/index.js.map +1 -0
- package/build/runners/native-runner.d.ts +95 -0
- package/build/runners/native-runner.d.ts.map +1 -0
- package/build/runners/native-runner.js +370 -0
- package/build/runners/native-runner.js.map +1 -0
- package/build/runners/types.d.ts +147 -0
- package/build/runners/types.d.ts.map +1 -0
- package/build/runners/types.js +25 -0
- package/build/runners/types.js.map +1 -0
- package/build/self-restart.d.ts +12 -0
- package/build/self-restart.d.ts.map +1 -0
- package/build/self-restart.js +41 -0
- package/build/self-restart.js.map +1 -0
- package/build/self-restart.test.d.ts +2 -0
- package/build/self-restart.test.d.ts.map +1 -0
- package/build/self-restart.test.js +34 -0
- package/build/self-restart.test.js.map +1 -0
- package/build/server-claims.d.ts +161 -0
- package/build/server-claims.d.ts.map +1 -0
- package/build/server-claims.js +382 -0
- package/build/server-claims.js.map +1 -0
- package/build/server-claims.test.d.ts +2 -0
- package/build/server-claims.test.d.ts.map +1 -0
- package/build/server-claims.test.js +197 -0
- package/build/server-claims.test.js.map +1 -0
- package/build/server-manager.d.ts +438 -0
- package/build/server-manager.d.ts.map +1 -0
- package/build/server-manager.js +1674 -0
- package/build/server-manager.js.map +1 -0
- package/build/server-manager.test.d.ts +17 -0
- package/build/server-manager.test.d.ts.map +1 -0
- package/build/server-manager.test.js +122 -0
- package/build/server-manager.test.js.map +1 -0
- package/build/server-ownership.test.d.ts +2 -0
- package/build/server-ownership.test.d.ts.map +1 -0
- package/build/server-ownership.test.js +238 -0
- package/build/server-ownership.test.js.map +1 -0
- package/build/server-watcher.d.ts +21 -0
- package/build/server-watcher.d.ts.map +1 -0
- package/build/server-watcher.js +105 -0
- package/build/server-watcher.js.map +1 -0
- package/build/session-detector.d.ts +47 -0
- package/build/session-detector.d.ts.map +1 -0
- package/build/session-detector.js +229 -0
- package/build/session-detector.js.map +1 -0
- package/build/session-detector.test.d.ts +9 -0
- package/build/session-detector.test.d.ts.map +1 -0
- package/build/session-detector.test.js +45 -0
- package/build/session-detector.test.js.map +1 -0
- package/build/sourcemap-handler.d.ts +114 -0
- package/build/sourcemap-handler.d.ts.map +1 -0
- package/build/sourcemap-handler.js +479 -0
- package/build/sourcemap-handler.js.map +1 -0
- package/build/supervisor/child-manager.d.ts +43 -0
- package/build/supervisor/child-manager.d.ts.map +1 -0
- package/build/supervisor/child-manager.js +148 -0
- package/build/supervisor/child-manager.js.map +1 -0
- package/build/supervisor/child-manager.test.d.ts +2 -0
- package/build/supervisor/child-manager.test.d.ts.map +1 -0
- package/build/supervisor/child-manager.test.js +107 -0
- package/build/supervisor/child-manager.test.js.map +1 -0
- package/build/supervisor/client-watcher.d.ts +48 -0
- package/build/supervisor/client-watcher.d.ts.map +1 -0
- package/build/supervisor/client-watcher.js +186 -0
- package/build/supervisor/client-watcher.js.map +1 -0
- package/build/supervisor/client-watcher.test.d.ts +2 -0
- package/build/supervisor/client-watcher.test.d.ts.map +1 -0
- package/build/supervisor/client-watcher.test.js +121 -0
- package/build/supervisor/client-watcher.test.js.map +1 -0
- package/build/supervisor/idle-config.d.ts +30 -0
- package/build/supervisor/idle-config.d.ts.map +1 -0
- package/build/supervisor/idle-config.js +76 -0
- package/build/supervisor/idle-config.js.map +1 -0
- package/build/supervisor/idle-config.test.d.ts +2 -0
- package/build/supervisor/idle-config.test.d.ts.map +1 -0
- package/build/supervisor/idle-config.test.js +119 -0
- package/build/supervisor/idle-config.test.js.map +1 -0
- package/build/supervisor/ndjson-reader.d.ts +47 -0
- package/build/supervisor/ndjson-reader.d.ts.map +1 -0
- package/build/supervisor/ndjson-reader.js +75 -0
- package/build/supervisor/ndjson-reader.js.map +1 -0
- package/build/supervisor/ndjson-reader.test.d.ts +2 -0
- package/build/supervisor/ndjson-reader.test.d.ts.map +1 -0
- package/build/supervisor/ndjson-reader.test.js +92 -0
- package/build/supervisor/ndjson-reader.test.js.map +1 -0
- package/build/supervisor/pidfile.d.ts +11 -0
- package/build/supervisor/pidfile.d.ts.map +1 -0
- package/build/supervisor/pidfile.js +29 -0
- package/build/supervisor/pidfile.js.map +1 -0
- package/build/supervisor/pidfile.test.d.ts +8 -0
- package/build/supervisor/pidfile.test.d.ts.map +1 -0
- package/build/supervisor/pidfile.test.js +46 -0
- package/build/supervisor/pidfile.test.js.map +1 -0
- package/build/supervisor/restart-coordinator.d.ts +73 -0
- package/build/supervisor/restart-coordinator.d.ts.map +1 -0
- package/build/supervisor/restart-coordinator.js +300 -0
- package/build/supervisor/restart-coordinator.js.map +1 -0
- package/build/supervisor/restart-coordinator.test.d.ts +2 -0
- package/build/supervisor/restart-coordinator.test.d.ts.map +1 -0
- package/build/supervisor/restart-coordinator.test.js +434 -0
- package/build/supervisor/restart-coordinator.test.js.map +1 -0
- package/build/test-support/fake-execute-tool-call.d.ts +11 -0
- package/build/test-support/fake-execute-tool-call.d.ts.map +1 -0
- package/build/test-support/fake-execute-tool-call.js +19 -0
- package/build/test-support/fake-execute-tool-call.js.map +1 -0
- package/build/tool-error.d.ts +14 -0
- package/build/tool-error.d.ts.map +1 -0
- package/build/tool-error.js +18 -0
- package/build/tool-error.js.map +1 -0
- package/build/tool-response.d.ts +293 -0
- package/build/tool-response.d.ts.map +1 -0
- package/build/tool-response.js +365 -0
- package/build/tool-response.js.map +1 -0
- package/build/tools/assert-tools.d.ts +62 -0
- package/build/tools/assert-tools.d.ts.map +1 -0
- package/build/tools/assert-tools.js +330 -0
- package/build/tools/assert-tools.js.map +1 -0
- package/build/tools/breakpoint-await-abort.test.d.ts +2 -0
- package/build/tools/breakpoint-await-abort.test.d.ts.map +1 -0
- package/build/tools/breakpoint-await-abort.test.js +124 -0
- package/build/tools/breakpoint-await-abort.test.js.map +1 -0
- package/build/tools/breakpoint-tools.d.ts +99 -0
- package/build/tools/breakpoint-tools.d.ts.map +1 -0
- package/build/tools/breakpoint-tools.js +1197 -0
- package/build/tools/breakpoint-tools.js.map +1 -0
- package/build/tools/config-tools.d.ts +58 -0
- package/build/tools/config-tools.d.ts.map +1 -0
- package/build/tools/config-tools.js +180 -0
- package/build/tools/config-tools.js.map +1 -0
- package/build/tools/connection-routing.test.d.ts +12 -0
- package/build/tools/connection-routing.test.d.ts.map +1 -0
- package/build/tools/connection-routing.test.js +206 -0
- package/build/tools/connection-routing.test.js.map +1 -0
- package/build/tools/console-tools.d.ts +84 -0
- package/build/tools/console-tools.d.ts.map +1 -0
- package/build/tools/console-tools.js +241 -0
- package/build/tools/console-tools.js.map +1 -0
- package/build/tools/content-tools.d.ts +74 -0
- package/build/tools/content-tools.d.ts.map +1 -0
- package/build/tools/content-tools.js +582 -0
- package/build/tools/content-tools.js.map +1 -0
- package/build/tools/dashboard-tools.d.ts +38 -0
- package/build/tools/dashboard-tools.d.ts.map +1 -0
- package/build/tools/dashboard-tools.js +123 -0
- package/build/tools/dashboard-tools.js.map +1 -0
- package/build/tools/dom-tools.d.ts +41 -0
- package/build/tools/dom-tools.d.ts.map +1 -0
- package/build/tools/dom-tools.js +277 -0
- package/build/tools/dom-tools.js.map +1 -0
- package/build/tools/download-tools.d.ts +55 -0
- package/build/tools/download-tools.d.ts.map +1 -0
- package/build/tools/download-tools.js +280 -0
- package/build/tools/download-tools.js.map +1 -0
- package/build/tools/execution-tools.d.ts +40 -0
- package/build/tools/execution-tools.d.ts.map +1 -0
- package/build/tools/execution-tools.js +121 -0
- package/build/tools/execution-tools.js.map +1 -0
- package/build/tools/input-abort.test.d.ts +2 -0
- package/build/tools/input-abort.test.d.ts.map +1 -0
- package/build/tools/input-abort.test.js +227 -0
- package/build/tools/input-abort.test.js.map +1 -0
- package/build/tools/input-ambiguous-selector.test.d.ts +2 -0
- package/build/tools/input-ambiguous-selector.test.d.ts.map +1 -0
- package/build/tools/input-ambiguous-selector.test.js +34 -0
- package/build/tools/input-ambiguous-selector.test.js.map +1 -0
- package/build/tools/input-tools.d.ts +168 -0
- package/build/tools/input-tools.d.ts.map +1 -0
- package/build/tools/input-tools.js +1397 -0
- package/build/tools/input-tools.js.map +1 -0
- package/build/tools/inspection-tools.d.ts +112 -0
- package/build/tools/inspection-tools.d.ts.map +1 -0
- package/build/tools/inspection-tools.js +637 -0
- package/build/tools/inspection-tools.js.map +1 -0
- package/build/tools/interpolation.d.ts +30 -0
- package/build/tools/interpolation.d.ts.map +1 -0
- package/build/tools/interpolation.js +143 -0
- package/build/tools/interpolation.js.map +1 -0
- package/build/tools/issues-abort-hygiene.test.d.ts +2 -0
- package/build/tools/issues-abort-hygiene.test.d.ts.map +1 -0
- package/build/tools/issues-abort-hygiene.test.js +79 -0
- package/build/tools/issues-abort-hygiene.test.js.map +1 -0
- package/build/tools/issues-tools.d.ts +98 -0
- package/build/tools/issues-tools.d.ts.map +1 -0
- package/build/tools/issues-tools.js +821 -0
- package/build/tools/issues-tools.js.map +1 -0
- package/build/tools/issues-tools.test.d.ts +8 -0
- package/build/tools/issues-tools.test.d.ts.map +1 -0
- package/build/tools/issues-tools.test.js +184 -0
- package/build/tools/issues-tools.test.js.map +1 -0
- package/build/tools/modal-tools.d.ts +73 -0
- package/build/tools/modal-tools.d.ts.map +1 -0
- package/build/tools/modal-tools.js +161 -0
- package/build/tools/modal-tools.js.map +1 -0
- package/build/tools/network-tools.d.ts +72 -0
- package/build/tools/network-tools.d.ts.map +1 -0
- package/build/tools/network-tools.js +432 -0
- package/build/tools/network-tools.js.map +1 -0
- package/build/tools/page-tools.d.ts +78 -0
- package/build/tools/page-tools.d.ts.map +1 -0
- package/build/tools/page-tools.js +255 -0
- package/build/tools/page-tools.js.map +1 -0
- package/build/tools/plugin-tools.d.ts +16 -0
- package/build/tools/plugin-tools.d.ts.map +1 -0
- package/build/tools/plugin-tools.js +17 -0
- package/build/tools/plugin-tools.js.map +1 -0
- package/build/tools/replay-abort.test.d.ts +2 -0
- package/build/tools/replay-abort.test.d.ts.map +1 -0
- package/build/tools/replay-abort.test.js +259 -0
- package/build/tools/replay-abort.test.js.map +1 -0
- package/build/tools/replay-add-conditional.test.d.ts +2 -0
- package/build/tools/replay-add-conditional.test.d.ts.map +1 -0
- package/build/tools/replay-add-conditional.test.js +205 -0
- package/build/tools/replay-add-conditional.test.js.map +1 -0
- package/build/tools/replay-background-run.test.d.ts +2 -0
- package/build/tools/replay-background-run.test.d.ts.map +1 -0
- package/build/tools/replay-background-run.test.js +176 -0
- package/build/tools/replay-background-run.test.js.map +1 -0
- package/build/tools/replay-capture-variables.test.d.ts +2 -0
- package/build/tools/replay-capture-variables.test.d.ts.map +1 -0
- package/build/tools/replay-capture-variables.test.js +331 -0
- package/build/tools/replay-capture-variables.test.js.map +1 -0
- package/build/tools/replay-conditional-idb-and-launch.test.d.ts +11 -0
- package/build/tools/replay-conditional-idb-and-launch.test.d.ts.map +1 -0
- package/build/tools/replay-conditional-idb-and-launch.test.js +429 -0
- package/build/tools/replay-conditional-idb-and-launch.test.js.map +1 -0
- package/build/tools/replay-conditional-timeout.test.d.ts +14 -0
- package/build/tools/replay-conditional-timeout.test.d.ts.map +1 -0
- package/build/tools/replay-conditional-timeout.test.js +126 -0
- package/build/tools/replay-conditional-timeout.test.js.map +1 -0
- package/build/tools/replay-declare.test.d.ts +2 -0
- package/build/tools/replay-declare.test.d.ts.map +1 -0
- package/build/tools/replay-declare.test.js +106 -0
- package/build/tools/replay-declare.test.js.map +1 -0
- package/build/tools/replay-declared-browser-cleanup.test.d.ts +2 -0
- package/build/tools/replay-declared-browser-cleanup.test.d.ts.map +1 -0
- package/build/tools/replay-declared-browser-cleanup.test.js +103 -0
- package/build/tools/replay-declared-browser-cleanup.test.js.map +1 -0
- package/build/tools/replay-declared-profile.test.d.ts +2 -0
- package/build/tools/replay-declared-profile.test.d.ts.map +1 -0
- package/build/tools/replay-declared-profile.test.js +116 -0
- package/build/tools/replay-declared-profile.test.js.map +1 -0
- package/build/tools/replay-executor.d.ts +556 -0
- package/build/tools/replay-executor.d.ts.map +1 -0
- package/build/tools/replay-executor.js +2347 -0
- package/build/tools/replay-executor.js.map +1 -0
- package/build/tools/replay-folder-save.test.d.ts +2 -0
- package/build/tools/replay-folder-save.test.d.ts.map +1 -0
- package/build/tools/replay-folder-save.test.js +63 -0
- package/build/tools/replay-folder-save.test.js.map +1 -0
- package/build/tools/replay-formatters.d.ts +148 -0
- package/build/tools/replay-formatters.d.ts.map +1 -0
- package/build/tools/replay-formatters.js +856 -0
- package/build/tools/replay-formatters.js.map +1 -0
- package/build/tools/replay-kill-chrome-on-finish.test.d.ts +2 -0
- package/build/tools/replay-kill-chrome-on-finish.test.d.ts.map +1 -0
- package/build/tools/replay-kill-chrome-on-finish.test.js +175 -0
- package/build/tools/replay-kill-chrome-on-finish.test.js.map +1 -0
- package/build/tools/replay-multi-connection.test.d.ts +2 -0
- package/build/tools/replay-multi-connection.test.d.ts.map +1 -0
- package/build/tools/replay-multi-connection.test.js +547 -0
- package/build/tools/replay-multi-connection.test.js.map +1 -0
- package/build/tools/replay-output-and-record-options.test.d.ts +2 -0
- package/build/tools/replay-output-and-record-options.test.d.ts.map +1 -0
- package/build/tools/replay-output-and-record-options.test.js +240 -0
- package/build/tools/replay-output-and-record-options.test.js.map +1 -0
- package/build/tools/replay-production-error-shape.test.d.ts +7 -0
- package/build/tools/replay-production-error-shape.test.d.ts.map +1 -0
- package/build/tools/replay-production-error-shape.test.js +93 -0
- package/build/tools/replay-production-error-shape.test.js.map +1 -0
- package/build/tools/replay-rebase.test.d.ts +2 -0
- package/build/tools/replay-rebase.test.d.ts.map +1 -0
- package/build/tools/replay-rebase.test.js +58 -0
- package/build/tools/replay-rebase.test.js.map +1 -0
- package/build/tools/replay-retry-classification.test.d.ts +9 -0
- package/build/tools/replay-retry-classification.test.d.ts.map +1 -0
- package/build/tools/replay-retry-classification.test.js +57 -0
- package/build/tools/replay-retry-classification.test.js.map +1 -0
- package/build/tools/replay-run-registry.d.ts +55 -0
- package/build/tools/replay-run-registry.d.ts.map +1 -0
- package/build/tools/replay-run-registry.js +65 -0
- package/build/tools/replay-run-registry.js.map +1 -0
- package/build/tools/replay-sequence-reload.test.d.ts +2 -0
- package/build/tools/replay-sequence-reload.test.d.ts.map +1 -0
- package/build/tools/replay-sequence-reload.test.js +82 -0
- package/build/tools/replay-sequence-reload.test.js.map +1 -0
- package/build/tools/replay-socket-scope.test.d.ts +2 -0
- package/build/tools/replay-socket-scope.test.d.ts.map +1 -0
- package/build/tools/replay-socket-scope.test.js +75 -0
- package/build/tools/replay-socket-scope.test.js.map +1 -0
- package/build/tools/replay-step-connection.test.d.ts +2 -0
- package/build/tools/replay-step-connection.test.d.ts.map +1 -0
- package/build/tools/replay-step-connection.test.js +292 -0
- package/build/tools/replay-step-connection.test.js.map +1 -0
- package/build/tools/replay-step-timeout.test.d.ts +2 -0
- package/build/tools/replay-step-timeout.test.d.ts.map +1 -0
- package/build/tools/replay-step-timeout.test.js +204 -0
- package/build/tools/replay-step-timeout.test.js.map +1 -0
- package/build/tools/replay-tags.test.d.ts +2 -0
- package/build/tools/replay-tags.test.d.ts.map +1 -0
- package/build/tools/replay-tags.test.js +99 -0
- package/build/tools/replay-tags.test.js.map +1 -0
- package/build/tools/replay-teardown-and-foreach.test.d.ts +13 -0
- package/build/tools/replay-teardown-and-foreach.test.d.ts.map +1 -0
- package/build/tools/replay-teardown-and-foreach.test.js +318 -0
- package/build/tools/replay-teardown-and-foreach.test.js.map +1 -0
- package/build/tools/replay-tool-name-validation.test.d.ts +2 -0
- package/build/tools/replay-tool-name-validation.test.d.ts.map +1 -0
- package/build/tools/replay-tool-name-validation.test.js +280 -0
- package/build/tools/replay-tool-name-validation.test.js.map +1 -0
- package/build/tools/replay-tools.d.ts +288 -0
- package/build/tools/replay-tools.d.ts.map +1 -0
- package/build/tools/replay-tools.js +2994 -0
- package/build/tools/replay-tools.js.map +1 -0
- package/build/tools/request-abort.test.d.ts +2 -0
- package/build/tools/request-abort.test.d.ts.map +1 -0
- package/build/tools/request-abort.test.js +130 -0
- package/build/tools/request-abort.test.js.map +1 -0
- package/build/tools/request-tools.d.ts +56 -0
- package/build/tools/request-tools.d.ts.map +1 -0
- package/build/tools/request-tools.js +174 -0
- package/build/tools/request-tools.js.map +1 -0
- package/build/tools/screenshot-tools.d.ts +135 -0
- package/build/tools/screenshot-tools.d.ts.map +1 -0
- package/build/tools/screenshot-tools.js +636 -0
- package/build/tools/screenshot-tools.js.map +1 -0
- package/build/tools/server-tools.d.ts +88 -0
- package/build/tools/server-tools.d.ts.map +1 -0
- package/build/tools/server-tools.js +485 -0
- package/build/tools/server-tools.js.map +1 -0
- package/build/tools/source-tools.d.ts +46 -0
- package/build/tools/source-tools.d.ts.map +1 -0
- package/build/tools/source-tools.js +47 -0
- package/build/tools/source-tools.js.map +1 -0
- package/build/tools/storage-tools.d.ts +141 -0
- package/build/tools/storage-tools.d.ts.map +1 -0
- package/build/tools/storage-tools.js +894 -0
- package/build/tools/storage-tools.js.map +1 -0
- package/build/tools/storage-tools.test.d.ts +13 -0
- package/build/tools/storage-tools.test.d.ts.map +1 -0
- package/build/tools/storage-tools.test.js +707 -0
- package/build/tools/storage-tools.test.js.map +1 -0
- package/build/tools/tab-tools.d.ts +42 -0
- package/build/tools/tab-tools.d.ts.map +1 -0
- package/build/tools/tab-tools.js +296 -0
- package/build/tools/tab-tools.js.map +1 -0
- package/build/tools/wait-tools.d.ts +85 -0
- package/build/tools/wait-tools.d.ts.map +1 -0
- package/build/tools/wait-tools.js +236 -0
- package/build/tools/wait-tools.js.map +1 -0
- package/build/tools/wait-tools.test.d.ts +9 -0
- package/build/tools/wait-tools.test.d.ts.map +1 -0
- package/build/tools/wait-tools.test.js +193 -0
- package/build/tools/wait-tools.test.js.map +1 -0
- package/build/types.d.ts +133 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +5 -0
- package/build/types.js.map +1 -0
- package/build/ui-verifier.d.ts +88 -0
- package/build/ui-verifier.d.ts.map +1 -0
- package/build/ui-verifier.js +540 -0
- package/build/ui-verifier.js.map +1 -0
- package/build/utils/abort.d.ts +68 -0
- package/build/utils/abort.d.ts.map +1 -0
- package/build/utils/abort.js +159 -0
- package/build/utils/abort.js.map +1 -0
- package/build/utils/abort.test.d.ts +2 -0
- package/build/utils/abort.test.d.ts.map +1 -0
- package/build/utils/abort.test.js +174 -0
- package/build/utils/abort.test.js.map +1 -0
- package/build/utils/modal-detection-core.d.ts +150 -0
- package/build/utils/modal-detection-core.d.ts.map +1 -0
- package/build/utils/modal-detection-core.js +332 -0
- package/build/utils/modal-detection-core.js.map +1 -0
- package/build/utils/modal-detection-core.test.d.ts +5 -0
- package/build/utils/modal-detection-core.test.d.ts.map +1 -0
- package/build/utils/modal-detection-core.test.js +492 -0
- package/build/utils/modal-detection-core.test.js.map +1 -0
- package/build/utils/modal-detector.d.ts +29 -0
- package/build/utils/modal-detector.d.ts.map +1 -0
- package/build/utils/modal-detector.js +281 -0
- package/build/utils/modal-detector.js.map +1 -0
- package/build/utils/modal-dismissal.d.ts +32 -0
- package/build/utils/modal-dismissal.d.ts.map +1 -0
- package/build/utils/modal-dismissal.js +190 -0
- package/build/utils/modal-dismissal.js.map +1 -0
- package/build/utils/port-check.d.ts +31 -0
- package/build/utils/port-check.d.ts.map +1 -0
- package/build/utils/port-check.js +87 -0
- package/build/utils/port-check.js.map +1 -0
- package/build/utils/port-check.test.d.ts +2 -0
- package/build/utils/port-check.test.d.ts.map +1 -0
- package/build/utils/port-check.test.js +66 -0
- package/build/utils/port-check.test.js.map +1 -0
- package/build/utils/selector-resolver.d.ts +66 -0
- package/build/utils/selector-resolver.d.ts.map +1 -0
- package/build/utils/selector-resolver.js +200 -0
- package/build/utils/selector-resolver.js.map +1 -0
- package/build/validation-helpers.d.ts +41 -0
- package/build/validation-helpers.d.ts.map +1 -0
- package/build/validation-helpers.js +236 -0
- package/build/validation-helpers.js.map +1 -0
- package/build/window-sizing.d.ts +26 -0
- package/build/window-sizing.d.ts.map +1 -0
- package/build/window-sizing.js +87 -0
- package/build/window-sizing.js.map +1 -0
- package/build/window-sizing.test.d.ts +8 -0
- package/build/window-sizing.test.d.ts.map +1 -0
- package/build/window-sizing.test.js +113 -0
- package/build/window-sizing.test.js.map +1 -0
- package/docs/README.md +74 -0
- package/docs/automation.md +562 -0
- package/docs/debugging.md +229 -0
- package/docs/installation.md +133 -0
- package/docs/instructions.md +227 -0
- package/docs/mcp-instructions.md +15 -0
- package/docs/message-system.md +327 -0
- package/docs/messages.md +3480 -0
- package/docs/parser-plugins.md +132 -0
- package/docs/replay.md +1411 -0
- package/docs/troubleshooting.md +272 -0
- package/docs/working_with_llm_notes.md +5 -0
- package/package.json +87 -0
- package/skills/devharness/SKILL.md +195 -0
- package/skills/devharness/references/sequences.md +613 -0
- package/skills/devharness/references/tool-categories.md +99 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-check.test.d.ts","sourceRoot":"","sources":["../../src/utils/port-check.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { checkPort, parseUrlForPortCheck, checkUrlPort } from './port-check.js';
|
|
3
|
+
describe('port-check', () => {
|
|
4
|
+
describe('parseUrlForPortCheck', () => {
|
|
5
|
+
it('should parse localhost URL with explicit port', () => {
|
|
6
|
+
const result = parseUrlForPortCheck('http://localhost:3000');
|
|
7
|
+
expect(result).toEqual({ host: 'localhost', port: 3000 });
|
|
8
|
+
});
|
|
9
|
+
it('should parse 127.0.0.1 URL with explicit port', () => {
|
|
10
|
+
const result = parseUrlForPortCheck('http://127.0.0.1:8080/path');
|
|
11
|
+
expect(result).toEqual({ host: '127.0.0.1', port: 8080 });
|
|
12
|
+
});
|
|
13
|
+
it('should use default port 80 for http', () => {
|
|
14
|
+
const result = parseUrlForPortCheck('http://localhost');
|
|
15
|
+
expect(result).toEqual({ host: 'localhost', port: 80 });
|
|
16
|
+
});
|
|
17
|
+
it('should use default port 443 for https', () => {
|
|
18
|
+
const result = parseUrlForPortCheck('https://example.com');
|
|
19
|
+
expect(result).toEqual({ host: 'example.com', port: 443 });
|
|
20
|
+
});
|
|
21
|
+
it('should return null for invalid URL', () => {
|
|
22
|
+
const result = parseUrlForPortCheck('not-a-url');
|
|
23
|
+
expect(result).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
it('should return null for file:// URLs', () => {
|
|
26
|
+
const result = parseUrlForPortCheck('file:///path/to/file');
|
|
27
|
+
expect(result).toBeNull();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('checkPort', () => {
|
|
31
|
+
it('should return open: false for closed port', async () => {
|
|
32
|
+
// Port 59999 is very unlikely to be in use
|
|
33
|
+
const result = await checkPort(59999, 'localhost', 500);
|
|
34
|
+
expect(result.open).toBe(false);
|
|
35
|
+
expect(result.port).toBe(59999);
|
|
36
|
+
expect(result.host).toBe('localhost');
|
|
37
|
+
expect(result.error).toBeDefined();
|
|
38
|
+
});
|
|
39
|
+
it('should timeout for unreachable host', async () => {
|
|
40
|
+
// Use a short timeout and non-routable IP
|
|
41
|
+
const result = await checkPort(80, '10.255.255.1', 100);
|
|
42
|
+
expect(result.open).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe('checkUrlPort', () => {
|
|
46
|
+
it('should return null for non-localhost URLs', async () => {
|
|
47
|
+
const result = await checkUrlPort('https://example.com');
|
|
48
|
+
expect(result).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
it('should check localhost URLs', async () => {
|
|
51
|
+
const result = await checkUrlPort('http://localhost:59999', 500);
|
|
52
|
+
expect(result).not.toBeNull();
|
|
53
|
+
expect(result?.open).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
it('should check 127.0.0.1 URLs', async () => {
|
|
56
|
+
const result = await checkUrlPort('http://127.0.0.1:59999', 500);
|
|
57
|
+
expect(result).not.toBeNull();
|
|
58
|
+
expect(result?.open).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
it('should return null for invalid URL', async () => {
|
|
61
|
+
const result = await checkUrlPort('not-a-url');
|
|
62
|
+
expect(result).toBeNull();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=port-check.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-check.test.js","sourceRoot":"","sources":["../../src/utils/port-check.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended Selector Resolver
|
|
3
|
+
*
|
|
4
|
+
* Supports Playwright-style extended selectors that aren't native CSS:
|
|
5
|
+
* - :has-text("text") - matches elements containing text (case-insensitive partial match)
|
|
6
|
+
* - :text("text") - matches elements with exact text content
|
|
7
|
+
* - :text-is("text") - alias for :text()
|
|
8
|
+
*
|
|
9
|
+
* Text matching includes: textContent, aria-label, and title attributes.
|
|
10
|
+
*
|
|
11
|
+
* Examples:
|
|
12
|
+
* button:has-text("Submit") -> finds <button>Submit Form</button>
|
|
13
|
+
* a:has-text("Login") -> finds <a href="/login">Login</a>
|
|
14
|
+
* a:has-text("Homepage") -> finds <a aria-label="Homepage">...</a>
|
|
15
|
+
* div:text("Exact Match") -> finds <div>Exact Match</div> (exact only)
|
|
16
|
+
* :has-text("Search") -> finds any element containing "Search"
|
|
17
|
+
*/
|
|
18
|
+
export interface ResolvedSelector {
|
|
19
|
+
/** The resolved CSS selector that can be used with querySelector */
|
|
20
|
+
selector: string;
|
|
21
|
+
/** Number of elements that matched */
|
|
22
|
+
matchCount: number;
|
|
23
|
+
/** Warning message if multiple matches found */
|
|
24
|
+
warning?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface SelectorError {
|
|
27
|
+
error: string;
|
|
28
|
+
originalSelector: string;
|
|
29
|
+
suggestion?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse extended selector syntax and extract components
|
|
33
|
+
* (exported for the wait tool, which needs the raw base-selector + text-match
|
|
34
|
+
* pieces to build a self-contained polling predicate instead of marking
|
|
35
|
+
* elements with data attributes that would not survive a navigation)
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseExtendedSelector(selector: string): {
|
|
38
|
+
baseSelector: string;
|
|
39
|
+
textMatch: {
|
|
40
|
+
type: 'has-text' | 'text' | 'text-is';
|
|
41
|
+
value: string;
|
|
42
|
+
} | null;
|
|
43
|
+
} | {
|
|
44
|
+
error: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Check if a selector uses extended syntax
|
|
48
|
+
*/
|
|
49
|
+
export declare function isExtendedSelector(selector: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Resolve an extended selector to a standard CSS selector
|
|
52
|
+
*
|
|
53
|
+
* For extended selectors, this finds matching elements and returns a
|
|
54
|
+
* data-attribute based selector that uniquely identifies the first match.
|
|
55
|
+
*
|
|
56
|
+
* @param page - Puppeteer page instance
|
|
57
|
+
* @param selector - The selector (may include extended syntax like :has-text())
|
|
58
|
+
* @returns Resolved selector info or error
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveSelector(page: any, selector: string): Promise<ResolvedSelector | SelectorError>;
|
|
61
|
+
/**
|
|
62
|
+
* Clean up the temporary data attribute after use
|
|
63
|
+
* Should be called after the selector has been used
|
|
64
|
+
*/
|
|
65
|
+
export declare function cleanupResolvedSelector(page: any, selector: string): Promise<void>;
|
|
66
|
+
//# sourceMappingURL=selector-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/selector-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE;QAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5E,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAoEpB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,aAAa,CAAC,CAuG3C;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWxF"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended Selector Resolver
|
|
3
|
+
*
|
|
4
|
+
* Supports Playwright-style extended selectors that aren't native CSS:
|
|
5
|
+
* - :has-text("text") - matches elements containing text (case-insensitive partial match)
|
|
6
|
+
* - :text("text") - matches elements with exact text content
|
|
7
|
+
* - :text-is("text") - alias for :text()
|
|
8
|
+
*
|
|
9
|
+
* Text matching includes: textContent, aria-label, and title attributes.
|
|
10
|
+
*
|
|
11
|
+
* Examples:
|
|
12
|
+
* button:has-text("Submit") -> finds <button>Submit Form</button>
|
|
13
|
+
* a:has-text("Login") -> finds <a href="/login">Login</a>
|
|
14
|
+
* a:has-text("Homepage") -> finds <a aria-label="Homepage">...</a>
|
|
15
|
+
* div:text("Exact Match") -> finds <div>Exact Match</div> (exact only)
|
|
16
|
+
* :has-text("Search") -> finds any element containing "Search"
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Parse extended selector syntax and extract components
|
|
20
|
+
* (exported for the wait tool, which needs the raw base-selector + text-match
|
|
21
|
+
* pieces to build a self-contained polling predicate instead of marking
|
|
22
|
+
* elements with data attributes that would not survive a navigation)
|
|
23
|
+
*/
|
|
24
|
+
export function parseExtendedSelector(selector) {
|
|
25
|
+
// Check if this looks like an extended selector
|
|
26
|
+
const extendedMatch = selector.match(/:(?:has-text|text|text-is)\(/);
|
|
27
|
+
if (!extendedMatch) {
|
|
28
|
+
return { baseSelector: selector, textMatch: null };
|
|
29
|
+
}
|
|
30
|
+
// Find the pseudo-class start position
|
|
31
|
+
const pseudoStart = extendedMatch.index;
|
|
32
|
+
const beforePart = selector.substring(0, pseudoStart);
|
|
33
|
+
// Extract the type (has-text, text, or text-is)
|
|
34
|
+
const typeMatch = selector.substring(pseudoStart).match(/^:(has-text|text|text-is)\(/);
|
|
35
|
+
if (!typeMatch) {
|
|
36
|
+
return { error: 'Invalid extended selector syntax' };
|
|
37
|
+
}
|
|
38
|
+
const matchType = typeMatch[1];
|
|
39
|
+
const afterTypeStart = pseudoStart + typeMatch[0].length;
|
|
40
|
+
// Parse the quoted string - handle both single and double quotes
|
|
41
|
+
const remaining = selector.substring(afterTypeStart);
|
|
42
|
+
const quoteChar = remaining[0];
|
|
43
|
+
if (quoteChar !== '"' && quoteChar !== "'") {
|
|
44
|
+
return { error: `Expected quote after :${matchType}(, got: ${quoteChar || 'end of string'}` };
|
|
45
|
+
}
|
|
46
|
+
// Find the closing quote, handling escaped quotes
|
|
47
|
+
let textValue = '';
|
|
48
|
+
let i = 1;
|
|
49
|
+
while (i < remaining.length) {
|
|
50
|
+
const char = remaining[i];
|
|
51
|
+
if (char === '\\' && i + 1 < remaining.length) {
|
|
52
|
+
// Escaped character - include the next char literally
|
|
53
|
+
textValue += remaining[i + 1];
|
|
54
|
+
i += 2;
|
|
55
|
+
}
|
|
56
|
+
else if (char === quoteChar) {
|
|
57
|
+
// Found closing quote
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
textValue += char;
|
|
62
|
+
i++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (i >= remaining.length || remaining[i] !== quoteChar) {
|
|
66
|
+
return { error: `Unterminated string in :${matchType}() selector` };
|
|
67
|
+
}
|
|
68
|
+
// Check for closing paren
|
|
69
|
+
if (remaining[i + 1] !== ')') {
|
|
70
|
+
return { error: `Expected ) after closing quote in :${matchType}() selector` };
|
|
71
|
+
}
|
|
72
|
+
// Get any remaining selector after the extended part
|
|
73
|
+
const afterPart = remaining.substring(i + 2);
|
|
74
|
+
// Combine before and after parts
|
|
75
|
+
let baseSelector = (beforePart + afterPart).trim();
|
|
76
|
+
if (!baseSelector) {
|
|
77
|
+
baseSelector = '*';
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
baseSelector,
|
|
81
|
+
textMatch: { type: matchType, value: textValue },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if a selector uses extended syntax
|
|
86
|
+
*/
|
|
87
|
+
export function isExtendedSelector(selector) {
|
|
88
|
+
return /:(?:has-text|text|text-is)\(/.test(selector);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Resolve an extended selector to a standard CSS selector
|
|
92
|
+
*
|
|
93
|
+
* For extended selectors, this finds matching elements and returns a
|
|
94
|
+
* data-attribute based selector that uniquely identifies the first match.
|
|
95
|
+
*
|
|
96
|
+
* @param page - Puppeteer page instance
|
|
97
|
+
* @param selector - The selector (may include extended syntax like :has-text())
|
|
98
|
+
* @returns Resolved selector info or error
|
|
99
|
+
*/
|
|
100
|
+
export async function resolveSelector(page, selector) {
|
|
101
|
+
// Check if it's an extended selector
|
|
102
|
+
if (!isExtendedSelector(selector)) {
|
|
103
|
+
// Standard CSS selector - return as-is, let caller validate
|
|
104
|
+
return {
|
|
105
|
+
selector,
|
|
106
|
+
matchCount: 1,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const parsed = parseExtendedSelector(selector);
|
|
110
|
+
if ('error' in parsed) {
|
|
111
|
+
return {
|
|
112
|
+
error: parsed.error,
|
|
113
|
+
originalSelector: selector,
|
|
114
|
+
suggestion: 'Check the selector syntax. Format: element:has-text("text") or element:text("exact text")',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const { baseSelector, textMatch } = parsed;
|
|
118
|
+
if (!textMatch) {
|
|
119
|
+
// Shouldn't happen since we checked isExtendedSelector, but handle it
|
|
120
|
+
return { selector, matchCount: 1 };
|
|
121
|
+
}
|
|
122
|
+
// Find matching elements and mark the first one with a unique attribute
|
|
123
|
+
const result = await page.evaluate((base, matchType, matchText) => {
|
|
124
|
+
const elements = globalThis.document.querySelectorAll(base);
|
|
125
|
+
const matches = [];
|
|
126
|
+
let firstMatchElement = null;
|
|
127
|
+
elements.forEach((el) => {
|
|
128
|
+
const textContent = el.textContent?.trim() || '';
|
|
129
|
+
const ariaLabel = el.getAttribute('aria-label') || '';
|
|
130
|
+
const title = el.getAttribute('title') || '';
|
|
131
|
+
// Combine all text sources for matching
|
|
132
|
+
const allText = [textContent, ariaLabel, title].filter(Boolean).join(' ');
|
|
133
|
+
let isMatch = false;
|
|
134
|
+
if (matchType === 'has-text') {
|
|
135
|
+
isMatch = allText.toLowerCase().includes(matchText.toLowerCase());
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// 'text' or 'text-is' - exact match (check each source separately)
|
|
139
|
+
isMatch = textContent === matchText || ariaLabel === matchText || title === matchText;
|
|
140
|
+
}
|
|
141
|
+
if (isMatch) {
|
|
142
|
+
if (!firstMatchElement) {
|
|
143
|
+
firstMatchElement = el;
|
|
144
|
+
}
|
|
145
|
+
const displayText = textContent || ariaLabel || title;
|
|
146
|
+
matches.push({
|
|
147
|
+
text: displayText.substring(0, 60) + (displayText.length > 60 ? '...' : ''),
|
|
148
|
+
tagName: el.tagName.toLowerCase(),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
if (matches.length === 0) {
|
|
153
|
+
return { error: 'no_match' };
|
|
154
|
+
}
|
|
155
|
+
// Mark the first matching element with a unique data attribute
|
|
156
|
+
const uniqueId = `cdp-ext-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
|
|
157
|
+
firstMatchElement.setAttribute('data-cdp-selector-match', uniqueId);
|
|
158
|
+
return {
|
|
159
|
+
uniqueId,
|
|
160
|
+
matchCount: matches.length,
|
|
161
|
+
matches: matches.slice(0, 5), // Return first 5 for context
|
|
162
|
+
tagName: matches[0].tagName,
|
|
163
|
+
};
|
|
164
|
+
}, baseSelector, textMatch.type, textMatch.value);
|
|
165
|
+
if ('error' in result && result.error === 'no_match') {
|
|
166
|
+
return {
|
|
167
|
+
error: `Element not found: \`${selector}\``,
|
|
168
|
+
originalSelector: selector,
|
|
169
|
+
suggestion: `No ${baseSelector === '*' ? 'element' : `\`${baseSelector}\``} contains text "${textMatch.value}". Use \`content({ action: 'findInteractive', search: '${textMatch.value}' })\` to see available elements.`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// Build response
|
|
173
|
+
const resolvedSelector = `[data-cdp-selector-match="${result.uniqueId}"]`;
|
|
174
|
+
let warning;
|
|
175
|
+
if (result.matchCount > 1) {
|
|
176
|
+
const othersText = result.matches.slice(1).map((m) => `"${m.text}"`).join(', ');
|
|
177
|
+
warning = `Found ${result.matchCount} matches. Using first match. Other matches: ${othersText}${result.matchCount > 5 ? ` (and ${result.matchCount - 5} more)` : ''}`;
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
selector: resolvedSelector,
|
|
181
|
+
matchCount: result.matchCount,
|
|
182
|
+
warning,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Clean up the temporary data attribute after use
|
|
187
|
+
* Should be called after the selector has been used
|
|
188
|
+
*/
|
|
189
|
+
export async function cleanupResolvedSelector(page, selector) {
|
|
190
|
+
if (!selector.startsWith('[data-cdp-selector-match=')) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
await page.evaluate((sel) => {
|
|
194
|
+
const el = globalThis.document.querySelector(sel);
|
|
195
|
+
if (el) {
|
|
196
|
+
el.removeAttribute('data-cdp-selector-match');
|
|
197
|
+
}
|
|
198
|
+
}, selector);
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=selector-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-resolver.js","sourceRoot":"","sources":["../../src/utils/selector-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod Validation Helpers
|
|
3
|
+
* Provides utilities for validating tool parameters with Zod schemas
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
/**
|
|
7
|
+
* Result of parameter validation
|
|
8
|
+
*/
|
|
9
|
+
export type ValidationResult<T> = {
|
|
10
|
+
success: true;
|
|
11
|
+
data: T;
|
|
12
|
+
} | {
|
|
13
|
+
success: false;
|
|
14
|
+
error: any;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Validates parameters against a Zod schema
|
|
18
|
+
* Returns validated data or formatted error response
|
|
19
|
+
*
|
|
20
|
+
* Supports an out-of-band `continuationToken` param: if a prior call to the
|
|
21
|
+
* same tool failed with missing required params, the caller can retry with
|
|
22
|
+
* just { continuationToken, <missing fields> } and this merges it with the
|
|
23
|
+
* originally-supplied args instead of requiring a full resend.
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateParams<T extends z.ZodTypeAny>(params: unknown, schema: T, toolName: string): ValidationResult<z.infer<T>>;
|
|
26
|
+
/**
|
|
27
|
+
* Helper to create tool definitions with Zod schemas
|
|
28
|
+
* Automatically generates JSON Schema for MCP ListTools response
|
|
29
|
+
*/
|
|
30
|
+
export declare function createTool<T extends z.ZodTypeAny>(description: string, zodSchema: T, handler: (args: z.infer<T>, abortSignal?: AbortSignal) => Promise<any>): {
|
|
31
|
+
description: string;
|
|
32
|
+
zodSchema: T;
|
|
33
|
+
inputSchema: import("zod-to-json-schema").JsonSchema7Type & {
|
|
34
|
+
$schema?: string | undefined;
|
|
35
|
+
definitions?: {
|
|
36
|
+
[key: string]: import("zod-to-json-schema").JsonSchema7Type;
|
|
37
|
+
} | undefined;
|
|
38
|
+
};
|
|
39
|
+
handler: (args: z.infer<T>, abortSignal?: AbortSignal) => Promise<any>;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=validation-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-helpers.d.ts","sourceRoot":"","sources":["../src/validation-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAC1B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,CAAC;AAyGnC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EACnD,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAoF9B;AA0DD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EAC/C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,GAAG,CAAC;;;;;;;;;oBAAtD,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,WAAW,KAAK,OAAO,CAAC,GAAG,CAAC;EAYvE"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod Validation Helpers
|
|
3
|
+
* Provides utilities for validating tool parameters with Zod schemas
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
7
|
+
import { randomUUID } from 'crypto';
|
|
8
|
+
const CONTINUATION_TTL_MS = 5 * 60 * 1000;
|
|
9
|
+
const pendingContinuations = new Map();
|
|
10
|
+
function sweepExpiredContinuations() {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
for (const [token, entry] of pendingContinuations) {
|
|
13
|
+
if (entry.expiresAt < now)
|
|
14
|
+
pendingContinuations.delete(token);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function isMissingRequiredIssue(issue) {
|
|
18
|
+
return issue.code === 'invalid_type' && issue.received === 'undefined';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Unwraps optional/default/nullable wrappers to get at the underlying type
|
|
22
|
+
* for describing enums, etc.
|
|
23
|
+
*/
|
|
24
|
+
function unwrapZodType(schema) {
|
|
25
|
+
let current = schema;
|
|
26
|
+
while (current instanceof z.ZodOptional ||
|
|
27
|
+
current instanceof z.ZodNullable ||
|
|
28
|
+
current instanceof z.ZodDefault) {
|
|
29
|
+
current = current instanceof z.ZodDefault ? current._def.innerType : current.unwrap();
|
|
30
|
+
}
|
|
31
|
+
return current;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Best-effort lookup of a field's Zod definition to describe what's expected.
|
|
35
|
+
* Only handles flat/dotted top-level object fields; falls back to a bare
|
|
36
|
+
* shape if the schema isn't a ZodObject or the path can't be resolved.
|
|
37
|
+
*/
|
|
38
|
+
function describeMissingField(schema, fieldPath) {
|
|
39
|
+
const info = { name: fieldPath, type: 'unknown' };
|
|
40
|
+
let currentSchema = schema;
|
|
41
|
+
let fieldSchema;
|
|
42
|
+
for (const part of fieldPath.split('.')) {
|
|
43
|
+
if (!(currentSchema instanceof z.ZodObject)) {
|
|
44
|
+
fieldSchema = undefined;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
fieldSchema = currentSchema.shape[part];
|
|
48
|
+
currentSchema = fieldSchema;
|
|
49
|
+
}
|
|
50
|
+
if (!fieldSchema)
|
|
51
|
+
return info;
|
|
52
|
+
info.description = fieldSchema._def?.description;
|
|
53
|
+
if (fieldSchema instanceof z.ZodDefault) {
|
|
54
|
+
try {
|
|
55
|
+
info.default = fieldSchema._def.defaultValue();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// ignore
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const unwrapped = unwrapZodType(fieldSchema);
|
|
62
|
+
if (unwrapped instanceof z.ZodEnum) {
|
|
63
|
+
info.type = 'enum';
|
|
64
|
+
info.enum = unwrapped.options;
|
|
65
|
+
}
|
|
66
|
+
else if (unwrapped instanceof z.ZodString) {
|
|
67
|
+
info.type = 'string';
|
|
68
|
+
}
|
|
69
|
+
else if (unwrapped instanceof z.ZodNumber) {
|
|
70
|
+
info.type = 'number';
|
|
71
|
+
}
|
|
72
|
+
else if (unwrapped instanceof z.ZodBoolean) {
|
|
73
|
+
info.type = 'boolean';
|
|
74
|
+
}
|
|
75
|
+
else if (unwrapped instanceof z.ZodArray) {
|
|
76
|
+
info.type = 'array';
|
|
77
|
+
}
|
|
78
|
+
else if (unwrapped instanceof z.ZodObject) {
|
|
79
|
+
info.type = 'object';
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
info.type = unwrapped._def?.typeName || 'unknown';
|
|
83
|
+
}
|
|
84
|
+
return info;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validates parameters against a Zod schema
|
|
88
|
+
* Returns validated data or formatted error response
|
|
89
|
+
*
|
|
90
|
+
* Supports an out-of-band `continuationToken` param: if a prior call to the
|
|
91
|
+
* same tool failed with missing required params, the caller can retry with
|
|
92
|
+
* just { continuationToken, <missing fields> } and this merges it with the
|
|
93
|
+
* originally-supplied args instead of requiring a full resend.
|
|
94
|
+
*/
|
|
95
|
+
export function validateParams(params, schema, toolName) {
|
|
96
|
+
sweepExpiredContinuations();
|
|
97
|
+
let effectiveParams = params;
|
|
98
|
+
let continuationToken;
|
|
99
|
+
if (params && typeof params === 'object' && 'continuationToken' in params) {
|
|
100
|
+
const { continuationToken: token, ...rest } = params;
|
|
101
|
+
if (typeof token === 'string') {
|
|
102
|
+
continuationToken = token;
|
|
103
|
+
const pending = pendingContinuations.get(token);
|
|
104
|
+
effectiveParams = pending && pending.toolName === toolName
|
|
105
|
+
? { ...pending.args, ...rest }
|
|
106
|
+
: rest;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
effectiveParams = rest;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const result = schema.safeParse(effectiveParams);
|
|
113
|
+
if (!result.success) {
|
|
114
|
+
const missingIssues = result.error.issues.filter(isMissingRequiredIssue);
|
|
115
|
+
const otherIssues = result.error.issues.filter(issue => !isMissingRequiredIssue(issue));
|
|
116
|
+
// Any failure keeps (or opens) a continuation slot with the latest attempt's
|
|
117
|
+
// args, so the caller can retry with just a fix/addition rather than the
|
|
118
|
+
// whole payload - whether the problem was a missing field or a bad value.
|
|
119
|
+
const token = continuationToken && pendingContinuations.has(continuationToken)
|
|
120
|
+
? continuationToken
|
|
121
|
+
: randomUUID();
|
|
122
|
+
pendingContinuations.set(token, {
|
|
123
|
+
toolName,
|
|
124
|
+
args: effectiveParams,
|
|
125
|
+
expiresAt: Date.now() + CONTINUATION_TTL_MS
|
|
126
|
+
});
|
|
127
|
+
const instructions = `Call '${toolName}' again with { continuationToken: '${token}', ...<only the field(s) to add/fix> }. Previously supplied arguments are cached for ${Math.round(CONTINUATION_TTL_MS / 60000)} minutes and merged automatically - no need to resend them.`;
|
|
128
|
+
if (missingIssues.length > 0) {
|
|
129
|
+
const missingParameters = missingIssues.map(issue => describeMissingField(schema, issue.path.join('.')));
|
|
130
|
+
const error = {
|
|
131
|
+
success: false,
|
|
132
|
+
error: `Missing required parameter(s) for tool '${toolName}'`,
|
|
133
|
+
code: otherIssues.length > 0 ? 'INVALID_PARAMS' : 'MISSING_PARAMETERS',
|
|
134
|
+
missingParameters,
|
|
135
|
+
continuationToken: token,
|
|
136
|
+
instructions
|
|
137
|
+
};
|
|
138
|
+
if (otherIssues.length > 0) {
|
|
139
|
+
error.validationErrors = formatZodErrors(result.error, otherIssues);
|
|
140
|
+
}
|
|
141
|
+
return { success: false, error };
|
|
142
|
+
}
|
|
143
|
+
// Only non-missing issues (bad types/enums/etc on values actually supplied)
|
|
144
|
+
return {
|
|
145
|
+
success: false,
|
|
146
|
+
error: {
|
|
147
|
+
success: false,
|
|
148
|
+
error: `Invalid parameters for tool '${toolName}'`,
|
|
149
|
+
code: 'INVALID_PARAMS',
|
|
150
|
+
validationErrors: formatZodErrors(result.error),
|
|
151
|
+
continuationToken: token,
|
|
152
|
+
instructions
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// Validation succeeded - the token's job (merging args) is done. Resuming a
|
|
157
|
+
// call that's blocked *after* this point by an unrelated guard (port
|
|
158
|
+
// failure, dead server, etc.) is already handled by the existing command
|
|
159
|
+
// recorder / replay({ action: 'repeat' }) mechanism, which records this same
|
|
160
|
+
// merged `result.data` right after this call returns - no need to keep the
|
|
161
|
+
// continuation cache alive for that case too.
|
|
162
|
+
if (continuationToken)
|
|
163
|
+
pendingContinuations.delete(continuationToken);
|
|
164
|
+
return { success: true, data: result.data };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Converts Zod validation errors to user-friendly messages
|
|
168
|
+
*/
|
|
169
|
+
function formatZodErrors(error, issues = error.issues) {
|
|
170
|
+
return issues.map(issue => {
|
|
171
|
+
const path = issue.path.length > 0 ? issue.path.join('.') : 'root';
|
|
172
|
+
switch (issue.code) {
|
|
173
|
+
case 'invalid_type':
|
|
174
|
+
if (issue.received === 'undefined') {
|
|
175
|
+
return `Missing required parameter: ${path}`;
|
|
176
|
+
}
|
|
177
|
+
return `Parameter '${path}' must be ${issue.expected}, got ${issue.received}`;
|
|
178
|
+
case 'unrecognized_keys':
|
|
179
|
+
return `Unknown parameter(s): ${issue.keys.join(', ')}`;
|
|
180
|
+
case 'too_small':
|
|
181
|
+
if (issue.type === 'string') {
|
|
182
|
+
return `Parameter '${path}' must be at least ${issue.minimum} characters`;
|
|
183
|
+
}
|
|
184
|
+
else if (issue.type === 'number') {
|
|
185
|
+
return `Parameter '${path}' must be at least ${issue.minimum}`;
|
|
186
|
+
}
|
|
187
|
+
else if (issue.type === 'array') {
|
|
188
|
+
return `Parameter '${path}' must contain at least ${issue.minimum} items`;
|
|
189
|
+
}
|
|
190
|
+
return `Parameter '${path}' is too small`;
|
|
191
|
+
case 'too_big':
|
|
192
|
+
if (issue.type === 'string') {
|
|
193
|
+
return `Parameter '${path}' must be at most ${issue.maximum} characters`;
|
|
194
|
+
}
|
|
195
|
+
else if (issue.type === 'number') {
|
|
196
|
+
return `Parameter '${path}' must be at most ${issue.maximum}`;
|
|
197
|
+
}
|
|
198
|
+
else if (issue.type === 'array') {
|
|
199
|
+
return `Parameter '${path}' must contain at most ${issue.maximum} items`;
|
|
200
|
+
}
|
|
201
|
+
return `Parameter '${path}' is too big`;
|
|
202
|
+
case 'invalid_enum_value':
|
|
203
|
+
return `Parameter '${path}' must be one of: ${issue.options.join(', ')}`;
|
|
204
|
+
case 'invalid_string':
|
|
205
|
+
if (issue.validation === 'email') {
|
|
206
|
+
return `Parameter '${path}' must be a valid email address`;
|
|
207
|
+
}
|
|
208
|
+
else if (issue.validation === 'url') {
|
|
209
|
+
return `Parameter '${path}' must be a valid URL`;
|
|
210
|
+
}
|
|
211
|
+
else if (issue.validation === 'regex') {
|
|
212
|
+
return `Parameter '${path}' does not match required pattern`;
|
|
213
|
+
}
|
|
214
|
+
return `Parameter '${path}' is invalid`;
|
|
215
|
+
default:
|
|
216
|
+
return issue.message || `Parameter '${path}' is invalid`;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Helper to create tool definitions with Zod schemas
|
|
222
|
+
* Automatically generates JSON Schema for MCP ListTools response
|
|
223
|
+
*/
|
|
224
|
+
export function createTool(description, zodSchema, handler) {
|
|
225
|
+
return {
|
|
226
|
+
description,
|
|
227
|
+
zodSchema,
|
|
228
|
+
inputSchema: zodToJsonSchema(zodSchema, {
|
|
229
|
+
$refStrategy: 'none', // Inline all schemas for compatibility
|
|
230
|
+
target: 'jsonSchema7',
|
|
231
|
+
strictUnions: true
|
|
232
|
+
}),
|
|
233
|
+
handler
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=validation-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-helpers.js","sourceRoot":"","sources":["../src/validation-helpers.ts"],"names":[],"mappings":"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"}
|