@xopcai/xopc 0.0.251 → 0.0.253
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/README.zh-CN.md +8 -5
- package/dist/browser-ext/dist/background.js +358 -768
- package/dist/browser-ext/manifest.json +1 -2
- package/dist/extensions/telegram/src/inbound-processor.js +2 -2
- package/dist/extensions/telegram/src/plugin.js +3 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DfBjTSo9.js → activity-store-CeS1bgXP.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bo_dmLv8.js → agent-avatar-dicebear-BdF3HhCW.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Bs34Kp0K.js +1 -0
- package/dist/gateway/static/root/assets/{agents-yuUn8n-f.js → agents-DARlgjTm.js} +1 -1
- package/dist/gateway/static/root/assets/{api-zxpcJfgj.js → api-zMPeC0yU.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cz56nrVF.js → app-management-settings-panel-BaAFln8W.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DxSws5U4.js → appearance-settings-CXvsoBlw.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BhgvfBJT.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-7k15-hqo.js → archive-plugin-C0o_mVQI.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-B-SFpjd9.js → attachment-load-B5Ry3tGL.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-Qy36j19q.js → automations-page-DY5QAEQd.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BzX4lILP.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CPOZQt8F.js → binary-plugins-BydpEgBA.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DhvVlIp9.js → block-editor-D0CpUOMo.js} +3 -3
- package/dist/gateway/static/root/assets/browser-automation-inputs-DzbTsGI6.js +1 -0
- package/dist/gateway/static/root/assets/browser-automations-page-D7fZYjni.js +3 -0
- package/dist/gateway/static/root/assets/browser-settings-page-BBdMqxl0.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-D_WfftDW.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-bdRLT9KA.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-CX-yWwLD.js → channels-status-swr-BGGRTkn6.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-1PJoxRuV.js → chat-terminal-dock-_CP4nvlg.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-CPDjU5wU.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-CBCc6zFA.js → cron-expression-g2U8Rllf.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-u8K5Kt_N.js → date-picker-SmVlhtj_.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-y_i_cnpz.js → dependency-picker-D-0gcbbM.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DyL0JxLm.js → desktop-pet-Cl3JRIu6.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-d2d_IsyP.js → desktop-pet-settings-D7kvWQ9H.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DqIBKJwl.js → extension-debug-page-DtP2tJHY.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DUW1xxj2.js → extension-page-CphZDdoT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BHY9qaNw.js → extension-settings-page-CsxVLV4-.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CMNbl0FZ.js → gateway-config-swr-BW3Bx-aV.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DxBZ05dX.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CR7Xg8As.js → gateway-startup-retry-DAq74TZe.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-7CD9iPR7.js → heartbeat-settings-DWcKsIoZ.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-BdvLZKQZ.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-C5mn73ca.js → image-generation-api-MPuaXDRs.js} +1 -1
- package/dist/gateway/static/root/assets/index-C7RDs6S-.js +74 -0
- package/dist/gateway/static/root/assets/index-Cu8xqZQ9.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BtlqMleF.js → keyboard-shortcuts-settings-CfhaTqgE.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-BjxfkjxE.js → local-app-workbench-page-CR6asX7L.js} +2 -2
- package/dist/gateway/static/root/assets/{local-apps-page-B7xqQe2s.js → local-apps-page-g01W3kEK.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CF4erhjB.js → locale-store-BkeaPZpn.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-kACaPZKL.js → logs-page-ZP4QTWoC.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-A432siER.js → management-settings-DeGxJF_Z.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-Ca7BRBLL.js +201 -0
- package/dist/gateway/static/root/assets/{media-plugins-CpvYiauZ.js → media-plugins-FmOhmzlD.js} +1 -1
- package/dist/gateway/static/root/assets/messages-C72stReU.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DyjVGngO.js → mobile-pairing-wizard-BXNbn05L.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-EeVeF4II.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-D7bMff96.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-B3FKzjR6.js → page-tabs-pyukZ1PJ.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DnjrwAHD.js → preview-open-alternatives-slFHoMUe.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-COcr_NUJ.js → product-open-page-CXa3FNNk.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BDF88VdN.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DeTD6pu1.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BsRBlji7.js → registry-api-CviQoUBf.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CxKrdQ6a.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-LO4wZ_dO.js → runtime-tools-settings-panel-O9D9o7-O.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-crcj4-Pm.js → schema-form-8FesicnL.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DUFJN-2t.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CcSYDjaH.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Bl4MvTmq.js → settings-form-section-CBic9TFH.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DplrjZ6x.js → settings-page-Xz66_Mjg.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-C6DuwrP5.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-CJP1kURj.js → share-preview-page--JpjwB58.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-CemgzEi4.js → shares-settings-CovcdHSC.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CrHagTsE.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-DsjcKg9Q.js → skills-page-fVKExKv5.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-D6gWBbvy.js → skills-page.utils-Yv9u3uJp.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-_eCXfqCo.js → system-settings-panel-CCWjVdc2.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-D0Z_K5JT.js → task-detail-page-I8hueJnG.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-BOgkc_9D.js → theme-store-BtkaVpMm.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-W5mktxl1.js → tunnel-api-C__W9BaN.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-Na2DYzT3.js → use-autosave-Dow9RRcq.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CU6nxmoM.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-OXweUxS_.js → voice-api-key-field-CvF3lEyx.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-C-ryeIxj.js → voice-config-api-BEUVAyM6.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BqOsO47I.js → work-discovery-overlay-B9PDfReq.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-B9S_lfT1.js → workflow-run-setup-panel-kWGFkhjz.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-B4Is5E42.js +5 -0
- package/dist/gateway/static/root/index.html +10 -10
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/new-session.js +9 -0
- package/dist/packages/realtime-protocol/src/voice.js +6 -1
- package/dist/src/agent/agent-manager.d.ts +2 -1
- package/dist/src/agent/agent-manager.js +26 -8
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/coding/repository-instructions.js +2 -2
- package/dist/src/agent/coding/workspace-revision.js +2 -2
- package/dist/src/agent/commands/command-isolation.js +2 -2
- package/dist/src/agent/embedded/execution-context.d.ts +2 -1
- package/dist/src/agent/embedded/execution-context.js +10 -4
- package/dist/src/agent/embedded/index.d.ts +1 -1
- package/dist/src/agent/embedded/index.js +2 -2
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +5 -4
- package/dist/src/agent/embedded/run-turn.js +22 -3
- package/dist/src/agent/embedded/types.d.ts +1 -1
- package/dist/src/agent/external-tools/composio-provider.d.ts +1 -0
- package/dist/src/agent/external-tools/composio-provider.js +64 -34
- package/dist/src/agent/external-tools/search-error.js +5 -3
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +6 -3
- package/dist/src/agent/service/process-direct-streaming.js +6 -3
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +25 -10
- package/dist/src/agent/service.types.d.ts +2 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +4 -0
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
- package/dist/src/agent/tool-manuals/browser.js +15 -226
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -21
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +48 -165
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +203 -16
- package/dist/src/agent/tools/browser/tool/schemas.js +146 -16
- package/dist/src/agent/tools/browser-automation-tool.d.ts +121 -0
- package/dist/src/agent/tools/browser-automation-tool.js +197 -0
- package/dist/src/agent/tools/clarify-tool.d.ts +17 -3
- package/dist/src/agent/tools/clarify-tool.js +27 -32
- package/dist/src/agent/tools/cli-clarify.js +23 -8
- package/dist/src/agent/tools/factory.d.ts +6 -9
- package/dist/src/agent/tools/factory.js +42 -59
- package/dist/src/agent/tools/index.d.ts +2 -2
- package/dist/src/agent/tools/index.js +3 -3
- package/dist/src/agent/tools/review-workspace.js +2 -2
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/oauth/xopc-cloud.js +3 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/automations/domain/defaults.js +1 -1
- package/dist/src/automations/domain/types.d.ts +5 -5
- package/dist/src/automations/domain/validation.d.ts +16 -16
- package/dist/src/automations/domain/validation.js +3 -3
- package/dist/src/automations/draft/automation-draft-validator.d.ts +4 -4
- package/dist/src/automations/draft/automation-draft-validator.js +1 -1
- package/dist/src/automations/service/action-executor.d.ts +1 -1
- package/dist/src/automations/service/action-executor.js +7 -7
- package/dist/src/browser/{recipes → automations}/index.d.ts +1 -0
- package/dist/src/browser/automations/index.js +4 -0
- package/dist/src/browser/automations/repository.d.ts +13 -0
- package/dist/src/browser/automations/repository.js +60 -0
- package/dist/src/browser/automations/runner.d.ts +17 -0
- package/dist/src/browser/automations/runner.js +173 -0
- package/dist/src/browser/automations/runtime-service.d.ts +6 -0
- package/dist/src/browser/automations/runtime-service.js +37 -0
- package/dist/src/browser/automations/schema.d.ts +144 -0
- package/dist/src/browser/automations/schema.js +135 -0
- package/dist/src/browser/automations/service.d.ts +146 -0
- package/dist/src/browser/automations/service.js +168 -0
- package/dist/src/browser/automations/types.d.ts +90 -0
- package/dist/src/browser/cache-dir-policy.d.ts +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -4
- package/dist/src/browser/drivers/browser-driver.d.ts +17 -0
- package/dist/src/browser/drivers/create-driver.d.ts +3 -0
- package/dist/src/browser/drivers/create-driver.js +84 -0
- package/dist/src/browser/drivers/extension-driver.d.ts +20 -0
- package/dist/src/browser/drivers/extension-driver.js +47 -0
- package/dist/src/browser/drivers/playwright-driver.d.ts +38 -0
- package/dist/src/browser/drivers/playwright-driver.js +406 -0
- package/dist/src/browser/index.d.ts +10 -15
- package/dist/src/browser/index.js +10 -15
- package/dist/src/browser/install-lock.d.ts +1 -2
- package/dist/src/browser/install-lock.js +3 -9
- package/dist/src/browser/install-progress.d.ts +1 -1
- package/dist/src/browser/observation/format.d.ts +2 -0
- package/dist/src/browser/observation/format.js +26 -0
- package/dist/src/browser/policy/approval-store.d.ts +17 -0
- package/dist/src/browser/policy/approval-store.js +62 -0
- package/dist/src/browser/policy/browser-policy.d.ts +3 -0
- package/dist/src/browser/policy/browser-policy.js +27 -0
- package/dist/src/browser/providers/browser-ext-install.d.ts +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +4 -6
- package/dist/src/browser/providers/browser-use.js +1 -1
- package/dist/src/browser/providers/browserbase.js +1 -1
- package/dist/src/browser/providers/extension-ws-acquire.d.ts +1 -4
- package/dist/src/browser/providers/extension-ws-acquire.js +1 -13
- package/dist/src/browser/providers/extension.d.ts +3 -22
- package/dist/src/browser/providers/extension.js +7 -15
- package/dist/src/browser/providers/index.d.ts +2 -2
- package/dist/src/browser/providers/index.js +3 -3
- package/dist/src/browser/providers/types.d.ts +0 -94
- package/dist/src/browser/readiness.d.ts +4 -22
- package/dist/src/browser/readiness.js +55 -118
- package/dist/src/browser/runtime/browser-runtime.d.ts +30 -0
- package/dist/src/browser/runtime/browser-runtime.js +362 -0
- package/dist/src/browser/url-policy.d.ts +3 -3
- package/dist/src/browser/url-policy.js +7 -6
- package/dist/src/browser/verification/expectation.d.ts +2 -0
- package/dist/src/browser/verification/expectation.js +17 -0
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-manifest.js +5 -1
- package/dist/src/cli/commands/browser-cli-helpers.d.ts +0 -6
- package/dist/src/cli/commands/browser-cli-helpers.js +11 -144
- package/dist/src/cli/commands/browser.d.ts +0 -5
- package/dist/src/cli/commands/browser.js +11 -152
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/node-version.js +25 -9
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/platform.d.ts +1 -0
- package/dist/src/cli/commands/platform.js +111 -0
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +10 -4
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +131 -84
- package/dist/src/config/schema.js +112 -59
- package/dist/src/connectors/composio-sessions.js +1 -3
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/extensions/marketplace.js +4 -0
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +5 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +5 -1
- package/dist/src/gateway/clarify-runtime.d.ts +7 -5
- package/dist/src/gateway/clarify-runtime.js +8 -11
- package/dist/src/gateway/ephemeral-clarification-waiter.d.ts +17 -0
- package/dist/src/gateway/ephemeral-clarification-waiter.js +46 -0
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +12 -26
- package/dist/src/gateway/hono/lib/config-payload.js +11 -40
- package/dist/src/gateway/hono/routes/agent-stream.js +44 -18
- package/dist/src/gateway/hono/routes/browser-automations.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-automations.js +77 -0
- package/dist/src/gateway/hono/routes/browser-install.js +0 -32
- package/dist/src/gateway/hono/routes/browser.d.ts +0 -17
- package/dist/src/gateway/hono/routes/browser.js +46 -568
- package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -1
- package/dist/src/gateway/hono/routes/config.js +0 -11
- package/dist/src/gateway/hono/routes/lazy-bundles.js +5 -5
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +10 -2
- package/dist/src/gateway/hono/routes/side-chats.js +24 -4
- package/dist/src/gateway/security/gateway-scopes.js +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +25 -36
- package/dist/src/gateway/service/agent-runner.js +103 -32
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +5 -2
- package/dist/src/gateway/service/session-input-coordinator.js +4 -1
- package/dist/src/gateway/service/sessions-api.js +1 -1
- package/dist/src/gateway/service.d.ts +8 -8
- package/dist/src/gateway/service.js +50 -37
- package/dist/src/gateway/side-chat/manager.d.ts +2 -1
- package/dist/src/gateway/side-chat/manager.js +5 -4
- package/dist/src/gateway/side-chat/run-service.d.ts +5 -1
- package/dist/src/gateway/side-chat/run-service.js +24 -23
- package/dist/src/gateway/side-chat/types.d.ts +3 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/platform/client.d.ts +121 -0
- package/dist/src/platform/client.js +108 -0
- package/dist/src/platform/contracts.d.ts +194 -0
- package/dist/src/platform/contracts.js +150 -0
- package/dist/src/platform/index.d.ts +4 -0
- package/dist/src/platform/index.js +9 -0
- package/dist/src/platform/resolution.d.ts +4 -0
- package/dist/src/platform/resolution.js +16 -0
- package/dist/src/platform/worker.d.ts +6 -0
- package/dist/src/platform/worker.js +75 -0
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/providers/xopc-cloud-config.js +3 -1
- package/dist/src/session/session-context-for-llm.js +41 -1
- package/dist/src/share/hosted-session-share.js +3 -1
- package/dist/src/share/share-thumbnail.js +1 -1
- package/dist/src/storage/sqlite/clarification-wait-repository.d.ts +41 -0
- package/dist/src/storage/sqlite/clarification-wait-repository.js +418 -0
- package/dist/src/storage/sqlite/index.d.ts +2 -1
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/migrations/153_browser_control_v2.sql +45 -0
- package/dist/src/storage/sqlite/migrations/154_session_clarification_waits.sql +60 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +16 -20
- package/dist/src/storage/sqlite/session-input-repository.d.ts +11 -6
- package/dist/src/tasks/home-query-service.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/tunnel/env.js +3 -1
- package/dist/src/voice/realtime/agentEngine.js +7 -2
- package/dist/src/voice/realtime/runtime.types.d.ts +5 -0
- package/dist/src/work-discovery/service.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +7 -7
- package/skills/creative/hatch-pet/SKILL.md +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-kILWelNb.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BnizTdgs.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CZRKqSqY.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-pN5LbChY.js +0 -8
- package/dist/gateway/static/root/assets/browser-workflow-inputs-BX1-uM9L.js +0 -1
- package/dist/gateway/static/root/assets/browser-workflows-page-C65MI57t.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CJw2e16J.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-CRgjb4Ck.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Dcpdy06y.js +0 -2
- package/dist/gateway/static/root/assets/gateway-config-api-e3BRcgDx.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-Cheo0Rkc.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DVrTRqNc.js +0 -1
- package/dist/gateway/static/root/assets/index-B7CX4Qob.css +0 -2
- package/dist/gateway/static/root/assets/index-BHrpyJ4t.js +0 -72
- package/dist/gateway/static/root/assets/markdown-view-CQvzsE24.js +0 -201
- package/dist/gateway/static/root/assets/messages-Cf5hpZE6.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-CUd8O4K7.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-BLQwd39W.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-NttW338u.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BzH8pjEz.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BxpjSDnL.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BLMaibOb.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BRvvKhoH.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DTOsxQC1.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BWYanBlQ.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-B_-SNat-.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CNOT2Coo.js +0 -5
- package/dist/src/agent/tools/browser-recipe-tool.d.ts +0 -12
- package/dist/src/agent/tools/browser-recipe-tool.js +0 -113
- package/dist/src/browser/actions/extension-registry-bridge.d.ts +0 -5
- package/dist/src/browser/actions/extension-registry-bridge.js +0 -312
- package/dist/src/browser/actions/registry.d.ts +0 -5
- package/dist/src/browser/actions/registry.js +0 -741
- package/dist/src/browser/actions/types.d.ts +0 -65
- package/dist/src/browser/backend-from-config.d.ts +0 -22
- package/dist/src/browser/backend-from-config.js +0 -99
- package/dist/src/browser/browser-command-timeout.d.ts +0 -2
- package/dist/src/browser/browser-command-timeout.js +0 -11
- package/dist/src/browser/cdp-local-launcher.d.ts +0 -35
- package/dist/src/browser/cdp-local-launcher.js +0 -154
- package/dist/src/browser/cdp-supervisor.d.ts +0 -58
- package/dist/src/browser/cdp-supervisor.js +0 -133
- package/dist/src/browser/humanize.d.ts +0 -80
- package/dist/src/browser/humanize.js +0 -363
- package/dist/src/browser/manager.d.ts +0 -50
- package/dist/src/browser/manager.js +0 -251
- package/dist/src/browser/pipeline/output.d.ts +0 -35
- package/dist/src/browser/pipeline/output.js +0 -74
- package/dist/src/browser/pipeline/runner.d.ts +0 -27
- package/dist/src/browser/pipeline/runner.js +0 -453
- package/dist/src/browser/pipeline/schema.d.ts +0 -42
- package/dist/src/browser/pipeline/schema.js +0 -116
- package/dist/src/browser/pipeline/template.d.ts +0 -30
- package/dist/src/browser/pipeline/template.js +0 -112
- package/dist/src/browser/providers/cloakbrowser.d.ts +0 -83
- package/dist/src/browser/providers/cloakbrowser.js +0 -612
- package/dist/src/browser/recipes/index.js +0 -3
- package/dist/src/browser/recipes/repository.d.ts +0 -13
- package/dist/src/browser/recipes/repository.js +0 -81
- package/dist/src/browser/recipes/runtime-service.d.ts +0 -6
- package/dist/src/browser/recipes/runtime-service.js +0 -30
- package/dist/src/browser/recipes/service.d.ts +0 -36
- package/dist/src/browser/recipes/service.js +0 -186
- package/dist/src/browser/recipes/types.d.ts +0 -36
- package/dist/src/browser/schemas.d.ts +0 -53
- package/dist/src/browser/schemas.js +0 -68
- package/dist/src/browser/session-lifecycle.d.ts +0 -40
- package/dist/src/browser/session-lifecycle.js +0 -136
- package/dist/src/browser/snapshot-helpers.d.ts +0 -24
- package/dist/src/browser/snapshot-helpers.js +0 -70
- package/dist/src/browser/stealth.d.ts +0 -46
- package/dist/src/browser/stealth.js +0 -163
- package/dist/src/gateway/clarify-bridge.d.ts +0 -46
- package/dist/src/gateway/clarify-bridge.js +0 -111
- package/dist/src/gateway/hono/routes/browser-workflows.d.ts +0 -3
- package/dist/src/gateway/hono/routes/browser-workflows.js +0 -78
- /package/dist/src/browser/{actions → automations}/types.js +0 -0
- /package/dist/src/browser/{recipes/types.js → drivers/browser-driver.js} +0 -0
|
@@ -1,741 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { checkWebsiteBlocklist } from "../../agent/tools/url-safety.js";
|
|
4
|
-
import { resolveBrowserCommandTimeoutMs } from "../browser-command-timeout.js";
|
|
5
|
-
import { assertBrowserUrlAllowed, checkPostRedirectUrl, containsApiKeyPattern } from "../url-policy.js";
|
|
6
|
-
import { truncateSnapshotAtBoundary } from "../snapshot-helpers.js";
|
|
7
|
-
import { humanizedClick, humanizedFill, humanizedScroll } from "../humanize.js";
|
|
8
|
-
import { isTruthyValue, resolvePath, valueContains } from "../pipeline/template.js";
|
|
9
|
-
//#region src/browser/actions/registry.ts
|
|
10
|
-
init_logger();
|
|
11
|
-
const log = createLogger("BrowserActionRegistry");
|
|
12
|
-
const DEFAULT_SNAPSHOT_MAX = 3e4;
|
|
13
|
-
const AUTO_SNAPSHOT_MAX = 8e3;
|
|
14
|
-
const networkMonitors = /* @__PURE__ */ new WeakMap();
|
|
15
|
-
function toMs(ctx) {
|
|
16
|
-
return resolveBrowserCommandTimeoutMs(ctx.config);
|
|
17
|
-
}
|
|
18
|
-
/** Whether humanize mode is active for this context (local/cdp/cloakbrowser only). */
|
|
19
|
-
function isHumanizeEnabled(_ctx) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
function humanPreset(_ctx) {
|
|
23
|
-
return "default";
|
|
24
|
-
}
|
|
25
|
-
async function ariaSnapshot(page, selector, maxLength, timeoutMs) {
|
|
26
|
-
const loc = selector?.trim() ? page.locator(selector.trim()).first() : page.locator("body");
|
|
27
|
-
await loc.waitFor({
|
|
28
|
-
state: "attached",
|
|
29
|
-
timeout: timeoutMs
|
|
30
|
-
});
|
|
31
|
-
let text = await loc.ariaSnapshot({
|
|
32
|
-
mode: "ai",
|
|
33
|
-
timeout: timeoutMs
|
|
34
|
-
});
|
|
35
|
-
if (!text || !text.trim()) text = "(empty snapshot)";
|
|
36
|
-
if (text.length > maxLength) text = truncateSnapshotAtBoundary(text, maxLength);
|
|
37
|
-
return text;
|
|
38
|
-
}
|
|
39
|
-
function resolveClickLocator(page, args) {
|
|
40
|
-
const selector = args.selector;
|
|
41
|
-
const text = args.text;
|
|
42
|
-
const role = args.role;
|
|
43
|
-
const hasSel = Boolean(selector?.trim());
|
|
44
|
-
const hasText = Boolean(text?.trim());
|
|
45
|
-
const hasRole = Boolean(role?.trim());
|
|
46
|
-
if ((hasSel ? 1 : 0) + (hasText ? 1 : 0) + (hasRole ? 1 : 0) !== 1) throw new Error("Provide exactly one of: selector, text, role");
|
|
47
|
-
if (hasSel) return page.locator(selector.trim()).first();
|
|
48
|
-
if (hasText) return page.getByText(text.trim(), { exact: false }).first();
|
|
49
|
-
const raw = role.trim();
|
|
50
|
-
const idx = raw.indexOf(":");
|
|
51
|
-
const roleName = (idx >= 0 ? raw.slice(0, idx) : raw).trim();
|
|
52
|
-
const name = idx >= 0 ? raw.slice(idx + 1).trim() : "";
|
|
53
|
-
if (!roleName) throw new Error("Invalid role: empty ARIA role");
|
|
54
|
-
return page.getByRole(roleName, name ? { name } : void 0).first();
|
|
55
|
-
}
|
|
56
|
-
function resolveTypeLocator(page, args) {
|
|
57
|
-
const selector = args.selector;
|
|
58
|
-
const label = args.label;
|
|
59
|
-
const hasSel = Boolean(selector?.trim());
|
|
60
|
-
if (hasSel === Boolean(label?.trim())) throw new Error("Provide exactly one of: selector, label");
|
|
61
|
-
if (hasSel) return page.locator(selector.trim()).first();
|
|
62
|
-
return page.getByLabel(label.trim()).first();
|
|
63
|
-
}
|
|
64
|
-
function ok(action, text, data, artifacts) {
|
|
65
|
-
return {
|
|
66
|
-
ok: true,
|
|
67
|
-
action,
|
|
68
|
-
text,
|
|
69
|
-
data,
|
|
70
|
-
artifacts
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function fail(action, code, message, diagnostics) {
|
|
74
|
-
return {
|
|
75
|
-
ok: false,
|
|
76
|
-
action,
|
|
77
|
-
error: {
|
|
78
|
-
code,
|
|
79
|
-
message
|
|
80
|
-
},
|
|
81
|
-
diagnostics
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function asObject(value) {
|
|
85
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
86
|
-
}
|
|
87
|
-
function pipelineLast(ctx) {
|
|
88
|
-
return ctx.pipeline?.last;
|
|
89
|
-
}
|
|
90
|
-
function valueFromArgs(ctx, args) {
|
|
91
|
-
if ("value" in args) return args.value;
|
|
92
|
-
if (typeof args.path === "string") return resolvePath(pipelineLast(ctx), args.path);
|
|
93
|
-
return pipelineLast(ctx);
|
|
94
|
-
}
|
|
95
|
-
function compareValues(a, b) {
|
|
96
|
-
const av = typeof a === "number" ? a : String(a ?? "");
|
|
97
|
-
const bv = typeof b === "number" ? b : String(b ?? "");
|
|
98
|
-
if (av < bv) return -1;
|
|
99
|
-
if (av > bv) return 1;
|
|
100
|
-
return 0;
|
|
101
|
-
}
|
|
102
|
-
function matchesNetworkPattern(url, pattern) {
|
|
103
|
-
if (!pattern) return true;
|
|
104
|
-
return url.includes(pattern);
|
|
105
|
-
}
|
|
106
|
-
const navigateAction = async (ctx, args) => {
|
|
107
|
-
const url = String(args.url ?? "");
|
|
108
|
-
if (!url) return fail("navigate", "MISSING_URL", "url is required");
|
|
109
|
-
const allowPrivate = false;
|
|
110
|
-
if (containsApiKeyPattern(url)) return fail("navigate", "BLOCKED", "URL contains API key/token");
|
|
111
|
-
const block = checkWebsiteBlocklist(url, ctx.config?.tools?.web?.blocklist);
|
|
112
|
-
if (block) return fail("navigate", "BLOCKED", block.message);
|
|
113
|
-
assertBrowserUrlAllowed(url, { allowPrivateUrls: allowPrivate });
|
|
114
|
-
const waitUntil = args.wait_until ?? args.waitFor ?? "domcontentloaded";
|
|
115
|
-
const navTimeout = toMs(ctx);
|
|
116
|
-
await ctx.page.goto(url, {
|
|
117
|
-
waitUntil,
|
|
118
|
-
timeout: navTimeout
|
|
119
|
-
});
|
|
120
|
-
const title = await ctx.page.title();
|
|
121
|
-
const finalUrl = ctx.page.url();
|
|
122
|
-
if (finalUrl && finalUrl !== url) {
|
|
123
|
-
const redirectBlock = checkPostRedirectUrl(finalUrl, { allowPrivateUrls: allowPrivate });
|
|
124
|
-
if (redirectBlock) {
|
|
125
|
-
await ctx.page.goto("about:blank").catch(() => {});
|
|
126
|
-
return fail("navigate", "REDIRECT_BLOCKED", redirectBlock);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
let snapshot = "";
|
|
130
|
-
try {
|
|
131
|
-
snapshot = await ariaSnapshot(ctx.page, void 0, AUTO_SNAPSHOT_MAX, navTimeout);
|
|
132
|
-
} catch {}
|
|
133
|
-
return ok("navigate", `Navigated to: ${title}\nURL: ${finalUrl}${snapshot ? `\n--- Page Snapshot ---\n${snapshot}` : ""}`, {
|
|
134
|
-
url: finalUrl,
|
|
135
|
-
title
|
|
136
|
-
});
|
|
137
|
-
};
|
|
138
|
-
const stateAction = async (ctx, args) => {
|
|
139
|
-
const maxLen = typeof args.maxLength === "number" ? args.maxLength : DEFAULT_SNAPSHOT_MAX;
|
|
140
|
-
const selector = args.selector;
|
|
141
|
-
const timeout = toMs(ctx);
|
|
142
|
-
try {
|
|
143
|
-
const text = await ariaSnapshot(ctx.page, selector, maxLen, timeout);
|
|
144
|
-
return ok("state", text, { length: text.length });
|
|
145
|
-
} catch (e) {
|
|
146
|
-
return fail("state", "SNAPSHOT_FAILED", e instanceof Error ? e.message : String(e));
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
const clickAction = async (ctx, args) => {
|
|
150
|
-
const timeout = toMs(ctx);
|
|
151
|
-
try {
|
|
152
|
-
if (isHumanizeEnabled(ctx) && args.selector) {
|
|
153
|
-
await humanizedClick(ctx.page, String(args.selector), humanPreset(ctx));
|
|
154
|
-
return ok("click", "Click succeeded (humanized).");
|
|
155
|
-
}
|
|
156
|
-
await resolveClickLocator(ctx.page, args).click({ timeout });
|
|
157
|
-
return ok("click", "Click succeeded.");
|
|
158
|
-
} catch (e) {
|
|
159
|
-
return fail("click", "CLICK_FAILED", e instanceof Error ? e.message : String(e));
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
const typeAction = async (ctx, args) => {
|
|
163
|
-
const timeout = toMs(ctx);
|
|
164
|
-
try {
|
|
165
|
-
if (isHumanizeEnabled(ctx) && args.selector) {
|
|
166
|
-
await humanizedFill(ctx.page, String(args.selector), String(args.text ?? ""), humanPreset(ctx));
|
|
167
|
-
if (args.pressEnter) await ctx.page.keyboard.press("Enter");
|
|
168
|
-
return ok("type", "Typed into field (humanized).");
|
|
169
|
-
}
|
|
170
|
-
const loc = resolveTypeLocator(ctx.page, args);
|
|
171
|
-
await loc.clear({ timeout: Math.min(5e3, timeout) }).catch(() => {});
|
|
172
|
-
await loc.fill(String(args.text ?? ""), { timeout });
|
|
173
|
-
if (args.pressEnter) await ctx.page.keyboard.press("Enter");
|
|
174
|
-
return ok("type", "Typed into field.");
|
|
175
|
-
} catch (e) {
|
|
176
|
-
return fail("type", "TYPE_FAILED", e instanceof Error ? e.message : String(e));
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
const scrollAction = async (ctx, args) => {
|
|
180
|
-
const direction = args.direction ?? "down";
|
|
181
|
-
const amount = typeof args.amount === "number" ? args.amount : 500;
|
|
182
|
-
const dy = direction === "down" ? amount : -amount;
|
|
183
|
-
try {
|
|
184
|
-
if (isHumanizeEnabled(ctx)) {
|
|
185
|
-
await humanizedScroll(ctx.page, dy, humanPreset(ctx));
|
|
186
|
-
return ok("scroll", `Scrolled ${direction} by ${amount}px (humanized).`);
|
|
187
|
-
}
|
|
188
|
-
await ctx.page.evaluate(({ deltaY }) => {
|
|
189
|
-
globalThis.scrollBy(0, deltaY);
|
|
190
|
-
}, { deltaY: dy });
|
|
191
|
-
return ok("scroll", `Scrolled ${direction} by ${amount}px.`);
|
|
192
|
-
} catch (e) {
|
|
193
|
-
return fail("scroll", "SCROLL_FAILED", e instanceof Error ? e.message : String(e));
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
const screenshotAction = async (ctx, args) => {
|
|
197
|
-
const timeout = toMs(ctx);
|
|
198
|
-
const selector = args.selector;
|
|
199
|
-
const fullPage = args.full_page === true || args.fullPage === true;
|
|
200
|
-
const path = args.path;
|
|
201
|
-
try {
|
|
202
|
-
let buf;
|
|
203
|
-
if (selector?.trim()) {
|
|
204
|
-
const loc = ctx.page.locator(selector.trim()).first();
|
|
205
|
-
await loc.waitFor({
|
|
206
|
-
state: "visible",
|
|
207
|
-
timeout
|
|
208
|
-
});
|
|
209
|
-
buf = await loc.screenshot({
|
|
210
|
-
type: "png",
|
|
211
|
-
timeout
|
|
212
|
-
});
|
|
213
|
-
} else buf = await ctx.page.screenshot({
|
|
214
|
-
type: "png",
|
|
215
|
-
fullPage,
|
|
216
|
-
timeout
|
|
217
|
-
});
|
|
218
|
-
const artifact = {
|
|
219
|
-
type: "screenshot",
|
|
220
|
-
path,
|
|
221
|
-
data: buf.toString("base64"),
|
|
222
|
-
mimeType: "image/png"
|
|
223
|
-
};
|
|
224
|
-
return ok("screenshot", `Screenshot captured (${buf.length} bytes).`, { bytes: buf.length }, [artifact]);
|
|
225
|
-
} catch (e) {
|
|
226
|
-
return fail("screenshot", "SCREENSHOT_FAILED", e instanceof Error ? e.message : String(e));
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
const backAction = async (ctx, args) => {
|
|
230
|
-
const waitUntil = args.waitFor ?? "domcontentloaded";
|
|
231
|
-
const timeout = toMs(ctx);
|
|
232
|
-
try {
|
|
233
|
-
if (!await ctx.page.goBack({
|
|
234
|
-
waitUntil,
|
|
235
|
-
timeout
|
|
236
|
-
})) return fail("back", "NO_HISTORY", "No previous page in history.");
|
|
237
|
-
const title = await ctx.page.title();
|
|
238
|
-
const url = ctx.page.url();
|
|
239
|
-
return ok("back", `Navigated back to: ${title}\nURL: ${url}`, {
|
|
240
|
-
url,
|
|
241
|
-
title
|
|
242
|
-
});
|
|
243
|
-
} catch (e) {
|
|
244
|
-
return fail("back", "BACK_FAILED", e instanceof Error ? e.message : String(e));
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
const pressAction = async (ctx, args) => {
|
|
248
|
-
const key = String(args.key ?? "");
|
|
249
|
-
if (!key) return fail("press", "MISSING_KEY", "key is required");
|
|
250
|
-
try {
|
|
251
|
-
await ctx.page.keyboard.press(key);
|
|
252
|
-
return ok("press", `Pressed key: ${key}`);
|
|
253
|
-
} catch (e) {
|
|
254
|
-
return fail("press", "PRESS_FAILED", e instanceof Error ? e.message : String(e));
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
const evalAction = async (ctx, args) => {
|
|
258
|
-
const js = args.javascript ?? args.expression ?? args.code ?? "";
|
|
259
|
-
if (!js.trim()) return fail("eval", "MISSING_JS", "javascript expression is required");
|
|
260
|
-
try {
|
|
261
|
-
const result = await ctx.page.evaluate(js);
|
|
262
|
-
const serialized = result === void 0 ? "undefined" : JSON.stringify(result, null, 2);
|
|
263
|
-
return ok("eval", serialized.length > DEFAULT_SNAPSHOT_MAX ? `${serialized.slice(0, DEFAULT_SNAPSHOT_MAX)}\n... (truncated)` : serialized, result);
|
|
264
|
-
} catch (e) {
|
|
265
|
-
return fail("eval", "EVAL_FAILED", e instanceof Error ? e.message : String(e));
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
const imagesAction = async (ctx, args) => {
|
|
269
|
-
const selector = args.selector;
|
|
270
|
-
const maxImages = typeof args.maxImages === "number" ? args.maxImages : 20;
|
|
271
|
-
try {
|
|
272
|
-
const images = await ctx.page.evaluate(([sel, max]) => {
|
|
273
|
-
const d = globalThis.document;
|
|
274
|
-
const root = sel ? d.querySelector(sel) : d;
|
|
275
|
-
if (!root) return [];
|
|
276
|
-
return Array.from(root.querySelectorAll("img")).slice(0, max).map((img) => ({
|
|
277
|
-
src: String(img.src ?? ""),
|
|
278
|
-
alt: String(img.alt ?? ""),
|
|
279
|
-
width: Number(img.naturalWidth ?? 0),
|
|
280
|
-
height: Number(img.naturalHeight ?? 0)
|
|
281
|
-
}));
|
|
282
|
-
}, [selector?.trim() || null, maxImages]);
|
|
283
|
-
if (!images || images.length === 0) return ok("images", "No images found on the page.", []);
|
|
284
|
-
const lines = images.map((img, i) => `${i + 1}. ${img.alt || "(no alt)"} — ${img.width}×${img.height}\n ${img.src}`);
|
|
285
|
-
return ok("images", `Found ${images.length} image(s):\n${lines.join("\n")}`, images);
|
|
286
|
-
} catch (e) {
|
|
287
|
-
return fail("images", "IMAGES_FAILED", e instanceof Error ? e.message : String(e));
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
const closeAction = async (ctx, _args) => {
|
|
291
|
-
await ctx.manager.closePage(ctx.taskId);
|
|
292
|
-
return ok("close", "Browser page closed.");
|
|
293
|
-
};
|
|
294
|
-
const dialogAction = async (ctx, args) => {
|
|
295
|
-
const action = args.action;
|
|
296
|
-
if (action !== "accept" && action !== "dismiss") return fail("dialog", "INVALID_ACTION", "action must be \"accept\" or \"dismiss\"");
|
|
297
|
-
if (!ctx.supervisor) return fail("dialog", "NO_SUPERVISOR", "No dialog supervisor available");
|
|
298
|
-
return ok("dialog", `Dialog ${action}ed.`);
|
|
299
|
-
};
|
|
300
|
-
const waitAction = async (ctx, args) => {
|
|
301
|
-
const selector = args.selector;
|
|
302
|
-
const text = args.text;
|
|
303
|
-
const state = args.state ?? "visible";
|
|
304
|
-
const timeoutMs = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
|
|
305
|
-
try {
|
|
306
|
-
if (selector?.trim()) await ctx.page.locator(selector.trim()).first().waitFor({
|
|
307
|
-
state,
|
|
308
|
-
timeout: timeoutMs
|
|
309
|
-
});
|
|
310
|
-
else if (text?.trim()) await ctx.page.getByText(text.trim()).first().waitFor({
|
|
311
|
-
state: "visible",
|
|
312
|
-
timeout: timeoutMs
|
|
313
|
-
});
|
|
314
|
-
else if (args.function || args.expression) await ctx.page.waitForFunction(String(args.function ?? args.expression), null, { timeout: timeoutMs });
|
|
315
|
-
else {
|
|
316
|
-
const ms = typeof args.ms === "number" ? args.ms : 1e3;
|
|
317
|
-
await ctx.page.waitForTimeout(ms);
|
|
318
|
-
}
|
|
319
|
-
return ok("wait", "Wait completed.");
|
|
320
|
-
} catch (e) {
|
|
321
|
-
return fail("wait", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
const outputAction = async (ctx, args) => {
|
|
325
|
-
return ok("output", "Output captured.", valueFromArgs(ctx, args));
|
|
326
|
-
};
|
|
327
|
-
const assertAction = async (ctx, args) => {
|
|
328
|
-
const actual = valueFromArgs(ctx, args);
|
|
329
|
-
if ("equals" in args && JSON.stringify(actual) !== JSON.stringify(args.equals)) return fail("assert", "ASSERTION_FAILED", `Expected value to equal ${JSON.stringify(args.equals)}, got ${JSON.stringify(actual)?.slice(0, 500)}`);
|
|
330
|
-
if ("contains" in args && !valueContains(actual, args.contains)) return fail("assert", "ASSERTION_FAILED", `Expected value to contain ${JSON.stringify(args.contains)}`);
|
|
331
|
-
if ("matches" in args) {
|
|
332
|
-
const pattern = new RegExp(String(args.matches));
|
|
333
|
-
if (!pattern.test(String(actual ?? ""))) return fail("assert", "ASSERTION_FAILED", `Expected value to match /${pattern.source}/`);
|
|
334
|
-
}
|
|
335
|
-
if (args.truthy === true && !isTruthyValue(actual)) return fail("assert", "ASSERTION_FAILED", `Expected value to be truthy, got ${JSON.stringify(actual)}`);
|
|
336
|
-
if (args.exists === true && (actual === void 0 || actual === null || actual === "")) return fail("assert", "ASSERTION_FAILED", "Expected value to exist");
|
|
337
|
-
return ok("assert", "Assertion passed.");
|
|
338
|
-
};
|
|
339
|
-
const waitForNavigationAction = async (ctx, args) => {
|
|
340
|
-
const timeout = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
|
|
341
|
-
const waitUntil = args.wait_until ?? "domcontentloaded";
|
|
342
|
-
try {
|
|
343
|
-
await ctx.page.waitForLoadState(waitUntil, { timeout });
|
|
344
|
-
return ok("wait_for_navigation", "Navigation wait completed.");
|
|
345
|
-
} catch (e) {
|
|
346
|
-
return fail("wait_for_navigation", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
const waitForTimeoutAction = async (ctx, args) => {
|
|
350
|
-
const ms = Number(args.ms ?? args.timeout_ms ?? 1e3);
|
|
351
|
-
await ctx.page.waitForTimeout(Number.isFinite(ms) ? ms : 1e3);
|
|
352
|
-
return ok("wait_for_timeout", `Waited ${ms}ms.`);
|
|
353
|
-
};
|
|
354
|
-
const waitForFunctionAction = async (ctx, args) => {
|
|
355
|
-
const expression = String(args.expression ?? args.function ?? "");
|
|
356
|
-
if (!expression.trim()) return fail("wait_for_function", "MISSING_EXPRESSION", "expression is required");
|
|
357
|
-
const timeout = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
|
|
358
|
-
try {
|
|
359
|
-
await ctx.page.waitForFunction(expression, null, { timeout });
|
|
360
|
-
return ok("wait_for_function", "Function wait completed.");
|
|
361
|
-
} catch (e) {
|
|
362
|
-
return fail("wait_for_function", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
const waitForNetworkIdleAction = async (ctx, args) => {
|
|
366
|
-
const timeout = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
|
|
367
|
-
try {
|
|
368
|
-
await ctx.page.waitForLoadState("networkidle", { timeout });
|
|
369
|
-
return ok("wait_for_network_idle", "Network idle reached.");
|
|
370
|
-
} catch (e) {
|
|
371
|
-
return fail("wait_for_network_idle", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
|
-
const elementTextAction = async (ctx, args) => {
|
|
375
|
-
const selector = String(args.selector ?? "");
|
|
376
|
-
if (!selector) return fail("element_text", "MISSING_SELECTOR", "selector is required");
|
|
377
|
-
const timeout = toMs(ctx);
|
|
378
|
-
const loc = ctx.page.locator(selector).first();
|
|
379
|
-
await loc.waitFor({
|
|
380
|
-
state: "attached",
|
|
381
|
-
timeout
|
|
382
|
-
});
|
|
383
|
-
const text = await loc.innerText({ timeout }).catch(() => loc.textContent({ timeout }));
|
|
384
|
-
return ok("element_text", String(text ?? ""), text ?? "");
|
|
385
|
-
};
|
|
386
|
-
const elementAttributeAction = async (ctx, args) => {
|
|
387
|
-
const selector = String(args.selector ?? "");
|
|
388
|
-
const attribute = String(args.attribute ?? "");
|
|
389
|
-
if (!selector || !attribute) return fail("element_attribute", "INVALID_ARGS", "selector and attribute are required");
|
|
390
|
-
const timeout = toMs(ctx);
|
|
391
|
-
const loc = ctx.page.locator(selector).first();
|
|
392
|
-
await loc.waitFor({
|
|
393
|
-
state: "attached",
|
|
394
|
-
timeout
|
|
395
|
-
});
|
|
396
|
-
const value = await loc.getAttribute(attribute, { timeout });
|
|
397
|
-
return ok("element_attribute", value ?? "", value);
|
|
398
|
-
};
|
|
399
|
-
const boundingBoxAction = async (ctx, args) => {
|
|
400
|
-
const selector = String(args.selector ?? "");
|
|
401
|
-
if (!selector) return fail("bounding_box", "MISSING_SELECTOR", "selector is required");
|
|
402
|
-
const timeout = toMs(ctx);
|
|
403
|
-
const loc = ctx.page.locator(selector).first();
|
|
404
|
-
await loc.waitFor({
|
|
405
|
-
state: "visible",
|
|
406
|
-
timeout
|
|
407
|
-
});
|
|
408
|
-
const box = await loc.boundingBox({ timeout });
|
|
409
|
-
return ok("bounding_box", JSON.stringify(box), box);
|
|
410
|
-
};
|
|
411
|
-
const setInputFilesAction = async (ctx, args) => {
|
|
412
|
-
const selector = String(args.selector ?? "");
|
|
413
|
-
const files = Array.isArray(args.files) ? args.files.map(String) : typeof args.file === "string" ? [args.file] : [];
|
|
414
|
-
if (!selector || files.length === 0) return fail("set_input_files", "INVALID_ARGS", "selector and files are required");
|
|
415
|
-
await ctx.page.locator(selector).first().setInputFiles(files, { timeout: toMs(ctx) });
|
|
416
|
-
return ok("set_input_files", `Attached ${files.length} file(s).`, { files });
|
|
417
|
-
};
|
|
418
|
-
const getCookiesAction = async (ctx, args) => {
|
|
419
|
-
const urls = Array.isArray(args.urls) ? args.urls.map(String) : void 0;
|
|
420
|
-
const cookies = await ctx.page.context().cookies(urls);
|
|
421
|
-
return ok("cookies", JSON.stringify(cookies, null, 2), cookies);
|
|
422
|
-
};
|
|
423
|
-
const addCookiesAction = async (ctx, args) => {
|
|
424
|
-
const cookies = Array.isArray(args.cookies) ? args.cookies : [];
|
|
425
|
-
if (cookies.length === 0) return fail("add_cookies", "INVALID_ARGS", "cookies must be a non-empty array");
|
|
426
|
-
await ctx.page.context().addCookies(cookies);
|
|
427
|
-
return ok("add_cookies", `Added ${cookies.length} cookie(s).`);
|
|
428
|
-
};
|
|
429
|
-
const clearCookiesAction = async (ctx) => {
|
|
430
|
-
await ctx.page.context().clearCookies();
|
|
431
|
-
return ok("clear_cookies", "Cookies cleared.");
|
|
432
|
-
};
|
|
433
|
-
const listTabsAction = async (ctx) => {
|
|
434
|
-
const pages = ctx.page.context().pages();
|
|
435
|
-
const tabs = await Promise.all(pages.map(async (page, index) => ({
|
|
436
|
-
index,
|
|
437
|
-
url: page.url(),
|
|
438
|
-
title: await page.title().catch(() => "")
|
|
439
|
-
})));
|
|
440
|
-
return ok("tabs", JSON.stringify(tabs, null, 2), tabs);
|
|
441
|
-
};
|
|
442
|
-
const newTabAction = async (ctx, args) => {
|
|
443
|
-
const page = await ctx.page.context().newPage();
|
|
444
|
-
if (args.url) await page.goto(String(args.url), {
|
|
445
|
-
waitUntil: "domcontentloaded",
|
|
446
|
-
timeout: toMs(ctx)
|
|
447
|
-
});
|
|
448
|
-
return ok("new_tab", `Opened tab: ${page.url()}`, {
|
|
449
|
-
url: page.url(),
|
|
450
|
-
title: await page.title().catch(() => "")
|
|
451
|
-
});
|
|
452
|
-
};
|
|
453
|
-
const switchTabAction = async (ctx, args) => {
|
|
454
|
-
const index = Number(args.index ?? args.tab_index ?? 0);
|
|
455
|
-
const page = ctx.page.context().pages()[index];
|
|
456
|
-
if (!page) return fail("switch_tab", "TAB_NOT_FOUND", `No tab at index ${index}`);
|
|
457
|
-
await page.bringToFront();
|
|
458
|
-
return ok("switch_tab", `Switched to tab ${index}.`, {
|
|
459
|
-
index,
|
|
460
|
-
url: page.url()
|
|
461
|
-
});
|
|
462
|
-
};
|
|
463
|
-
const selectAction = async (ctx, args) => {
|
|
464
|
-
const source = "from" in args ? args.from : pipelineLast(ctx);
|
|
465
|
-
const path = String(args.path ?? args.value ?? "");
|
|
466
|
-
const value = path ? resolvePath(source, path) : source;
|
|
467
|
-
return ok("select", typeof value === "string" ? value : JSON.stringify(value, null, 2), value);
|
|
468
|
-
};
|
|
469
|
-
const mapAction = async (ctx, args) => {
|
|
470
|
-
const source = "from" in args ? args.from : pipelineLast(ctx);
|
|
471
|
-
if (!Array.isArray(source)) return fail("map", "INVALID_INPUT", "map input must be an array");
|
|
472
|
-
const path = String(args.path ?? "");
|
|
473
|
-
const result = path ? source.map((item) => resolvePath(item, path)) : source;
|
|
474
|
-
return ok("map", JSON.stringify(result, null, 2), result);
|
|
475
|
-
};
|
|
476
|
-
const filterAction = async (ctx, args) => {
|
|
477
|
-
const source = "from" in args ? args.from : pipelineLast(ctx);
|
|
478
|
-
if (!Array.isArray(source)) return fail("filter", "INVALID_INPUT", "filter input must be an array");
|
|
479
|
-
const path = String(args.path ?? "");
|
|
480
|
-
const equals = args.equals;
|
|
481
|
-
const contains = args.contains;
|
|
482
|
-
const truthy = args.truthy === true;
|
|
483
|
-
const result = source.filter((item) => {
|
|
484
|
-
const value = path ? resolvePath(item, path) : item;
|
|
485
|
-
if ("equals" in args) return JSON.stringify(value) === JSON.stringify(equals);
|
|
486
|
-
if ("contains" in args) return valueContains(value, contains);
|
|
487
|
-
if (truthy) return isTruthyValue(value);
|
|
488
|
-
return isTruthyValue(value);
|
|
489
|
-
});
|
|
490
|
-
return ok("filter", JSON.stringify(result, null, 2), result);
|
|
491
|
-
};
|
|
492
|
-
const sortAction = async (ctx, args) => {
|
|
493
|
-
const source = "from" in args ? args.from : pipelineLast(ctx);
|
|
494
|
-
if (!Array.isArray(source)) return fail("sort", "INVALID_INPUT", "sort input must be an array");
|
|
495
|
-
const path = String(args.path ?? "");
|
|
496
|
-
const direction = String(args.direction ?? "asc");
|
|
497
|
-
const result = [...source].sort((a, b) => {
|
|
498
|
-
const cmp = compareValues(path ? resolvePath(a, path) : a, path ? resolvePath(b, path) : b);
|
|
499
|
-
return direction === "desc" ? -cmp : cmp;
|
|
500
|
-
});
|
|
501
|
-
return ok("sort", JSON.stringify(result, null, 2), result);
|
|
502
|
-
};
|
|
503
|
-
const limitAction = async (ctx, args) => {
|
|
504
|
-
const source = "from" in args ? args.from : pipelineLast(ctx);
|
|
505
|
-
if (!Array.isArray(source)) return fail("limit", "INVALID_INPUT", "limit input must be an array");
|
|
506
|
-
const count = Math.max(0, Number(args.count ?? args.limit ?? 10));
|
|
507
|
-
const offset = Math.max(0, Number(args.offset ?? 0));
|
|
508
|
-
const result = source.slice(offset, offset + count);
|
|
509
|
-
return ok("limit", JSON.stringify(result, null, 2), result);
|
|
510
|
-
};
|
|
511
|
-
const fetchAction = async (ctx, args) => {
|
|
512
|
-
const url = String(args.url ?? "");
|
|
513
|
-
if (!url) return fail("fetch", "MISSING_URL", "url is required");
|
|
514
|
-
const method = String(args.method ?? "GET");
|
|
515
|
-
const headers = asObject(args.headers);
|
|
516
|
-
const body = args.body === void 0 ? void 0 : typeof args.body === "string" ? args.body : JSON.stringify(args.body);
|
|
517
|
-
const result = await ctx.page.evaluate(async ({ url, method, headers, body }) => {
|
|
518
|
-
const response = await fetch(url, {
|
|
519
|
-
method,
|
|
520
|
-
headers,
|
|
521
|
-
body
|
|
522
|
-
});
|
|
523
|
-
const text = await response.text();
|
|
524
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
525
|
-
let parsed = text;
|
|
526
|
-
if (contentType.includes("application/json")) try {
|
|
527
|
-
parsed = JSON.parse(text);
|
|
528
|
-
} catch {
|
|
529
|
-
parsed = text;
|
|
530
|
-
}
|
|
531
|
-
return {
|
|
532
|
-
ok: response.ok,
|
|
533
|
-
status: response.status,
|
|
534
|
-
url: response.url,
|
|
535
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
536
|
-
body: parsed
|
|
537
|
-
};
|
|
538
|
-
}, {
|
|
539
|
-
url,
|
|
540
|
-
method,
|
|
541
|
-
headers,
|
|
542
|
-
body
|
|
543
|
-
});
|
|
544
|
-
return ok("fetch", JSON.stringify(result, null, 2), result);
|
|
545
|
-
};
|
|
546
|
-
const networkStartAction = async (ctx, args) => {
|
|
547
|
-
networkMonitors.get(ctx.page)?.dispose();
|
|
548
|
-
const includeBody = args.include_body === true || args.includeBody === true;
|
|
549
|
-
const urlPattern = typeof args.url_pattern === "string" ? args.url_pattern : typeof args.urlPattern === "string" ? args.urlPattern : void 0;
|
|
550
|
-
const events = [];
|
|
551
|
-
const onRequest = (request) => {
|
|
552
|
-
if (!matchesNetworkPattern(request.url(), urlPattern)) return;
|
|
553
|
-
events.push({
|
|
554
|
-
type: "request",
|
|
555
|
-
url: request.url(),
|
|
556
|
-
method: request.method(),
|
|
557
|
-
resourceType: request.resourceType(),
|
|
558
|
-
postData: request.postData(),
|
|
559
|
-
timestamp: Date.now()
|
|
560
|
-
});
|
|
561
|
-
};
|
|
562
|
-
const onResponse = async (response) => {
|
|
563
|
-
if (!matchesNetworkPattern(response.url(), urlPattern)) return;
|
|
564
|
-
const event = {
|
|
565
|
-
type: "response",
|
|
566
|
-
url: response.url(),
|
|
567
|
-
status: response.status(),
|
|
568
|
-
timestamp: Date.now()
|
|
569
|
-
};
|
|
570
|
-
if (includeBody) event.body = await response.text().catch(() => void 0);
|
|
571
|
-
events.push(event);
|
|
572
|
-
};
|
|
573
|
-
const onRequestFailed = (request) => {
|
|
574
|
-
if (!matchesNetworkPattern(request.url(), urlPattern)) return;
|
|
575
|
-
events.push({
|
|
576
|
-
type: "requestfailed",
|
|
577
|
-
url: request.url(),
|
|
578
|
-
method: request.method(),
|
|
579
|
-
errorText: request.failure()?.errorText,
|
|
580
|
-
timestamp: Date.now()
|
|
581
|
-
});
|
|
582
|
-
};
|
|
583
|
-
ctx.page.on("request", onRequest);
|
|
584
|
-
ctx.page.on("response", onResponse);
|
|
585
|
-
ctx.page.on("requestfailed", onRequestFailed);
|
|
586
|
-
networkMonitors.set(ctx.page, {
|
|
587
|
-
events,
|
|
588
|
-
includeBody,
|
|
589
|
-
urlPattern,
|
|
590
|
-
dispose: () => {
|
|
591
|
-
ctx.page.off("request", onRequest);
|
|
592
|
-
ctx.page.off("response", onResponse);
|
|
593
|
-
ctx.page.off("requestfailed", onRequestFailed);
|
|
594
|
-
networkMonitors.delete(ctx.page);
|
|
595
|
-
}
|
|
596
|
-
});
|
|
597
|
-
return ok("network_start", "Network monitoring started.", {
|
|
598
|
-
includeBody,
|
|
599
|
-
urlPattern
|
|
600
|
-
});
|
|
601
|
-
};
|
|
602
|
-
const networkEventsAction = async (ctx) => {
|
|
603
|
-
const events = networkMonitors.get(ctx.page)?.events ?? [];
|
|
604
|
-
return ok("network_events", JSON.stringify(events, null, 2), events);
|
|
605
|
-
};
|
|
606
|
-
const networkStopAction = async (ctx) => {
|
|
607
|
-
const events = networkMonitors.get(ctx.page)?.events ?? [];
|
|
608
|
-
networkMonitors.get(ctx.page)?.dispose();
|
|
609
|
-
return ok("network_stop", JSON.stringify(events, null, 2), events);
|
|
610
|
-
};
|
|
611
|
-
const collectAction = async (ctx, args) => {
|
|
612
|
-
const events = networkMonitors.get(ctx.page)?.events ?? [];
|
|
613
|
-
if (args.parse) {
|
|
614
|
-
const parsed = await ctx.page.evaluate(({ events, parse }) => {
|
|
615
|
-
return (0, eval)(`(${parse})`)(events);
|
|
616
|
-
}, {
|
|
617
|
-
events,
|
|
618
|
-
parse: String(args.parse)
|
|
619
|
-
});
|
|
620
|
-
return ok("collect", JSON.stringify(parsed, null, 2), parsed);
|
|
621
|
-
}
|
|
622
|
-
return ok("collect", JSON.stringify(events, null, 2), events);
|
|
623
|
-
};
|
|
624
|
-
const tapAction = async (ctx, args) => {
|
|
625
|
-
const pattern = String(args.capture ?? args.url ?? args.pattern ?? "");
|
|
626
|
-
const timeoutMs = Number(args.timeout_ms ?? args.timeoutMs ?? 5e3);
|
|
627
|
-
const captured = await ctx.page.evaluate(async ({ pattern, timeoutMs }) => {
|
|
628
|
-
let result = null;
|
|
629
|
-
const g = globalThis;
|
|
630
|
-
const originalFetch = g.fetch;
|
|
631
|
-
g.fetch = async (...fetchArgs) => {
|
|
632
|
-
const response = await originalFetch(...fetchArgs);
|
|
633
|
-
try {
|
|
634
|
-
const url = typeof fetchArgs[0] === "string" ? fetchArgs[0] : fetchArgs[0]?.url ?? String(fetchArgs[0]);
|
|
635
|
-
if ((!pattern || url.includes(pattern)) && result === null) {
|
|
636
|
-
const text = await response.clone().text();
|
|
637
|
-
try {
|
|
638
|
-
result = JSON.parse(text);
|
|
639
|
-
} catch {
|
|
640
|
-
result = text;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
} catch {}
|
|
644
|
-
return response;
|
|
645
|
-
};
|
|
646
|
-
try {
|
|
647
|
-
await new Promise((resolve) => setTimeout(resolve, timeoutMs));
|
|
648
|
-
} finally {
|
|
649
|
-
g.fetch = originalFetch;
|
|
650
|
-
}
|
|
651
|
-
return result;
|
|
652
|
-
}, {
|
|
653
|
-
pattern,
|
|
654
|
-
timeoutMs
|
|
655
|
-
});
|
|
656
|
-
return ok("tap", JSON.stringify(captured, null, 2), captured);
|
|
657
|
-
};
|
|
658
|
-
function createBrowserActionRegistry() {
|
|
659
|
-
const handlers = /* @__PURE__ */ new Map();
|
|
660
|
-
handlers.set("open", navigateAction);
|
|
661
|
-
handlers.set("navigate", navigateAction);
|
|
662
|
-
handlers.set("state", stateAction);
|
|
663
|
-
handlers.set("snapshot", stateAction);
|
|
664
|
-
handlers.set("click", clickAction);
|
|
665
|
-
handlers.set("type", typeAction);
|
|
666
|
-
handlers.set("input", typeAction);
|
|
667
|
-
handlers.set("scroll", scrollAction);
|
|
668
|
-
handlers.set("back", backAction);
|
|
669
|
-
handlers.set("keys", pressAction);
|
|
670
|
-
handlers.set("press", pressAction);
|
|
671
|
-
handlers.set("screenshot", screenshotAction);
|
|
672
|
-
handlers.set("images", imagesAction);
|
|
673
|
-
handlers.set("console", evalAction);
|
|
674
|
-
handlers.set("eval", evalAction);
|
|
675
|
-
handlers.set("evaluate", evalAction);
|
|
676
|
-
handlers.set("dialog", dialogAction);
|
|
677
|
-
handlers.set("close", closeAction);
|
|
678
|
-
handlers.set("wait", waitAction);
|
|
679
|
-
handlers.set("wait_for_navigation", waitForNavigationAction);
|
|
680
|
-
handlers.set("wait_for_timeout", waitForTimeoutAction);
|
|
681
|
-
handlers.set("wait_for_function", waitForFunctionAction);
|
|
682
|
-
handlers.set("wait_for_network_idle", waitForNetworkIdleAction);
|
|
683
|
-
handlers.set("output", outputAction);
|
|
684
|
-
handlers.set("assert", assertAction);
|
|
685
|
-
handlers.set("select", selectAction);
|
|
686
|
-
handlers.set("map", mapAction);
|
|
687
|
-
handlers.set("filter", filterAction);
|
|
688
|
-
handlers.set("sort", sortAction);
|
|
689
|
-
handlers.set("limit", limitAction);
|
|
690
|
-
handlers.set("fetch", fetchAction);
|
|
691
|
-
handlers.set("collect", collectAction);
|
|
692
|
-
handlers.set("tap", tapAction);
|
|
693
|
-
handlers.set("element_text", elementTextAction);
|
|
694
|
-
handlers.set("element_attribute", elementAttributeAction);
|
|
695
|
-
handlers.set("bounding_box", boundingBoxAction);
|
|
696
|
-
handlers.set("set_input_files", setInputFilesAction);
|
|
697
|
-
handlers.set("cookies", getCookiesAction);
|
|
698
|
-
handlers.set("get_cookies", getCookiesAction);
|
|
699
|
-
handlers.set("add_cookies", addCookiesAction);
|
|
700
|
-
handlers.set("clear_cookies", clearCookiesAction);
|
|
701
|
-
handlers.set("tabs", listTabsAction);
|
|
702
|
-
handlers.set("list_tabs", listTabsAction);
|
|
703
|
-
handlers.set("new_tab", newTabAction);
|
|
704
|
-
handlers.set("switch_tab", switchTabAction);
|
|
705
|
-
handlers.set("network_start", networkStartAction);
|
|
706
|
-
handlers.set("network_events", networkEventsAction);
|
|
707
|
-
handlers.set("network_stop", networkStopAction);
|
|
708
|
-
return {
|
|
709
|
-
get(name) {
|
|
710
|
-
return handlers.get(name);
|
|
711
|
-
},
|
|
712
|
-
has(name) {
|
|
713
|
-
return handlers.has(name);
|
|
714
|
-
},
|
|
715
|
-
names() {
|
|
716
|
-
return [...handlers.keys()];
|
|
717
|
-
},
|
|
718
|
-
async execute(name, ctx, args) {
|
|
719
|
-
if (ctx.signal?.aborted) return fail(name, "ABORTED", "Operation was aborted");
|
|
720
|
-
if (ctx.manager.getExtensionProvider()) {
|
|
721
|
-
const { runExtensionRegistryAction } = await import("./extension-registry-bridge.js");
|
|
722
|
-
return runExtensionRegistryAction(name, ctx, args);
|
|
723
|
-
}
|
|
724
|
-
const handler = handlers.get(name);
|
|
725
|
-
if (!handler) return fail(name, "UNKNOWN_ACTION", `Unknown browser action: ${name}`);
|
|
726
|
-
if (ctx.signal?.aborted) return fail(name, "ABORTED", "Operation was aborted");
|
|
727
|
-
try {
|
|
728
|
-
return await handler(ctx, args);
|
|
729
|
-
} catch (e) {
|
|
730
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
731
|
-
log.error({
|
|
732
|
-
err: e,
|
|
733
|
-
action: name
|
|
734
|
-
}, `Action failed: ${message}`);
|
|
735
|
-
return fail(name, "ACTION_ERROR", message);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
};
|
|
739
|
-
}
|
|
740
|
-
//#endregion
|
|
741
|
-
export { createBrowserActionRegistry };
|