@ddwang/magnitude-core 0.3.1-ddwang.2 → 0.3.1-ddwang.21
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/dist/cli.cjs +2 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.mjs +1 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.cjs +2704 -1522
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +188 -50
- package/dist/index.d.ts +1147 -23
- package/dist/index.mjs +2527 -1362
- package/dist/index.mjs.map +1 -0
- package/node_modules/patchright-core/README.md +3 -0
- package/node_modules/patchright-core/ThirdPartyNotices.txt +13 -0
- package/node_modules/patchright-core/bin/install_media_pack.ps1 +5 -0
- package/node_modules/patchright-core/bin/install_webkit_wsl.ps1 +33 -0
- package/node_modules/patchright-core/bin/reinstall_chrome_beta_linux.sh +42 -0
- package/node_modules/patchright-core/bin/reinstall_chrome_beta_mac.sh +13 -0
- package/node_modules/patchright-core/bin/reinstall_chrome_beta_win.ps1 +24 -0
- package/node_modules/patchright-core/bin/reinstall_chrome_stable_linux.sh +42 -0
- package/node_modules/patchright-core/bin/reinstall_chrome_stable_mac.sh +12 -0
- package/node_modules/patchright-core/bin/reinstall_chrome_stable_win.ps1 +24 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_beta_linux.sh +48 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_beta_mac.sh +11 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_beta_win.ps1 +23 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_dev_linux.sh +48 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_dev_mac.sh +11 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_dev_win.ps1 +23 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_stable_linux.sh +48 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_stable_mac.sh +11 -0
- package/node_modules/patchright-core/bin/reinstall_msedge_stable_win.ps1 +24 -0
- package/node_modules/patchright-core/browsers.json +52 -0
- package/node_modules/patchright-core/cli.js +22 -0
- package/node_modules/patchright-core/index.d.ts +17 -0
- package/node_modules/patchright-core/index.js +17 -0
- package/node_modules/patchright-core/index.mjs +28 -0
- package/node_modules/patchright-core/lib/bootstrap.js +149 -0
- package/node_modules/patchright-core/lib/coreBundle.js +80653 -0
- package/node_modules/patchright-core/lib/entry/cliDaemon.js +5 -0
- package/node_modules/patchright-core/lib/entry/dashboardApp.js +3 -0
- package/node_modules/patchright-core/lib/entry/mcp.js +10 -0
- package/node_modules/patchright-core/lib/entry/oopBrowserDownload.js +3 -0
- package/node_modules/patchright-core/lib/package.js +50 -0
- package/node_modules/patchright-core/lib/server/chromium/appIcon.png +0 -0
- package/node_modules/patchright-core/lib/server/electron/loader.js +112 -0
- package/node_modules/patchright-core/lib/serverRegistry.js +1939 -0
- package/node_modules/patchright-core/lib/serverRegistry.js.LICENSE +65 -0
- package/node_modules/patchright-core/lib/tools/cli-client/channelSessions.js +141 -0
- package/node_modules/patchright-core/lib/tools/cli-client/cli.js +7 -0
- package/node_modules/patchright-core/lib/tools/cli-client/help.json +808 -0
- package/node_modules/patchright-core/lib/tools/cli-client/minimist.js +128 -0
- package/node_modules/patchright-core/lib/tools/cli-client/output.js +352 -0
- package/node_modules/patchright-core/lib/tools/cli-client/program.js +422 -0
- package/node_modules/patchright-core/lib/tools/cli-client/registry.js +180 -0
- package/node_modules/patchright-core/lib/tools/cli-client/session.js +261 -0
- package/node_modules/patchright-core/lib/tools/dashboard/appIcon.png +0 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/SKILL.md +493 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/element-attributes.md +23 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/pr-attachments.md +60 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/request-mocking.md +87 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/running-code.md +245 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/session-management.md +227 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/storage-state.md +275 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/test-generation.md +433 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/tracing.md +139 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-cli/references/video-recording.md +216 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-component-testing/SKILL.md +136 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-component-testing/references/migration.md +89 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-component-testing/references/react.md +69 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-component-testing/references/typing.md +173 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-component-testing/references/vue.md +77 -0
- package/node_modules/patchright-core/lib/tools/skills/playwright-trace/SKILL.md +174 -0
- package/node_modules/patchright-core/lib/tools/utils/extension.js +112 -0
- package/node_modules/patchright-core/lib/tools/utils/socketConnection.js +108 -0
- package/node_modules/patchright-core/lib/utilsBundle.js +86225 -0
- package/node_modules/patchright-core/lib/utilsBundle.js.LICENSE +1890 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/codeMirrorModule--QdMvsKi.css +1 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/codeMirrorModule-CQ8RZGBm.js +32 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/codicon-DCmgc-ay.ttf +0 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/firefox-1bWoP6pv.svg +1 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/firefox-beta-k3eOH_eK.svg +1 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/firefox-nightly-Cp5nfeDT.svg +1 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/index-AwgwcYie.css +1 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/index-hRvO4yU2.js +12 -0
- package/node_modules/patchright-core/lib/vite/dashboard/assets/safari-na3_-uQk.svg +1 -0
- package/node_modules/patchright-core/lib/vite/dashboard/index.html +29 -0
- package/node_modules/patchright-core/lib/vite/dashboard/playwright-logo.svg +24 -0
- package/node_modules/patchright-core/lib/vite/htmlReport/index.html +16 -0
- package/node_modules/patchright-core/lib/vite/htmlReport/report.css +2 -0
- package/node_modules/patchright-core/lib/vite/htmlReport/report.js +32 -0
- package/node_modules/patchright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
- package/node_modules/patchright-core/lib/vite/recorder/assets/codeMirrorModule-GBnsXk4c.js +32 -0
- package/node_modules/patchright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- package/node_modules/patchright-core/lib/vite/recorder/assets/index-BZpYJZ-P.css +1 -0
- package/node_modules/patchright-core/lib/vite/recorder/assets/index-CVDOfo-j.js +129 -0
- package/node_modules/patchright-core/lib/vite/recorder/index.html +29 -0
- package/node_modules/patchright-core/lib/vite/recorder/playwright-logo.svg +9 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/assets/codeMirrorModule-G79327TW.js +32 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/assets/defaultSettingsView-D9EV0iaS.js +184 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/assets/xtermModule-Al_u-Nk5.js +7 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/defaultSettingsView.C8BeHuxd.css +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/index.CMB2-c8e.js +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/index.html +44 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/playwright-logo.svg +9 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/snapshot.html +10 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/sw.bundle.js +4 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/uiMode.C3yLoy2G.js +5 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/uiMode.CyMfwkXJ.css +1 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/uiMode.html +18 -0
- package/node_modules/patchright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
- package/node_modules/patchright-core/lib/webp_codec.LICENSE +173 -0
- package/node_modules/patchright-core/lib/webp_codec.wasm +0 -0
- package/node_modules/patchright-core/lib/xdg-open +1267 -0
- package/node_modules/patchright-core/package.json +34 -0
- package/node_modules/patchright-core/types/protocol.d.ts +24776 -0
- package/node_modules/patchright-core/types/structs.d.ts +52 -0
- package/node_modules/patchright-core/types/types.d.ts +27167 -0
- package/node_modules/playwright/.bun-tag-91d746a6045e143f +0 -0
- package/node_modules/playwright/README.md +300 -0
- package/node_modules/playwright/ThirdPartyNotices.txt +14 -0
- package/node_modules/playwright/cli.js +19 -0
- package/node_modules/playwright/index.d.ts +17 -0
- package/node_modules/playwright/index.js +17 -0
- package/node_modules/playwright/index.mjs +18 -0
- package/node_modules/playwright/lib/agents/agentParser.js +89 -0
- package/node_modules/playwright/lib/agents/copilot-setup-steps.yml +34 -0
- package/node_modules/playwright/lib/agents/generateAgents.js +395 -0
- package/node_modules/playwright/lib/agents/playwright-test-coverage.prompt.md +31 -0
- package/node_modules/playwright/lib/agents/playwright-test-generate.prompt.md +8 -0
- package/node_modules/playwright/lib/agents/playwright-test-generator.agent.md +88 -0
- package/node_modules/playwright/lib/agents/playwright-test-heal.prompt.md +6 -0
- package/node_modules/playwright/lib/agents/playwright-test-healer.agent.md +56 -0
- package/node_modules/playwright/lib/agents/playwright-test-plan.prompt.md +9 -0
- package/node_modules/playwright/lib/agents/playwright-test-planner.agent.md +74 -0
- package/node_modules/playwright/lib/cli/reportActions.js +78 -0
- package/node_modules/playwright/lib/cli/testActions.js +217 -0
- package/node_modules/playwright/lib/common/index.js +2937 -0
- package/node_modules/playwright/lib/common/index.js.txt +33 -0
- package/node_modules/playwright/lib/errorContext.js +129 -0
- package/node_modules/playwright/lib/globals.js +58 -0
- package/node_modules/playwright/lib/index.js +827 -0
- package/node_modules/playwright/lib/isomorphic.js +260 -0
- package/node_modules/playwright/lib/isomorphic.js.txt +9 -0
- package/node_modules/playwright/lib/loader/loaderProcessEntry.js +34 -0
- package/node_modules/playwright/lib/loader/loaderProcessEntry.js.txt +9 -0
- package/node_modules/playwright/lib/matchers/expect.js +13496 -0
- package/node_modules/playwright/lib/matchers/expect.js.LICENSE +640 -0
- package/node_modules/playwright/lib/matchers/expect.js.txt +67 -0
- package/node_modules/playwright/lib/mcp/test/browserBackend.js +135 -0
- package/node_modules/playwright/lib/mcp/test/generatorTools.js +122 -0
- package/node_modules/playwright/lib/mcp/test/plannerTools.js +150 -0
- package/node_modules/playwright/lib/mcp/test/seed.js +82 -0
- package/node_modules/playwright/lib/mcp/test/streams.js +44 -0
- package/node_modules/playwright/lib/mcp/test/testBackend.js +99 -0
- package/node_modules/playwright/lib/mcp/test/testContext.js +306 -0
- package/node_modules/playwright/lib/mcp/test/testTool.js +30 -0
- package/node_modules/playwright/lib/mcp/test/testTools.js +98 -0
- package/node_modules/playwright/lib/package.js +47 -0
- package/node_modules/playwright/lib/program.js +242 -0
- package/node_modules/playwright/lib/runner/index.js +8721 -0
- package/node_modules/playwright/lib/runner/index.js.txt +62 -0
- package/node_modules/playwright/lib/transform/babelBundle.js +72490 -0
- package/node_modules/playwright/lib/transform/babelBundle.js.LICENSE +2384 -0
- package/node_modules/playwright/lib/transform/babelBundle.js.txt +328 -0
- package/node_modules/playwright/lib/transform/esmLoader.js +8213 -0
- package/node_modules/playwright/lib/transform/esmLoader.js.LICENSE +355 -0
- package/node_modules/playwright/lib/transform/esmLoader.js.txt +60 -0
- package/node_modules/playwright/lib/util.js +373 -0
- package/node_modules/playwright/lib/worker/workerProcessEntry.js +1860 -0
- package/node_modules/playwright/lib/worker/workerProcessEntry.js.txt +19 -0
- package/node_modules/playwright/package.json +50 -0
- package/node_modules/playwright/test.d.ts +18 -0
- package/node_modules/playwright/test.js +24 -0
- package/node_modules/playwright/test.mjs +35 -0
- package/node_modules/playwright/types/test.d.ts +11191 -0
- package/node_modules/playwright/types/testReporter.d.ts +950 -0
- package/package.json +21 -12
- package/dist/actions/desktopActions.d.ts +0 -58
- package/dist/actions/desktopActions.js +0 -155
- package/dist/actions/index.d.ts +0 -27
- package/dist/actions/index.js +0 -11
- package/dist/actions/memoryActions.d.ts +0 -9
- package/dist/actions/memoryActions.js +0 -34
- package/dist/actions/taskActions.d.ts +0 -8
- package/dist/actions/taskActions.js +0 -27
- package/dist/actions/types.d.ts +0 -35
- package/dist/actions/types.js +0 -5
- package/dist/actions/util.d.ts +0 -21
- package/dist/actions/util.js +0 -280
- package/dist/actions/webActions.d.ts +0 -87
- package/dist/actions/webActions.js +0 -214
- package/dist/actions/webActions.test.d.ts +0 -1
- package/dist/actions/webActions.test.js +0 -43
- package/dist/agent/browserAgent.d.ts +0 -31
- package/dist/agent/browserAgent.js +0 -136
- package/dist/agent/errors.d.ts +0 -22
- package/dist/agent/errors.js +0 -97
- package/dist/agent/index.d.ts +0 -64
- package/dist/agent/index.js +0 -505
- package/dist/agent/narrator.d.ts +0 -4
- package/dist/agent/narrator.js +0 -63
- package/dist/agent/pause.test.d.ts +0 -1
- package/dist/agent/pause.test.js +0 -194
- package/dist/ai/baml_client/async_client.d.ts +0 -64
- package/dist/ai/baml_client/async_client.js +0 -284
- package/dist/ai/baml_client/async_request.d.ts +0 -39
- package/dist/ai/baml_client/async_request.js +0 -134
- package/dist/ai/baml_client/config.d.ts +0 -11
- package/dist/ai/baml_client/config.js +0 -20
- package/dist/ai/baml_client/globals.d.ts +0 -16
- package/dist/ai/baml_client/globals.js +0 -37
- package/dist/ai/baml_client/index.d.ts +0 -17
- package/dist/ai/baml_client/index.js +0 -42
- package/dist/ai/baml_client/inlinedbaml.d.ts +0 -19
- package/dist/ai/baml_client/inlinedbaml.js +0 -31
- package/dist/ai/baml_client/parser.d.ts +0 -53
- package/dist/ai/baml_client/parser.js +0 -86
- package/dist/ai/baml_client/partial_types.d.ts +0 -61
- package/dist/ai/baml_client/partial_types.js +0 -10
- package/dist/ai/baml_client/sync_client.d.ts +0 -57
- package/dist/ai/baml_client/sync_client.js +0 -142
- package/dist/ai/baml_client/sync_request.d.ts +0 -37
- package/dist/ai/baml_client/sync_request.js +0 -134
- package/dist/ai/baml_client/tracing.d.ts +0 -16
- package/dist/ai/baml_client/tracing.js +0 -18
- package/dist/ai/baml_client/type_builder.d.ts +0 -40
- package/dist/ai/baml_client/type_builder.js +0 -120
- package/dist/ai/baml_client/types.d.ts +0 -69
- package/dist/ai/baml_client/types.js +0 -15
- package/dist/ai/baml_client/watchers.d.ts +0 -32
- package/dist/ai/baml_client/watchers.js +0 -50
- package/dist/ai/baseten.d.ts +0 -4
- package/dist/ai/baseten.js +0 -10
- package/dist/ai/claudeCode.d.ts +0 -1
- package/dist/ai/claudeCode.js +0 -186
- package/dist/ai/modelHarness.d.ts +0 -39
- package/dist/ai/modelHarness.js +0 -324
- package/dist/ai/modelResponseError.d.ts +0 -4
- package/dist/ai/modelResponseError.js +0 -8
- package/dist/ai/multiModelHarness.d.ts +0 -24
- package/dist/ai/multiModelHarness.js +0 -52
- package/dist/ai/plannerResponse.d.ts +0 -34
- package/dist/ai/plannerResponse.js +0 -96
- package/dist/ai/plannerResponse.test.d.ts +0 -1
- package/dist/ai/plannerResponse.test.js +0 -112
- package/dist/ai/structuredOutput.d.ts +0 -11
- package/dist/ai/structuredOutput.js +0 -94
- package/dist/ai/structuredOutput.test.d.ts +0 -1
- package/dist/ai/structuredOutput.test.js +0 -91
- package/dist/ai/types.d.ts +0 -119
- package/dist/ai/types.js +0 -5
- package/dist/ai/util.d.ts +0 -13
- package/dist/ai/util.js +0 -200
- package/dist/ai/util.test.d.ts +0 -1
- package/dist/ai/util.test.js +0 -95
- package/dist/cli.js +0 -3
- package/dist/common/actions.js +0 -14
- package/dist/common/events.d.ts +0 -17
- package/dist/common/events.js +0 -3
- package/dist/common/failure.d.ts +0 -68
- package/dist/common/failure.js +0 -1
- package/dist/common/index.d.ts +0 -3
- package/dist/common/index.js +0 -3
- package/dist/common/operation.d.ts +0 -31
- package/dist/common/operation.js +0 -102
- package/dist/common/operation.test.d.ts +0 -1
- package/dist/common/operation.test.js +0 -53
- package/dist/common/retry.d.ts +0 -16
- package/dist/common/retry.js +0 -35
- package/dist/common/util.d.ts +0 -23
- package/dist/common/util.js +0 -139
- package/dist/connectors/browserConnector.d.ts +0 -53
- package/dist/connectors/browserConnector.js +0 -290
- package/dist/connectors/desktopConnector.d.ts +0 -58
- package/dist/connectors/desktopConnector.js +0 -68
- package/dist/connectors/index.d.ts +0 -14
- package/dist/connectors/index.js +0 -2
- package/dist/index.js +0 -28
- package/dist/logger.d.ts +0 -3
- package/dist/logger.js +0 -15
- package/dist/memory/agentMemory.d.ts +0 -47
- package/dist/memory/agentMemory.js +0 -167
- package/dist/memory/agentMemory.test.d.ts +0 -1
- package/dist/memory/agentMemory.test.js +0 -150
- package/dist/memory/image.d.ts +0 -28
- package/dist/memory/image.js +0 -95
- package/dist/memory/image.test.d.ts +0 -1
- package/dist/memory/image.test.js +0 -46
- package/dist/memory/index.d.ts +0 -3
- package/dist/memory/index.js +0 -3
- package/dist/memory/masking.d.ts +0 -7
- package/dist/memory/masking.js +0 -141
- package/dist/memory/masking.test.d.ts +0 -1
- package/dist/memory/masking.test.js +0 -117
- package/dist/memory/notebook.d.ts +0 -58
- package/dist/memory/notebook.js +0 -75
- package/dist/memory/notebook.test.d.ts +0 -1
- package/dist/memory/notebook.test.js +0 -99
- package/dist/memory/observation.d.ts +0 -38
- package/dist/memory/observation.js +0 -79
- package/dist/memory/rendering/index.d.ts +0 -10
- package/dist/memory/rendering/index.js +0 -13
- package/dist/memory/rendering/renderJsonParts.d.ts +0 -3
- package/dist/memory/rendering/renderJsonParts.js +0 -115
- package/dist/memory/rendering/renderJsonParts.test.d.ts +0 -1
- package/dist/memory/rendering/renderJsonParts.test.js +0 -217
- package/dist/memory/rendering/renderXmlParts.d.ts +0 -7
- package/dist/memory/rendering/renderXmlParts.js +0 -127
- package/dist/memory/serde.d.ts +0 -20
- package/dist/memory/serde.js +0 -67
- package/dist/memory/serde.test.d.ts +0 -1
- package/dist/memory/serde.test.js +0 -64
- package/dist/memory/util.d.ts +0 -2
- package/dist/memory/util.js +0 -17
- package/dist/telemetry/events.d.ts +0 -9
- package/dist/telemetry/events.js +0 -80
- package/dist/telemetry/index.d.ts +0 -6
- package/dist/telemetry/index.js +0 -91
- package/dist/types.d.ts +0 -30
- package/dist/types.js +0 -1
- package/dist/util.d.ts +0 -1
- package/dist/util.js +0 -12
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -3
- package/dist/web/browserProvider.d.ts +0 -24
- package/dist/web/browserProvider.js +0 -164
- package/dist/web/browserProvider.test.d.ts +0 -1
- package/dist/web/browserProvider.test.js +0 -44
- package/dist/web/harness.d.ts +0 -109
- package/dist/web/harness.js +0 -401
- package/dist/web/recovery.d.ts +0 -46
- package/dist/web/recovery.js +0 -137
- package/dist/web/recovery.test.d.ts +0 -1
- package/dist/web/recovery.test.js +0 -182
- package/dist/web/stability.d.ts +0 -57
- package/dist/web/stability.js +0 -323
- package/dist/web/tabs.d.ts +0 -58
- package/dist/web/tabs.js +0 -293
- package/dist/web/transformer.d.ts +0 -7
- package/dist/web/transformer.js +0 -41
- package/dist/web/types.d.ts +0 -37
- package/dist/web/types.js +0 -2
- package/dist/web/util.d.ts +0 -3
- package/dist/web/util.js +0 -81
- package/dist/web/visualizer/cursor.d.ts +0 -16
- package/dist/web/visualizer/cursor.js +0 -153
- package/dist/web/visualizer/index.d.ts +0 -22
- package/dist/web/visualizer/index.js +0 -47
- package/dist/web/visualizer/mouseEffects.d.ts +0 -18
- package/dist/web/visualizer/mouseEffects.js +0 -287
- package/dist/web/visualizer/typeEffects.d.ts +0 -10
- package/dist/web/visualizer/typeEffects.js +0 -190
- package/dist/web/zodReexport.test.d.ts +0 -1
- package/dist/web/zodReexport.test.js +0 -14
- /package/{dist/common/actions.d.ts → node_modules/patchright-core/.bun-tag-19f23bd68c84ec1f} +0 -0
package/dist/web/harness.js
DELETED
|
@@ -1,401 +0,0 @@
|
|
|
1
|
-
import { PageStabilityAnalyzer } from "./stability";
|
|
2
|
-
import { parseTypeContent } from "./util";
|
|
3
|
-
import { ActionVisualizer } from "./visualizer";
|
|
4
|
-
import logger from "@/logger";
|
|
5
|
-
import { TabManager } from "./tabs";
|
|
6
|
-
import { DOMTransformer } from "./transformer";
|
|
7
|
-
import { Image } from '@/memory/image';
|
|
8
|
-
import EventEmitter from "eventemitter3";
|
|
9
|
-
import { checkOperation, drainAll, operationSleep } from '@/common/operation';
|
|
10
|
-
export class WebHarness {
|
|
11
|
-
/**
|
|
12
|
-
* Executes web actions on a page
|
|
13
|
-
* Not responsible for browser lifecycle
|
|
14
|
-
*/
|
|
15
|
-
context;
|
|
16
|
-
options;
|
|
17
|
-
stability;
|
|
18
|
-
visualizer;
|
|
19
|
-
transformer;
|
|
20
|
-
tabs;
|
|
21
|
-
events = new EventEmitter();
|
|
22
|
-
constructor(context, options = {}) {
|
|
23
|
-
//this.page = page;
|
|
24
|
-
this.context = context;
|
|
25
|
-
this.options = options;
|
|
26
|
-
this.stability = new PageStabilityAnalyzer({ disableVisualStability: true });
|
|
27
|
-
this.visualizer = new ActionVisualizer(this.context, this.options.visuals ?? {});
|
|
28
|
-
this.transformer = new DOMTransformer();
|
|
29
|
-
this.tabs = new TabManager(context, {
|
|
30
|
-
switchOnActivity: options.switchTabsOnActivity ?? true
|
|
31
|
-
});
|
|
32
|
-
// this.context.on('page', (page: Page) => {
|
|
33
|
-
// this.setActivePage(page);
|
|
34
|
-
// //logger.info('ayo we got a new page');
|
|
35
|
-
// });
|
|
36
|
-
this.tabs.events.on('tabChanged', async (page) => {
|
|
37
|
-
await this.setActivePage(page);
|
|
38
|
-
// need to wait for page to load before evaluating a script
|
|
39
|
-
//page.on('load', () => { this.transformer.setActivePage(page); });
|
|
40
|
-
//console.log('tabs:', await this.tabs.getState())
|
|
41
|
-
}, this);
|
|
42
|
-
}
|
|
43
|
-
async setActivePage(page) {
|
|
44
|
-
logger.trace(`WebHarness active page: ${page.url()}`);
|
|
45
|
-
this.stability.setActivePage(page);
|
|
46
|
-
await this.visualizer.setActivePage(page);
|
|
47
|
-
this.transformer.setActivePage(page);
|
|
48
|
-
this.events.emit('activePageChanged', page);
|
|
49
|
-
}
|
|
50
|
-
async retrieveTabState() {
|
|
51
|
-
return this.tabs.retrieveState();
|
|
52
|
-
}
|
|
53
|
-
// setActivePage(page: Page) {
|
|
54
|
-
// this.page = page;
|
|
55
|
-
// this.stability.setActivePage(this.page);
|
|
56
|
-
// this.visualizer.setActivePage(this.page);
|
|
57
|
-
// }
|
|
58
|
-
async start() {
|
|
59
|
-
// Initialize tab manager first
|
|
60
|
-
await this.tabs.initialize();
|
|
61
|
-
if (this.context.pages().length > 0) {
|
|
62
|
-
// If context already contains a page, set it as active
|
|
63
|
-
this.tabs.setActivePage(this.context.pages()[0]);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
const page = await this.context.newPage();
|
|
67
|
-
// Force the initial page to be set as active and emit tabChanged
|
|
68
|
-
this.tabs.setActivePage(page);
|
|
69
|
-
}
|
|
70
|
-
await this.visualizer.setup();
|
|
71
|
-
}
|
|
72
|
-
async stop() {
|
|
73
|
-
// Clean up tab manager resources
|
|
74
|
-
this.tabs.destroy();
|
|
75
|
-
}
|
|
76
|
-
get page() {
|
|
77
|
-
return this.tabs.getActivePage();
|
|
78
|
-
}
|
|
79
|
-
async screenshot(options = {}) {
|
|
80
|
-
/**
|
|
81
|
-
* Get b64 encoded string of screenshot (PNG) with screen dimensions
|
|
82
|
-
*/
|
|
83
|
-
// Target page, context or browser has been closed
|
|
84
|
-
let dpr;
|
|
85
|
-
let buffer;
|
|
86
|
-
const retries = 3;
|
|
87
|
-
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
88
|
-
checkOperation();
|
|
89
|
-
try {
|
|
90
|
-
dpr = await this.page.evaluate(() => window.devicePixelRatio);
|
|
91
|
-
checkOperation();
|
|
92
|
-
buffer = await this.page.screenshot({ type: 'png', ...options });
|
|
93
|
-
checkOperation();
|
|
94
|
-
break; // Success! Exit the retry loop
|
|
95
|
-
}
|
|
96
|
-
catch (err) {
|
|
97
|
-
checkOperation();
|
|
98
|
-
// A few possibilities:
|
|
99
|
-
// 1. Target page, context or browser has been closed
|
|
100
|
-
// 2. Page navigation in progress
|
|
101
|
-
// In theory 2 shouldn't shouldn't happen during typical execution as we wait for page load - unless screenshot is triggered at an usual time.
|
|
102
|
-
const error = err;
|
|
103
|
-
if (error.message.includes('Target page, context or browser has been closed')) {
|
|
104
|
-
// Irrecoverable, no point in retrying
|
|
105
|
-
throw new Error("Attempted to take screenshot but page, context or browser is closed");
|
|
106
|
-
}
|
|
107
|
-
if (attempt >= retries) {
|
|
108
|
-
throw new Error(`Unable to capture screenshot after retries, error: ${error.message}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const base64data = buffer.toString('base64');
|
|
113
|
-
const image = Image.fromBase64(base64data);
|
|
114
|
-
// Now, need to rescale the image based on DPR. This is so that:
|
|
115
|
-
// (1) Save on tokens, dont need huge high res images
|
|
116
|
-
// (2) More importantly, clicks happen in the standard resolution space, so need to do this for coordinates to be correct
|
|
117
|
-
// for any agent not using a virtual screen space (e.g. those that aren't Claude)
|
|
118
|
-
const { width, height } = await image.getDimensions();
|
|
119
|
-
const rescaledImage = await image.resize(width / dpr, height / dpr);
|
|
120
|
-
return rescaledImage;
|
|
121
|
-
}
|
|
122
|
-
// async goto(url: string) {
|
|
123
|
-
// // No need to redraw here anymore, the 'load' event listener handles it
|
|
124
|
-
// await this.page.goto(url);
|
|
125
|
-
// }
|
|
126
|
-
async _type(content) {
|
|
127
|
-
/** Util for typing + keypresses */
|
|
128
|
-
const chunks = parseTypeContent(content);
|
|
129
|
-
// Total typing period to make typing more natural, in ms
|
|
130
|
-
const totalTextDelay = 500;
|
|
131
|
-
let totalTextLength = 0;
|
|
132
|
-
for (const chunk of chunks) {
|
|
133
|
-
if (chunk != '<enter>' && chunk != '<tab>') {
|
|
134
|
-
totalTextLength += chunk.length;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
for (const chunk of chunks) {
|
|
138
|
-
checkOperation();
|
|
139
|
-
if (chunk == '<enter>') {
|
|
140
|
-
await this.page.keyboard.press('Enter');
|
|
141
|
-
}
|
|
142
|
-
else if (chunk == '<tab>') {
|
|
143
|
-
await this.page.keyboard.press('Tab');
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
const chunkProportion = chunk.length / totalTextLength;
|
|
147
|
-
const chunkDelay = totalTextDelay * chunkProportion;
|
|
148
|
-
const chunkCharDelay = chunkDelay / chunk.length;
|
|
149
|
-
await this.page.keyboard.type(chunk, { delay: chunkCharDelay });
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
// safer might be Coordinate interface/obj tied to certain screen space dims
|
|
154
|
-
async transformCoordinates({ x, y }) {
|
|
155
|
-
const virtual = this.options.virtualScreenDimensions;
|
|
156
|
-
if (!virtual) {
|
|
157
|
-
return { x, y };
|
|
158
|
-
}
|
|
159
|
-
let vp = this.page.viewportSize();
|
|
160
|
-
if (!vp) {
|
|
161
|
-
vp = await this.page.evaluate(() => ({
|
|
162
|
-
width: window.innerWidth,
|
|
163
|
-
height: window.innerHeight
|
|
164
|
-
}));
|
|
165
|
-
}
|
|
166
|
-
if (!vp)
|
|
167
|
-
throw new Error("Could not get viewport dimensions to transform coordinates");
|
|
168
|
-
return {
|
|
169
|
-
x: x * (vp.width / virtual.width),
|
|
170
|
-
y: y * (vp.height / virtual.height),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
async click({ x, y }, options) {
|
|
174
|
-
if (options?.transform ?? true)
|
|
175
|
-
({ x, y } = await this.transformCoordinates({ x, y }));
|
|
176
|
-
// console.log("x:", x);
|
|
177
|
-
// console.log("y:", y);
|
|
178
|
-
//await this.visualizer.visualizeAction(x, y);
|
|
179
|
-
//await this.page.mouse.click(x, y);
|
|
180
|
-
//await this.page.mouse.move(x, y, { steps: 20 });
|
|
181
|
-
//console.log('clicking:', x, y);
|
|
182
|
-
// const loc = this.page.getByText('Where are you going?');
|
|
183
|
-
// console.log('found:', loc);
|
|
184
|
-
// await loc.click();
|
|
185
|
-
await this._click(x, y);
|
|
186
|
-
// await this.page.waitForTimeout(1000);
|
|
187
|
-
// await this.page.mouse.click(x, y);
|
|
188
|
-
// await this.page.waitForTimeout(1000);
|
|
189
|
-
// await this.page.mouse.click(x, y);
|
|
190
|
-
// await this.page.waitForTimeout(1000);
|
|
191
|
-
// await this.page.mouse.click(x, y);
|
|
192
|
-
// await this.page.waitForTimeout(1000);
|
|
193
|
-
// await this.page.mouse.click(x, y);
|
|
194
|
-
// await this.page.waitForTimeout(1000);
|
|
195
|
-
// await Promise.all([
|
|
196
|
-
// this.page.mouse.move(x, y, { steps: 20 }),
|
|
197
|
-
// this.visualizer.visualizeAction(x, y),
|
|
198
|
-
// ]);
|
|
199
|
-
// await this.page.mouse.down();
|
|
200
|
-
// await this.page.waitForTimeout(200);
|
|
201
|
-
// await this.page.mouse.up();
|
|
202
|
-
// await this.page.evaluate(({ x, y }) => {
|
|
203
|
-
// // Find the topmost element at the given coordinates
|
|
204
|
-
// const targetElement = document.elementFromPoint(x, y);
|
|
205
|
-
// if (!targetElement) {
|
|
206
|
-
// console.error('No element found at coordinates:', x, y);
|
|
207
|
-
// return;
|
|
208
|
-
// }
|
|
209
|
-
// // Create and dispatch the events with properties that mimic a real click
|
|
210
|
-
// const options = {
|
|
211
|
-
// bubbles: true,
|
|
212
|
-
// cancelable: true,
|
|
213
|
-
// composed: true,
|
|
214
|
-
// // We can't set isTrusted, the browser forces it to false
|
|
215
|
-
// };
|
|
216
|
-
// targetElement.dispatchEvent(new MouseEvent('mouseover', options));
|
|
217
|
-
// targetElement.dispatchEvent(new MouseEvent('mousedown', options));
|
|
218
|
-
// targetElement.dispatchEvent(new MouseEvent('mouseup', options));
|
|
219
|
-
// targetElement.dispatchEvent(new MouseEvent('click', options));
|
|
220
|
-
// }, { x, y });
|
|
221
|
-
await this.waitForStability();
|
|
222
|
-
//await this.visualizer.removeActionVisuals();
|
|
223
|
-
}
|
|
224
|
-
async _click(x, y, options) {
|
|
225
|
-
checkOperation();
|
|
226
|
-
await drainAll([
|
|
227
|
-
this.visualizer.moveVirtualCursor(x, y),
|
|
228
|
-
this.page.mouse.move(x, y, { steps: 20 })
|
|
229
|
-
]);
|
|
230
|
-
// await this.visualizer.moveVirtualCursor(x, y);
|
|
231
|
-
// await this.page.mouse.move(x, y, { steps: 20 });
|
|
232
|
-
checkOperation();
|
|
233
|
-
await this.visualizer.hideAll(); // The visualizer can block clicks.
|
|
234
|
-
try {
|
|
235
|
-
checkOperation();
|
|
236
|
-
await this.page.mouse.click(x, y);
|
|
237
|
-
}
|
|
238
|
-
finally {
|
|
239
|
-
await this.visualizer.showAll();
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
async hover({ x, y }, options) {
|
|
243
|
-
if (options?.transform ?? true)
|
|
244
|
-
({ x, y } = await this.transformCoordinates({ x, y }));
|
|
245
|
-
checkOperation();
|
|
246
|
-
await drainAll([
|
|
247
|
-
this.visualizer.moveVirtualCursor(x, y),
|
|
248
|
-
this.page.mouse.move(x, y, { steps: 20 })
|
|
249
|
-
]);
|
|
250
|
-
await this.waitForStability();
|
|
251
|
-
}
|
|
252
|
-
async rightClick({ x, y }, options) {
|
|
253
|
-
if (options?.transform ?? true)
|
|
254
|
-
({ x, y } = await this.transformCoordinates({ x, y }));
|
|
255
|
-
await this._click(x, y, { button: "right" });
|
|
256
|
-
await this.waitForStability();
|
|
257
|
-
}
|
|
258
|
-
async doubleClick({ x, y }, options) {
|
|
259
|
-
if (options?.transform ?? true)
|
|
260
|
-
({ x, y } = await this.transformCoordinates({ x, y }));
|
|
261
|
-
checkOperation();
|
|
262
|
-
await this.visualizer.moveVirtualCursor(x, y);
|
|
263
|
-
checkOperation();
|
|
264
|
-
await this.visualizer.hideAll();
|
|
265
|
-
try {
|
|
266
|
-
checkOperation();
|
|
267
|
-
await this.page.mouse.dblclick(x, y);
|
|
268
|
-
}
|
|
269
|
-
finally {
|
|
270
|
-
await this.visualizer.showAll();
|
|
271
|
-
}
|
|
272
|
-
await this.waitForStability();
|
|
273
|
-
}
|
|
274
|
-
async drag({ x1, y1, x2, y2 }, options) {
|
|
275
|
-
if (options?.transform ?? true)
|
|
276
|
-
({ x: x1, y: y1 } = await this.transformCoordinates({ x: x1, y: y1 }));
|
|
277
|
-
if (options?.transform ?? true)
|
|
278
|
-
({ x: x2, y: y2 } = await this.transformCoordinates({ x: x2, y: y2 }));
|
|
279
|
-
//console.log(`Dragging: (${x1}, ${y1}) -> (${x2}, ${y2})`);
|
|
280
|
-
checkOperation();
|
|
281
|
-
await this.page.mouse.move(x1, y1, { steps: 1 });
|
|
282
|
-
checkOperation();
|
|
283
|
-
await this.page.mouse.down();
|
|
284
|
-
try {
|
|
285
|
-
checkOperation();
|
|
286
|
-
await this.visualizer.moveVirtualCursor(x1, y1);
|
|
287
|
-
await operationSleep(500);
|
|
288
|
-
checkOperation();
|
|
289
|
-
await drainAll([
|
|
290
|
-
this.page.mouse.move(x2, y2, { steps: 20 }),
|
|
291
|
-
this.visualizer.moveVirtualCursor(x2, y2)
|
|
292
|
-
]);
|
|
293
|
-
}
|
|
294
|
-
finally {
|
|
295
|
-
// Release input state even on cancellation; an already-sent drag cannot be undone.
|
|
296
|
-
await this.page.mouse.up();
|
|
297
|
-
}
|
|
298
|
-
await this.waitForStability();
|
|
299
|
-
//await this.visualizer.removeActionVisuals();
|
|
300
|
-
}
|
|
301
|
-
async type({ content }) {
|
|
302
|
-
await this._type(content);
|
|
303
|
-
await this.waitForStability();
|
|
304
|
-
}
|
|
305
|
-
async clickAndType({ x, y, content }, options) {
|
|
306
|
-
// TODO: transforms incorrect for moondream grounding with virtual screen dims (claude) - unsure why
|
|
307
|
-
//console.log(`Pre transform: ${x}, ${y}`);
|
|
308
|
-
if (options?.transform ?? true)
|
|
309
|
-
({ x, y } = await this.transformCoordinates({ x, y }));
|
|
310
|
-
//console.log(`Post transform: ${x}, ${y}`);
|
|
311
|
-
await this._click(x, y);
|
|
312
|
-
await this._type(content);
|
|
313
|
-
await this.waitForStability();
|
|
314
|
-
}
|
|
315
|
-
async scroll({ x, y, deltaX, deltaY }, options) {
|
|
316
|
-
if (options?.transform ?? true)
|
|
317
|
-
({ x, y } = await this.transformCoordinates({ x, y }));
|
|
318
|
-
checkOperation();
|
|
319
|
-
await this.visualizer.moveVirtualCursor(x, y);
|
|
320
|
-
checkOperation();
|
|
321
|
-
await this.page.mouse.move(x, y);
|
|
322
|
-
checkOperation();
|
|
323
|
-
await this.page.mouse.wheel(deltaX, deltaY);
|
|
324
|
-
await this.waitForStability();
|
|
325
|
-
}
|
|
326
|
-
async switchTab({ index }) {
|
|
327
|
-
checkOperation();
|
|
328
|
-
await this.tabs.switchTab(index);
|
|
329
|
-
await this.waitForStability();
|
|
330
|
-
}
|
|
331
|
-
async newTab() {
|
|
332
|
-
checkOperation();
|
|
333
|
-
await this.context.newPage();
|
|
334
|
-
// Reasonable default and less confusing than white about:blank page
|
|
335
|
-
await this.navigate("https://google.com");
|
|
336
|
-
}
|
|
337
|
-
async navigate(url) {
|
|
338
|
-
checkOperation();
|
|
339
|
-
// Only wait for DOM content on goto since we handle waiting for network idle etc ourselves
|
|
340
|
-
await this.page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
341
|
-
await this.waitForStability();
|
|
342
|
-
}
|
|
343
|
-
async selectAll() {
|
|
344
|
-
checkOperation();
|
|
345
|
-
await this.page.keyboard.down('ControlOrMeta');
|
|
346
|
-
try {
|
|
347
|
-
checkOperation();
|
|
348
|
-
await this.page.keyboard.press('KeyA');
|
|
349
|
-
}
|
|
350
|
-
finally {
|
|
351
|
-
await this.page.keyboard.up('ControlOrMeta');
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
async enter() {
|
|
355
|
-
checkOperation();
|
|
356
|
-
await this.page.keyboard.press('Enter');
|
|
357
|
-
}
|
|
358
|
-
async backspace() {
|
|
359
|
-
checkOperation();
|
|
360
|
-
await this.page.keyboard.press('Backspace');
|
|
361
|
-
}
|
|
362
|
-
async tab() {
|
|
363
|
-
checkOperation();
|
|
364
|
-
await this.page.keyboard.press('Tab');
|
|
365
|
-
}
|
|
366
|
-
async goBack() {
|
|
367
|
-
checkOperation();
|
|
368
|
-
await this.page.goBack();
|
|
369
|
-
}
|
|
370
|
-
async escape() {
|
|
371
|
-
checkOperation();
|
|
372
|
-
await this.page.keyboard.press('Escape');
|
|
373
|
-
}
|
|
374
|
-
async executeAction(action) {
|
|
375
|
-
if (action.variant === 'click') {
|
|
376
|
-
await this.click(action);
|
|
377
|
-
}
|
|
378
|
-
else if (action.variant === 'hover') {
|
|
379
|
-
await this.hover(action);
|
|
380
|
-
}
|
|
381
|
-
else if (action.variant === 'type') {
|
|
382
|
-
await this.clickAndType(action);
|
|
383
|
-
}
|
|
384
|
-
else if (action.variant === 'scroll') {
|
|
385
|
-
await this.scroll(action);
|
|
386
|
-
}
|
|
387
|
-
else if (action.variant === 'tab') {
|
|
388
|
-
await this.switchTab(action);
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
throw Error(`Unhandled web action variant: ${action.variant}`);
|
|
392
|
-
}
|
|
393
|
-
//await this.stability.waitForStability();
|
|
394
|
-
//await this.visualizer.redrawLastPosition();
|
|
395
|
-
}
|
|
396
|
-
async waitForStability(timeout) {
|
|
397
|
-
checkOperation();
|
|
398
|
-
await this.stability.waitForStability(timeout);
|
|
399
|
-
checkOperation();
|
|
400
|
-
}
|
|
401
|
-
}
|
package/dist/web/recovery.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { Action } from '@/actions/types';
|
|
2
|
-
export type BlockReason = 'rate_limit' | 'subscription' | 'authentication' | 'no_progress';
|
|
3
|
-
export interface BrowserBlock {
|
|
4
|
-
reason: BlockReason;
|
|
5
|
-
evidence: string;
|
|
6
|
-
retryAt?: number;
|
|
7
|
-
}
|
|
8
|
-
export declare class BrowserBlockedError extends Error {
|
|
9
|
-
readonly block: BrowserBlock;
|
|
10
|
-
constructor(block: BrowserBlock);
|
|
11
|
-
}
|
|
12
|
-
export interface HttpDiagnostic {
|
|
13
|
-
timestamp: number;
|
|
14
|
-
url: string;
|
|
15
|
-
status: number;
|
|
16
|
-
retryAt?: number;
|
|
17
|
-
navigation?: boolean;
|
|
18
|
-
}
|
|
19
|
-
export declare function diagnosticUrl(value: string): string;
|
|
20
|
-
export declare function retryAt(value: string | undefined, now: number): number | undefined;
|
|
21
|
-
export declare function detectBlock(headings: string[], response?: HttpDiagnostic): BrowserBlock | undefined;
|
|
22
|
-
export interface RecoveryOptions {
|
|
23
|
-
maxRateLimitWaitMs?: number;
|
|
24
|
-
repeatedActionLimit?: number;
|
|
25
|
-
/** Opt in to heuristic loop warnings and automatic no-progress termination. */
|
|
26
|
-
noProgress?: boolean;
|
|
27
|
-
}
|
|
28
|
-
export declare class BrowserRecovery {
|
|
29
|
-
block?: BrowserBlock;
|
|
30
|
-
warning?: string;
|
|
31
|
-
waitUntil?: number;
|
|
32
|
-
private rateWaitMs;
|
|
33
|
-
private blockedActions;
|
|
34
|
-
private recent;
|
|
35
|
-
private recentStates;
|
|
36
|
-
private repetitions;
|
|
37
|
-
private lastFingerprint?;
|
|
38
|
-
readonly maxRateLimitWaitMs: number;
|
|
39
|
-
readonly repeatedActionLimit: number;
|
|
40
|
-
readonly noProgress: boolean;
|
|
41
|
-
constructor(options?: RecoveryOptions);
|
|
42
|
-
reset(): void;
|
|
43
|
-
observe(fingerprint: string, action: Action | undefined, block: BrowserBlock | undefined, now?: number): void;
|
|
44
|
-
check(): void;
|
|
45
|
-
waitDuration(requestedMs: number, now?: number, deadline?: number): number;
|
|
46
|
-
}
|
package/dist/web/recovery.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
export class BrowserBlockedError extends Error {
|
|
2
|
-
block;
|
|
3
|
-
constructor(block) {
|
|
4
|
-
super(`Browser blocked (${block.reason}): ${block.evidence}`);
|
|
5
|
-
this.block = block;
|
|
6
|
-
this.name = 'BrowserBlockedError';
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
// Strip userinfo, query strings and fragments; do not persist arbitrary headers.
|
|
10
|
-
export function diagnosticUrl(value) {
|
|
11
|
-
try {
|
|
12
|
-
const url = new URL(value);
|
|
13
|
-
return `${url.origin}${url.pathname}`;
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return 'unknown';
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export function retryAt(value, now) {
|
|
20
|
-
if (!value)
|
|
21
|
-
return undefined;
|
|
22
|
-
const seconds = Number(value);
|
|
23
|
-
if (Number.isFinite(seconds))
|
|
24
|
-
return seconds >= 0 ? now + seconds * 1000 : undefined;
|
|
25
|
-
const date = Date.parse(value);
|
|
26
|
-
return Number.isFinite(date) ? Math.max(now, date) : undefined;
|
|
27
|
-
}
|
|
28
|
-
export function detectBlock(headings, response) {
|
|
29
|
-
const rate = headings.find(text => /too many requests|you have exceeded a secondary rate limit|rate limit exceeded/i.test(text));
|
|
30
|
-
if ((response?.status === 429 && response.navigation !== false) || rate)
|
|
31
|
-
return {
|
|
32
|
-
reason: 'rate_limit', evidence: rate ?? `HTTP 429 at ${response.url}`,
|
|
33
|
-
retryAt: response?.retryAt ?? (response ? response.timestamp + 60_000 : undefined),
|
|
34
|
-
};
|
|
35
|
-
const subscription = headings.find(text => /subscri(?:be|ption required).{0,60}(?:to continue|to (?:read|access)|required)/i.test(text));
|
|
36
|
-
if (subscription)
|
|
37
|
-
return { reason: 'subscription', evidence: subscription };
|
|
38
|
-
const authentication = headings.find(text => /(?:sign|log) in to (?:continue|read|access)/i.test(text));
|
|
39
|
-
if (authentication)
|
|
40
|
-
return { reason: 'authentication', evidence: authentication };
|
|
41
|
-
// A bare 403 can have many causes; it is not proof of rate limiting.
|
|
42
|
-
}
|
|
43
|
-
export class BrowserRecovery {
|
|
44
|
-
block;
|
|
45
|
-
warning;
|
|
46
|
-
waitUntil;
|
|
47
|
-
rateWaitMs = 0;
|
|
48
|
-
blockedActions = 0;
|
|
49
|
-
recent = [];
|
|
50
|
-
recentStates = new Set();
|
|
51
|
-
repetitions = 0;
|
|
52
|
-
lastFingerprint;
|
|
53
|
-
maxRateLimitWaitMs;
|
|
54
|
-
repeatedActionLimit;
|
|
55
|
-
noProgress;
|
|
56
|
-
constructor(options = {}) {
|
|
57
|
-
this.maxRateLimitWaitMs = options.maxRateLimitWaitMs ?? 120_000;
|
|
58
|
-
this.repeatedActionLimit = options.repeatedActionLimit ?? 6;
|
|
59
|
-
this.noProgress = options.noProgress ?? false;
|
|
60
|
-
if (!Number.isFinite(this.maxRateLimitWaitMs) || this.maxRateLimitWaitMs < 0
|
|
61
|
-
|| !Number.isSafeInteger(this.repeatedActionLimit) || this.repeatedActionLimit < 3) {
|
|
62
|
-
throw new Error('Invalid browser recovery limits');
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
reset() {
|
|
66
|
-
this.block = undefined;
|
|
67
|
-
this.warning = undefined;
|
|
68
|
-
this.rateWaitMs = 0;
|
|
69
|
-
this.blockedActions = 0;
|
|
70
|
-
this.recent = [];
|
|
71
|
-
this.recentStates.clear();
|
|
72
|
-
this.repetitions = 0;
|
|
73
|
-
this.lastFingerprint = undefined;
|
|
74
|
-
}
|
|
75
|
-
observe(fingerprint, action, block, now = Date.now()) {
|
|
76
|
-
const previousFingerprint = this.lastFingerprint ?? fingerprint;
|
|
77
|
-
if (block?.reason !== this.block?.reason || fingerprint !== this.lastFingerprint)
|
|
78
|
-
this.blockedActions = 0;
|
|
79
|
-
if (fingerprint !== this.lastFingerprint || block) {
|
|
80
|
-
this.warning = undefined;
|
|
81
|
-
this.repetitions = 0;
|
|
82
|
-
}
|
|
83
|
-
this.lastFingerprint = fingerprint;
|
|
84
|
-
// New evidence breaks a loop, even when reaching it requires familiar paths.
|
|
85
|
-
// Keep a bounded LRU of states separate from the repetition history.
|
|
86
|
-
if (!this.recentStates.has(fingerprint) || block)
|
|
87
|
-
this.recent = [];
|
|
88
|
-
this.recentStates.delete(fingerprint);
|
|
89
|
-
this.recentStates.add(fingerprint);
|
|
90
|
-
if (this.recentStates.size > 30)
|
|
91
|
-
this.recentStates.delete(this.recentStates.values().next().value);
|
|
92
|
-
if (block?.reason === 'rate_limit') {
|
|
93
|
-
block.retryAt ??= this.block?.reason === 'rate_limit' ? this.block.retryAt : now + 60_000;
|
|
94
|
-
}
|
|
95
|
-
this.block = block;
|
|
96
|
-
// Waiting is deliberate inactivity, not evidence of a navigation loop.
|
|
97
|
-
if (!action || action.variant === 'wait' || action.variant === 'mouse:hover')
|
|
98
|
-
return;
|
|
99
|
-
if (block) {
|
|
100
|
-
this.blockedActions++;
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (!this.noProgress)
|
|
104
|
-
return;
|
|
105
|
-
// Returning from different pages is not repeating the same transition.
|
|
106
|
-
// Ignore coordinates so jitter cannot disguise genuinely unchanged clicks.
|
|
107
|
-
const key = JSON.stringify([previousFingerprint, action.variant, fingerprint]);
|
|
108
|
-
this.recent.push(key);
|
|
109
|
-
if (this.recent.length > 30)
|
|
110
|
-
this.recent.shift();
|
|
111
|
-
this.repetitions = this.recent.filter(value => value === key).length;
|
|
112
|
-
this.warning = this.repetitions >= 3
|
|
113
|
-
? 'This action has repeatedly produced a previously seen page state. Review tried searches and visited pages; use a materially different approach, or report browser:blocked with reason no_progress. Do not repeat the same search or click without new evidence.'
|
|
114
|
-
: undefined;
|
|
115
|
-
}
|
|
116
|
-
check() {
|
|
117
|
-
if (this.block && this.block.reason !== 'rate_limit' && this.blockedActions >= 3) {
|
|
118
|
-
throw new BrowserBlockedError(this.block);
|
|
119
|
-
}
|
|
120
|
-
if (this.noProgress && !this.block && this.repetitions >= this.repeatedActionLimit) {
|
|
121
|
-
throw new BrowserBlockedError({ reason: 'no_progress', evidence: this.warning });
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
waitDuration(requestedMs, now = Date.now(), deadline) {
|
|
125
|
-
const duration = Math.max(requestedMs, (this.block?.retryAt ?? now) - now, 0);
|
|
126
|
-
if (this.block?.reason === 'rate_limit') {
|
|
127
|
-
if (deadline !== undefined && (this.block.retryAt ?? now) >= deadline) {
|
|
128
|
-
throw new BrowserBlockedError({ ...this.block, evidence: `${this.block.evidence}; Retry-After exceeds the remaining operation deadline` });
|
|
129
|
-
}
|
|
130
|
-
if (this.rateWaitMs + duration > this.maxRateLimitWaitMs) {
|
|
131
|
-
throw new BrowserBlockedError({ ...this.block, evidence: `${this.block.evidence}; required wait exceeds the remaining rate-limit wait budget` });
|
|
132
|
-
}
|
|
133
|
-
this.rateWaitMs += duration;
|
|
134
|
-
}
|
|
135
|
-
return duration;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|