@xopcai/xopc 0.0.250 → 0.0.252
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/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DfBjTSo9.js → activity-store-w3eq3YpP.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BN6FJXkJ.js → agent-avatar-dicebear-k039rbUz.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-C7rZH1A2.js → agent-defaults-settings-panel-D4J4oq8p.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-CgGaoo4z.js → agents-Bmth_bSQ.js} +1 -1
- package/dist/gateway/static/root/assets/{api-zxpcJfgj.js → api-2joIfbrH.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-D2gMshuS.js → app-management-settings-panel-ByJ4kiD0.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-wMu0jSKx.js → appearance-settings-BK2Jga-B.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-B3ky7cWU.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-u6EE3JV8.js → archive-plugin-DMDKtYpi.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DbJurnv-.js → attachment-load-B764Ql3Z.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-Ew_e5HDn.js → automations-page-D-sO8CZe.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-Ds5-_-9z.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DtDFNfPM.js → binary-plugins-fxtzYRpv.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CnAwmabq.js → block-editor-Bcjtvckh.js} +50 -50
- package/dist/gateway/static/root/assets/browser-automation-inputs-BSmnusjD.js +1 -0
- package/dist/gateway/static/root/assets/browser-automations-page-DC_OQIBk.js +3 -0
- package/dist/gateway/static/root/assets/browser-settings-page-C1FojyG6.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Bs59UCut.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-CM9vNmoo.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-CX-yWwLD.js → channels-status-swr-BuWjIG_a.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CryTDNdD.js → chat-terminal-dock-5SevEo_I.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-BPZ44D-V.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-ji5aWrjG.js → cron-expression-DtsfalBM.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-Dro_w3eX.js → date-picker-tDEQV5TP.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Ce19KKnX.js → dependency-picker-HhNwg0Y2.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DsSi-3uZ.js → desktop-pet-acU4Li-C.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-8WQ4woJy.js → desktop-pet-settings-R84AR0Pe.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CgvEBfLZ.js → extension-debug-page-CrLlRkSN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DkznBbMj.js → extension-page-BH5lmZXE.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BOjhchK2.js → extension-settings-page-BscjNAd1.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CMNbl0FZ.js → gateway-config-swr-9HidFZUd.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-BxLcW6ij.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CR7Xg8As.js → gateway-startup-retry-DRCPXONr.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-K5Zhl2rx.js +1 -0
- package/dist/gateway/static/root/assets/home-page-CZAg9RBv.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-C5mn73ca.js → image-generation-api-CR6Kle8H.js} +1 -1
- package/dist/gateway/static/root/assets/index-D4Ykja-U.js +72 -0
- package/dist/gateway/static/root/assets/index-zIJ3AXgR.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BYhfzsqe.js → keyboard-shortcuts-settings-B1QR49-7.js} +1 -1
- package/dist/gateway/static/root/assets/languages-5WaOu0Lf.js +2 -0
- package/dist/gateway/static/root/assets/local-app-workbench-page-wicoV-ti.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-vBlknU7C.js → local-apps-page-C74It-T8.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CF4erhjB.js → locale-store-BfZGZKSs.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-xX-7S49A.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-Dnx6mSNe.js → management-settings-1kNnYL97.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-editor-BjMTIM-m.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-CQvzsE24.js → markdown-view-DjiwT28p.js} +2 -2
- package/dist/gateway/static/root/assets/{media-plugins-DrMYeHe7.js → media-plugins-B5c0AoS1.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DaIwVWar.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-AKgGy3Kx.js → mobile-pairing-wizard-CsIZqK51.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-CfWxopl4.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-CYN-LCHJ.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-CX9T71by.js → page-tabs-CqJN6Ljz.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DvEHoimN.js → preview-open-alternatives-DqRIGxf4.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-COcr_NUJ.js → product-open-page-DE2nPE_K.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-B5G3LzDq.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CuVK2mKu.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BsRBlji7.js → registry-api-Bpy8XX-5.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Dnd73xWt.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CQ13P-mS.js → runtime-tools-settings-panel-Bb4b74-P.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BUVyTpZj.js → schema-form-DoPU5j3J.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-XL4LyKZe.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-0ForzDSS.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DVY-8_B9.js → settings-form-section-Ci-9WajJ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-CdiVYyTl.js → settings-page-CL_2F95D.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DVws6XZc.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-C88YLKm4.js → share-preview-page-XUA3oKQX.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BwDvcacF.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BJjrATqE.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-DLir1nM0.js → skills-page-sXXAZDc9.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-BMZAfS3G.js → skills-page.utils-DD79Bl1I.js} +1 -1
- package/dist/gateway/static/root/assets/source-workspace-editor-CVWzt0oT.js +1 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BM8ivYan.js → system-settings-panel-BEH64qBV.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-0jxMi75O.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BOgkc_9D.js → theme-store-CISSxU1c.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-DemxChjo.js → tunnel-api-DrKDhnJm.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-CV3Ui5hu.js → use-autosave-CPYePL-Q.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-B6zLDfDl.js +2 -0
- package/dist/gateway/static/root/assets/{vendor-codemirror--gTq3YAI.js → vendor-codemirror-Qdcjid65.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CUoCi4Sq.js → voice-api-key-field-DKqzrCXx.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-C-ryeIxj.js → voice-config-api-e9xWjwBX.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BhDlkCMB.js → work-discovery-overlay-kTQug6bq.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D8CcPc_C.js → workflow-run-setup-panel-m9SKj_GT.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Bcd1XqP7.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/src/agent/agent-manager.d.ts +2 -1
- package/dist/src/agent/agent-manager.js +2 -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/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/service.js +2 -1
- package/dist/src/agent/service.types.d.ts +2 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +4 -0
- 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/factory.d.ts +6 -9
- package/dist/src/agent/tools/factory.js +28 -55
- 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/auth/oauth/xopc-cloud.js +3 -1
- 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 +12 -12
- package/dist/src/automations/domain/validation.js +3 -3
- package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -3
- 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 +3 -5
- 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/platform.d.ts +1 -0
- package/dist/src/cli/commands/platform.js +111 -0
- package/dist/src/config/loader.js +9 -3
- 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/marketplace.js +4 -0
- package/dist/src/files/file-service.js +139 -14
- package/dist/src/gateway/hono/lib/config-payload.d.ts +12 -26
- package/dist/src/gateway/hono/lib/config-payload.js +10 -39
- 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/service.d.ts +4 -6
- package/dist/src/gateway/service.js +20 -23
- 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/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/migrations/153_browser_control_v2.sql +45 -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/tasks/home-query-service.js +1 -1
- package/dist/src/tunnel/env.js +3 -1
- package/dist/src/voice/realtime/agentEngine.js +0 -1
- package/package.json +7 -7
- package/dist/gateway/static/root/assets/apps-page-KF1Gnv36.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-Ch-ldu35.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DtVhsHJW.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-CcbUOWDF.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel--sXeylhe.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-AXSBDujZ.js +0 -1
- package/dist/gateway/static/root/assets/code-editor-D4_k-6QN.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-HBHUWohz.js +0 -2
- package/dist/gateway/static/root/assets/gateway-config-api-OEruhhX3.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-BgH3A0LO.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-C97naDkO.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BBKKme4G.js +0 -1
- package/dist/gateway/static/root/assets/html-workspace-editor-C3DKAkMc.js +0 -1
- package/dist/gateway/static/root/assets/index-BcaF-dgQ.js +0 -72
- package/dist/gateway/static/root/assets/index-DAryGvZ7.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-DNncc2tn.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-CizZInrT.js +0 -2
- package/dist/gateway/static/root/assets/markdown-editor-nDLmA_LF.js +0 -2
- package/dist/gateway/static/root/assets/markdown-split-DtBtcHWi.js +0 -1
- package/dist/gateway/static/root/assets/messages-Cf5hpZE6.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-Bw3jD9Jf.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-Dpqq7Z-J.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-BuT6MCTs.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DXWMxOjf.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-7rBCUWzZ.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-gmEOYNb4.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DYYoJcl7.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BhenBnUj.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Dq7xIj0_.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-MDI9Lz6z.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-P0_RldWv.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-CxfnoRVn.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-Bxn2Dc16.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/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,612 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { assertCacheDir, expandHome, init_cache_dir_policy } from "../cache-dir-policy.js";
|
|
4
|
-
import { init_paths, resolveBinDir } from "../../config/paths.js";
|
|
5
|
-
import { loadPlaywrightCoreModule } from "./playwright-doctor.js";
|
|
6
|
-
import { WEBDRIVER_OVERRIDE_SCRIPT, buildStealthArgs, filterCloakBrowserExtraArgs, generateFingerprintSeed, makeExecutable, removeQuarantineAttr } from "../stealth.js";
|
|
7
|
-
import { pickFreePort } from "../free-port.js";
|
|
8
|
-
import { arch, platform, tmpdir } from "node:os";
|
|
9
|
-
import { join, resolve } from "node:path";
|
|
10
|
-
import { createReadStream, createWriteStream } from "node:fs";
|
|
11
|
-
import { spawn } from "node:child_process";
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
13
|
-
import { mkdir, mkdtemp, rm, stat } from "node:fs/promises";
|
|
14
|
-
import AdmZip from "adm-zip";
|
|
15
|
-
import { pipeline } from "node:stream/promises";
|
|
16
|
-
import { Readable, Transform } from "node:stream";
|
|
17
|
-
//#region src/browser/providers/cloakbrowser.ts
|
|
18
|
-
/**
|
|
19
|
-
* CloakBrowser provider — anti-fingerprint Chromium with stealth capabilities.
|
|
20
|
-
*
|
|
21
|
-
* Manages CloakBrowser binary download, stealth launch, CDP connection,
|
|
22
|
-
* keep-open process reuse, and temporary profile lifecycle.
|
|
23
|
-
*
|
|
24
|
-
* Ported from brocli's cloak.rs to TypeScript, using Playwright's connectOverCDP
|
|
25
|
-
* to produce a standard Browser/BrowserContext pair.
|
|
26
|
-
*/
|
|
27
|
-
init_logger();
|
|
28
|
-
init_paths();
|
|
29
|
-
init_cache_dir_policy();
|
|
30
|
-
const log = createLogger("CloakBrowser");
|
|
31
|
-
const DOWNLOAD_BASE_URL = "https://cloakbrowser.dev";
|
|
32
|
-
const GITHUB_DOWNLOAD_BASE_URL = "https://github.com/CloakHQ/CloakBrowser/releases/download";
|
|
33
|
-
const XOPC_CLOAKBROWSER_PROXY_BASE = process.env.XOPC_CLOAKBROWSER_DOWNLOAD_BASE?.trim().replace(/\/$/, "") || "https://xopc.ai/api/cloakbrowser/download";
|
|
34
|
-
const READY_TIMEOUT_MS = 45e3;
|
|
35
|
-
const READY_POLL_INTERVAL_MS = 300;
|
|
36
|
-
const DEFAULT_KEEP_OPEN_CDP_PORT = 9222;
|
|
37
|
-
const PLATFORMS = {
|
|
38
|
-
"darwin-arm64": {
|
|
39
|
-
tag: "darwin-arm64",
|
|
40
|
-
chromiumVersion: "145.0.7632.109.2",
|
|
41
|
-
archiveExt: ".tar.gz",
|
|
42
|
-
executableRelativePath: "Chromium.app/Contents/MacOS/Chromium",
|
|
43
|
-
fingerprintPlatform: "macos",
|
|
44
|
-
expectedSha256: ""
|
|
45
|
-
},
|
|
46
|
-
"darwin-x64": {
|
|
47
|
-
tag: "darwin-x64",
|
|
48
|
-
chromiumVersion: "145.0.7632.109.2",
|
|
49
|
-
archiveExt: ".tar.gz",
|
|
50
|
-
executableRelativePath: "Chromium.app/Contents/MacOS/Chromium",
|
|
51
|
-
fingerprintPlatform: "macos",
|
|
52
|
-
expectedSha256: ""
|
|
53
|
-
},
|
|
54
|
-
"linux-arm64": {
|
|
55
|
-
tag: "linux-arm64",
|
|
56
|
-
chromiumVersion: "146.0.7680.177.4",
|
|
57
|
-
archiveExt: ".tar.gz",
|
|
58
|
-
executableRelativePath: "chrome",
|
|
59
|
-
fingerprintPlatform: "windows",
|
|
60
|
-
expectedSha256: ""
|
|
61
|
-
},
|
|
62
|
-
"linux-x64": {
|
|
63
|
-
tag: "linux-x64",
|
|
64
|
-
chromiumVersion: "146.0.7680.177.4",
|
|
65
|
-
archiveExt: ".tar.gz",
|
|
66
|
-
executableRelativePath: "chrome",
|
|
67
|
-
fingerprintPlatform: "windows",
|
|
68
|
-
expectedSha256: ""
|
|
69
|
-
},
|
|
70
|
-
"win32-x64": {
|
|
71
|
-
tag: "windows-x64",
|
|
72
|
-
chromiumVersion: "146.0.7680.177.4",
|
|
73
|
-
archiveExt: ".zip",
|
|
74
|
-
executableRelativePath: "chrome.exe",
|
|
75
|
-
fingerprintPlatform: "windows",
|
|
76
|
-
expectedSha256: ""
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
function detectPlatform() {
|
|
80
|
-
const os = platform();
|
|
81
|
-
const architecture = arch();
|
|
82
|
-
const info = PLATFORMS[`${os}-${{
|
|
83
|
-
arm64: "arm64",
|
|
84
|
-
x64: "x64"
|
|
85
|
-
}[architecture] ?? architecture}`];
|
|
86
|
-
if (!info) throw new Error(`Unsupported CloakBrowser platform: ${os}/${architecture}`);
|
|
87
|
-
return info;
|
|
88
|
-
}
|
|
89
|
-
/** Test-only: enumerate platform manifests. */
|
|
90
|
-
function listCloakBrowserPlatforms() {
|
|
91
|
-
return Object.values(PLATFORMS);
|
|
92
|
-
}
|
|
93
|
-
function archiveDownloadUrls(platformInfo) {
|
|
94
|
-
const archiveName = `cloakbrowser-${platformInfo.tag}${platformInfo.archiveExt}`;
|
|
95
|
-
return [
|
|
96
|
-
`${XOPC_CLOAKBROWSER_PROXY_BASE}/${archiveName}`,
|
|
97
|
-
`${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${platformInfo.chromiumVersion}/${archiveName}`,
|
|
98
|
-
`${DOWNLOAD_BASE_URL}/download/${archiveName}`
|
|
99
|
-
];
|
|
100
|
-
}
|
|
101
|
-
/** Test-only: resolved download URLs for a platform manifest (proxy first). */
|
|
102
|
-
function cloakBrowserArchiveDownloadUrls(platformInfo) {
|
|
103
|
-
return archiveDownloadUrls(platformInfo);
|
|
104
|
-
}
|
|
105
|
-
async function sha256OfFile(path) {
|
|
106
|
-
const hash = createHash("sha256");
|
|
107
|
-
await pipeline(createReadStream(path), hash);
|
|
108
|
-
return hash.digest("hex");
|
|
109
|
-
}
|
|
110
|
-
const CLOAKBROWSER_DIR_NAME = "cloakbrowser";
|
|
111
|
-
/** Default CloakBrowser home: ~/.xopc/bin/cloakbrowser (chromium-v*, profiles/, …). */
|
|
112
|
-
function defaultCloakBrowserCacheDir() {
|
|
113
|
-
return join(resolveBinDir(), CLOAKBROWSER_DIR_NAME);
|
|
114
|
-
}
|
|
115
|
-
/** Resolve configured or default CloakBrowser cache root. */
|
|
116
|
-
function resolveCloakBrowserCacheDir(configured) {
|
|
117
|
-
if (configured?.trim()) {
|
|
118
|
-
const resolved = assertCacheDir(configured.trim());
|
|
119
|
-
if (resolve(resolved) === resolve(resolveBinDir())) return defaultCloakBrowserCacheDir();
|
|
120
|
-
return resolved;
|
|
121
|
-
}
|
|
122
|
-
return defaultCloakBrowserCacheDir();
|
|
123
|
-
}
|
|
124
|
-
async function resolveCloakExecutablePath(cacheDir, platformInfo, configuredBinaryPath) {
|
|
125
|
-
const trimmed = configuredBinaryPath?.trim();
|
|
126
|
-
const autoPath = binaryPath(cacheDir, platformInfo);
|
|
127
|
-
if (!trimmed) return {
|
|
128
|
-
execPath: autoPath,
|
|
129
|
-
installed: await fileExists(autoPath),
|
|
130
|
-
customBinaryPath: false
|
|
131
|
-
};
|
|
132
|
-
const customPath = resolve(expandHome(trimmed));
|
|
133
|
-
if (await fileExists(customPath)) return {
|
|
134
|
-
execPath: customPath,
|
|
135
|
-
installed: true,
|
|
136
|
-
customBinaryPath: true
|
|
137
|
-
};
|
|
138
|
-
if (await fileExists(autoPath)) return {
|
|
139
|
-
execPath: autoPath,
|
|
140
|
-
installed: true,
|
|
141
|
-
customBinaryPath: true
|
|
142
|
-
};
|
|
143
|
-
return {
|
|
144
|
-
execPath: customPath,
|
|
145
|
-
installed: false,
|
|
146
|
-
customBinaryPath: true
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
function binaryDir(cacheDir, platformInfo) {
|
|
150
|
-
return join(cacheDir, `chromium-v${platformInfo.chromiumVersion}`);
|
|
151
|
-
}
|
|
152
|
-
function binaryPath(cacheDir, platformInfo) {
|
|
153
|
-
return join(binaryDir(cacheDir, platformInfo), platformInfo.executableRelativePath);
|
|
154
|
-
}
|
|
155
|
-
async function fileExists(path) {
|
|
156
|
-
try {
|
|
157
|
-
await stat(path);
|
|
158
|
-
return true;
|
|
159
|
-
} catch {
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
function runCommand(command, args) {
|
|
164
|
-
return new Promise((resolve, reject) => {
|
|
165
|
-
const child = spawn(command, args, { stdio: [
|
|
166
|
-
"ignore",
|
|
167
|
-
"ignore",
|
|
168
|
-
"pipe"
|
|
169
|
-
] });
|
|
170
|
-
let stderr = "";
|
|
171
|
-
child.stderr?.on("data", (data) => {
|
|
172
|
-
stderr += data.toString();
|
|
173
|
-
});
|
|
174
|
-
child.once("error", reject);
|
|
175
|
-
child.once("exit", (code, signal) => {
|
|
176
|
-
if (code === 0) {
|
|
177
|
-
resolve();
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
const reason = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
|
|
181
|
-
const detail = stderr.trim() ? `: ${stderr.trim().slice(0, 500)}` : "";
|
|
182
|
-
reject(/* @__PURE__ */ new Error(`${command} failed with ${reason}${detail}`));
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
async function extractArchive(archivePath, targetDir, platformInfo) {
|
|
187
|
-
if (platformInfo.archiveExt === ".tar.gz") {
|
|
188
|
-
await runCommand("tar", [
|
|
189
|
-
"-xzf",
|
|
190
|
-
archivePath,
|
|
191
|
-
"-C",
|
|
192
|
-
targetDir
|
|
193
|
-
]);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (platformInfo.archiveExt === ".zip") {
|
|
197
|
-
new AdmZip(archivePath).extractAllTo(targetDir, true);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
throw new Error(`Unsupported CloakBrowser archive format: ${platformInfo.archiveExt}`);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Download and extract CloakBrowser binary.
|
|
204
|
-
*
|
|
205
|
-
* After download, verifies SHA-256 against the platform manifest when one is
|
|
206
|
-
* present. Set `XOPC_CLOAKBROWSER_SKIP_HASH=1` to bypass (development only;
|
|
207
|
-
* the gateway logs a warning when the env var is honoured).
|
|
208
|
-
*/
|
|
209
|
-
async function downloadArchiveToFile(url, archivePath, onProgress, signal) {
|
|
210
|
-
if (signal?.aborted) throw new Error("Install cancelled");
|
|
211
|
-
const response = await fetch(url, {
|
|
212
|
-
redirect: "follow",
|
|
213
|
-
signal
|
|
214
|
-
});
|
|
215
|
-
if (!response.ok || !response.body) throw new Error(`download returned HTTP ${response.status}`);
|
|
216
|
-
const contentLength = response.headers.get("content-length");
|
|
217
|
-
const totalBytes = contentLength && Number.isFinite(Number(contentLength)) ? Number(contentLength) : null;
|
|
218
|
-
let bytesReceived = 0;
|
|
219
|
-
let lastReportAt = 0;
|
|
220
|
-
const report = (force = false) => {
|
|
221
|
-
const now = Date.now();
|
|
222
|
-
if (!force && now - lastReportAt < 250) return;
|
|
223
|
-
lastReportAt = now;
|
|
224
|
-
onProgress?.({
|
|
225
|
-
phase: "downloading",
|
|
226
|
-
message: "Downloading CloakBrowser archive",
|
|
227
|
-
bytesReceived,
|
|
228
|
-
totalBytes,
|
|
229
|
-
percent: totalBytes && totalBytes > 0 ? Math.min(100, Math.round(bytesReceived / totalBytes * 100)) : null
|
|
230
|
-
});
|
|
231
|
-
};
|
|
232
|
-
report(true);
|
|
233
|
-
await pipeline(Readable.fromWeb(response.body), new Transform({ transform(chunk, _encoding, callback) {
|
|
234
|
-
bytesReceived += chunk.length;
|
|
235
|
-
report();
|
|
236
|
-
callback(null, chunk);
|
|
237
|
-
} }), createWriteStream(archivePath));
|
|
238
|
-
report(true);
|
|
239
|
-
}
|
|
240
|
-
async function downloadBinary(cacheDir, platformInfo, onProgress, signal) {
|
|
241
|
-
const targetDir = binaryDir(cacheDir, platformInfo);
|
|
242
|
-
const execPath = binaryPath(cacheDir, platformInfo);
|
|
243
|
-
if (await fileExists(execPath)) {
|
|
244
|
-
log.info({ path: execPath }, "CloakBrowser binary already cached");
|
|
245
|
-
await onProgress?.({
|
|
246
|
-
phase: "ready",
|
|
247
|
-
message: "CloakBrowser binary already cached",
|
|
248
|
-
percent: 100
|
|
249
|
-
});
|
|
250
|
-
return execPath;
|
|
251
|
-
}
|
|
252
|
-
await mkdir(cacheDir, { recursive: true });
|
|
253
|
-
await onProgress?.({
|
|
254
|
-
phase: "starting",
|
|
255
|
-
message: "Preparing CloakBrowser download"
|
|
256
|
-
});
|
|
257
|
-
const archiveName = `cloakbrowser-${platformInfo.tag}${platformInfo.archiveExt}`;
|
|
258
|
-
const urls = archiveDownloadUrls(platformInfo);
|
|
259
|
-
const expectedSha256 = platformInfo.expectedSha256.trim().toLowerCase();
|
|
260
|
-
const skipHash = process.env.XOPC_CLOAKBROWSER_SKIP_HASH === "1";
|
|
261
|
-
log.info({
|
|
262
|
-
version: platformInfo.chromiumVersion,
|
|
263
|
-
platform: platformInfo.tag
|
|
264
|
-
}, "Downloading CloakBrowser...");
|
|
265
|
-
let downloadError;
|
|
266
|
-
for (const url of urls) {
|
|
267
|
-
if (signal?.aborted) throw new Error("Install cancelled");
|
|
268
|
-
const stagingDir = await mkdtemp(join(cacheDir, ".download-"));
|
|
269
|
-
const archivePath = join(stagingDir, archiveName);
|
|
270
|
-
try {
|
|
271
|
-
await downloadArchiveToFile(url, archivePath, onProgress, signal);
|
|
272
|
-
if (expectedSha256) {
|
|
273
|
-
if (signal?.aborted) throw new Error("Install cancelled");
|
|
274
|
-
await onProgress?.({
|
|
275
|
-
phase: "verifying",
|
|
276
|
-
message: "Verifying SHA-256 checksum"
|
|
277
|
-
});
|
|
278
|
-
const actual = await sha256OfFile(archivePath);
|
|
279
|
-
if (actual !== expectedSha256) throw new Error(`SHA-256 mismatch: expected ${expectedSha256}, got ${actual}. Aborted to avoid running unverified binary.`);
|
|
280
|
-
log.info({ archivePath }, "SHA-256 verified");
|
|
281
|
-
} else if (skipHash) log.warn({
|
|
282
|
-
platform: platformInfo.tag,
|
|
283
|
-
version: platformInfo.chromiumVersion
|
|
284
|
-
}, "CloakBrowser SHA-256 verification skipped (XOPC_CLOAKBROWSER_SKIP_HASH=1)");
|
|
285
|
-
else log.warn({
|
|
286
|
-
platform: platformInfo.tag,
|
|
287
|
-
version: platformInfo.chromiumVersion
|
|
288
|
-
}, "CloakBrowser manifest has no expectedSha256; integrity NOT verified");
|
|
289
|
-
await onProgress?.({
|
|
290
|
-
phase: "extracting",
|
|
291
|
-
message: "Extracting CloakBrowser archive"
|
|
292
|
-
});
|
|
293
|
-
log.info({ archivePath }, "Extracting CloakBrowser archive...");
|
|
294
|
-
await rm(targetDir, {
|
|
295
|
-
recursive: true,
|
|
296
|
-
force: true
|
|
297
|
-
}).catch(() => {});
|
|
298
|
-
await mkdir(targetDir, { recursive: true });
|
|
299
|
-
await extractArchive(archivePath, targetDir, platformInfo);
|
|
300
|
-
if (!await fileExists(execPath)) throw new Error(`archive did not contain expected executable: ${execPath}`);
|
|
301
|
-
await makeExecutable(execPath);
|
|
302
|
-
await removeQuarantineAttr(execPath);
|
|
303
|
-
await rm(stagingDir, {
|
|
304
|
-
recursive: true,
|
|
305
|
-
force: true
|
|
306
|
-
}).catch(() => {});
|
|
307
|
-
await onProgress?.({
|
|
308
|
-
phase: "ready",
|
|
309
|
-
message: "CloakBrowser binary ready",
|
|
310
|
-
percent: 100
|
|
311
|
-
});
|
|
312
|
-
log.info({ path: execPath }, "CloakBrowser binary ready");
|
|
313
|
-
return execPath;
|
|
314
|
-
} catch (e) {
|
|
315
|
-
await rm(stagingDir, {
|
|
316
|
-
recursive: true,
|
|
317
|
-
force: true
|
|
318
|
-
}).catch(() => {});
|
|
319
|
-
await rm(targetDir, {
|
|
320
|
-
recursive: true,
|
|
321
|
-
force: true
|
|
322
|
-
}).catch(() => {});
|
|
323
|
-
downloadError = e instanceof Error ? e : new Error(String(e));
|
|
324
|
-
log.debug({
|
|
325
|
-
url,
|
|
326
|
-
errorMessage: downloadError.message
|
|
327
|
-
}, "Download attempt failed");
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
throw new Error(`Failed to download CloakBrowser v${platformInfo.chromiumVersion} for ${platformInfo.tag}: ${downloadError?.message ?? "all URLs failed"}`);
|
|
331
|
-
}
|
|
332
|
-
async function waitForCdpEndpoint(port) {
|
|
333
|
-
const deadline = Date.now() + READY_TIMEOUT_MS;
|
|
334
|
-
while (Date.now() < deadline) {
|
|
335
|
-
try {
|
|
336
|
-
const response = await fetch(`http://127.0.0.1:${port}/json/version`);
|
|
337
|
-
if (response.ok) {
|
|
338
|
-
const data = await response.json();
|
|
339
|
-
if (data.webSocketDebuggerUrl) return data.webSocketDebuggerUrl;
|
|
340
|
-
}
|
|
341
|
-
} catch {}
|
|
342
|
-
await new Promise((resolve) => setTimeout(resolve, READY_POLL_INTERVAL_MS));
|
|
343
|
-
}
|
|
344
|
-
throw new Error(`CloakBrowser did not expose CDP page within ${READY_TIMEOUT_MS / 1e3}s on port ${port}`);
|
|
345
|
-
}
|
|
346
|
-
/** Try to find an existing CDP page endpoint on the given port. */
|
|
347
|
-
async function reuseOrCreatePageEndpoint(port) {
|
|
348
|
-
try {
|
|
349
|
-
const response = await fetch(`http://127.0.0.1:${port}/json/list`, { signal: AbortSignal.timeout(2e3) });
|
|
350
|
-
if (!response.ok) return null;
|
|
351
|
-
const page = (await response.json()).find((p) => p.type === "page" && p.webSocketDebuggerUrl);
|
|
352
|
-
if (page?.webSocketDebuggerUrl) return page.webSocketDebuggerUrl;
|
|
353
|
-
const newResponse = await fetch(`http://127.0.0.1:${port}/json/new`);
|
|
354
|
-
if (newResponse.ok) {
|
|
355
|
-
const newPage = await newResponse.json();
|
|
356
|
-
if (newPage.webSocketDebuggerUrl) return newPage.webSocketDebuggerUrl;
|
|
357
|
-
}
|
|
358
|
-
} catch {}
|
|
359
|
-
return null;
|
|
360
|
-
}
|
|
361
|
-
function resolveCloakBrowserProfilePaths(config, cacheDir) {
|
|
362
|
-
if (config.userDataDir) return {
|
|
363
|
-
userDataDir: config.userDataDir,
|
|
364
|
-
temporaryProfileDir: null
|
|
365
|
-
};
|
|
366
|
-
if (config.temporaryProfile) {
|
|
367
|
-
const userDataDir = join(tmpdir(), `xopc-cloakbrowser-${process.pid}-${generateFingerprintSeed()}`);
|
|
368
|
-
return {
|
|
369
|
-
userDataDir,
|
|
370
|
-
temporaryProfileDir: userDataDir
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
return {
|
|
374
|
-
userDataDir: join(cacheDir, "profiles", "default"),
|
|
375
|
-
temporaryProfileDir: null
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
/** Resolve the persistent profile directory agents use (not ephemeral temp dirs). */
|
|
379
|
-
function resolveCloakBrowserPersistentProfileDir(config = {}) {
|
|
380
|
-
if (config.userDataDir) return config.userDataDir;
|
|
381
|
-
return join(resolveCloakBrowserCacheDir(config.cacheDir), "profiles", "default");
|
|
382
|
-
}
|
|
383
|
-
async function probeCdpPort(port) {
|
|
384
|
-
try {
|
|
385
|
-
return (await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(2e3) })).ok;
|
|
386
|
-
} catch {
|
|
387
|
-
return false;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
/** Probe whether CloakBrowser CDP is listening on the configured keep-open port. */
|
|
391
|
-
async function probeCloakBrowserRuntime(config = {}) {
|
|
392
|
-
const keepOpen = config.keepOpen ?? true;
|
|
393
|
-
const cdpPort = config.cdpPort ?? (keepOpen ? DEFAULT_KEEP_OPEN_CDP_PORT : DEFAULT_KEEP_OPEN_CDP_PORT);
|
|
394
|
-
const { userDataDir } = resolveCloakBrowserProfilePaths(config, resolveCloakBrowserCacheDir(config.cacheDir));
|
|
395
|
-
return {
|
|
396
|
-
running: await probeCdpPort(cdpPort),
|
|
397
|
-
port: cdpPort,
|
|
398
|
-
userDataDir,
|
|
399
|
-
temporaryProfile: config.temporaryProfile === true
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
function launchResultMeta(cdpPort, userDataDir, reused, pid, childProcess, temporaryProfileDir) {
|
|
403
|
-
return {
|
|
404
|
-
cdpPort,
|
|
405
|
-
userDataDir,
|
|
406
|
-
reused,
|
|
407
|
-
pid,
|
|
408
|
-
childProcess,
|
|
409
|
-
temporaryProfileDir
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Launch or connect to a CloakBrowser instance and return a Playwright Browser + Context.
|
|
414
|
-
*/
|
|
415
|
-
async function launchCloakBrowser(config = {}) {
|
|
416
|
-
const platformInfo = detectPlatform();
|
|
417
|
-
const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);
|
|
418
|
-
const keepOpen = config.keepOpen ?? true;
|
|
419
|
-
const reuseExisting = config.reuseExisting ?? keepOpen;
|
|
420
|
-
const configuredBinary = config.binaryPath?.trim() || void 0;
|
|
421
|
-
const execPath = configuredBinary ? (await resolveCloakExecutablePath(cacheDir, platformInfo, configuredBinary)).execPath : await downloadBinary(cacheDir, platformInfo, config.onProgress, config.signal);
|
|
422
|
-
if (configuredBinary) {
|
|
423
|
-
await makeExecutable(execPath);
|
|
424
|
-
await removeQuarantineAttr(execPath);
|
|
425
|
-
}
|
|
426
|
-
const cdpPort = config.cdpPort ?? (keepOpen ? DEFAULT_KEEP_OPEN_CDP_PORT : await pickFreePort());
|
|
427
|
-
const skipPlaywrightConnect = config.skipPlaywrightConnect === true;
|
|
428
|
-
const { userDataDir, temporaryProfileDir: plannedTempProfileDir } = resolveCloakBrowserProfilePaths(config, cacheDir);
|
|
429
|
-
if (reuseExisting) {
|
|
430
|
-
if (await reuseOrCreatePageEndpoint(cdpPort)) {
|
|
431
|
-
log.info({ port: cdpPort }, "Reusing existing CloakBrowser instance");
|
|
432
|
-
const meta = launchResultMeta(cdpPort, userDataDir, true, null, null, null);
|
|
433
|
-
if (skipPlaywrightConnect) return meta;
|
|
434
|
-
const pw = await loadPlaywrightCoreModule();
|
|
435
|
-
const chromium = pw.chromium ?? pw.default?.chromium;
|
|
436
|
-
if (!chromium?.connectOverCDP) throw new Error("playwright-core does not support connectOverCDP");
|
|
437
|
-
const wsUrl = `ws://127.0.0.1:${cdpPort}`;
|
|
438
|
-
const browserWsUrl = (await (await fetch(`http://127.0.0.1:${cdpPort}/json/version`)).json()).webSocketDebuggerUrl ?? wsUrl;
|
|
439
|
-
const browser = await chromium.connectOverCDP(browserWsUrl);
|
|
440
|
-
const contexts = browser.contexts();
|
|
441
|
-
const context = contexts.length > 0 ? contexts[0] : await browser.newContext();
|
|
442
|
-
await context.addInitScript(WEBDRIVER_OVERRIDE_SCRIPT);
|
|
443
|
-
return {
|
|
444
|
-
browser,
|
|
445
|
-
context,
|
|
446
|
-
...meta
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
let temporaryProfileDir = plannedTempProfileDir;
|
|
451
|
-
await mkdir(userDataDir, { recursive: true });
|
|
452
|
-
const stealthArgs = buildStealthArgs(filterCloakBrowserExtraArgs(config.extraArgs ?? []), {
|
|
453
|
-
timezone: config.timezone,
|
|
454
|
-
locale: config.locale,
|
|
455
|
-
webrtcIp: config.webrtcIp,
|
|
456
|
-
fingerprintPlatform: config.fingerprintPlatform ?? platformInfo.fingerprintPlatform
|
|
457
|
-
});
|
|
458
|
-
const launchArgs = [
|
|
459
|
-
`--remote-debugging-address=127.0.0.1`,
|
|
460
|
-
`--remote-debugging-port=${cdpPort}`,
|
|
461
|
-
`--user-data-dir=${userDataDir}`,
|
|
462
|
-
"--no-first-run",
|
|
463
|
-
"--no-default-browser-check",
|
|
464
|
-
...stealthArgs
|
|
465
|
-
];
|
|
466
|
-
if (config.headless) launchArgs.push("--headless=new");
|
|
467
|
-
if (platform() === "darwin") launchArgs.push("--use-mock-keychain");
|
|
468
|
-
await config.onProgress?.({
|
|
469
|
-
phase: "running",
|
|
470
|
-
message: "Launching CloakBrowser for verification"
|
|
471
|
-
});
|
|
472
|
-
if (config.signal?.aborted) throw new Error("Install cancelled");
|
|
473
|
-
log.info({
|
|
474
|
-
execPath,
|
|
475
|
-
port: cdpPort,
|
|
476
|
-
headless: !!config.headless,
|
|
477
|
-
keepOpen
|
|
478
|
-
}, "Launching CloakBrowser");
|
|
479
|
-
const child = spawn(execPath, launchArgs, {
|
|
480
|
-
stdio: [
|
|
481
|
-
"ignore",
|
|
482
|
-
"ignore",
|
|
483
|
-
"ignore"
|
|
484
|
-
],
|
|
485
|
-
detached: keepOpen
|
|
486
|
-
});
|
|
487
|
-
let onLaunchError = null;
|
|
488
|
-
let onLaunchExit = null;
|
|
489
|
-
const launchFailure = new Promise((_resolve, reject) => {
|
|
490
|
-
onLaunchError = (error) => {
|
|
491
|
-
reject(/* @__PURE__ */ new Error(`Failed to launch CloakBrowser at ${execPath}: ${error.message}`));
|
|
492
|
-
};
|
|
493
|
-
onLaunchExit = (code, signal) => {
|
|
494
|
-
const reason = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
|
|
495
|
-
reject(/* @__PURE__ */ new Error(`CloakBrowser exited before CDP became ready (${reason})`));
|
|
496
|
-
};
|
|
497
|
-
child.once("error", onLaunchError);
|
|
498
|
-
child.once("exit", onLaunchExit);
|
|
499
|
-
});
|
|
500
|
-
if (keepOpen) child.unref();
|
|
501
|
-
let browserWsUrl;
|
|
502
|
-
try {
|
|
503
|
-
browserWsUrl = await Promise.race([waitForCdpEndpoint(cdpPort), launchFailure]);
|
|
504
|
-
if (onLaunchError) child.off("error", onLaunchError);
|
|
505
|
-
if (onLaunchExit) child.off("exit", onLaunchExit);
|
|
506
|
-
} catch (e) {
|
|
507
|
-
if (onLaunchError) child.off("error", onLaunchError);
|
|
508
|
-
if (onLaunchExit) child.off("exit", onLaunchExit);
|
|
509
|
-
child.kill();
|
|
510
|
-
if (temporaryProfileDir) await rm(temporaryProfileDir, {
|
|
511
|
-
recursive: true,
|
|
512
|
-
force: true
|
|
513
|
-
}).catch(() => {});
|
|
514
|
-
throw e;
|
|
515
|
-
}
|
|
516
|
-
let browserLevelWsUrl;
|
|
517
|
-
try {
|
|
518
|
-
browserLevelWsUrl = (await (await fetch(`http://127.0.0.1:${cdpPort}/json/version`)).json()).webSocketDebuggerUrl ?? browserWsUrl;
|
|
519
|
-
} catch {
|
|
520
|
-
browserLevelWsUrl = browserWsUrl;
|
|
521
|
-
}
|
|
522
|
-
const meta = launchResultMeta(cdpPort, userDataDir, false, child.pid ?? null, keepOpen ? null : child, temporaryProfileDir);
|
|
523
|
-
if (skipPlaywrightConnect) {
|
|
524
|
-
log.info({
|
|
525
|
-
port: cdpPort,
|
|
526
|
-
pid: child.pid
|
|
527
|
-
}, "CloakBrowser launched (CDP only)");
|
|
528
|
-
return meta;
|
|
529
|
-
}
|
|
530
|
-
const pw = await loadPlaywrightCoreModule();
|
|
531
|
-
const chromium = pw.chromium ?? pw.default?.chromium;
|
|
532
|
-
if (!chromium?.connectOverCDP) {
|
|
533
|
-
child.kill();
|
|
534
|
-
throw new Error("playwright-core does not support connectOverCDP");
|
|
535
|
-
}
|
|
536
|
-
const browser = await chromium.connectOverCDP(browserLevelWsUrl);
|
|
537
|
-
const contexts = browser.contexts();
|
|
538
|
-
const context = contexts.length > 0 ? contexts[0] : await browser.newContext();
|
|
539
|
-
await context.addInitScript(WEBDRIVER_OVERRIDE_SCRIPT);
|
|
540
|
-
log.info({
|
|
541
|
-
port: cdpPort,
|
|
542
|
-
pid: child.pid
|
|
543
|
-
}, "CloakBrowser launched and connected");
|
|
544
|
-
return {
|
|
545
|
-
browser,
|
|
546
|
-
context,
|
|
547
|
-
...meta
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Cleanup a CloakBrowser session — kill process and remove temp profile if applicable.
|
|
552
|
-
*/
|
|
553
|
-
async function cleanupCloakBrowser(childProcess, temporaryProfileDir) {
|
|
554
|
-
if (childProcess) {
|
|
555
|
-
childProcess.kill();
|
|
556
|
-
await new Promise((resolve) => {
|
|
557
|
-
const timer = setTimeout(resolve, 2e3);
|
|
558
|
-
childProcess.once("exit", () => {
|
|
559
|
-
clearTimeout(timer);
|
|
560
|
-
resolve();
|
|
561
|
-
});
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
if (temporaryProfileDir) {
|
|
565
|
-
await rm(temporaryProfileDir, {
|
|
566
|
-
recursive: true,
|
|
567
|
-
force: true
|
|
568
|
-
}).catch(() => {});
|
|
569
|
-
log.debug({ dir: temporaryProfileDir }, "Cleaned up temporary profile");
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Download (if needed), launch headlessly to verify, then return doctor status.
|
|
574
|
-
* Used by gateway install endpoints and CLI.
|
|
575
|
-
*/
|
|
576
|
-
async function installCloakBrowser(config = {}) {
|
|
577
|
-
const result = await launchCloakBrowser({
|
|
578
|
-
headless: true,
|
|
579
|
-
temporaryProfile: true,
|
|
580
|
-
keepOpen: false,
|
|
581
|
-
cacheDir: config.cacheDir,
|
|
582
|
-
binaryPath: config.binaryPath,
|
|
583
|
-
onProgress: config.onProgress,
|
|
584
|
-
signal: config.signal
|
|
585
|
-
});
|
|
586
|
-
await result.browser?.close().catch(() => {});
|
|
587
|
-
await cleanupCloakBrowser(result.childProcess, result.temporaryProfileDir);
|
|
588
|
-
return cloakBrowserDoctor({
|
|
589
|
-
cacheDir: config.cacheDir,
|
|
590
|
-
binaryPath: config.binaryPath
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
/** Check CloakBrowser installation status. */
|
|
594
|
-
async function cloakBrowserDoctor(config = {}) {
|
|
595
|
-
const platformInfo = detectPlatform();
|
|
596
|
-
const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);
|
|
597
|
-
const { execPath, installed, customBinaryPath } = await resolveCloakExecutablePath(cacheDir, platformInfo, config.binaryPath);
|
|
598
|
-
const [primary, ...fallbacks] = archiveDownloadUrls(platformInfo);
|
|
599
|
-
return {
|
|
600
|
-
installed,
|
|
601
|
-
version: installed ? platformInfo.chromiumVersion : null,
|
|
602
|
-
binaryPath: installed ? execPath : null,
|
|
603
|
-
platform: platformInfo.tag,
|
|
604
|
-
cacheDir,
|
|
605
|
-
expectedSha256: platformInfo.expectedSha256,
|
|
606
|
-
downloadUrl: primary ?? "",
|
|
607
|
-
fallbackUrls: fallbacks,
|
|
608
|
-
customBinaryPath
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
//#endregion
|
|
612
|
-
export { cleanupCloakBrowser, cloakBrowserArchiveDownloadUrls, cloakBrowserDoctor, defaultCloakBrowserCacheDir, installCloakBrowser, launchCloakBrowser, listCloakBrowserPlatforms, probeCloakBrowserRuntime, resolveCloakBrowserCacheDir, resolveCloakBrowserPersistentProfileDir };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { BrowserRecipe, BrowserRecipeRun, BrowserRecipeRunEvent } from './types.js';
|
|
2
|
-
export declare function listBrowserRecipes(): BrowserRecipe[];
|
|
3
|
-
export declare function getBrowserRecipe(id: string): BrowserRecipe | null;
|
|
4
|
-
export declare function saveBrowserRecipe(recipe: BrowserRecipe): void;
|
|
5
|
-
export declare function deleteBrowserRecipe(id: string): boolean;
|
|
6
|
-
export declare function saveBrowserRecipeRun(run: BrowserRecipeRun): void;
|
|
7
|
-
export declare function getBrowserRecipeRun(id: string): BrowserRecipeRun | null;
|
|
8
|
-
export declare function listBrowserRecipeRuns(recipeId?: string): BrowserRecipeRun[];
|
|
9
|
-
export declare function hasActiveBrowserRecipeRuns(recipeId: string): boolean;
|
|
10
|
-
export declare function listActiveBrowserRecipeRuns(): BrowserRecipeRun[];
|
|
11
|
-
export declare function nextBrowserRecipeRunEventSeq(runId: string): number;
|
|
12
|
-
export declare function appendBrowserRecipeRunEvent(event: BrowserRecipeRunEvent): void;
|
|
13
|
-
export declare function listBrowserRecipeRunEvents(runId: string): BrowserRecipeRunEvent[];
|