@xopcai/xopc 0.0.82 → 0.0.84
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 +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +2 -3
- package/dist/extensions/feishu/src/outbound/media-load.js.map +1 -1
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/config-schema.d.ts +6 -6
- package/dist/extensions/telegram/src/plugin.d.ts +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +3 -3
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/gateway/static/root/assets/agents-tR-nNP04.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-pJ27dsqn.js → apps-page-BDw6SP-d.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DEFd-jj1.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D1KYmOmi.js → channels-status-swr-DI5FHdGe.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-Y2wfSJVI.js → cron-api-BSqY8LwW.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-B97KU_RG.js → cron-page-D7lVDjcR.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-CboA_Css.js → dist-CqNMNhJM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DN_zNmpo.js → extension-debug-page-gf2L0kY_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BUXtOzv5.js → extension-page-CQo2Xsmg.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C2dX4KCW.js → extension-settings-page-CZf0WoZg.js} +1 -1
- package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +3 -0
- package/dist/gateway/static/root/assets/{field-primitives-B9rOLqdm.js → field-primitives-DTtlp-l8.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-DvfiRVrc.js → heartbeat-config-api-B0drdQEJ.js} +1 -1
- package/dist/gateway/static/root/assets/{index-DQuaMye9.js → index-0Gt3TG4j.js} +94 -85
- package/dist/gateway/static/root/assets/index-BuFldCsB.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-BQuBpHcc.js → logs-page-DMuORLfC.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-_UO8g6NN.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-2Yu-FASs.js → settings-form-section-DkmHkknc.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-Cz8FoW_A.js +3 -0
- package/dist/gateway/static/root/assets/skills-page-HrUOxF7H.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DnwYutiX.js → theme-store-D01dJt95.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-D2Gn2qod.js → utils-BFwcR6pL.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-JF8-aqc5.js +1 -0
- package/dist/gateway/static/root/index.html +4 -4
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +50 -0
- package/dist/src/agent/agent-instance-gateway.js +1 -0
- package/dist/src/agent/agent-manager.d.ts +20 -14
- package/dist/src/agent/agent-manager.js +74 -186
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/coordinator.d.ts +61 -0
- package/dist/src/agent/background-review/coordinator.js +120 -0
- package/dist/src/agent/background-review/coordinator.js.map +1 -0
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +14 -0
- package/dist/src/agent/child-agent-factory.js +2 -8
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +3 -3
- package/dist/src/agent/embedded/index.d.ts +1 -2
- package/dist/src/agent/embedded/index.js +2 -3
- package/dist/src/agent/embedded/run-for-session.d.ts +2 -2
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/runs.d.ts +32 -0
- package/dist/src/agent/embedded/runs.js +79 -19
- package/dist/src/agent/embedded/runs.js.map +1 -1
- package/dist/src/agent/embedded/session-manager-cache.d.ts +14 -0
- package/dist/src/agent/embedded/session-manager-cache.js +32 -11
- package/dist/src/agent/embedded/session-manager-cache.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.d.ts +37 -7
- package/dist/src/agent/embedded/session-runner.js +184 -153
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.d.ts +57 -9
- package/dist/src/agent/embedded/session-tool-result-guard.js +159 -67
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.d.ts +84 -0
- package/dist/src/agent/goals/persistent-goal-service.js +139 -0
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -0
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/goals/state.d.ts +1 -1
- package/dist/src/agent/goals/state.js.map +1 -1
- package/dist/src/agent/image/load-image-media.js +1 -1
- package/dist/src/agent/inbound/inbound-loop.d.ts +77 -0
- package/dist/src/agent/inbound/inbound-loop.js +226 -0
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +80 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +138 -0
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -0
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/manager.d.ts +1 -1
- package/dist/src/agent/lifecycle/manager.js.map +1 -1
- package/dist/src/agent/lifecycle/types.d.ts +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.d.ts +12 -2
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
- package/dist/src/agent/memory/index.js +3 -3
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/memory/prefetch-coordinator.d.ts +37 -0
- package/dist/src/agent/memory/prefetch-coordinator.js +45 -0
- package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -0
- package/dist/src/agent/messaging/command-handler.d.ts +5 -1
- package/dist/src/agent/messaging/command-handler.js +24 -96
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/messaging/index.d.ts +1 -0
- package/dist/src/agent/messaging/index.js +2 -1
- package/dist/src/agent/messaging/message-router.d.ts +1 -1
- package/dist/src/agent/messaging/message-router.js.map +1 -1
- package/dist/src/agent/messaging/outbound-coordinator.d.ts +82 -0
- package/dist/src/agent/messaging/outbound-coordinator.js +123 -0
- package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -0
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +36 -33
- package/dist/src/agent/orchestration/agent-event-handler.js +212 -174
- package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +4 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +4 -8
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/orchestration/index.d.ts +1 -1
- package/dist/src/agent/orchestration/index.js +2 -2
- package/dist/src/agent/prompt/service-prompt-builder.js +4 -4
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +1 -1
- package/dist/src/agent/service/async-queue.d.ts +20 -0
- package/dist/src/agent/service/async-queue.js +53 -0
- package/dist/src/agent/service/async-queue.js.map +1 -0
- package/dist/src/agent/service/build-direct-message-content.d.ts +2 -2
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +70 -0
- package/dist/src/agent/service/direct-turn-helpers.js +90 -0
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -0
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
- package/dist/src/agent/service/process-direct-one-shot.js +17 -34
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +122 -168
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +2 -2
- package/dist/src/agent/service/webchat-tts.js +1 -1
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +62 -167
- package/dist/src/agent/service.js +177 -786
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/index.d.ts +4 -0
- package/dist/src/agent/session/index.js +5 -1
- package/dist/src/agent/session/session-config-service.d.ts +68 -0
- package/dist/src/agent/session/session-config-service.js +172 -0
- package/dist/src/agent/session/session-config-service.js.map +1 -0
- package/dist/src/agent/session/session-context.d.ts +27 -19
- package/dist/src/agent/session/session-context.js +39 -24
- package/dist/src/agent/session/session-context.js.map +1 -1
- package/dist/src/agent/session/session-hydrator.d.ts +42 -0
- package/dist/src/agent/session/session-hydrator.js +66 -0
- package/dist/src/agent/session/session-hydrator.js.map +1 -0
- package/dist/src/agent/session/session-inspector.d.ts +80 -0
- package/dist/src/agent/session/session-inspector.js +119 -0
- package/dist/src/agent/session/session-inspector.js.map +1 -0
- package/dist/src/agent/session/session-state-bag.d.ts +83 -0
- package/dist/src/agent/session/session-state-bag.js +192 -0
- package/dist/src/agent/session/session-state-bag.js.map +1 -0
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.d.ts +0 -2
- package/dist/src/agent/skills/index.js +3 -5
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -6
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +35 -7
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -2
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +7 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +37 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/delegate-tool.d.ts +7 -0
- package/dist/src/agent/tools/delegate-tool.js +2 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/executor.d.ts +34 -15
- package/dist/src/agent/tools/executor.js +44 -79
- package/dist/src/agent/tools/executor.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +6 -0
- package/dist/src/agent/tools/factory.js +63 -4
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/skills-tools.js +1 -1
- package/dist/src/agent/tools/tts-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +48 -0
- package/dist/src/agent/workspace-runtime/registry.js +59 -0
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +4 -3
- package/dist/src/browser/cdp-local-launcher.js.map +1 -1
- package/dist/src/browser/index.d.ts +1 -0
- package/dist/src/browser/index.js +2 -1
- package/dist/src/browser/manager.js +3 -2
- package/dist/src/browser/manager.js.map +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/browser-use.js +2 -1
- package/dist/src/browser/providers/browser-use.js.map +1 -1
- package/dist/src/browser/providers/browserbase.js +2 -1
- package/dist/src/browser/providers/browserbase.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +7 -6
- package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
- package/dist/src/browser/providers/playwright-doctor.d.ts +2 -0
- package/dist/src/browser/providers/playwright-doctor.js +7 -3
- package/dist/src/browser/providers/playwright-doctor.js.map +1 -1
- package/dist/src/browser/readiness.d.ts +33 -0
- package/dist/src/browser/readiness.js +138 -0
- package/dist/src/browser/readiness.js.map +1 -0
- package/dist/src/browser/stealth.js +2 -2
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/channel-domain.d.ts +1 -1
- package/dist/src/channels/config-helpers.d.ts +1 -1
- package/dist/src/channels/config-helpers.js.map +1 -1
- package/dist/src/channels/heartbeat-scheduler.d.ts +40 -0
- package/dist/src/channels/heartbeat-scheduler.js +94 -0
- package/dist/src/channels/heartbeat-scheduler.js.map +1 -0
- package/dist/src/channels/lifecycle-supervisor.d.ts +81 -0
- package/dist/src/channels/lifecycle-supervisor.js +263 -0
- package/dist/src/channels/lifecycle-supervisor.js.map +1 -0
- package/dist/src/channels/manager.d.ts +34 -68
- package/dist/src/channels/manager.js +107 -477
- package/dist/src/channels/manager.js.map +1 -1
- package/dist/src/channels/outbound/deliver.d.ts +1 -1
- package/dist/src/channels/outbound/deliver.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/outbound-sender.d.ts +51 -0
- package/dist/src/channels/outbound-sender.js +125 -0
- package/dist/src/channels/outbound-sender.js.map +1 -0
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-service.d.ts +3 -10
- package/dist/src/channels/pairing/pairing-service.js.map +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/pairing/pairing-types.d.ts +15 -0
- package/dist/src/channels/pairing/pairing-types.js +1 -0
- package/dist/src/channels/plugin-registry.d.ts +22 -0
- package/dist/src/channels/plugin-registry.js +44 -0
- package/dist/src/channels/plugin-registry.js.map +1 -0
- package/dist/src/channels/plugin-types.d.ts +1 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
- package/dist/src/channels/security-helpers.d.ts +1 -1
- package/dist/src/channels/security-helpers.js.map +1 -1
- package/dist/src/channels/setup-wizard.d.ts +1 -1
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/command-catalog.js +110 -8
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +2 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +9 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js.map +1 -1
- package/dist/src/cli/commands/agent.js +4 -4
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +2 -1
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/config.js +70 -19
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/cron-cli.d.ts +2 -0
- package/dist/src/cli/commands/cron-cli.js +15 -0
- package/dist/src/cli/commands/cron-cli.js.map +1 -0
- package/dist/src/cli/commands/cron.d.ts +4 -1
- package/dist/src/cli/commands/cron.js +76 -41
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-health.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/gateway-service.js +2 -2
- package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +2 -2
- package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +4 -4
- package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/call.js +1 -1
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/health.js +1 -1
- package/dist/src/cli/commands/gateway/health.js.map +1 -1
- package/dist/src/cli/commands/gateway/index.d.ts +1 -1
- package/dist/src/cli/commands/gateway/index.js +2 -2
- package/dist/src/cli/commands/gateway/lifecycle-core.d.ts +31 -12
- package/dist/src/cli/commands/gateway/lifecycle-core.js +167 -116
- package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.d.ts +11 -0
- package/dist/src/cli/commands/gateway/lifecycle.js +102 -0
- package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -0
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js.map +1 -1
- package/dist/src/cli/commands/gateway/probe.js +1 -1
- package/dist/src/cli/commands/gateway/probe.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart-health.d.ts +12 -0
- package/dist/src/cli/commands/gateway/restart-health.js +45 -1
- package/dist/src/cli/commands/gateway/restart-health.js.map +1 -1
- package/dist/src/cli/commands/gateway/restart.js +3 -3
- package/dist/src/cli/commands/gateway/restart.js.map +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.d.ts +0 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +0 -35
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/gateway/service.d.ts +4 -0
- package/dist/src/cli/commands/gateway/service.js +18 -3
- package/dist/src/cli/commands/gateway/service.js.map +1 -1
- package/dist/src/cli/commands/gateway/shared.d.ts +3 -0
- package/dist/src/cli/commands/gateway/shared.js +54 -0
- package/dist/src/cli/commands/gateway/shared.js.map +1 -0
- package/dist/src/cli/commands/gateway/status.js +1 -1
- package/dist/src/cli/commands/gateway/status.js.map +1 -1
- package/dist/src/cli/commands/gateway/stop.js +2 -2
- package/dist/src/cli/commands/gateway/stop.js.map +1 -1
- package/dist/src/cli/commands/gateway/subcommands.js +1 -4
- package/dist/src/cli/commands/gateway/subcommands.js.map +1 -1
- package/dist/src/cli/commands/gateway/token.js +1 -1
- package/dist/src/cli/commands/gateway/token.js.map +1 -1
- package/dist/src/cli/commands/gateway.js +5 -5
- package/dist/src/cli/commands/gateway.js.map +1 -1
- package/dist/src/cli/commands/image.js +2 -2
- package/dist/src/cli/commands/image.js.map +1 -1
- package/dist/src/cli/commands/init.js +31 -4
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/models.d.ts +4 -1
- package/dist/src/cli/commands/models.js +87 -75
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/gateway.d.ts +0 -8
- package/dist/src/cli/commands/onboard/gateway.js +48 -49
- package/dist/src/cli/commands/onboard/gateway.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +11 -64
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/profile.d.ts +3 -5
- package/dist/src/cli/commands/profile.js +31 -31
- package/dist/src/cli/commands/profile.js.map +1 -1
- package/dist/src/cli/commands/session/utils.js +1 -1
- package/dist/src/cli/commands/session/utils.js.map +1 -1
- package/dist/src/cli/commands/setup.js +6 -1
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/commands/tailscale.js +1 -1
- package/dist/src/cli/commands/tailscale.js.map +1 -1
- package/dist/src/cli/context.d.ts +20 -0
- package/dist/src/cli/context.js +23 -0
- package/dist/src/cli/context.js.map +1 -0
- package/dist/src/cli/extension-cli-register.js +3 -3
- package/dist/src/cli/gateway-run-argv.js +16 -9
- package/dist/src/cli/gateway-run-argv.js.map +1 -1
- package/dist/src/cli/gateway-run-fast-path.js +1 -1
- package/dist/src/cli/gateway-run-fast-path.js.map +1 -1
- package/dist/src/cli/index.d.ts +1 -7
- package/dist/src/cli/index.js +4 -6
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/commands.flags.d.ts +3 -0
- package/dist/src/config/commands.flags.js +11 -0
- package/dist/src/config/commands.flags.js.map +1 -0
- package/dist/src/config/index.d.ts +1 -0
- package/dist/src/config/index.js +6 -5
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +11 -4
- package/dist/src/config/schema.js +13 -12
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path-helpers.d.ts +15 -0
- package/dist/src/config/workspace-path-helpers.js +14 -0
- package/dist/src/config/workspace-path-helpers.js.map +1 -0
- package/dist/src/cron/executor.js +4 -4
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/index.d.ts +0 -1
- package/dist/src/daemon/index.js +1 -2
- package/dist/src/daemon/install-plan.js +3 -2
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/daemon/types.d.ts +0 -6
- package/dist/src/extensions/api.d.ts +1 -1
- package/dist/src/extensions/api.js +2 -2
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +51 -0
- package/dist/src/extensions/extension-registry-impl.js +117 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -0
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/index.js +3 -2
- package/dist/src/extensions/loader.d.ts +3 -43
- package/dist/src/extensions/loader.js +3 -110
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/sdk/index.js +2 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/types/events.d.ts +7 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +5 -53
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +5 -14
- package/dist/src/gateway/hono/middleware/auth.js +89 -126
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/logger.js.map +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +14 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +62 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js.map +1 -0
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -4
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
- package/dist/src/gateway/hono/routes/browser.d.ts +20 -0
- package/dist/src/gateway/hono/routes/browser.js +626 -0
- package/dist/src/gateway/hono/routes/browser.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +13 -13
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js +418 -0
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +12 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js +186 -0
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +264 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/index.d.ts +9 -0
- package/dist/src/gateway/hono/routes/config-patch/index.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +23 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js +139 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -0
- package/dist/src/gateway/hono/routes/config-patch/result.d.ts +18 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js +13 -0
- package/dist/src/gateway/hono/routes/config-patch/result.js.map +1 -0
- package/dist/src/gateway/hono/routes/config.js +20 -1764
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +2 -3
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -5
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -2
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +32 -32
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +4 -4
- package/dist/src/gateway/hono/routes/shares.js.map +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +6 -7
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.js +2 -2
- package/dist/src/gateway/index.d.ts +1 -1
- package/dist/src/gateway/index.js +4 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/rate-limit/auth-policy.d.ts +34 -0
- package/dist/src/gateway/rate-limit/auth-policy.js +49 -0
- package/dist/src/gateway/rate-limit/auth-policy.js.map +1 -0
- package/dist/src/gateway/rate-limit/buckets.d.ts +63 -0
- package/dist/src/gateway/rate-limit/buckets.js +143 -0
- package/dist/src/gateway/rate-limit/buckets.js.map +1 -0
- package/dist/src/gateway/rate-limit/env-flags.d.ts +13 -0
- package/dist/src/gateway/rate-limit/env-flags.js +16 -0
- package/dist/src/gateway/rate-limit/env-flags.js.map +1 -0
- package/dist/src/gateway/rate-limit/index.d.ts +3 -0
- package/dist/src/gateway/rate-limit/index.js +4 -0
- package/dist/src/gateway/run-loop.d.ts +1 -1
- package/dist/src/gateway/run-loop.js +24 -4
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/runtime-config.js +2 -1
- package/dist/src/gateway/runtime-config.js.map +1 -1
- package/dist/src/gateway/security/audit.js +2 -1
- package/dist/src/gateway/security/audit.js.map +1 -1
- package/dist/src/gateway/security/index.d.ts +0 -1
- package/dist/src/gateway/security/index.js +1 -2
- package/dist/src/gateway/security/loopback.d.ts +13 -0
- package/dist/src/gateway/security/loopback.js +45 -0
- package/dist/src/gateway/security/loopback.js.map +1 -0
- package/dist/src/gateway/service/agent-runner.d.ts +108 -0
- package/dist/src/gateway/service/agent-runner.js +184 -0
- package/dist/src/gateway/service/agent-runner.js.map +1 -0
- package/dist/src/gateway/service/config-coordinator.d.ts +119 -0
- package/dist/src/gateway/service/config-coordinator.js +351 -0
- package/dist/src/gateway/service/config-coordinator.js.map +1 -0
- package/dist/src/gateway/service/marketplace-service.d.ts +85 -0
- package/dist/src/gateway/service/marketplace-service.js +239 -0
- package/dist/src/gateway/service/marketplace-service.js.map +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +5 -5
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +125 -0
- package/dist/src/gateway/service/sessions-api.js +135 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -0
- package/dist/src/gateway/service.d.ts +30 -360
- package/dist/src/gateway/service.js +122 -904
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/gateway/workspace-heartbeat-path.js +1 -2
- package/dist/src/gateway/workspace-heartbeat-path.js.map +1 -1
- package/dist/src/infra/gateway-process-argv.d.ts +4 -0
- package/dist/src/infra/gateway-process-argv.js +26 -0
- package/dist/src/infra/gateway-process-argv.js.map +1 -0
- package/dist/src/infra/gateway-processes.d.ts +5 -0
- package/dist/src/infra/gateway-processes.js +65 -0
- package/dist/src/infra/gateway-processes.js.map +1 -0
- package/dist/src/infra/rate-limit/failure-limiter.d.ts +50 -0
- package/dist/src/infra/rate-limit/failure-limiter.js +100 -0
- package/dist/src/infra/rate-limit/failure-limiter.js.map +1 -0
- package/dist/src/infra/rate-limit/index.d.ts +5 -0
- package/dist/src/infra/rate-limit/index.js +3 -0
- package/dist/src/infra/rate-limit/keyed-store.d.ts +34 -0
- package/dist/src/infra/rate-limit/keyed-store.js +44 -0
- package/dist/src/infra/rate-limit/keyed-store.js.map +1 -0
- package/dist/src/infra/rate-limit/rate-limiter.d.ts +39 -0
- package/dist/src/infra/rate-limit/rate-limiter.js +65 -0
- package/dist/src/infra/rate-limit/rate-limiter.js.map +1 -0
- package/dist/src/infra/restart.d.ts +21 -0
- package/dist/src/infra/restart.js +122 -0
- package/dist/src/infra/restart.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-bridge.d.ts +0 -6
- package/dist/src/mcp/channel-bridge.js +1 -5
- package/dist/src/mcp/channel-bridge.js.map +1 -1
- package/dist/src/media-shared/http/ssrf-guard.js +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file-read.d.ts +2 -1
- package/dist/src/session/parity/sessions-json-file-read.js.map +1 -1
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +1 -1
- package/dist/src/session/store.js +5 -5
- package/dist/src/share/share-rate-limit.d.ts +10 -2
- package/dist/src/share/share-rate-limit.js +33 -42
- package/dist/src/share/share-rate-limit.js.map +1 -1
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/tui/backends/embedded-backend.js +16 -12
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +2 -2
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/format-tui-hotkeys.js +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +1 -1
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js +1 -1
- package/dist/src/tui/tui.js +1 -2
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +0 -1
- package/dist/src/tui/xopc-tui-keybindings.js +1 -2
- package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
- package/dist/src/tunnel/frpc-binary.js +2 -2
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/pairing-rate-limit.d.ts +10 -2
- package/dist/src/tunnel/pairing-rate-limit.js +19 -15
- package/dist/src/tunnel/pairing-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-rate-limit.d.ts +6 -3
- package/dist/src/tunnel/tunnel-rate-limit.js +11 -22
- package/dist/src/tunnel/tunnel-rate-limit.js.map +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/factory.js +1 -1
- package/dist/src/voice/tts/index.js +2 -2
- package/dist/src/voice/tts/merge-config.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +1 -1
- package/dist/src/voice/tts/service.js +1 -1
- package/dist/src/voice/tts/service.js.map +1 -1
- package/dist/src/voice/tts/speak-core.js +1 -1
- package/package.json +10 -5
- package/dist/gateway/static/root/assets/agents-Cqh1ts38.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-wTiWStg9.js +0 -1
- package/dist/gateway/static/root/assets/fetch-BAAh_kXG.js +0 -3
- package/dist/gateway/static/root/assets/index-C8yHX-AA.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BeiFm0Ms.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-RPAz_Wg_.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-Wu4aNWDx.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-BxIGhhEL.js +0 -1
- package/dist/src/agent/embedded/session-raw-append-message.d.ts +0 -11
- package/dist/src/agent/embedded/session-raw-append-message.js +0 -15
- package/dist/src/agent/embedded/session-raw-append-message.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.d.ts +0 -15
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js +0 -24
- package/dist/src/agent/embedded/session-tool-result-guard-wrapper.js.map +0 -1
- package/dist/src/agent/embedded/session-tool-result-state.d.ts +0 -17
- package/dist/src/agent/embedded/session-tool-result-state.js +0 -26
- package/dist/src/agent/embedded/session-tool-result-state.js.map +0 -1
- package/dist/src/daemon/launchd-restart-handoff.d.ts +0 -25
- package/dist/src/daemon/launchd-restart-handoff.js +0 -132
- package/dist/src/daemon/launchd-restart-handoff.js.map +0 -1
- package/dist/src/gateway/auth-rate-limit.d.ts +0 -71
- package/dist/src/gateway/auth-rate-limit.js +0 -192
- package/dist/src/gateway/auth-rate-limit.js.map +0 -1
- package/dist/src/gateway/restart-handler.d.ts +0 -14
- package/dist/src/gateway/restart-handler.js +0 -64
- package/dist/src/gateway/restart-handler.js.map +0 -1
- package/dist/src/gateway/security/flood-guard.d.ts +0 -28
- package/dist/src/gateway/security/flood-guard.js +0 -42
- package/dist/src/gateway/security/flood-guard.js.map +0 -1
- package/dist/src/infra/rate-limit.d.ts +0 -38
- package/dist/src/infra/rate-limit.js +0 -60
- package/dist/src/infra/rate-limit.js.map +0 -1
- package/dist/src/infra/restart-intent.d.ts +0 -13
- package/dist/src/infra/restart-intent.js +0 -40
- package/dist/src/infra/restart-intent.js.map +0 -1
- package/dist/src/infra/restart-sentinel.d.ts +0 -23
- package/dist/src/infra/restart-sentinel.js +0 -75
- package/dist/src/infra/restart-sentinel.js.map +0 -1
- package/skills/creative/canvas-design/LICENSE.txt +0 -202
- package/skills/creative/canvas-design/SKILL-zh.md +0 -130
- package/skills/creative/canvas-design/SKILL.md +0 -130
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloakbrowser.js","names":["osPlatform","osArch"],"sources":["../../../../src/browser/providers/cloakbrowser.ts"],"sourcesContent":["/**\n * CloakBrowser provider — anti-fingerprint Chromium with stealth capabilities.\n *\n * Manages CloakBrowser binary download, stealth launch, CDP connection,\n * keep-open process reuse, and temporary profile lifecycle.\n *\n * Ported from brocli's cloak.rs to TypeScript, using Playwright's connectOverCDP\n * to produce a standard Browser/BrowserContext pair.\n */\n\nimport { createHash } from 'node:crypto';\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { mkdir, mkdtemp, readdir, rename, rm, stat } from 'node:fs/promises';\nimport { platform as osPlatform, arch as osArch, tmpdir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { Readable, Transform } from 'node:stream';\nimport { ChildProcess, spawn } from 'node:child_process';\n\nimport AdmZip from 'adm-zip';\nimport type { Browser, BrowserContext } from 'playwright-core';\n\nimport type { BrowserInstallProgress } from '../install-progress.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { resolveBinDir } from '../../config/paths.js';\nimport { assertCacheDir, expandHome } from '../cache-dir-policy.js';\nimport { pickFreePort } from '../free-port.js';\nimport {\n buildStealthArgs,\n filterCloakBrowserExtraArgs,\n generateFingerprintSeed,\n makeExecutable,\n removeQuarantineAttr,\n WEBDRIVER_OVERRIDE_SCRIPT,\n} from '../stealth.js';\nimport type { CloakBrowserConfig } from './types.js';\n\nconst log = createLogger('CloakBrowser');\n\n// ── Platform info ───────────────────────────────────────────────────────────\n\ninterface PlatformInfo {\n tag: string;\n chromiumVersion: string;\n archiveExt: string;\n executableRelativePath: string;\n fingerprintPlatform: string;\n /**\n * Expected SHA-256 of the downloaded archive (lowercase hex). Empty string =\n * verification opt-out for this platform; warned but not fatal. To populate:\n * download the archive once, run `shasum -a 256 <file>`, paste here.\n */\n expectedSha256: string;\n}\n\nconst DOWNLOAD_BASE_URL = 'https://cloakbrowser.dev';\nconst GITHUB_DOWNLOAD_BASE_URL = 'https://github.com/CloakHQ/CloakBrowser/releases/download';\nconst XOPC_CLOAKBROWSER_PROXY_BASE =\n process.env.XOPC_CLOAKBROWSER_DOWNLOAD_BASE?.trim().replace(/\\/$/, '') ||\n 'https://xopc.ai/api/cloakbrowser/download';\nconst READY_TIMEOUT_MS = 45_000;\nconst READY_POLL_INTERVAL_MS = 300;\nconst DEFAULT_KEEP_OPEN_CDP_PORT = 9222;\n\nconst PLATFORMS: Record<string, PlatformInfo> = {\n 'darwin-arm64': {\n tag: 'darwin-arm64',\n chromiumVersion: '145.0.7632.109.2',\n archiveExt: '.tar.gz',\n executableRelativePath: 'Chromium.app/Contents/MacOS/Chromium',\n fingerprintPlatform: 'macos',\n expectedSha256: '',\n },\n 'darwin-x64': {\n tag: 'darwin-x64',\n chromiumVersion: '145.0.7632.109.2',\n archiveExt: '.tar.gz',\n executableRelativePath: 'Chromium.app/Contents/MacOS/Chromium',\n fingerprintPlatform: 'macos',\n expectedSha256: '',\n },\n 'linux-arm64': {\n tag: 'linux-arm64',\n chromiumVersion: '146.0.7680.177.4',\n archiveExt: '.tar.gz',\n executableRelativePath: 'chrome',\n fingerprintPlatform: 'windows',\n expectedSha256: '',\n },\n 'linux-x64': {\n tag: 'linux-x64',\n chromiumVersion: '146.0.7680.177.4',\n archiveExt: '.tar.gz',\n executableRelativePath: 'chrome',\n fingerprintPlatform: 'windows',\n expectedSha256: '',\n },\n 'win32-x64': {\n tag: 'windows-x64',\n chromiumVersion: '146.0.7680.177.4',\n archiveExt: '.zip',\n executableRelativePath: 'chrome.exe',\n fingerprintPlatform: 'windows',\n expectedSha256: '',\n },\n};\n\nfunction detectPlatform(): PlatformInfo {\n const os = osPlatform();\n const architecture = osArch();\n const archMap: Record<string, string> = { arm64: 'arm64', x64: 'x64' };\n const key = `${os}-${archMap[architecture] ?? architecture}`;\n const info = PLATFORMS[key];\n if (!info) {\n throw new Error(`Unsupported CloakBrowser platform: ${os}/${architecture}`);\n }\n return info;\n}\n\n/** Test-only: enumerate platform manifests. */\nexport function listCloakBrowserPlatforms(): PlatformInfo[] {\n return Object.values(PLATFORMS);\n}\n\nfunction archiveDownloadUrls(platformInfo: PlatformInfo): string[] {\n const archiveName = `cloakbrowser-${platformInfo.tag}${platformInfo.archiveExt}`;\n return [\n `${XOPC_CLOAKBROWSER_PROXY_BASE}/${archiveName}`,\n `${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${platformInfo.chromiumVersion}/${archiveName}`,\n `${DOWNLOAD_BASE_URL}/download/${archiveName}`,\n ];\n}\n\n/** Test-only: resolved download URLs for a platform manifest (proxy first). */\nexport function cloakBrowserArchiveDownloadUrls(platformInfo: PlatformInfo): string[] {\n return archiveDownloadUrls(platformInfo);\n}\n\nasync function sha256OfFile(path: string): Promise<string> {\n const hash = createHash('sha256');\n await pipeline(createReadStream(path), hash);\n return hash.digest('hex');\n}\n\n// ── Binary management ───────────────────────────────────────────────────────\n\nconst CLOAKBROWSER_DIR_NAME = 'cloakbrowser';\n\n/** Default CloakBrowser home: ~/.xopc/bin/cloakbrowser (chromium-v*, profiles/, …). */\nexport function defaultCloakBrowserCacheDir(): string {\n return join(resolveBinDir(), CLOAKBROWSER_DIR_NAME);\n}\n\n/** Resolve configured or default CloakBrowser cache root. */\nexport function resolveCloakBrowserCacheDir(configured?: string): string {\n if (configured?.trim()) {\n const resolved = assertCacheDir(configured.trim());\n // Legacy configs used ~/.xopc/bin — normalize to ~/.xopc/bin/cloakbrowser.\n if (resolve(resolved) === resolve(resolveBinDir())) {\n return defaultCloakBrowserCacheDir();\n }\n return resolved;\n }\n return defaultCloakBrowserCacheDir();\n}\n\nasync function resolveCloakExecutablePath(\n cacheDir: string,\n platformInfo: PlatformInfo,\n configuredBinaryPath?: string,\n): Promise<{ execPath: string; installed: boolean; customBinaryPath: boolean }> {\n const trimmed = configuredBinaryPath?.trim();\n const autoPath = binaryPath(cacheDir, platformInfo);\n if (!trimmed) {\n return {\n execPath: autoPath,\n installed: await fileExists(autoPath),\n customBinaryPath: false,\n };\n }\n\n const customPath = resolve(expandHome(trimmed));\n if (await fileExists(customPath)) {\n return { execPath: customPath, installed: true, customBinaryPath: true };\n }\n\n if (await fileExists(autoPath)) {\n return { execPath: autoPath, installed: true, customBinaryPath: true };\n }\n\n return { execPath: customPath, installed: false, customBinaryPath: true };\n}\n\n/**\n * Move legacy layout (~/.xopc/bin/chromium-v* and profiles/) into ~/.xopc/bin/cloakbrowser/.\n * No-op when using a custom cacheDir or when the new layout already exists.\n */\nexport async function migrateLegacyCloakBrowserLayout(cacheDir: string): Promise<void> {\n if (cacheDir !== defaultCloakBrowserCacheDir()) return;\n\n const binDir = resolveBinDir();\n await mkdir(cacheDir, { recursive: true });\n\n let entries: string[];\n try {\n entries = await readdir(binDir);\n } catch {\n return;\n }\n\n for (const name of entries) {\n if (!name.startsWith('chromium-v')) continue;\n const from = join(binDir, name);\n const to = join(cacheDir, name);\n if (await fileExists(to)) continue;\n if (!(await fileExists(from))) continue;\n try {\n await rename(from, to);\n log.info({ from, to }, 'Migrated legacy CloakBrowser binary directory');\n } catch (err) {\n log.warn({ err, from, to }, 'Failed to migrate legacy CloakBrowser binary directory');\n }\n }\n\n const legacyProfiles = join(binDir, 'profiles');\n const newProfiles = join(cacheDir, 'profiles');\n if (await fileExists(newProfiles) || !(await fileExists(legacyProfiles))) return;\n\n try {\n await rename(legacyProfiles, newProfiles);\n log.info({ from: legacyProfiles, to: newProfiles }, 'Migrated legacy CloakBrowser profiles directory');\n } catch (err) {\n log.warn({ err, from: legacyProfiles, to: newProfiles }, 'Failed to migrate legacy CloakBrowser profiles');\n }\n}\n\nfunction binaryDir(cacheDir: string, platformInfo: PlatformInfo): string {\n return join(cacheDir, `chromium-v${platformInfo.chromiumVersion}`);\n}\n\nfunction binaryPath(cacheDir: string, platformInfo: PlatformInfo): string {\n return join(binaryDir(cacheDir, platformInfo), platformInfo.executableRelativePath);\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction runCommand(command: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, { stdio: ['ignore', 'ignore', 'pipe'] });\n let stderr = '';\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n child.once('error', reject);\n child.once('exit', (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n const reason = signal ? `signal ${signal}` : `exit code ${code ?? 'unknown'}`;\n const detail = stderr.trim() ? `: ${stderr.trim().slice(0, 500)}` : '';\n reject(new Error(`${command} failed with ${reason}${detail}`));\n });\n });\n}\n\nasync function extractArchive(archivePath: string, targetDir: string, platformInfo: PlatformInfo): Promise<void> {\n if (platformInfo.archiveExt === '.tar.gz') {\n await runCommand('tar', ['-xzf', archivePath, '-C', targetDir]);\n return;\n }\n\n if (platformInfo.archiveExt === '.zip') {\n const zip = new AdmZip(archivePath);\n zip.extractAllTo(targetDir, true);\n return;\n }\n\n throw new Error(`Unsupported CloakBrowser archive format: ${platformInfo.archiveExt}`);\n}\n\n/**\n * Download and extract CloakBrowser binary.\n *\n * After download, verifies SHA-256 against the platform manifest when one is\n * present. Set `XOPC_CLOAKBROWSER_SKIP_HASH=1` to bypass (development only;\n * the gateway logs a warning when the env var is honoured).\n */\nasync function downloadArchiveToFile(\n url: string,\n archivePath: string,\n onProgress?: (progress: BrowserInstallProgress) => void | Promise<void>,\n signal?: AbortSignal,\n): Promise<void> {\n if (signal?.aborted) throw new Error('Install cancelled');\n\n const response = await fetch(url, { redirect: 'follow', signal });\n if (!response.ok || !response.body) {\n throw new Error(`download returned HTTP ${response.status}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const totalBytes =\n contentLength && Number.isFinite(Number(contentLength)) ? Number(contentLength) : null;\n let bytesReceived = 0;\n\n let lastReportAt = 0;\n const report = (force = false) => {\n const now = Date.now();\n if (!force && now - lastReportAt < 250) return;\n lastReportAt = now;\n void onProgress?.({\n phase: 'downloading',\n message: 'Downloading CloakBrowser archive',\n bytesReceived,\n totalBytes,\n percent:\n totalBytes && totalBytes > 0\n ? Math.min(100, Math.round((bytesReceived / totalBytes) * 100))\n : null,\n });\n };\n\n report(true);\n\n const nodeStream = Readable.fromWeb(response.body as Parameters<typeof Readable.fromWeb>[0]);\n const counting = new Transform({\n transform(chunk, _encoding, callback) {\n bytesReceived += chunk.length;\n report();\n callback(null, chunk);\n },\n });\n\n await pipeline(nodeStream, counting, createWriteStream(archivePath));\n report(true);\n}\n\nasync function downloadBinary(\n cacheDir: string,\n platformInfo: PlatformInfo,\n onProgress?: (progress: BrowserInstallProgress) => void | Promise<void>,\n signal?: AbortSignal,\n): Promise<string> {\n const targetDir = binaryDir(cacheDir, platformInfo);\n const execPath = binaryPath(cacheDir, platformInfo);\n\n if (await fileExists(execPath)) {\n log.info({ path: execPath }, 'CloakBrowser binary already cached');\n await onProgress?.({ phase: 'ready', message: 'CloakBrowser binary already cached', percent: 100 });\n return execPath;\n }\n\n await mkdir(cacheDir, { recursive: true });\n await onProgress?.({ phase: 'starting', message: 'Preparing CloakBrowser download' });\n\n const archiveName = `cloakbrowser-${platformInfo.tag}${platformInfo.archiveExt}`;\n const urls = archiveDownloadUrls(platformInfo);\n const expectedSha256 = platformInfo.expectedSha256.trim().toLowerCase();\n const skipHash = process.env.XOPC_CLOAKBROWSER_SKIP_HASH === '1';\n\n log.info({ version: platformInfo.chromiumVersion, platform: platformInfo.tag }, 'Downloading CloakBrowser...');\n\n let downloadError: Error | undefined;\n for (const url of urls) {\n if (signal?.aborted) throw new Error('Install cancelled');\n const stagingDir = await mkdtemp(join(cacheDir, '.download-'));\n const archivePath = join(stagingDir, archiveName);\n try {\n await downloadArchiveToFile(url, archivePath, onProgress, signal);\n\n if (expectedSha256) {\n if (signal?.aborted) throw new Error('Install cancelled');\n await onProgress?.({ phase: 'verifying', message: 'Verifying SHA-256 checksum' });\n const actual = await sha256OfFile(archivePath);\n if (actual !== expectedSha256) {\n throw new Error(\n `SHA-256 mismatch: expected ${expectedSha256}, got ${actual}. Aborted to avoid running unverified binary.`,\n );\n }\n log.info({ archivePath }, 'SHA-256 verified');\n } else if (skipHash) {\n log.warn(\n { platform: platformInfo.tag, version: platformInfo.chromiumVersion },\n 'CloakBrowser SHA-256 verification skipped (XOPC_CLOAKBROWSER_SKIP_HASH=1)',\n );\n } else {\n log.warn(\n { platform: platformInfo.tag, version: platformInfo.chromiumVersion },\n 'CloakBrowser manifest has no expectedSha256; integrity NOT verified',\n );\n }\n\n await onProgress?.({ phase: 'extracting', message: 'Extracting CloakBrowser archive' });\n log.info({ archivePath }, 'Extracting CloakBrowser archive...');\n await rm(targetDir, { recursive: true, force: true }).catch(() => {});\n await mkdir(targetDir, { recursive: true });\n await extractArchive(archivePath, targetDir, platformInfo);\n\n if (!(await fileExists(execPath))) {\n throw new Error(`archive did not contain expected executable: ${execPath}`);\n }\n\n await makeExecutable(execPath);\n await removeQuarantineAttr(execPath);\n await rm(stagingDir, { recursive: true, force: true }).catch(() => {});\n\n await onProgress?.({ phase: 'ready', message: 'CloakBrowser binary ready', percent: 100 });\n log.info({ path: execPath }, 'CloakBrowser binary ready');\n return execPath;\n } catch (e) {\n await rm(stagingDir, { recursive: true, force: true }).catch(() => {});\n await rm(targetDir, { recursive: true, force: true }).catch(() => {});\n downloadError = e instanceof Error ? e : new Error(String(e));\n log.debug({ url, errorMessage: downloadError.message }, 'Download attempt failed');\n }\n }\n\n throw new Error(\n `Failed to download CloakBrowser v${platformInfo.chromiumVersion} for ${platformInfo.tag}: ${downloadError?.message ?? 'all URLs failed'}`,\n );\n}\n\n// ── CDP endpoint discovery ──────────────────────────────────────────────────\n\nasync function waitForCdpEndpoint(port: number): Promise<string> {\n const deadline = Date.now() + READY_TIMEOUT_MS;\n\n while (Date.now() < deadline) {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/version`);\n if (response.ok) {\n const data = (await response.json()) as { webSocketDebuggerUrl?: string };\n if (data.webSocketDebuggerUrl) {\n return data.webSocketDebuggerUrl;\n }\n }\n } catch {\n // Not ready yet\n }\n await new Promise((resolve) => setTimeout(resolve, READY_POLL_INTERVAL_MS));\n }\n\n throw new Error(`CloakBrowser did not expose CDP page within ${READY_TIMEOUT_MS / 1000}s on port ${port}`);\n}\n\n/** Try to find an existing CDP page endpoint on the given port. */\nasync function reuseOrCreatePageEndpoint(port: number): Promise<string | null> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/list`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!response.ok) return null;\n const pages = (await response.json()) as Array<{ webSocketDebuggerUrl?: string; type?: string }>;\n const page = pages.find((p) => p.type === 'page' && p.webSocketDebuggerUrl);\n if (page?.webSocketDebuggerUrl) return page.webSocketDebuggerUrl;\n\n // No pages — create one\n const newResponse = await fetch(`http://127.0.0.1:${port}/json/new`);\n if (newResponse.ok) {\n const newPage = (await newResponse.json()) as { webSocketDebuggerUrl?: string };\n if (newPage.webSocketDebuggerUrl) return newPage.webSocketDebuggerUrl;\n }\n } catch {\n // Not running\n }\n return null;\n}\n\n// ── Provider ────────────────────────────────────────────────────────────────\n\nexport interface CloakBrowserLaunchResult {\n browser?: Browser;\n context?: BrowserContext;\n childProcess: ChildProcess | null;\n temporaryProfileDir: string | null;\n cdpPort: number;\n userDataDir: string;\n reused: boolean;\n pid: number | null;\n}\n\nfunction resolveCloakBrowserProfilePaths(\n config: CloakBrowserConfig,\n cacheDir: string,\n): { userDataDir: string; temporaryProfileDir: string | null } {\n if (config.userDataDir) {\n return { userDataDir: config.userDataDir, temporaryProfileDir: null };\n }\n if (config.temporaryProfile) {\n const userDataDir = join(tmpdir(), `xopc-cloakbrowser-${process.pid}-${generateFingerprintSeed()}`);\n return { userDataDir, temporaryProfileDir: userDataDir };\n }\n return { userDataDir: join(cacheDir, 'profiles', 'default'), temporaryProfileDir: null };\n}\n\n/** Resolve the persistent profile directory agents use (not ephemeral temp dirs). */\nexport function resolveCloakBrowserPersistentProfileDir(config: CloakBrowserConfig = {}): string {\n if (config.userDataDir) return config.userDataDir;\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n return join(cacheDir, 'profiles', 'default');\n}\n\nexport interface CloakBrowserRuntimeStatus {\n running: boolean;\n port: number;\n userDataDir: string;\n temporaryProfile: boolean;\n}\n\nasync function probeCdpPort(port: number): Promise<boolean> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/version`, {\n signal: AbortSignal.timeout(2000),\n });\n return response.ok;\n } catch {\n return false;\n }\n}\n\n/** Probe whether CloakBrowser CDP is listening on the configured keep-open port. */\nexport async function probeCloakBrowserRuntime(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserRuntimeStatus> {\n const keepOpen = config.keepOpen ?? true;\n const cdpPort = config.cdpPort ?? (keepOpen ? DEFAULT_KEEP_OPEN_CDP_PORT : DEFAULT_KEEP_OPEN_CDP_PORT);\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n const { userDataDir } = resolveCloakBrowserProfilePaths(config, cacheDir);\n const running = await probeCdpPort(cdpPort);\n return {\n running,\n port: cdpPort,\n userDataDir,\n temporaryProfile: config.temporaryProfile === true,\n };\n}\n\nfunction launchResultMeta(\n cdpPort: number,\n userDataDir: string,\n reused: boolean,\n pid: number | null,\n childProcess: ChildProcess | null,\n temporaryProfileDir: string | null,\n): Pick<\n CloakBrowserLaunchResult,\n 'cdpPort' | 'userDataDir' | 'reused' | 'pid' | 'childProcess' | 'temporaryProfileDir'\n> {\n return { cdpPort, userDataDir, reused, pid, childProcess, temporaryProfileDir };\n}\n\n/**\n * Launch or connect to a CloakBrowser instance and return a Playwright Browser + Context.\n */\nexport async function launchCloakBrowser(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserLaunchResult> {\n const platformInfo = detectPlatform();\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n await migrateLegacyCloakBrowserLayout(cacheDir);\n const keepOpen = config.keepOpen ?? true;\n const reuseExisting = config.reuseExisting ?? keepOpen;\n\n // Resolve binary\n const configuredBinary = config.binaryPath?.trim() || undefined;\n const execPath = configuredBinary\n ? (await resolveCloakExecutablePath(cacheDir, platformInfo, configuredBinary)).execPath\n : await downloadBinary(cacheDir, platformInfo, config.onProgress, config.signal);\n if (configuredBinary) {\n await makeExecutable(execPath);\n await removeQuarantineAttr(execPath);\n }\n\n // Resolve CDP port\n const cdpPort = config.cdpPort ?? (keepOpen ? DEFAULT_KEEP_OPEN_CDP_PORT : await pickFreePort());\n const skipPlaywrightConnect = config.skipPlaywrightConnect === true;\n const { userDataDir, temporaryProfileDir: plannedTempProfileDir } = resolveCloakBrowserProfilePaths(\n config,\n cacheDir,\n );\n\n // Try to reuse existing instance\n if (reuseExisting) {\n const existingEndpoint = await reuseOrCreatePageEndpoint(cdpPort);\n if (existingEndpoint) {\n log.info({ port: cdpPort }, 'Reusing existing CloakBrowser instance');\n const meta = launchResultMeta(cdpPort, userDataDir, true, null, null, null);\n if (skipPlaywrightConnect) {\n return meta;\n }\n const pw = await import('playwright-core');\n const chromium = pw.chromium ?? (pw as { default?: { chromium?: (typeof pw)['chromium'] } }).default?.chromium;\n if (!chromium?.connectOverCDP) throw new Error('playwright-core does not support connectOverCDP');\n\n const wsUrl = `ws://127.0.0.1:${cdpPort}`;\n // connectOverCDP wants the browser-level WS URL\n const versionResp = await fetch(`http://127.0.0.1:${cdpPort}/json/version`);\n const versionData = (await versionResp.json()) as { webSocketDebuggerUrl?: string };\n const browserWsUrl = versionData.webSocketDebuggerUrl ?? wsUrl;\n\n const browser = await chromium.connectOverCDP(browserWsUrl);\n const contexts = browser.contexts();\n const context = contexts.length > 0 ? contexts[0] : await browser.newContext();\n\n // Inject stealth script\n await context.addInitScript(WEBDRIVER_OVERRIDE_SCRIPT);\n\n return { browser, context, ...meta };\n }\n }\n\n // Resolve user data dir for a new launch\n let temporaryProfileDir: string | null = plannedTempProfileDir;\n await mkdir(userDataDir, { recursive: true });\n\n // Build launch args\n const stealthArgs = buildStealthArgs(filterCloakBrowserExtraArgs(config.extraArgs ?? []), {\n timezone: config.timezone,\n locale: config.locale,\n webrtcIp: config.webrtcIp,\n fingerprintPlatform: config.fingerprintPlatform ?? platformInfo.fingerprintPlatform,\n });\n\n const launchArgs = [\n `--remote-debugging-address=127.0.0.1`,\n `--remote-debugging-port=${cdpPort}`,\n `--user-data-dir=${userDataDir}`,\n '--no-first-run',\n '--no-default-browser-check',\n ...stealthArgs,\n ];\n\n if (config.headless) {\n launchArgs.push('--headless=new');\n }\n\n // macOS keychain bypass\n if (osPlatform() === 'darwin') {\n launchArgs.push('--use-mock-keychain');\n }\n\n await config.onProgress?.({ phase: 'running', message: 'Launching CloakBrowser for verification' });\n if (config.signal?.aborted) throw new Error('Install cancelled');\n\n log.info(\n { execPath, port: cdpPort, headless: !!config.headless, keepOpen },\n 'Launching CloakBrowser',\n );\n\n // Spawn browser process\n const child = spawn(execPath, launchArgs, {\n stdio: ['ignore', 'ignore', 'ignore'],\n detached: keepOpen, // Detach so it survives parent exit if keep-open\n });\n\n let onLaunchError: ((error: Error) => void) | null = null;\n let onLaunchExit: ((code: number | null, signal: NodeJS.Signals | null) => void) | null = null;\n const launchFailure = new Promise<never>((_resolve, reject) => {\n onLaunchError = (error) => {\n reject(new Error(`Failed to launch CloakBrowser at ${execPath}: ${error.message}`));\n };\n onLaunchExit = (code, signal) => {\n const reason = signal ? `signal ${signal}` : `exit code ${code ?? 'unknown'}`;\n reject(new Error(`CloakBrowser exited before CDP became ready (${reason})`));\n };\n child.once('error', onLaunchError);\n child.once('exit', onLaunchExit);\n });\n\n if (keepOpen) {\n child.unref();\n }\n\n // Wait for CDP to become available\n let browserWsUrl: string;\n try {\n browserWsUrl = await Promise.race([waitForCdpEndpoint(cdpPort), launchFailure]);\n if (onLaunchError) child.off('error', onLaunchError);\n if (onLaunchExit) child.off('exit', onLaunchExit);\n } catch (e) {\n if (onLaunchError) child.off('error', onLaunchError);\n if (onLaunchExit) child.off('exit', onLaunchExit);\n child.kill();\n if (temporaryProfileDir) {\n await rm(temporaryProfileDir, { recursive: true, force: true }).catch(() => {});\n }\n throw e;\n }\n\n // Get browser-level WS URL\n let browserLevelWsUrl: string;\n try {\n const versionResp = await fetch(`http://127.0.0.1:${cdpPort}/json/version`);\n const versionData = (await versionResp.json()) as { webSocketDebuggerUrl?: string };\n browserLevelWsUrl = versionData.webSocketDebuggerUrl ?? browserWsUrl;\n } catch {\n browserLevelWsUrl = browserWsUrl;\n }\n\n const meta = launchResultMeta(\n cdpPort,\n userDataDir,\n false,\n child.pid ?? null,\n keepOpen ? null : child,\n temporaryProfileDir,\n );\n\n if (skipPlaywrightConnect) {\n log.info({ port: cdpPort, pid: child.pid }, 'CloakBrowser launched (CDP only)');\n return meta;\n }\n\n // Connect Playwright over CDP\n const pw = await import('playwright-core');\n const chromium = pw.chromium ?? (pw as { default?: { chromium?: (typeof pw)['chromium'] } }).default?.chromium;\n if (!chromium?.connectOverCDP) {\n child.kill();\n throw new Error('playwright-core does not support connectOverCDP');\n }\n\n const browser = await chromium.connectOverCDP(browserLevelWsUrl);\n const contexts = browser.contexts();\n const context = contexts.length > 0 ? contexts[0] : await browser.newContext();\n\n // Inject stealth overrides\n await context.addInitScript(WEBDRIVER_OVERRIDE_SCRIPT);\n\n log.info({ port: cdpPort, pid: child.pid }, 'CloakBrowser launched and connected');\n\n return {\n browser,\n context,\n ...meta,\n };\n}\n\n/**\n * Cleanup a CloakBrowser session — kill process and remove temp profile if applicable.\n */\nexport async function cleanupCloakBrowser(\n childProcess: ChildProcess | null,\n temporaryProfileDir: string | null,\n): Promise<void> {\n if (childProcess) {\n childProcess.kill();\n // Wait briefly for exit\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, 2000);\n childProcess.once('exit', () => {\n clearTimeout(timer);\n resolve();\n });\n });\n }\n if (temporaryProfileDir) {\n await rm(temporaryProfileDir, { recursive: true, force: true }).catch(() => {});\n log.debug({ dir: temporaryProfileDir }, 'Cleaned up temporary profile');\n }\n}\n\n// ── Doctor / status ─────────────────────────────────────────────────────────\n\nexport interface CloakBrowserDoctorResult {\n installed: boolean;\n version: string | null;\n binaryPath: string | null;\n platform: string;\n cacheDir: string;\n expectedSha256: string;\n /** Primary URL the install flow would fetch from. */\n downloadUrl: string;\n /** Fallback URLs (rendered as alternatives in the install confirm dialog). */\n fallbackUrls: string[];\n /** True when `binaryPath` was user-supplied (UI should surface a warning). */\n customBinaryPath: boolean;\n}\n\n/**\n * Download (if needed), launch headlessly to verify, then return doctor status.\n * Used by gateway install endpoints and CLI.\n */\nexport async function installCloakBrowser(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserDoctorResult> {\n const result = await launchCloakBrowser({\n headless: true,\n temporaryProfile: true,\n keepOpen: false,\n cacheDir: config.cacheDir,\n binaryPath: config.binaryPath,\n onProgress: config.onProgress,\n signal: config.signal,\n });\n await result.browser?.close().catch(() => {});\n await cleanupCloakBrowser(result.childProcess, result.temporaryProfileDir);\n return cloakBrowserDoctor({ cacheDir: config.cacheDir, binaryPath: config.binaryPath });\n}\n\n/** Check CloakBrowser installation status. */\nexport async function cloakBrowserDoctor(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserDoctorResult> {\n const platformInfo = detectPlatform();\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n await migrateLegacyCloakBrowserLayout(cacheDir);\n const { execPath, installed, customBinaryPath } = await resolveCloakExecutablePath(\n cacheDir,\n platformInfo,\n config.binaryPath,\n );\n const [primary, ...fallbacks] = archiveDownloadUrls(platformInfo);\n\n return {\n installed,\n version: installed ? platformInfo.chromiumVersion : null,\n binaryPath: installed ? execPath : null,\n platform: platformInfo.tag,\n cacheDir,\n expectedSha256: platformInfo.expectedSha256,\n downloadUrl: primary ?? '',\n fallbackUrls: fallbacks,\n customBinaryPath,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cloakbrowser.js","names":["osPlatform","osArch"],"sources":["../../../../src/browser/providers/cloakbrowser.ts"],"sourcesContent":["/**\n * CloakBrowser provider — anti-fingerprint Chromium with stealth capabilities.\n *\n * Manages CloakBrowser binary download, stealth launch, CDP connection,\n * keep-open process reuse, and temporary profile lifecycle.\n *\n * Ported from brocli's cloak.rs to TypeScript, using Playwright's connectOverCDP\n * to produce a standard Browser/BrowserContext pair.\n */\n\nimport { createHash } from 'node:crypto';\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { mkdir, mkdtemp, readdir, rename, rm, stat } from 'node:fs/promises';\nimport { platform as osPlatform, arch as osArch, tmpdir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { Readable, Transform } from 'node:stream';\nimport { ChildProcess, spawn } from 'node:child_process';\n\nimport AdmZip from 'adm-zip';\nimport type { Browser, BrowserContext } from 'playwright-core';\n\nimport type { BrowserInstallProgress } from '../install-progress.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { resolveBinDir } from '../../config/paths.js';\nimport { assertCacheDir, expandHome } from '../cache-dir-policy.js';\nimport { pickFreePort } from '../free-port.js';\nimport { loadPlaywrightCoreModule } from './playwright-doctor.js';\nimport {\n buildStealthArgs,\n filterCloakBrowserExtraArgs,\n generateFingerprintSeed,\n makeExecutable,\n removeQuarantineAttr,\n WEBDRIVER_OVERRIDE_SCRIPT,\n} from '../stealth.js';\nimport type { CloakBrowserConfig } from './types.js';\n\nconst log = createLogger('CloakBrowser');\n\n// ── Platform info ───────────────────────────────────────────────────────────\n\ninterface PlatformInfo {\n tag: string;\n chromiumVersion: string;\n archiveExt: string;\n executableRelativePath: string;\n fingerprintPlatform: string;\n /**\n * Expected SHA-256 of the downloaded archive (lowercase hex). Empty string =\n * verification opt-out for this platform; warned but not fatal. To populate:\n * download the archive once, run `shasum -a 256 <file>`, paste here.\n */\n expectedSha256: string;\n}\n\nconst DOWNLOAD_BASE_URL = 'https://cloakbrowser.dev';\nconst GITHUB_DOWNLOAD_BASE_URL = 'https://github.com/CloakHQ/CloakBrowser/releases/download';\nconst XOPC_CLOAKBROWSER_PROXY_BASE =\n process.env.XOPC_CLOAKBROWSER_DOWNLOAD_BASE?.trim().replace(/\\/$/, '') ||\n 'https://xopc.ai/api/cloakbrowser/download';\nconst READY_TIMEOUT_MS = 45_000;\nconst READY_POLL_INTERVAL_MS = 300;\nconst DEFAULT_KEEP_OPEN_CDP_PORT = 9222;\n\nconst PLATFORMS: Record<string, PlatformInfo> = {\n 'darwin-arm64': {\n tag: 'darwin-arm64',\n chromiumVersion: '145.0.7632.109.2',\n archiveExt: '.tar.gz',\n executableRelativePath: 'Chromium.app/Contents/MacOS/Chromium',\n fingerprintPlatform: 'macos',\n expectedSha256: '',\n },\n 'darwin-x64': {\n tag: 'darwin-x64',\n chromiumVersion: '145.0.7632.109.2',\n archiveExt: '.tar.gz',\n executableRelativePath: 'Chromium.app/Contents/MacOS/Chromium',\n fingerprintPlatform: 'macos',\n expectedSha256: '',\n },\n 'linux-arm64': {\n tag: 'linux-arm64',\n chromiumVersion: '146.0.7680.177.4',\n archiveExt: '.tar.gz',\n executableRelativePath: 'chrome',\n fingerprintPlatform: 'windows',\n expectedSha256: '',\n },\n 'linux-x64': {\n tag: 'linux-x64',\n chromiumVersion: '146.0.7680.177.4',\n archiveExt: '.tar.gz',\n executableRelativePath: 'chrome',\n fingerprintPlatform: 'windows',\n expectedSha256: '',\n },\n 'win32-x64': {\n tag: 'windows-x64',\n chromiumVersion: '146.0.7680.177.4',\n archiveExt: '.zip',\n executableRelativePath: 'chrome.exe',\n fingerprintPlatform: 'windows',\n expectedSha256: '',\n },\n};\n\nfunction detectPlatform(): PlatformInfo {\n const os = osPlatform();\n const architecture = osArch();\n const archMap: Record<string, string> = { arm64: 'arm64', x64: 'x64' };\n const key = `${os}-${archMap[architecture] ?? architecture}`;\n const info = PLATFORMS[key];\n if (!info) {\n throw new Error(`Unsupported CloakBrowser platform: ${os}/${architecture}`);\n }\n return info;\n}\n\n/** Test-only: enumerate platform manifests. */\nexport function listCloakBrowserPlatforms(): PlatformInfo[] {\n return Object.values(PLATFORMS);\n}\n\nfunction archiveDownloadUrls(platformInfo: PlatformInfo): string[] {\n const archiveName = `cloakbrowser-${platformInfo.tag}${platformInfo.archiveExt}`;\n return [\n `${XOPC_CLOAKBROWSER_PROXY_BASE}/${archiveName}`,\n `${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${platformInfo.chromiumVersion}/${archiveName}`,\n `${DOWNLOAD_BASE_URL}/download/${archiveName}`,\n ];\n}\n\n/** Test-only: resolved download URLs for a platform manifest (proxy first). */\nexport function cloakBrowserArchiveDownloadUrls(platformInfo: PlatformInfo): string[] {\n return archiveDownloadUrls(platformInfo);\n}\n\nasync function sha256OfFile(path: string): Promise<string> {\n const hash = createHash('sha256');\n await pipeline(createReadStream(path), hash);\n return hash.digest('hex');\n}\n\n// ── Binary management ───────────────────────────────────────────────────────\n\nconst CLOAKBROWSER_DIR_NAME = 'cloakbrowser';\n\n/** Default CloakBrowser home: ~/.xopc/bin/cloakbrowser (chromium-v*, profiles/, …). */\nexport function defaultCloakBrowserCacheDir(): string {\n return join(resolveBinDir(), CLOAKBROWSER_DIR_NAME);\n}\n\n/** Resolve configured or default CloakBrowser cache root. */\nexport function resolveCloakBrowserCacheDir(configured?: string): string {\n if (configured?.trim()) {\n const resolved = assertCacheDir(configured.trim());\n // Legacy configs used ~/.xopc/bin — normalize to ~/.xopc/bin/cloakbrowser.\n if (resolve(resolved) === resolve(resolveBinDir())) {\n return defaultCloakBrowserCacheDir();\n }\n return resolved;\n }\n return defaultCloakBrowserCacheDir();\n}\n\nasync function resolveCloakExecutablePath(\n cacheDir: string,\n platformInfo: PlatformInfo,\n configuredBinaryPath?: string,\n): Promise<{ execPath: string; installed: boolean; customBinaryPath: boolean }> {\n const trimmed = configuredBinaryPath?.trim();\n const autoPath = binaryPath(cacheDir, platformInfo);\n if (!trimmed) {\n return {\n execPath: autoPath,\n installed: await fileExists(autoPath),\n customBinaryPath: false,\n };\n }\n\n const customPath = resolve(expandHome(trimmed));\n if (await fileExists(customPath)) {\n return { execPath: customPath, installed: true, customBinaryPath: true };\n }\n\n if (await fileExists(autoPath)) {\n return { execPath: autoPath, installed: true, customBinaryPath: true };\n }\n\n return { execPath: customPath, installed: false, customBinaryPath: true };\n}\n\n/**\n * Move legacy layout (~/.xopc/bin/chromium-v* and profiles/) into ~/.xopc/bin/cloakbrowser/.\n * No-op when using a custom cacheDir or when the new layout already exists.\n */\nexport async function migrateLegacyCloakBrowserLayout(cacheDir: string): Promise<void> {\n if (cacheDir !== defaultCloakBrowserCacheDir()) return;\n\n const binDir = resolveBinDir();\n await mkdir(cacheDir, { recursive: true });\n\n let entries: string[];\n try {\n entries = await readdir(binDir);\n } catch {\n return;\n }\n\n for (const name of entries) {\n if (!name.startsWith('chromium-v')) continue;\n const from = join(binDir, name);\n const to = join(cacheDir, name);\n if (await fileExists(to)) continue;\n if (!(await fileExists(from))) continue;\n try {\n await rename(from, to);\n log.info({ from, to }, 'Migrated legacy CloakBrowser binary directory');\n } catch (err) {\n log.warn({ err, from, to }, 'Failed to migrate legacy CloakBrowser binary directory');\n }\n }\n\n const legacyProfiles = join(binDir, 'profiles');\n const newProfiles = join(cacheDir, 'profiles');\n if (await fileExists(newProfiles) || !(await fileExists(legacyProfiles))) return;\n\n try {\n await rename(legacyProfiles, newProfiles);\n log.info({ from: legacyProfiles, to: newProfiles }, 'Migrated legacy CloakBrowser profiles directory');\n } catch (err) {\n log.warn({ err, from: legacyProfiles, to: newProfiles }, 'Failed to migrate legacy CloakBrowser profiles');\n }\n}\n\nfunction binaryDir(cacheDir: string, platformInfo: PlatformInfo): string {\n return join(cacheDir, `chromium-v${platformInfo.chromiumVersion}`);\n}\n\nfunction binaryPath(cacheDir: string, platformInfo: PlatformInfo): string {\n return join(binaryDir(cacheDir, platformInfo), platformInfo.executableRelativePath);\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction runCommand(command: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, { stdio: ['ignore', 'ignore', 'pipe'] });\n let stderr = '';\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n child.once('error', reject);\n child.once('exit', (code, signal) => {\n if (code === 0) {\n resolve();\n return;\n }\n const reason = signal ? `signal ${signal}` : `exit code ${code ?? 'unknown'}`;\n const detail = stderr.trim() ? `: ${stderr.trim().slice(0, 500)}` : '';\n reject(new Error(`${command} failed with ${reason}${detail}`));\n });\n });\n}\n\nasync function extractArchive(archivePath: string, targetDir: string, platformInfo: PlatformInfo): Promise<void> {\n if (platformInfo.archiveExt === '.tar.gz') {\n await runCommand('tar', ['-xzf', archivePath, '-C', targetDir]);\n return;\n }\n\n if (platformInfo.archiveExt === '.zip') {\n const zip = new AdmZip(archivePath);\n zip.extractAllTo(targetDir, true);\n return;\n }\n\n throw new Error(`Unsupported CloakBrowser archive format: ${platformInfo.archiveExt}`);\n}\n\n/**\n * Download and extract CloakBrowser binary.\n *\n * After download, verifies SHA-256 against the platform manifest when one is\n * present. Set `XOPC_CLOAKBROWSER_SKIP_HASH=1` to bypass (development only;\n * the gateway logs a warning when the env var is honoured).\n */\nasync function downloadArchiveToFile(\n url: string,\n archivePath: string,\n onProgress?: (progress: BrowserInstallProgress) => void | Promise<void>,\n signal?: AbortSignal,\n): Promise<void> {\n if (signal?.aborted) throw new Error('Install cancelled');\n\n const response = await fetch(url, { redirect: 'follow', signal });\n if (!response.ok || !response.body) {\n throw new Error(`download returned HTTP ${response.status}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const totalBytes =\n contentLength && Number.isFinite(Number(contentLength)) ? Number(contentLength) : null;\n let bytesReceived = 0;\n\n let lastReportAt = 0;\n const report = (force = false) => {\n const now = Date.now();\n if (!force && now - lastReportAt < 250) return;\n lastReportAt = now;\n void onProgress?.({\n phase: 'downloading',\n message: 'Downloading CloakBrowser archive',\n bytesReceived,\n totalBytes,\n percent:\n totalBytes && totalBytes > 0\n ? Math.min(100, Math.round((bytesReceived / totalBytes) * 100))\n : null,\n });\n };\n\n report(true);\n\n const nodeStream = Readable.fromWeb(response.body as Parameters<typeof Readable.fromWeb>[0]);\n const counting = new Transform({\n transform(chunk, _encoding, callback) {\n bytesReceived += chunk.length;\n report();\n callback(null, chunk);\n },\n });\n\n await pipeline(nodeStream, counting, createWriteStream(archivePath));\n report(true);\n}\n\nasync function downloadBinary(\n cacheDir: string,\n platformInfo: PlatformInfo,\n onProgress?: (progress: BrowserInstallProgress) => void | Promise<void>,\n signal?: AbortSignal,\n): Promise<string> {\n const targetDir = binaryDir(cacheDir, platformInfo);\n const execPath = binaryPath(cacheDir, platformInfo);\n\n if (await fileExists(execPath)) {\n log.info({ path: execPath }, 'CloakBrowser binary already cached');\n await onProgress?.({ phase: 'ready', message: 'CloakBrowser binary already cached', percent: 100 });\n return execPath;\n }\n\n await mkdir(cacheDir, { recursive: true });\n await onProgress?.({ phase: 'starting', message: 'Preparing CloakBrowser download' });\n\n const archiveName = `cloakbrowser-${platformInfo.tag}${platformInfo.archiveExt}`;\n const urls = archiveDownloadUrls(platformInfo);\n const expectedSha256 = platformInfo.expectedSha256.trim().toLowerCase();\n const skipHash = process.env.XOPC_CLOAKBROWSER_SKIP_HASH === '1';\n\n log.info({ version: platformInfo.chromiumVersion, platform: platformInfo.tag }, 'Downloading CloakBrowser...');\n\n let downloadError: Error | undefined;\n for (const url of urls) {\n if (signal?.aborted) throw new Error('Install cancelled');\n const stagingDir = await mkdtemp(join(cacheDir, '.download-'));\n const archivePath = join(stagingDir, archiveName);\n try {\n await downloadArchiveToFile(url, archivePath, onProgress, signal);\n\n if (expectedSha256) {\n if (signal?.aborted) throw new Error('Install cancelled');\n await onProgress?.({ phase: 'verifying', message: 'Verifying SHA-256 checksum' });\n const actual = await sha256OfFile(archivePath);\n if (actual !== expectedSha256) {\n throw new Error(\n `SHA-256 mismatch: expected ${expectedSha256}, got ${actual}. Aborted to avoid running unverified binary.`,\n );\n }\n log.info({ archivePath }, 'SHA-256 verified');\n } else if (skipHash) {\n log.warn(\n { platform: platformInfo.tag, version: platformInfo.chromiumVersion },\n 'CloakBrowser SHA-256 verification skipped (XOPC_CLOAKBROWSER_SKIP_HASH=1)',\n );\n } else {\n log.warn(\n { platform: platformInfo.tag, version: platformInfo.chromiumVersion },\n 'CloakBrowser manifest has no expectedSha256; integrity NOT verified',\n );\n }\n\n await onProgress?.({ phase: 'extracting', message: 'Extracting CloakBrowser archive' });\n log.info({ archivePath }, 'Extracting CloakBrowser archive...');\n await rm(targetDir, { recursive: true, force: true }).catch(() => {});\n await mkdir(targetDir, { recursive: true });\n await extractArchive(archivePath, targetDir, platformInfo);\n\n if (!(await fileExists(execPath))) {\n throw new Error(`archive did not contain expected executable: ${execPath}`);\n }\n\n await makeExecutable(execPath);\n await removeQuarantineAttr(execPath);\n await rm(stagingDir, { recursive: true, force: true }).catch(() => {});\n\n await onProgress?.({ phase: 'ready', message: 'CloakBrowser binary ready', percent: 100 });\n log.info({ path: execPath }, 'CloakBrowser binary ready');\n return execPath;\n } catch (e) {\n await rm(stagingDir, { recursive: true, force: true }).catch(() => {});\n await rm(targetDir, { recursive: true, force: true }).catch(() => {});\n downloadError = e instanceof Error ? e : new Error(String(e));\n log.debug({ url, errorMessage: downloadError.message }, 'Download attempt failed');\n }\n }\n\n throw new Error(\n `Failed to download CloakBrowser v${platformInfo.chromiumVersion} for ${platformInfo.tag}: ${downloadError?.message ?? 'all URLs failed'}`,\n );\n}\n\n// ── CDP endpoint discovery ──────────────────────────────────────────────────\n\nasync function waitForCdpEndpoint(port: number): Promise<string> {\n const deadline = Date.now() + READY_TIMEOUT_MS;\n\n while (Date.now() < deadline) {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/version`);\n if (response.ok) {\n const data = (await response.json()) as { webSocketDebuggerUrl?: string };\n if (data.webSocketDebuggerUrl) {\n return data.webSocketDebuggerUrl;\n }\n }\n } catch {\n // Not ready yet\n }\n await new Promise((resolve) => setTimeout(resolve, READY_POLL_INTERVAL_MS));\n }\n\n throw new Error(`CloakBrowser did not expose CDP page within ${READY_TIMEOUT_MS / 1000}s on port ${port}`);\n}\n\n/** Try to find an existing CDP page endpoint on the given port. */\nasync function reuseOrCreatePageEndpoint(port: number): Promise<string | null> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/list`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!response.ok) return null;\n const pages = (await response.json()) as Array<{ webSocketDebuggerUrl?: string; type?: string }>;\n const page = pages.find((p) => p.type === 'page' && p.webSocketDebuggerUrl);\n if (page?.webSocketDebuggerUrl) return page.webSocketDebuggerUrl;\n\n // No pages — create one\n const newResponse = await fetch(`http://127.0.0.1:${port}/json/new`);\n if (newResponse.ok) {\n const newPage = (await newResponse.json()) as { webSocketDebuggerUrl?: string };\n if (newPage.webSocketDebuggerUrl) return newPage.webSocketDebuggerUrl;\n }\n } catch {\n // Not running\n }\n return null;\n}\n\n// ── Provider ────────────────────────────────────────────────────────────────\n\nexport interface CloakBrowserLaunchResult {\n browser?: Browser;\n context?: BrowserContext;\n childProcess: ChildProcess | null;\n temporaryProfileDir: string | null;\n cdpPort: number;\n userDataDir: string;\n reused: boolean;\n pid: number | null;\n}\n\nfunction resolveCloakBrowserProfilePaths(\n config: CloakBrowserConfig,\n cacheDir: string,\n): { userDataDir: string; temporaryProfileDir: string | null } {\n if (config.userDataDir) {\n return { userDataDir: config.userDataDir, temporaryProfileDir: null };\n }\n if (config.temporaryProfile) {\n const userDataDir = join(tmpdir(), `xopc-cloakbrowser-${process.pid}-${generateFingerprintSeed()}`);\n return { userDataDir, temporaryProfileDir: userDataDir };\n }\n return { userDataDir: join(cacheDir, 'profiles', 'default'), temporaryProfileDir: null };\n}\n\n/** Resolve the persistent profile directory agents use (not ephemeral temp dirs). */\nexport function resolveCloakBrowserPersistentProfileDir(config: CloakBrowserConfig = {}): string {\n if (config.userDataDir) return config.userDataDir;\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n return join(cacheDir, 'profiles', 'default');\n}\n\nexport interface CloakBrowserRuntimeStatus {\n running: boolean;\n port: number;\n userDataDir: string;\n temporaryProfile: boolean;\n}\n\nasync function probeCdpPort(port: number): Promise<boolean> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/version`, {\n signal: AbortSignal.timeout(2000),\n });\n return response.ok;\n } catch {\n return false;\n }\n}\n\n/** Probe whether CloakBrowser CDP is listening on the configured keep-open port. */\nexport async function probeCloakBrowserRuntime(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserRuntimeStatus> {\n const keepOpen = config.keepOpen ?? true;\n const cdpPort = config.cdpPort ?? (keepOpen ? DEFAULT_KEEP_OPEN_CDP_PORT : DEFAULT_KEEP_OPEN_CDP_PORT);\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n const { userDataDir } = resolveCloakBrowserProfilePaths(config, cacheDir);\n const running = await probeCdpPort(cdpPort);\n return {\n running,\n port: cdpPort,\n userDataDir,\n temporaryProfile: config.temporaryProfile === true,\n };\n}\n\nfunction launchResultMeta(\n cdpPort: number,\n userDataDir: string,\n reused: boolean,\n pid: number | null,\n childProcess: ChildProcess | null,\n temporaryProfileDir: string | null,\n): Pick<\n CloakBrowserLaunchResult,\n 'cdpPort' | 'userDataDir' | 'reused' | 'pid' | 'childProcess' | 'temporaryProfileDir'\n> {\n return { cdpPort, userDataDir, reused, pid, childProcess, temporaryProfileDir };\n}\n\n/**\n * Launch or connect to a CloakBrowser instance and return a Playwright Browser + Context.\n */\nexport async function launchCloakBrowser(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserLaunchResult> {\n const platformInfo = detectPlatform();\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n await migrateLegacyCloakBrowserLayout(cacheDir);\n const keepOpen = config.keepOpen ?? true;\n const reuseExisting = config.reuseExisting ?? keepOpen;\n\n // Resolve binary\n const configuredBinary = config.binaryPath?.trim() || undefined;\n const execPath = configuredBinary\n ? (await resolveCloakExecutablePath(cacheDir, platformInfo, configuredBinary)).execPath\n : await downloadBinary(cacheDir, platformInfo, config.onProgress, config.signal);\n if (configuredBinary) {\n await makeExecutable(execPath);\n await removeQuarantineAttr(execPath);\n }\n\n // Resolve CDP port\n const cdpPort = config.cdpPort ?? (keepOpen ? DEFAULT_KEEP_OPEN_CDP_PORT : await pickFreePort());\n const skipPlaywrightConnect = config.skipPlaywrightConnect === true;\n const { userDataDir, temporaryProfileDir: plannedTempProfileDir } = resolveCloakBrowserProfilePaths(\n config,\n cacheDir,\n );\n\n // Try to reuse existing instance\n if (reuseExisting) {\n const existingEndpoint = await reuseOrCreatePageEndpoint(cdpPort);\n if (existingEndpoint) {\n log.info({ port: cdpPort }, 'Reusing existing CloakBrowser instance');\n const meta = launchResultMeta(cdpPort, userDataDir, true, null, null, null);\n if (skipPlaywrightConnect) {\n return meta;\n }\n const pw = await loadPlaywrightCoreModule();\n const chromium = pw.chromium ?? (pw as { default?: { chromium?: (typeof pw)['chromium'] } }).default?.chromium;\n if (!chromium?.connectOverCDP) throw new Error('playwright-core does not support connectOverCDP');\n\n const wsUrl = `ws://127.0.0.1:${cdpPort}`;\n // connectOverCDP wants the browser-level WS URL\n const versionResp = await fetch(`http://127.0.0.1:${cdpPort}/json/version`);\n const versionData = (await versionResp.json()) as { webSocketDebuggerUrl?: string };\n const browserWsUrl = versionData.webSocketDebuggerUrl ?? wsUrl;\n\n const browser = await chromium.connectOverCDP(browserWsUrl);\n const contexts = browser.contexts();\n const context = contexts.length > 0 ? contexts[0] : await browser.newContext();\n\n // Inject stealth script\n await context.addInitScript(WEBDRIVER_OVERRIDE_SCRIPT);\n\n return { browser, context, ...meta };\n }\n }\n\n // Resolve user data dir for a new launch\n let temporaryProfileDir: string | null = plannedTempProfileDir;\n await mkdir(userDataDir, { recursive: true });\n\n // Build launch args\n const stealthArgs = buildStealthArgs(filterCloakBrowserExtraArgs(config.extraArgs ?? []), {\n timezone: config.timezone,\n locale: config.locale,\n webrtcIp: config.webrtcIp,\n fingerprintPlatform: config.fingerprintPlatform ?? platformInfo.fingerprintPlatform,\n });\n\n const launchArgs = [\n `--remote-debugging-address=127.0.0.1`,\n `--remote-debugging-port=${cdpPort}`,\n `--user-data-dir=${userDataDir}`,\n '--no-first-run',\n '--no-default-browser-check',\n ...stealthArgs,\n ];\n\n if (config.headless) {\n launchArgs.push('--headless=new');\n }\n\n // macOS keychain bypass\n if (osPlatform() === 'darwin') {\n launchArgs.push('--use-mock-keychain');\n }\n\n await config.onProgress?.({ phase: 'running', message: 'Launching CloakBrowser for verification' });\n if (config.signal?.aborted) throw new Error('Install cancelled');\n\n log.info(\n { execPath, port: cdpPort, headless: !!config.headless, keepOpen },\n 'Launching CloakBrowser',\n );\n\n // Spawn browser process\n const child = spawn(execPath, launchArgs, {\n stdio: ['ignore', 'ignore', 'ignore'],\n detached: keepOpen, // Detach so it survives parent exit if keep-open\n });\n\n let onLaunchError: ((error: Error) => void) | null = null;\n let onLaunchExit: ((code: number | null, signal: NodeJS.Signals | null) => void) | null = null;\n const launchFailure = new Promise<never>((_resolve, reject) => {\n onLaunchError = (error) => {\n reject(new Error(`Failed to launch CloakBrowser at ${execPath}: ${error.message}`));\n };\n onLaunchExit = (code, signal) => {\n const reason = signal ? `signal ${signal}` : `exit code ${code ?? 'unknown'}`;\n reject(new Error(`CloakBrowser exited before CDP became ready (${reason})`));\n };\n child.once('error', onLaunchError);\n child.once('exit', onLaunchExit);\n });\n\n if (keepOpen) {\n child.unref();\n }\n\n // Wait for CDP to become available\n let browserWsUrl: string;\n try {\n browserWsUrl = await Promise.race([waitForCdpEndpoint(cdpPort), launchFailure]);\n if (onLaunchError) child.off('error', onLaunchError);\n if (onLaunchExit) child.off('exit', onLaunchExit);\n } catch (e) {\n if (onLaunchError) child.off('error', onLaunchError);\n if (onLaunchExit) child.off('exit', onLaunchExit);\n child.kill();\n if (temporaryProfileDir) {\n await rm(temporaryProfileDir, { recursive: true, force: true }).catch(() => {});\n }\n throw e;\n }\n\n // Get browser-level WS URL\n let browserLevelWsUrl: string;\n try {\n const versionResp = await fetch(`http://127.0.0.1:${cdpPort}/json/version`);\n const versionData = (await versionResp.json()) as { webSocketDebuggerUrl?: string };\n browserLevelWsUrl = versionData.webSocketDebuggerUrl ?? browserWsUrl;\n } catch {\n browserLevelWsUrl = browserWsUrl;\n }\n\n const meta = launchResultMeta(\n cdpPort,\n userDataDir,\n false,\n child.pid ?? null,\n keepOpen ? null : child,\n temporaryProfileDir,\n );\n\n if (skipPlaywrightConnect) {\n log.info({ port: cdpPort, pid: child.pid }, 'CloakBrowser launched (CDP only)');\n return meta;\n }\n\n // Connect Playwright over CDP\n const pw = await loadPlaywrightCoreModule();\n const chromium = pw.chromium ?? (pw as { default?: { chromium?: (typeof pw)['chromium'] } }).default?.chromium;\n if (!chromium?.connectOverCDP) {\n child.kill();\n throw new Error('playwright-core does not support connectOverCDP');\n }\n\n const browser = await chromium.connectOverCDP(browserLevelWsUrl);\n const contexts = browser.contexts();\n const context = contexts.length > 0 ? contexts[0] : await browser.newContext();\n\n // Inject stealth overrides\n await context.addInitScript(WEBDRIVER_OVERRIDE_SCRIPT);\n\n log.info({ port: cdpPort, pid: child.pid }, 'CloakBrowser launched and connected');\n\n return {\n browser,\n context,\n ...meta,\n };\n}\n\n/**\n * Cleanup a CloakBrowser session — kill process and remove temp profile if applicable.\n */\nexport async function cleanupCloakBrowser(\n childProcess: ChildProcess | null,\n temporaryProfileDir: string | null,\n): Promise<void> {\n if (childProcess) {\n childProcess.kill();\n // Wait briefly for exit\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, 2000);\n childProcess.once('exit', () => {\n clearTimeout(timer);\n resolve();\n });\n });\n }\n if (temporaryProfileDir) {\n await rm(temporaryProfileDir, { recursive: true, force: true }).catch(() => {});\n log.debug({ dir: temporaryProfileDir }, 'Cleaned up temporary profile');\n }\n}\n\n// ── Doctor / status ─────────────────────────────────────────────────────────\n\nexport interface CloakBrowserDoctorResult {\n installed: boolean;\n version: string | null;\n binaryPath: string | null;\n platform: string;\n cacheDir: string;\n expectedSha256: string;\n /** Primary URL the install flow would fetch from. */\n downloadUrl: string;\n /** Fallback URLs (rendered as alternatives in the install confirm dialog). */\n fallbackUrls: string[];\n /** True when `binaryPath` was user-supplied (UI should surface a warning). */\n customBinaryPath: boolean;\n}\n\n/**\n * Download (if needed), launch headlessly to verify, then return doctor status.\n * Used by gateway install endpoints and CLI.\n */\nexport async function installCloakBrowser(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserDoctorResult> {\n const result = await launchCloakBrowser({\n headless: true,\n temporaryProfile: true,\n keepOpen: false,\n cacheDir: config.cacheDir,\n binaryPath: config.binaryPath,\n onProgress: config.onProgress,\n signal: config.signal,\n });\n await result.browser?.close().catch(() => {});\n await cleanupCloakBrowser(result.childProcess, result.temporaryProfileDir);\n return cloakBrowserDoctor({ cacheDir: config.cacheDir, binaryPath: config.binaryPath });\n}\n\n/** Check CloakBrowser installation status. */\nexport async function cloakBrowserDoctor(\n config: CloakBrowserConfig = {},\n): Promise<CloakBrowserDoctorResult> {\n const platformInfo = detectPlatform();\n const cacheDir = resolveCloakBrowserCacheDir(config.cacheDir);\n await migrateLegacyCloakBrowserLayout(cacheDir);\n const { execPath, installed, customBinaryPath } = await resolveCloakExecutablePath(\n cacheDir,\n platformInfo,\n config.binaryPath,\n );\n const [primary, ...fallbacks] = archiveDownloadUrls(platformInfo);\n\n return {\n installed,\n version: installed ? platformInfo.chromiumVersion : null,\n binaryPath: installed ? execPath : null,\n platform: platformInfo.tag,\n cacheDir,\n expectedSha256: platformInfo.expectedSha256,\n downloadUrl: primary ?? '',\n fallbackUrls: fallbacks,\n customBinaryPath,\n };\n}\n"],"mappings":"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"}
|
|
@@ -7,5 +7,7 @@ export interface PlaywrightChromiumDoctorResult {
|
|
|
7
7
|
export declare function resolvePlaywrightCoreRoot(): string;
|
|
8
8
|
/** Absolute path to bundled `playwright-core/cli.js` (same revision as runtime). */
|
|
9
9
|
export declare function resolvePlaywrightCoreCliPath(): string;
|
|
10
|
+
/** Load playwright-core (Electron extraResources or node_modules). */
|
|
11
|
+
export declare function loadPlaywrightCoreModule(): Promise<typeof import('playwright-core')>;
|
|
10
12
|
/** Check whether playwright-core's default Chromium revision is on disk. */
|
|
11
13
|
export declare function playwrightChromiumDoctor(): Promise<PlaywrightChromiumDoctorResult>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
2
|
import { existsSync } from "node:fs";
|
|
4
3
|
import { stat } from "node:fs/promises";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
//#region src/browser/providers/playwright-doctor.ts
|
|
7
7
|
/** Root directory of the `playwright-core` package (Electron extraResources or node_modules). */
|
|
@@ -17,9 +17,13 @@ function resolvePlaywrightCoreRoot() {
|
|
|
17
17
|
function resolvePlaywrightCoreCliPath() {
|
|
18
18
|
return join(resolvePlaywrightCoreRoot(), "cli.js");
|
|
19
19
|
}
|
|
20
|
+
/** Load playwright-core (Electron extraResources or node_modules). */
|
|
20
21
|
async function loadPlaywrightCoreModule() {
|
|
21
22
|
const envRoot = process.env.XOPC_PLAYWRIGHT_CORE_ROOT?.trim();
|
|
22
|
-
if (envRoot)
|
|
23
|
+
if (envRoot) {
|
|
24
|
+
const entry = join(envRoot, "index.js");
|
|
25
|
+
return createRequire(import.meta.url)(entry);
|
|
26
|
+
}
|
|
23
27
|
return import("playwright-core");
|
|
24
28
|
}
|
|
25
29
|
/** Check whether playwright-core's default Chromium revision is on disk. */
|
|
@@ -60,6 +64,6 @@ async function playwrightChromiumDoctor() {
|
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
//#endregion
|
|
63
|
-
export { playwrightChromiumDoctor, resolvePlaywrightCoreCliPath, resolvePlaywrightCoreRoot };
|
|
67
|
+
export { loadPlaywrightCoreModule, playwrightChromiumDoctor, resolvePlaywrightCoreCliPath, resolvePlaywrightCoreRoot };
|
|
64
68
|
|
|
65
69
|
//# sourceMappingURL=playwright-doctor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright-doctor.js","names":[],"sources":["../../../../src/browser/providers/playwright-doctor.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { stat } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface PlaywrightChromiumDoctorResult {\n installed: boolean;\n executablePath?: string | null;\n reason?: string;\n}\n\n/** Root directory of the `playwright-core` package (Electron extraResources or node_modules). */\nexport function resolvePlaywrightCoreRoot(): string {\n const envRoot = process.env.XOPC_PLAYWRIGHT_CORE_ROOT?.trim();\n if (envRoot) {\n const pkgJson = join(envRoot, 'package.json');\n if (!existsSync(pkgJson)) {\n throw new Error(`playwright-core package.json not found under XOPC_PLAYWRIGHT_CORE_ROOT (${envRoot})`);\n }\n return envRoot;\n }\n\n const require = createRequire(fileURLToPath(import.meta.url));\n const pkgJson = require.resolve('playwright-core/package.json');\n return dirname(pkgJson);\n}\n\n/** Absolute path to bundled `playwright-core/cli.js` (same revision as runtime). */\nexport function resolvePlaywrightCoreCliPath(): string {\n return join(resolvePlaywrightCoreRoot(), 'cli.js');\n}\n\
|
|
1
|
+
{"version":3,"file":"playwright-doctor.js","names":[],"sources":["../../../../src/browser/providers/playwright-doctor.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { stat } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface PlaywrightChromiumDoctorResult {\n installed: boolean;\n executablePath?: string | null;\n reason?: string;\n}\n\n/** Root directory of the `playwright-core` package (Electron extraResources or node_modules). */\nexport function resolvePlaywrightCoreRoot(): string {\n const envRoot = process.env.XOPC_PLAYWRIGHT_CORE_ROOT?.trim();\n if (envRoot) {\n const pkgJson = join(envRoot, 'package.json');\n if (!existsSync(pkgJson)) {\n throw new Error(`playwright-core package.json not found under XOPC_PLAYWRIGHT_CORE_ROOT (${envRoot})`);\n }\n return envRoot;\n }\n\n const require = createRequire(fileURLToPath(import.meta.url));\n const pkgJson = require.resolve('playwright-core/package.json');\n return dirname(pkgJson);\n}\n\n/** Absolute path to bundled `playwright-core/cli.js` (same revision as runtime). */\nexport function resolvePlaywrightCoreCliPath(): string {\n return join(resolvePlaywrightCoreRoot(), 'cli.js');\n}\n\n/** Load playwright-core (Electron extraResources or node_modules). */\nexport async function loadPlaywrightCoreModule(): Promise<typeof import('playwright-core')> {\n const envRoot = process.env.XOPC_PLAYWRIGHT_CORE_ROOT?.trim();\n if (envRoot) {\n const entry = join(envRoot, 'index.js');\n const require = createRequire(import.meta.url);\n return require(entry) as typeof import('playwright-core');\n }\n return import('playwright-core');\n}\n\n/** Check whether playwright-core's default Chromium revision is on disk. */\nexport async function playwrightChromiumDoctor(): Promise<PlaywrightChromiumDoctorResult> {\n try {\n const pw = await loadPlaywrightCoreModule();\n const chromium = pw.chromium\n ?? (pw as { default?: { chromium?: (typeof pw)['chromium'] } }).default?.chromium;\n if (!chromium?.executablePath) {\n return { installed: false, reason: 'playwright-core missing' };\n }\n\n let executablePath: string;\n try {\n executablePath = chromium.executablePath();\n } catch (err) {\n return {\n installed: false,\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n try {\n const st = await stat(executablePath);\n return { installed: st.isFile(), executablePath };\n } catch {\n return {\n installed: false,\n executablePath,\n reason: 'Chromium executable not found on disk',\n };\n }\n } catch (e) {\n return { installed: false, reason: e instanceof Error ? e.message : String(e) };\n }\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,4BAAoC;CAClD,MAAM,UAAU,QAAQ,IAAI,2BAA2B,MAAM;AAC7D,KAAI,SAAS;AAEX,MAAI,CAAC,WADW,KAAK,SAAS,eACP,CAAC,CACtB,OAAM,IAAI,MAAM,2EAA2E,QAAQ,GAAG;AAExG,SAAO;;AAKT,QAAO,QAFS,cAAc,cAAc,OAAO,KAAK,IAAI,CACrC,CAAC,QAAQ,+BACV,CAAC;;;AAIzB,SAAgB,+BAAuC;AACrD,QAAO,KAAK,2BAA2B,EAAE,SAAS;;;AAIpD,eAAsB,2BAAsE;CAC1F,MAAM,UAAU,QAAQ,IAAI,2BAA2B,MAAM;AAC7D,KAAI,SAAS;EACX,MAAM,QAAQ,KAAK,SAAS,WAAW;AAEvC,SADgB,cAAc,OAAO,KAAK,IAC5B,CAAC,MAAM;;AAEvB,QAAO,OAAO;;;AAIhB,eAAsB,2BAAoE;AACxF,KAAI;EACF,MAAM,KAAK,MAAM,0BAA0B;EAC3C,MAAM,WAAW,GAAG,YACd,GAA4D,SAAS;AAC3E,MAAI,CAAC,UAAU,eACb,QAAO;GAAE,WAAW;GAAO,QAAQ;GAA2B;EAGhE,IAAI;AACJ,MAAI;AACF,oBAAiB,SAAS,gBAAgB;WACnC,KAAK;AACZ,UAAO;IACL,WAAW;IACX,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACzD;;AAGH,MAAI;AAEF,UAAO;IAAE,YAAW,MADH,KAAK,eAAe,EACd,QAAQ;IAAE;IAAgB;UAC3C;AACN,UAAO;IACL,WAAW;IACX;IACA,QAAQ;IACT;;UAEI,GAAG;AACV,SAAO;GAAE,WAAW;GAAO,QAAQ,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;GAAE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend readiness preflight for the `browser_use` tool.
|
|
3
|
+
*
|
|
4
|
+
* Reuses the same doctor functions that power the Settings → Browser page so
|
|
5
|
+
* the agent never tries to launch a backend that the UI already knows is
|
|
6
|
+
* broken. Produces a structured signal the chat surface can render as a
|
|
7
|
+
* "Setup browser" card instead of a bare error string.
|
|
8
|
+
*/
|
|
9
|
+
import type { Config } from '../config/schema.js';
|
|
10
|
+
export type BrowserBackendKind = 'extension' | 'local' | 'cloakbrowser' | 'cdp' | 'cloud';
|
|
11
|
+
export type BrowserNotReadyReason = 'extension_not_installed' | 'extension_bridge_offline' | 'extension_not_connected' | 'local_chromium_missing' | 'cloakbrowser_not_installed' | 'cdp_unreachable' | 'cloud_api_key_missing';
|
|
12
|
+
export interface BrowserSetupHint {
|
|
13
|
+
backend: BrowserBackendKind;
|
|
14
|
+
reason: BrowserNotReadyReason;
|
|
15
|
+
/** Raw probe diagnostic; surfaced behind a disclosure for debugging. */
|
|
16
|
+
detail?: string;
|
|
17
|
+
/** Deep link into Settings → Browser focused on the right backend tab. */
|
|
18
|
+
deepLink: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class BrowserNotReadyError extends Error {
|
|
21
|
+
readonly hint: BrowserSetupHint;
|
|
22
|
+
constructor(hint: BrowserSetupHint);
|
|
23
|
+
}
|
|
24
|
+
/** Map backend → settings tab id (matches `BROWSER_BACKEND_TABS` on the web side). */
|
|
25
|
+
export declare function buildBrowserSetupDeepLink(backend: BrowserBackendKind): string;
|
|
26
|
+
/**
|
|
27
|
+
* Probe the currently-configured browser backend. Returns `null` when ready.
|
|
28
|
+
*
|
|
29
|
+
* Probe budget is small (filesystem stats + loopback fetches with a 2s timeout)
|
|
30
|
+
* so it's safe to call before every `browser_use` invocation — but callers
|
|
31
|
+
* typically cache the result for a few seconds to handle bursts.
|
|
32
|
+
*/
|
|
33
|
+
export declare function checkBrowserReadiness(cfg: Config | undefined): Promise<BrowserNotReadyError | null>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { resolveBrowserBackendFromConfig } from "./backend-from-config.js";
|
|
4
|
+
//#region src/browser/readiness.ts
|
|
5
|
+
init_logger();
|
|
6
|
+
const log = createLogger("browser-readiness");
|
|
7
|
+
var BrowserNotReadyError = class extends Error {
|
|
8
|
+
constructor(hint) {
|
|
9
|
+
super(`Browser backend "${hint.backend}" not ready: ${hint.reason}`);
|
|
10
|
+
this.hint = hint;
|
|
11
|
+
this.name = "BrowserNotReadyError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/** Map backend → settings tab id (matches `BROWSER_BACKEND_TABS` on the web side). */
|
|
15
|
+
function buildBrowserSetupDeepLink(backend) {
|
|
16
|
+
return `/settings/agent-browser?tab=${backend}`;
|
|
17
|
+
}
|
|
18
|
+
function hint(backend, reason, detail) {
|
|
19
|
+
return {
|
|
20
|
+
backend,
|
|
21
|
+
reason,
|
|
22
|
+
detail,
|
|
23
|
+
deepLink: buildBrowserSetupDeepLink(backend)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async function checkExtension(cfg) {
|
|
27
|
+
try {
|
|
28
|
+
const { browserExtDoctor } = await import("./providers/browser-ext-install.js");
|
|
29
|
+
if (!(await browserExtDoctor()).installed) return hint("extension", "extension_not_installed", "extension artifacts not on disk");
|
|
30
|
+
} catch (e) {
|
|
31
|
+
return hint("extension", "extension_not_installed", e instanceof Error ? e.message : String(e));
|
|
32
|
+
}
|
|
33
|
+
const ext = cfg?.agents?.defaults?.browser?.extension;
|
|
34
|
+
const host = typeof ext?.host === "string" && ext.host.trim() ? ext.host.trim() : "127.0.0.1";
|
|
35
|
+
const port = typeof ext?.port === "number" && ext.port >= 1024 && ext.port <= 65535 ? Math.floor(ext.port) : 19820;
|
|
36
|
+
try {
|
|
37
|
+
const { getExtensionBrowserServerSnapshot } = await import("./providers/extension-ws-acquire.js");
|
|
38
|
+
if (getExtensionBrowserServerSnapshot().active) try {
|
|
39
|
+
if ((await (await fetch(`http://${host}:${port}/`, { signal: AbortSignal.timeout(2e3) })).json().catch(() => null))?.connected) return null;
|
|
40
|
+
return hint("extension", "extension_not_connected", "WS bridge is listening but no Chrome Extension client connected yet");
|
|
41
|
+
} catch {
|
|
42
|
+
return hint("extension", "extension_bridge_offline", `health probe failed on ${host}:${port}`);
|
|
43
|
+
}
|
|
44
|
+
return hint("extension", "extension_bridge_offline", `bridge not started on ${host}:${port}`);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
return hint("extension", "extension_bridge_offline", e instanceof Error ? e.message : String(e));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function checkLocal() {
|
|
50
|
+
try {
|
|
51
|
+
const { playwrightChromiumDoctor } = await import("./providers/playwright-doctor.js");
|
|
52
|
+
const doctor = await playwrightChromiumDoctor();
|
|
53
|
+
if (!doctor.installed) return hint("local", "local_chromium_missing", doctor.reason ?? "Chromium binary not found on disk");
|
|
54
|
+
return null;
|
|
55
|
+
} catch (e) {
|
|
56
|
+
return hint("local", "local_chromium_missing", e instanceof Error ? e.message : String(e));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function checkCloak(cfg) {
|
|
60
|
+
const cb = cfg?.agents?.defaults?.browser?.cloakbrowser;
|
|
61
|
+
try {
|
|
62
|
+
const { cloakBrowserDoctor } = await import("./providers/cloakbrowser.js");
|
|
63
|
+
const doctor = await cloakBrowserDoctor({
|
|
64
|
+
cacheDir: cb?.cacheDir,
|
|
65
|
+
binaryPath: cb?.binaryPath
|
|
66
|
+
});
|
|
67
|
+
if (!doctor.installed) return hint("cloakbrowser", "cloakbrowser_not_installed", `CloakBrowser binary not found (cacheDir=${doctor.cacheDir})`);
|
|
68
|
+
return null;
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return hint("cloakbrowser", "cloakbrowser_not_installed", e instanceof Error ? e.message : String(e));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function checkCdp(cdpUrl) {
|
|
74
|
+
let httpBase;
|
|
75
|
+
try {
|
|
76
|
+
httpBase = new URL(cdpUrl);
|
|
77
|
+
httpBase.protocol = httpBase.protocol === "wss:" ? "https:" : "http:";
|
|
78
|
+
httpBase.pathname = "/json/version";
|
|
79
|
+
httpBase.search = "";
|
|
80
|
+
httpBase.hash = "";
|
|
81
|
+
} catch (e) {
|
|
82
|
+
return hint("cdp", "cdp_unreachable", `invalid cdpUrl: ${e instanceof Error ? e.message : String(e)}`);
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const res = await fetch(httpBase.toString(), { signal: AbortSignal.timeout(2e3) });
|
|
86
|
+
if (!res.ok) return hint("cdp", "cdp_unreachable", `HTTP ${res.status} from ${httpBase.toString()}`);
|
|
87
|
+
return null;
|
|
88
|
+
} catch (e) {
|
|
89
|
+
return hint("cdp", "cdp_unreachable", e instanceof Error ? e.message : String(e));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function checkCloud(cfg, providerType) {
|
|
93
|
+
const cloud = cfg?.agents?.defaults?.browser?.cloud;
|
|
94
|
+
if (typeof cloud?.apiKey === "string" ? cloud.apiKey.trim() : "") return null;
|
|
95
|
+
if (providerType === "browserbase" ? process.env.BROWSERBASE_API_KEY?.trim() : process.env.BROWSER_USE_API_KEY?.trim()) return null;
|
|
96
|
+
return hint("cloud", "cloud_api_key_missing", `no API key configured for ${providerType}`);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Probe the currently-configured browser backend. Returns `null` when ready.
|
|
100
|
+
*
|
|
101
|
+
* Probe budget is small (filesystem stats + loopback fetches with a 2s timeout)
|
|
102
|
+
* so it's safe to call before every `browser_use` invocation — but callers
|
|
103
|
+
* typically cache the result for a few seconds to handle bursts.
|
|
104
|
+
*/
|
|
105
|
+
async function checkBrowserReadiness(cfg) {
|
|
106
|
+
const backend = resolveBrowserBackendFromConfig(cfg);
|
|
107
|
+
let probe = null;
|
|
108
|
+
try {
|
|
109
|
+
switch (backend.mode) {
|
|
110
|
+
case "extension":
|
|
111
|
+
probe = await checkExtension(cfg);
|
|
112
|
+
break;
|
|
113
|
+
case "local":
|
|
114
|
+
probe = await checkLocal();
|
|
115
|
+
break;
|
|
116
|
+
case "cloakbrowser":
|
|
117
|
+
probe = await checkCloak(cfg);
|
|
118
|
+
break;
|
|
119
|
+
case "cdp":
|
|
120
|
+
probe = await checkCdp(backend.config.wsEndpoint);
|
|
121
|
+
break;
|
|
122
|
+
case "cloud":
|
|
123
|
+
probe = checkCloud(cfg, backend.config.type);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
} catch (e) {
|
|
127
|
+
log.warn({
|
|
128
|
+
err: e,
|
|
129
|
+
backend: backend.mode
|
|
130
|
+
}, "Readiness probe threw unexpectedly");
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return probe ? new BrowserNotReadyError(probe) : null;
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { BrowserNotReadyError, buildBrowserSetupDeepLink, checkBrowserReadiness };
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.js","names":[],"sources":["../../../src/browser/readiness.ts"],"sourcesContent":["/**\n * Backend readiness preflight for the `browser_use` tool.\n *\n * Reuses the same doctor functions that power the Settings → Browser page so\n * the agent never tries to launch a backend that the UI already knows is\n * broken. Produces a structured signal the chat surface can render as a\n * \"Setup browser\" card instead of a bare error string.\n */\n\nimport type { Config } from '../config/schema.js';\n\nimport { resolveBrowserBackendFromConfig } from './backend-from-config.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('browser-readiness');\n\nexport type BrowserBackendKind =\n | 'extension'\n | 'local'\n | 'cloakbrowser'\n | 'cdp'\n | 'cloud';\n\nexport type BrowserNotReadyReason =\n | 'extension_not_installed'\n | 'extension_bridge_offline'\n | 'extension_not_connected'\n | 'local_chromium_missing'\n | 'cloakbrowser_not_installed'\n | 'cdp_unreachable'\n | 'cloud_api_key_missing';\n\nexport interface BrowserSetupHint {\n backend: BrowserBackendKind;\n reason: BrowserNotReadyReason;\n /** Raw probe diagnostic; surfaced behind a disclosure for debugging. */\n detail?: string;\n /** Deep link into Settings → Browser focused on the right backend tab. */\n deepLink: string;\n}\n\nexport class BrowserNotReadyError extends Error {\n constructor(public readonly hint: BrowserSetupHint) {\n super(`Browser backend \"${hint.backend}\" not ready: ${hint.reason}`);\n this.name = 'BrowserNotReadyError';\n }\n}\n\n/** Map backend → settings tab id (matches `BROWSER_BACKEND_TABS` on the web side). */\nexport function buildBrowserSetupDeepLink(backend: BrowserBackendKind): string {\n return `/settings/agent-browser?tab=${backend}`;\n}\n\nfunction hint(\n backend: BrowserBackendKind,\n reason: BrowserNotReadyReason,\n detail?: string,\n): BrowserSetupHint {\n return { backend, reason, detail, deepLink: buildBrowserSetupDeepLink(backend) };\n}\n\nasync function checkExtension(cfg: Config | undefined): Promise<BrowserSetupHint | null> {\n try {\n const { browserExtDoctor } = await import('./providers/browser-ext-install.js');\n const doctor = await browserExtDoctor();\n if (!doctor.installed) {\n return hint('extension', 'extension_not_installed', 'extension artifacts not on disk');\n }\n } catch (e) {\n return hint('extension', 'extension_not_installed', e instanceof Error ? e.message : String(e));\n }\n\n const ext = cfg?.agents?.defaults?.browser?.extension;\n const host = (typeof ext?.host === 'string' && ext.host.trim()) ? ext.host.trim() : '127.0.0.1';\n const port = (typeof ext?.port === 'number' && ext.port >= 1024 && ext.port <= 65535)\n ? Math.floor(ext.port)\n : 19820;\n\n try {\n const { getExtensionBrowserServerSnapshot } = await import(\n './providers/extension-ws-acquire.js'\n );\n const snapshot = getExtensionBrowserServerSnapshot();\n if (snapshot.active) {\n // Probe the HTTP `/` health endpoint to read `.connected`.\n try {\n const res = await fetch(`http://${host}:${port}/`, {\n signal: AbortSignal.timeout(2000),\n });\n const data = (await res.json().catch(() => null)) as { connected?: boolean } | null;\n if (data?.connected) return null;\n return hint(\n 'extension',\n 'extension_not_connected',\n 'WS bridge is listening but no Chrome Extension client connected yet',\n );\n } catch {\n // Bridge claims active but health probe failed — treat as offline.\n return hint('extension', 'extension_bridge_offline', `health probe failed on ${host}:${port}`);\n }\n }\n return hint('extension', 'extension_bridge_offline', `bridge not started on ${host}:${port}`);\n } catch (e) {\n return hint(\n 'extension',\n 'extension_bridge_offline',\n e instanceof Error ? e.message : String(e),\n );\n }\n}\n\nasync function checkLocal(): Promise<BrowserSetupHint | null> {\n try {\n const { playwrightChromiumDoctor } = await import('./providers/playwright-doctor.js');\n const doctor = await playwrightChromiumDoctor();\n if (!doctor.installed) {\n return hint(\n 'local',\n 'local_chromium_missing',\n doctor.reason ?? 'Chromium binary not found on disk',\n );\n }\n return null;\n } catch (e) {\n return hint('local', 'local_chromium_missing', e instanceof Error ? e.message : String(e));\n }\n}\n\nasync function checkCloak(cfg: Config | undefined): Promise<BrowserSetupHint | null> {\n const cb = cfg?.agents?.defaults?.browser?.cloakbrowser;\n try {\n const { cloakBrowserDoctor } = await import('./providers/cloakbrowser.js');\n const doctor = await cloakBrowserDoctor({\n cacheDir: cb?.cacheDir,\n binaryPath: cb?.binaryPath,\n });\n if (!doctor.installed) {\n return hint(\n 'cloakbrowser',\n 'cloakbrowser_not_installed',\n `CloakBrowser binary not found (cacheDir=${doctor.cacheDir})`,\n );\n }\n return null;\n } catch (e) {\n return hint(\n 'cloakbrowser',\n 'cloakbrowser_not_installed',\n e instanceof Error ? e.message : String(e),\n );\n }\n}\n\nasync function checkCdp(cdpUrl: string): Promise<BrowserSetupHint | null> {\n let httpBase: URL;\n try {\n httpBase = new URL(cdpUrl);\n httpBase.protocol = httpBase.protocol === 'wss:' ? 'https:' : 'http:';\n httpBase.pathname = '/json/version';\n httpBase.search = '';\n httpBase.hash = '';\n } catch (e) {\n return hint('cdp', 'cdp_unreachable', `invalid cdpUrl: ${e instanceof Error ? e.message : String(e)}`);\n }\n try {\n const res = await fetch(httpBase.toString(), { signal: AbortSignal.timeout(2000) });\n if (!res.ok) {\n return hint('cdp', 'cdp_unreachable', `HTTP ${res.status} from ${httpBase.toString()}`);\n }\n return null;\n } catch (e) {\n return hint('cdp', 'cdp_unreachable', e instanceof Error ? e.message : String(e));\n }\n}\n\nfunction checkCloud(cfg: Config | undefined, providerType: 'browserbase' | 'browser-use'): BrowserSetupHint | null {\n const cloud = cfg?.agents?.defaults?.browser?.cloud;\n const cfgKey = typeof cloud?.apiKey === 'string' ? cloud.apiKey.trim() : '';\n if (cfgKey) return null;\n const envKey =\n providerType === 'browserbase'\n ? process.env.BROWSERBASE_API_KEY?.trim()\n : process.env.BROWSER_USE_API_KEY?.trim();\n if (envKey) return null;\n return hint(\n 'cloud',\n 'cloud_api_key_missing',\n `no API key configured for ${providerType}`,\n );\n}\n\n/**\n * Probe the currently-configured browser backend. Returns `null` when ready.\n *\n * Probe budget is small (filesystem stats + loopback fetches with a 2s timeout)\n * so it's safe to call before every `browser_use` invocation — but callers\n * typically cache the result for a few seconds to handle bursts.\n */\nexport async function checkBrowserReadiness(\n cfg: Config | undefined,\n): Promise<BrowserNotReadyError | null> {\n const backend = resolveBrowserBackendFromConfig(cfg);\n let probe: BrowserSetupHint | null = null;\n try {\n switch (backend.mode) {\n case 'extension':\n probe = await checkExtension(cfg);\n break;\n case 'local':\n probe = await checkLocal();\n break;\n case 'cloakbrowser':\n probe = await checkCloak(cfg);\n break;\n case 'cdp':\n probe = await checkCdp(backend.config.wsEndpoint);\n break;\n case 'cloud':\n probe = checkCloud(cfg, backend.config.type);\n break;\n }\n } catch (e) {\n log.warn({ err: e, backend: backend.mode }, 'Readiness probe threw unexpectedly');\n return null;\n }\n return probe ? new BrowserNotReadyError(probe) : null;\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { platform } from "node:os";
|
|
4
3
|
import { chmod, stat } from "node:fs/promises";
|
|
5
|
-
import {
|
|
4
|
+
import { platform } from "node:os";
|
|
6
5
|
import { exec } from "node:child_process";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
7
|
//#region src/browser/stealth.ts
|
|
8
8
|
/**
|
|
9
9
|
* Stealth launch utilities for anti-detection browser automation.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { join, resolve } from "path";
|
|
4
3
|
import { mkdir, writeFile } from "fs/promises";
|
|
4
|
+
import { join, resolve } from "path";
|
|
5
5
|
import { randomBytes } from "crypto";
|
|
6
6
|
//#region src/channels/attachments/inbound-persist.ts
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { join, resolve } from "path";
|
|
4
3
|
import { mkdir, writeFile } from "fs/promises";
|
|
4
|
+
import { join, resolve } from "path";
|
|
5
5
|
import { randomBytes } from "crypto";
|
|
6
6
|
//#region src/channels/attachments/outbound-tts-persist.ts
|
|
7
7
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Channel domain types (Telegram config, message context, send options).
|
|
3
3
|
*/
|
|
4
4
|
import type { MessageBus } from '../infra/bus/index.js';
|
|
5
|
-
import type { Config } from '../config/
|
|
5
|
+
import type { Config } from '../config/schema.js';
|
|
6
6
|
import type { ProgressStage } from '../agent/lifecycle/progress.js';
|
|
7
7
|
export type { ProgressStage } from '../agent/lifecycle/progress.js';
|
|
8
8
|
export type ChannelType = 'telegram' | 'system';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Channel config adapter factories.
|
|
3
3
|
*/
|
|
4
|
-
import type { Config } from '../config/
|
|
4
|
+
import type { Config } from '../config/schema.js';
|
|
5
5
|
import type { ChannelConfigAdapter } from './plugin-types.js';
|
|
6
6
|
export declare function createTopLevelChannelConfigAdapter<ResolvedAccount>(params: {
|
|
7
7
|
sectionKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-helpers.js","names":[],"sources":["../../../src/channels/config-helpers.ts"],"sourcesContent":["/**\n * Channel config adapter factories.\n */\n\nimport type { Config } from '../config/
|
|
1
|
+
{"version":3,"file":"config-helpers.js","names":[],"sources":["../../../src/channels/config-helpers.ts"],"sourcesContent":["/**\n * Channel config adapter factories.\n */\n\nimport type { Config } from '../config/schema.js';\nimport type { ChannelConfigAdapter } from './plugin-types.js';\n\nexport function createTopLevelChannelConfigAdapter<ResolvedAccount>(params: {\n sectionKey: string;\n resolveAccount: (cfg: Config) => ResolvedAccount;\n deleteMode?: 'remove-section' | 'clear-fields';\n resolveAllowFrom?: (account: ResolvedAccount) => Array<string | number> | undefined;\n formatAllowFrom?: (allowFrom: Array<string | number>) => string[];\n}): ChannelConfigAdapter<ResolvedAccount> {\n return {\n listAccountIds: () => ['default'],\n resolveAccount: (cfg) => params.resolveAccount(cfg),\n defaultAccountId: () => 'default',\n isEnabled: (account) => (account as { enabled?: boolean }).enabled !== false,\n resolveAllowFrom: params.resolveAllowFrom\n ? ({ cfg }) => params.resolveAllowFrom!(params.resolveAccount(cfg))\n : undefined,\n formatAllowFrom: params.formatAllowFrom\n ? ({ allowFrom }) => params.formatAllowFrom!(allowFrom)\n : undefined,\n };\n}\n\nexport function createScopedChannelConfigAdapter<ResolvedAccount>(params: {\n sectionKey: string;\n listAccountIds: (cfg: Config) => string[];\n resolveAccount: (cfg: Config, accountId?: string | null) => ResolvedAccount;\n defaultAccountId: (cfg: Config) => string;\n resolveAllowFrom: (account: ResolvedAccount) => Array<string | number> | undefined;\n formatAllowFrom: (allowFrom: Array<string | number>) => string[];\n}): ChannelConfigAdapter<ResolvedAccount> {\n return {\n listAccountIds: params.listAccountIds,\n resolveAccount: params.resolveAccount,\n defaultAccountId: params.defaultAccountId,\n isEnabled: (account) => (account as { enabled?: boolean }).enabled !== false,\n resolveAllowFrom: ({ cfg, accountId }) =>\n params.resolveAllowFrom(params.resolveAccount(cfg, accountId)),\n formatAllowFrom: ({ allowFrom }) => params.formatAllowFrom(allowFrom),\n };\n}\n\nexport function createHybridChannelConfigAdapter<ResolvedAccount>(params: {\n sectionKey: string;\n listAccountIds: (cfg: Config) => string[];\n resolveAccount: (cfg: Config, accountId?: string | null) => ResolvedAccount;\n resolveAllowFrom?: (account: ResolvedAccount) => Array<string | number> | undefined;\n formatAllowFrom?: (allowFrom: Array<string | number>) => string[];\n}): ChannelConfigAdapter<ResolvedAccount> {\n return {\n listAccountIds: params.listAccountIds,\n resolveAccount: params.resolveAccount,\n defaultAccountId: () => 'default',\n isEnabled: (account) => (account as { enabled?: boolean }).enabled !== false,\n resolveAllowFrom: params.resolveAllowFrom\n ? ({ cfg, accountId }) => params.resolveAllowFrom!(params.resolveAccount(cfg, accountId))\n : undefined,\n formatAllowFrom: params.formatAllowFrom\n ? ({ allowFrom }) => params.formatAllowFrom!(allowFrom)\n : undefined,\n };\n}\n"],"mappings":";AAOA,SAAgB,mCAAoD,QAM1B;AACxC,QAAO;EACL,sBAAsB,CAAC,UAAU;EACjC,iBAAiB,QAAQ,OAAO,eAAe,IAAI;EACnD,wBAAwB;EACxB,YAAY,YAAa,QAAkC,YAAY;EACvE,kBAAkB,OAAO,oBACpB,EAAE,UAAU,OAAO,iBAAkB,OAAO,eAAe,IAAI,CAAC,GACjE,KAAA;EACJ,iBAAiB,OAAO,mBACnB,EAAE,gBAAgB,OAAO,gBAAiB,UAAU,GACrD,KAAA;EACL;;AAGH,SAAgB,iCAAkD,QAOxB;AACxC,QAAO;EACL,gBAAgB,OAAO;EACvB,gBAAgB,OAAO;EACvB,kBAAkB,OAAO;EACzB,YAAY,YAAa,QAAkC,YAAY;EACvE,mBAAmB,EAAE,KAAK,gBACxB,OAAO,iBAAiB,OAAO,eAAe,KAAK,UAAU,CAAC;EAChE,kBAAkB,EAAE,gBAAgB,OAAO,gBAAgB,UAAU;EACtE;;AAGH,SAAgB,iCAAkD,QAMxB;AACxC,QAAO;EACL,gBAAgB,OAAO;EACvB,gBAAgB,OAAO;EACvB,wBAAwB;EACxB,YAAY,YAAa,QAAkC,YAAY;EACvE,kBAAkB,OAAO,oBACpB,EAAE,KAAK,gBAAgB,OAAO,iBAAkB,OAAO,eAAe,KAAK,UAAU,CAAC,GACvF,KAAA;EACJ,iBAAiB,OAAO,mBACnB,EAAE,gBAAgB,OAAO,gBAAiB,UAAU,GACrD,KAAA;EACL"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChannelHeartbeatScheduler — runs per-account heartbeat probes for plugins
|
|
3
|
+
* that expose a `heartbeat.check(...)` hook, records the result in the shared
|
|
4
|
+
* {@link ChannelHealthMonitor}, and asks the lifecycle supervisor for a soft
|
|
5
|
+
* restart when a check fails (rate-limited to once per minute per channel).
|
|
6
|
+
*
|
|
7
|
+
* Previously this lived as `_scheduleHeartbeat` + `_clearHeartbeatTimers` +
|
|
8
|
+
* `_softRestartChannel` + two private Maps on `ChannelManager`. Extracting it
|
|
9
|
+
* makes the heartbeat policy testable in isolation and lets the lifecycle
|
|
10
|
+
* supervisor focus on plugin start/stop without worrying about timer wiring.
|
|
11
|
+
*/
|
|
12
|
+
import type { Config } from '../config/schema.js';
|
|
13
|
+
import type { ChannelPlugin } from './plugin-types.js';
|
|
14
|
+
import type { ChannelHealthMonitor } from './health-monitor.js';
|
|
15
|
+
export interface ChannelHeartbeatSchedulerOptions {
|
|
16
|
+
/** Effective config snapshot (per-account listing comes from `plugin.config.listAccountIds(cfg)`). */
|
|
17
|
+
getConfig: () => Config;
|
|
18
|
+
/** Shared health monitor that channel APIs surface to the UI. */
|
|
19
|
+
healthMonitor: ChannelHealthMonitor;
|
|
20
|
+
/**
|
|
21
|
+
* Triggered when a check fails AND we are past the restart-throttle window.
|
|
22
|
+
* The supervisor performs `stop()` + `startPlugin()`; the scheduler does not
|
|
23
|
+
* touch plugin lifecycle directly.
|
|
24
|
+
*/
|
|
25
|
+
requestSoftRestart: (channelId: string) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare class ChannelHeartbeatScheduler {
|
|
28
|
+
private readonly opts;
|
|
29
|
+
/** Key shape: `${pluginId}:${accountId}`. */
|
|
30
|
+
private readonly timers;
|
|
31
|
+
private readonly lastRestartAt;
|
|
32
|
+
constructor(opts: ChannelHeartbeatSchedulerOptions);
|
|
33
|
+
/** Register heartbeat checks for every account exposed by the plugin. */
|
|
34
|
+
schedule(plugin: ChannelPlugin): void;
|
|
35
|
+
/** Drop every probe scheduled for `pluginId` (called on stop / soft-restart). */
|
|
36
|
+
clear(pluginId: string): void;
|
|
37
|
+
/** Test helper / process shutdown. */
|
|
38
|
+
clearAll(): void;
|
|
39
|
+
private runProbe;
|
|
40
|
+
}
|