agent-nuvira 2.7.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/agents/writer-tool-calling.d.ts +14 -0
- package/dist/agents/agents/writer-tool-calling.d.ts.map +1 -1
- package/dist/agents/agents/writer-tool-calling.js +20 -0
- package/dist/agents/agents/writer-tool-calling.js.map +1 -1
- package/dist/agents/agents/writer.d.ts.map +1 -1
- package/dist/agents/agents/writer.js +15 -4
- package/dist/agents/agents/writer.js.map +1 -1
- package/dist/agents/edit-module.d.ts +7 -0
- package/dist/agents/edit-module.d.ts.map +1 -1
- package/dist/agents/edit-module.js +21 -6
- package/dist/agents/edit-module.js.map +1 -1
- package/dist/agents/orchestrator.d.ts +40 -0
- package/dist/agents/orchestrator.d.ts.map +1 -1
- package/dist/agents/orchestrator.js +116 -27
- package/dist/agents/orchestrator.js.map +1 -1
- package/dist/agents/tool-calling-agent.d.ts +19 -0
- package/dist/agents/tool-calling-agent.d.ts.map +1 -1
- package/dist/agents/tool-calling-agent.js +42 -2
- package/dist/agents/tool-calling-agent.js.map +1 -1
- package/dist/cli/chat.d.ts +55 -1
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +239 -63
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/cli-program.d.ts +6 -0
- package/dist/cli/cli-program.d.ts.map +1 -0
- package/dist/cli/cli-program.js +222 -0
- package/dist/cli/cli-program.js.map +1 -0
- package/dist/cli/edit.d.ts.map +1 -1
- package/dist/cli/edit.js +18 -3
- package/dist/cli/edit.js.map +1 -1
- package/dist/cli/execute.d.ts.map +1 -1
- package/dist/cli/execute.js +29 -5
- package/dist/cli/execute.js.map +1 -1
- package/dist/cli/failover-runner.d.ts +13 -0
- package/dist/cli/failover-runner.d.ts.map +1 -1
- package/dist/cli/failover-runner.js +11 -0
- package/dist/cli/failover-runner.js.map +1 -1
- package/dist/cli/gateway.d.ts +16 -0
- package/dist/cli/gateway.d.ts.map +1 -1
- package/dist/cli/gateway.js +108 -2
- package/dist/cli/gateway.js.map +1 -1
- package/dist/cli/loop-executor.d.ts.map +1 -1
- package/dist/cli/loop-executor.js +245 -12
- package/dist/cli/loop-executor.js.map +1 -1
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +20 -6
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/process-control.d.ts +10 -0
- package/dist/cli/process-control.d.ts.map +1 -1
- package/dist/cli/process-control.js +73 -7
- package/dist/cli/process-control.js.map +1 -1
- package/dist/cli/router.d.ts +16 -5
- package/dist/cli/router.d.ts.map +1 -1
- package/dist/cli/router.js +31 -206
- package/dist/cli/router.js.map +1 -1
- package/dist/config/paths.d.ts +23 -0
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +30 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/config/provider-env.d.ts +37 -0
- package/dist/config/provider-env.d.ts.map +1 -0
- package/dist/config/provider-env.js +86 -0
- package/dist/config/provider-env.js.map +1 -0
- package/dist/context/history.d.ts.map +1 -1
- package/dist/context/history.js +24 -8
- package/dist/context/history.js.map +1 -1
- package/dist/context/session-recall.d.ts +30 -0
- package/dist/context/session-recall.d.ts.map +1 -1
- package/dist/context/session-recall.js +61 -0
- package/dist/context/session-recall.js.map +1 -1
- package/dist/file.js +0 -1
- package/dist/file.js.map +1 -1
- package/dist/gateway/adapters.d.ts +10 -0
- package/dist/gateway/adapters.d.ts.map +1 -1
- package/dist/gateway/adapters.js +4 -1
- package/dist/gateway/adapters.js.map +1 -1
- package/dist/gateway/dedup.d.ts +105 -0
- package/dist/gateway/dedup.d.ts.map +1 -0
- package/dist/gateway/dedup.js +160 -0
- package/dist/gateway/dedup.js.map +1 -0
- package/dist/gateway/heartbeat.d.ts +99 -0
- package/dist/gateway/heartbeat.d.ts.map +1 -0
- package/dist/gateway/heartbeat.js +122 -0
- package/dist/gateway/heartbeat.js.map +1 -0
- package/dist/gateway/inbox.d.ts +14 -1
- package/dist/gateway/inbox.d.ts.map +1 -1
- package/dist/gateway/inbox.js.map +1 -1
- package/dist/gateway/platform-config.d.ts +5 -0
- package/dist/gateway/platform-config.d.ts.map +1 -1
- package/dist/gateway/platform-config.js +8 -13
- package/dist/gateway/platform-config.js.map +1 -1
- package/dist/gateway/registry.d.ts +47 -0
- package/dist/gateway/registry.d.ts.map +1 -1
- package/dist/gateway/registry.js +227 -21
- package/dist/gateway/registry.js.map +1 -1
- package/dist/gateway/whatsapp/baileys-bridge.d.ts +11 -1
- package/dist/gateway/whatsapp/baileys-bridge.d.ts.map +1 -1
- package/dist/gateway/whatsapp/baileys-bridge.js +64 -1
- package/dist/gateway/whatsapp/baileys-bridge.js.map +1 -1
- package/dist/gateway/whatsapp/bridge.d.ts +4 -2
- package/dist/gateway/whatsapp/bridge.d.ts.map +1 -1
- package/dist/gateway/whatsapp/bridge.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inference/factory.d.ts +16 -0
- package/dist/inference/factory.d.ts.map +1 -1
- package/dist/inference/factory.js +42 -0
- package/dist/inference/factory.js.map +1 -1
- package/dist/inference/gemini-adapter.d.ts.map +1 -1
- package/dist/inference/gemini-adapter.js +3 -0
- package/dist/inference/gemini-adapter.js.map +1 -1
- package/dist/inference/interface.d.ts +12 -0
- package/dist/inference/interface.d.ts.map +1 -1
- package/dist/inference/local-adapter.d.ts +2 -0
- package/dist/inference/local-adapter.d.ts.map +1 -1
- package/dist/inference/local-adapter.js +36 -5
- package/dist/inference/local-adapter.js.map +1 -1
- package/dist/inference/native-tools.d.ts +8 -0
- package/dist/inference/native-tools.d.ts.map +1 -1
- package/dist/inference/native-tools.js +14 -3
- package/dist/inference/native-tools.js.map +1 -1
- package/dist/inference/tool-call-utils.d.ts +66 -7
- package/dist/inference/tool-call-utils.d.ts.map +1 -1
- package/dist/inference/tool-call-utils.js +134 -13
- package/dist/inference/tool-call-utils.js.map +1 -1
- package/dist/learning/auto-router.d.ts.map +1 -1
- package/dist/learning/auto-router.js +90 -5
- package/dist/learning/auto-router.js.map +1 -1
- package/dist/learning/context-budget.d.ts +133 -0
- package/dist/learning/context-budget.d.ts.map +1 -0
- package/dist/learning/context-budget.js +196 -0
- package/dist/learning/context-budget.js.map +1 -0
- package/dist/learning/cost-tracker.d.ts.map +1 -1
- package/dist/learning/cost-tracker.js +20 -8
- package/dist/learning/cost-tracker.js.map +1 -1
- package/dist/learning/eval-framework.d.ts.map +1 -1
- package/dist/learning/eval-framework.js +6 -2
- package/dist/learning/eval-framework.js.map +1 -1
- package/dist/learning/failure-bookkeeping.d.ts +19 -0
- package/dist/learning/failure-bookkeeping.d.ts.map +1 -1
- package/dist/learning/failure-bookkeeping.js +67 -2
- package/dist/learning/failure-bookkeeping.js.map +1 -1
- package/dist/learning/feedback.d.ts.map +1 -1
- package/dist/learning/feedback.js +19 -8
- package/dist/learning/feedback.js.map +1 -1
- package/dist/learning/model-harness.d.ts +76 -0
- package/dist/learning/model-harness.d.ts.map +1 -0
- package/dist/learning/model-harness.js +119 -0
- package/dist/learning/model-harness.js.map +1 -0
- package/dist/learning/model-selection.d.ts +15 -0
- package/dist/learning/model-selection.d.ts.map +1 -1
- package/dist/learning/model-selection.js +27 -1
- package/dist/learning/model-selection.js.map +1 -1
- package/dist/learning/provider-fallback.d.ts +12 -0
- package/dist/learning/provider-fallback.d.ts.map +1 -1
- package/dist/learning/provider-fallback.js +74 -0
- package/dist/learning/provider-fallback.js.map +1 -1
- package/dist/learning/provider-revival.d.ts +106 -0
- package/dist/learning/provider-revival.d.ts.map +1 -0
- package/dist/learning/provider-revival.js +154 -0
- package/dist/learning/provider-revival.js.map +1 -0
- package/dist/learning/resilient-call.d.ts.map +1 -1
- package/dist/learning/resilient-call.js +48 -3
- package/dist/learning/resilient-call.js.map +1 -1
- package/dist/nlu/conversation-gate.d.ts +37 -0
- package/dist/nlu/conversation-gate.d.ts.map +1 -1
- package/dist/nlu/conversation-gate.js +49 -0
- package/dist/nlu/conversation-gate.js.map +1 -1
- package/dist/nlu/schema.d.ts +2 -2
- package/dist/observability/dag-bridge.d.ts +69 -0
- package/dist/observability/dag-bridge.d.ts.map +1 -0
- package/dist/observability/dag-bridge.js +56 -0
- package/dist/observability/dag-bridge.js.map +1 -0
- package/dist/observability/event-bus.d.ts +5 -10
- package/dist/observability/event-bus.d.ts.map +1 -1
- package/dist/observability/event-bus.js +10 -42
- package/dist/observability/event-bus.js.map +1 -1
- package/dist/skills/execution-audit.d.ts.map +1 -1
- package/dist/skills/execution-audit.js +17 -5
- package/dist/skills/execution-audit.js.map +1 -1
- package/dist/skills/sandbox-executor.d.ts +12 -1
- package/dist/skills/sandbox-executor.d.ts.map +1 -1
- package/dist/skills/sandbox-executor.js +28 -6
- package/dist/skills/sandbox-executor.js.map +1 -1
- package/dist/skills/secret-capture.d.ts +45 -1
- package/dist/skills/secret-capture.d.ts.map +1 -1
- package/dist/skills/secret-capture.js +82 -19
- package/dist/skills/secret-capture.js.map +1 -1
- package/dist/skills/skill-env-inventory.d.ts +79 -0
- package/dist/skills/skill-env-inventory.d.ts.map +1 -0
- package/dist/skills/skill-env-inventory.js +167 -0
- package/dist/skills/skill-env-inventory.js.map +1 -0
- package/dist/skills/skill-executor.d.ts +2 -0
- package/dist/skills/skill-executor.d.ts.map +1 -1
- package/dist/skills/skill-executor.js +19 -24
- package/dist/skills/skill-executor.js.map +1 -1
- package/dist/tools/ask-user.d.ts +14 -1
- package/dist/tools/ask-user.d.ts.map +1 -1
- package/dist/tools/ask-user.js +25 -1
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/followup-utils.d.ts +64 -0
- package/dist/tools/followup-utils.d.ts.map +1 -0
- package/dist/tools/followup-utils.js +158 -0
- package/dist/tools/followup-utils.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +35 -0
- package/dist/tools/memory-tools.d.ts.map +1 -1
- package/dist/tools/memory-tools.js +76 -0
- package/dist/tools/memory-tools.js.map +1 -1
- package/dist/tools/pipeline-tool.d.ts.map +1 -1
- package/dist/tools/pipeline-tool.js +8 -3
- package/dist/tools/pipeline-tool.js.map +1 -1
- package/dist/tools/registry.d.ts +25 -12
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +31 -6
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/skill-tool.d.ts.map +1 -1
- package/dist/tools/skill-tool.js +52 -5
- package/dist/tools/skill-tool.js.map +1 -1
- package/dist/tools/tool-loop.d.ts +63 -1
- package/dist/tools/tool-loop.d.ts.map +1 -1
- package/dist/tools/tool-loop.js +305 -66
- package/dist/tools/tool-loop.js.map +1 -1
- package/dist/tools/toolsets.d.ts +19 -3
- package/dist/tools/toolsets.d.ts.map +1 -1
- package/dist/tools/toolsets.js +21 -5
- package/dist/tools/toolsets.js.map +1 -1
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +9 -13
- package/dist/utils/env.js.map +1 -1
- package/dist/web-dashboard/chat-console.d.ts +13 -1
- package/dist/web-dashboard/chat-console.d.ts.map +1 -1
- package/dist/web-dashboard/chat-console.js +16 -2
- package/dist/web-dashboard/chat-console.js.map +1 -1
- package/dist/web-dashboard/hub-data.d.ts +2 -0
- package/dist/web-dashboard/hub-data.d.ts.map +1 -1
- package/dist/web-dashboard/hub-data.js +4 -0
- package/dist/web-dashboard/hub-data.js.map +1 -1
- package/dist/web-dashboard/server.d.ts +6 -0
- package/dist/web-dashboard/server.d.ts.map +1 -1
- package/dist/web-dashboard/server.js +192 -3
- package/dist/web-dashboard/server.js.map +1 -1
- package/dist/web-dashboard/src/types.d.ts +31 -1
- package/dist/web-dashboard/src/types.d.ts.map +1 -1
- package/package.json +11 -1
- package/src/web-dashboard/public/assets/index-56yPnN_m.js +207 -0
- package/src/web-dashboard/public/assets/index-56yPnN_m.js.map +1 -0
- package/src/web-dashboard/public/assets/{index-C507EUWf.css → index-Cyd6tIew.css} +1 -1
- package/src/web-dashboard/public/index.html +2 -2
- package/dist/example.d.ts +0 -1
- package/dist/example.d.ts.map +0 -1
- package/dist/example.js +0 -3
- package/dist/example.js.map +0 -1
- package/dist/fresh.d.ts +0 -2
- package/dist/fresh.d.ts.map +0 -1
- package/dist/fresh.js +0 -2
- package/dist/fresh.js.map +0 -1
- package/dist/mcp/mcp-dashboard-oauth.d.ts +0 -94
- package/dist/mcp/mcp-dashboard-oauth.d.ts.map +0 -1
- package/dist/mcp/mcp-dashboard-oauth.js +0 -140
- package/dist/mcp/mcp-dashboard-oauth.js.map +0 -1
- package/dist/memory/background-sync.d.ts +0 -107
- package/dist/memory/background-sync.d.ts.map +0 -1
- package/dist/memory/background-sync.js +0 -242
- package/dist/memory/background-sync.js.map +0 -1
- package/dist/memory/cross-session.d.ts +0 -68
- package/dist/memory/cross-session.d.ts.map +0 -1
- package/dist/memory/cross-session.js +0 -153
- package/dist/memory/cross-session.js.map +0 -1
- package/dist/memory/drift-detector.d.ts +0 -76
- package/dist/memory/drift-detector.d.ts.map +0 -1
- package/dist/memory/drift-detector.js +0 -216
- package/dist/memory/drift-detector.js.map +0 -1
- package/dist/memory/enhanced-manager.d.ts +0 -105
- package/dist/memory/enhanced-manager.d.ts.map +0 -1
- package/dist/memory/enhanced-manager.js +0 -280
- package/dist/memory/enhanced-manager.js.map +0 -1
- package/dist/memory/session-extraction.d.ts +0 -93
- package/dist/memory/session-extraction.d.ts.map +0 -1
- package/dist/memory/session-extraction.js +0 -290
- package/dist/memory/session-extraction.js.map +0 -1
- package/dist/memory/sqlite-store.d.ts +0 -208
- package/dist/memory/sqlite-store.d.ts.map +0 -1
- package/dist/memory/sqlite-store.js +0 -556
- package/dist/memory/sqlite-store.js.map +0 -1
- package/dist/skills/daytona-executor.d.ts +0 -78
- package/dist/skills/daytona-executor.d.ts.map +0 -1
- package/dist/skills/daytona-executor.js +0 -256
- package/dist/skills/daytona-executor.js.map +0 -1
- package/dist/skills/modal-executor.d.ts +0 -81
- package/dist/skills/modal-executor.d.ts.map +0 -1
- package/dist/skills/modal-executor.js +0 -285
- package/dist/skills/modal-executor.js.map +0 -1
- package/dist/sync/inventory.d.ts +0 -1
- package/dist/sync/inventory.d.ts.map +0 -1
- package/dist/sync/inventory.js +0 -3
- package/dist/sync/inventory.js.map +0 -1
- package/dist/sync/validate.d.ts +0 -1
- package/dist/sync/validate.d.ts.map +0 -1
- package/dist/sync/validate.js +0 -3
- package/dist/sync/validate.js.map +0 -1
- package/dist/test.d.ts +0 -2
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js +0 -3
- package/dist/test.js.map +0 -1
- package/dist/tools/browser-tool.d.ts +0 -206
- package/dist/tools/browser-tool.d.ts.map +0 -1
- package/dist/tools/browser-tool.js +0 -726
- package/dist/tools/browser-tool.js.map +0 -1
- package/dist/tools/delegate-tool.d.ts +0 -109
- package/dist/tools/delegate-tool.d.ts.map +0 -1
- package/dist/tools/delegate-tool.js +0 -185
- package/dist/tools/delegate-tool.js.map +0 -1
- package/dist/tools/delegation-state.d.ts +0 -87
- package/dist/tools/delegation-state.d.ts.map +0 -1
- package/dist/tools/delegation-state.js +0 -278
- package/dist/tools/delegation-state.js.map +0 -1
- package/dist/tools/desktop-ui.d.ts +0 -148
- package/dist/tools/desktop-ui.d.ts.map +0 -1
- package/dist/tools/desktop-ui.js +0 -486
- package/dist/tools/desktop-ui.js.map +0 -1
- package/dist/tools/image-video-tool.d.ts +0 -88
- package/dist/tools/image-video-tool.d.ts.map +0 -1
- package/dist/tools/image-video-tool.js +0 -276
- package/dist/tools/image-video-tool.js.map +0 -1
- package/dist/tools/kanban-cron-tools.d.ts +0 -92
- package/dist/tools/kanban-cron-tools.d.ts.map +0 -1
- package/dist/tools/kanban-cron-tools.js +0 -197
- package/dist/tools/kanban-cron-tools.js.map +0 -1
- package/dist/tools/messaging-tool.d.ts +0 -127
- package/dist/tools/messaging-tool.d.ts.map +0 -1
- package/dist/tools/messaging-tool.js +0 -314
- package/dist/tools/messaging-tool.js.map +0 -1
- package/dist/tools/modality/generic-caller.d.ts +0 -43
- package/dist/tools/modality/generic-caller.d.ts.map +0 -1
- package/dist/tools/modality/generic-caller.js +0 -254
- package/dist/tools/modality/generic-caller.js.map +0 -1
- package/dist/tools/modality/modality-catalog.d.ts +0 -134
- package/dist/tools/modality/modality-catalog.d.ts.map +0 -1
- package/dist/tools/modality/modality-catalog.js +0 -445
- package/dist/tools/modality/modality-catalog.js.map +0 -1
- package/dist/tools/modality/tool-router.d.ts +0 -81
- package/dist/tools/modality/tool-router.d.ts.map +0 -1
- package/dist/tools/modality/tool-router.js +0 -84
- package/dist/tools/modality/tool-router.js.map +0 -1
- package/dist/tools/security-tools.d.ts +0 -107
- package/dist/tools/security-tools.d.ts.map +0 -1
- package/dist/tools/security-tools.js +0 -264
- package/dist/tools/security-tools.js.map +0 -1
- package/dist/tools/ssh-tool.d.ts +0 -130
- package/dist/tools/ssh-tool.d.ts.map +0 -1
- package/dist/tools/ssh-tool.js +0 -328
- package/dist/tools/ssh-tool.js.map +0 -1
- package/dist/tools/tts-tool.d.ts +0 -91
- package/dist/tools/tts-tool.d.ts.map +0 -1
- package/dist/tools/tts-tool.js +0 -406
- package/dist/tools/tts-tool.js.map +0 -1
- package/dist/utils/shell-detection.d.ts +0 -124
- package/dist/utils/shell-detection.d.ts.map +0 -1
- package/dist/utils/shell-detection.js +0 -305
- package/dist/utils/shell-detection.js.map +0 -1
- package/dist/utils/windows-paths.d.ts +0 -185
- package/dist/utils/windows-paths.d.ts.map +0 -1
- package/dist/utils/windows-paths.js +0 -472
- package/dist/utils/windows-paths.js.map +0 -1
- package/src/web-dashboard/public/assets/index-C4frng1Q.js +0 -207
- package/src/web-dashboard/public/assets/index-C4frng1Q.js.map +0 -1
|
@@ -1,726 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser Tool — Chrome DevTools Protocol (CDP) integration.
|
|
3
|
-
*
|
|
4
|
-
* This provides browser automation capabilities:
|
|
5
|
-
* - Page navigation
|
|
6
|
-
* - Element interaction (click, type, select)
|
|
7
|
-
* - JavaScript execution
|
|
8
|
-
* - Screenshot capture
|
|
9
|
-
* - PDF generation
|
|
10
|
-
* - Network interception
|
|
11
|
-
* - Cookie management
|
|
12
|
-
* - Local storage access
|
|
13
|
-
* - Dialog handling
|
|
14
|
-
* - Multi-tab support
|
|
15
|
-
* - Headless mode
|
|
16
|
-
* - Proxy support
|
|
17
|
-
* - User agent rotation
|
|
18
|
-
*
|
|
19
|
-
* Better than Hermes:
|
|
20
|
-
* - Full CDP protocol support
|
|
21
|
-
* - Built-in rate limiting
|
|
22
|
-
* - Automatic retry on failures
|
|
23
|
-
* - Detailed error reporting
|
|
24
|
-
* - Integration with skill system
|
|
25
|
-
*/
|
|
26
|
-
import { spawn } from 'node:child_process';
|
|
27
|
-
import { writeFile, readFile } from 'node:fs/promises';
|
|
28
|
-
import { randomBytes } from 'node:crypto';
|
|
29
|
-
// ─── Browser Class ───────────────────────────────────────────────────────
|
|
30
|
-
export class BrowserTool {
|
|
31
|
-
process = null;
|
|
32
|
-
config;
|
|
33
|
-
cdpPort;
|
|
34
|
-
sessionId;
|
|
35
|
-
constructor(config = {}) {
|
|
36
|
-
this.config = {
|
|
37
|
-
headless: true,
|
|
38
|
-
viewport: { width: 1280, height: 720 },
|
|
39
|
-
timeout: 30000,
|
|
40
|
-
...config,
|
|
41
|
-
};
|
|
42
|
-
this.cdpPort = 9222;
|
|
43
|
-
this.sessionId = randomBytes(8).toString('hex');
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Launch browser instance.
|
|
47
|
-
*/
|
|
48
|
-
async launch() {
|
|
49
|
-
const startTime = Date.now();
|
|
50
|
-
try {
|
|
51
|
-
// Find Chrome executable
|
|
52
|
-
const chromePath = this.config.executablePath ?? await this.findChrome();
|
|
53
|
-
if (!chromePath) {
|
|
54
|
-
return {
|
|
55
|
-
success: false,
|
|
56
|
-
error: 'Chrome not found. Install Chrome or provide executablePath.',
|
|
57
|
-
durationMs: Date.now() - startTime,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
// Build Chrome arguments
|
|
61
|
-
const args = this.buildArgs();
|
|
62
|
-
// Launch Chrome with CDP
|
|
63
|
-
this.process = spawn(chromePath, args, {
|
|
64
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
65
|
-
});
|
|
66
|
-
// Wait for CDP to be ready
|
|
67
|
-
await this.waitForCdp();
|
|
68
|
-
return {
|
|
69
|
-
success: true,
|
|
70
|
-
data: { port: this.cdpPort, sessionId: this.sessionId },
|
|
71
|
-
durationMs: Date.now() - startTime,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
return {
|
|
76
|
-
success: false,
|
|
77
|
-
error: err instanceof Error ? err.message : String(err),
|
|
78
|
-
durationMs: Date.now() - startTime,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Navigate to a URL.
|
|
84
|
-
*/
|
|
85
|
-
async navigate(options) {
|
|
86
|
-
const startTime = Date.now();
|
|
87
|
-
try {
|
|
88
|
-
const result = await this.cdpCommand('Page.navigate', {
|
|
89
|
-
url: options.url,
|
|
90
|
-
});
|
|
91
|
-
// Wait for load
|
|
92
|
-
if (options.waitUntil === 'networkidle') {
|
|
93
|
-
await this.waitForNetworkIdle(options.timeout ?? this.config.timeout ?? 30000);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
await this.waitForLoad(options.timeout ?? this.config.timeout ?? 30000);
|
|
97
|
-
}
|
|
98
|
-
return {
|
|
99
|
-
success: true,
|
|
100
|
-
data: result,
|
|
101
|
-
durationMs: Date.now() - startTime,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
return {
|
|
106
|
-
success: false,
|
|
107
|
-
error: err instanceof Error ? err.message : String(err),
|
|
108
|
-
durationMs: Date.now() - startTime,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Click an element.
|
|
114
|
-
*/
|
|
115
|
-
async click(options) {
|
|
116
|
-
const startTime = Date.now();
|
|
117
|
-
try {
|
|
118
|
-
// Find element
|
|
119
|
-
const element = await this.querySelector(options.selector);
|
|
120
|
-
if (!element) {
|
|
121
|
-
return {
|
|
122
|
-
success: false,
|
|
123
|
-
error: `Element not found: ${options.selector}`,
|
|
124
|
-
durationMs: Date.now() - startTime,
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
// Get element position
|
|
128
|
-
const box = await this.getBoundingBox(element);
|
|
129
|
-
if (!box) {
|
|
130
|
-
return {
|
|
131
|
-
success: false,
|
|
132
|
-
error: `Could not get bounding box for: ${options.selector}`,
|
|
133
|
-
durationMs: Date.now() - startTime,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
// Click element
|
|
137
|
-
const x = box.x + box.width / 2;
|
|
138
|
-
const y = box.y + box.height / 2;
|
|
139
|
-
await this.cdpCommand('Input.dispatchMouseEvent', {
|
|
140
|
-
type: 'mousePressed',
|
|
141
|
-
x,
|
|
142
|
-
y,
|
|
143
|
-
button: options.button ?? 'left',
|
|
144
|
-
clickCount: options.clickCount ?? 1,
|
|
145
|
-
});
|
|
146
|
-
await this.cdpCommand('Input.dispatchMouseEvent', {
|
|
147
|
-
type: 'mouseReleased',
|
|
148
|
-
x,
|
|
149
|
-
y,
|
|
150
|
-
button: options.button ?? 'left',
|
|
151
|
-
clickCount: options.clickCount ?? 1,
|
|
152
|
-
});
|
|
153
|
-
return {
|
|
154
|
-
success: true,
|
|
155
|
-
data: { x, y },
|
|
156
|
-
durationMs: Date.now() - startTime,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
catch (err) {
|
|
160
|
-
return {
|
|
161
|
-
success: false,
|
|
162
|
-
error: err instanceof Error ? err.message : String(err),
|
|
163
|
-
durationMs: Date.now() - startTime,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Type text into an element.
|
|
169
|
-
*/
|
|
170
|
-
async type(options) {
|
|
171
|
-
const startTime = Date.now();
|
|
172
|
-
try {
|
|
173
|
-
// Focus element
|
|
174
|
-
await this.focus(options.selector);
|
|
175
|
-
// Type text
|
|
176
|
-
for (const char of options.text) {
|
|
177
|
-
await this.cdpCommand('Input.dispatchKeyEvent', {
|
|
178
|
-
type: 'keyDown',
|
|
179
|
-
text: char,
|
|
180
|
-
});
|
|
181
|
-
await this.cdpCommand('Input.dispatchKeyEvent', {
|
|
182
|
-
type: 'keyUp',
|
|
183
|
-
text: char,
|
|
184
|
-
});
|
|
185
|
-
if (options.delay) {
|
|
186
|
-
await this.sleep(options.delay);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return {
|
|
190
|
-
success: true,
|
|
191
|
-
data: { text: options.text },
|
|
192
|
-
durationMs: Date.now() - startTime,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
catch (err) {
|
|
196
|
-
return {
|
|
197
|
-
success: false,
|
|
198
|
-
error: err instanceof Error ? err.message : String(err),
|
|
199
|
-
durationMs: Date.now() - startTime,
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Execute JavaScript in the page.
|
|
205
|
-
*/
|
|
206
|
-
async evaluate(expression) {
|
|
207
|
-
const startTime = Date.now();
|
|
208
|
-
try {
|
|
209
|
-
const result = await this.cdpCommand('Runtime.evaluate', {
|
|
210
|
-
expression,
|
|
211
|
-
returnByValue: true,
|
|
212
|
-
});
|
|
213
|
-
return {
|
|
214
|
-
success: true,
|
|
215
|
-
data: result?.result?.value,
|
|
216
|
-
durationMs: Date.now() - startTime,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
catch (err) {
|
|
220
|
-
return {
|
|
221
|
-
success: false,
|
|
222
|
-
error: err instanceof Error ? err.message : String(err),
|
|
223
|
-
durationMs: Date.now() - startTime,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Take a screenshot.
|
|
229
|
-
*/
|
|
230
|
-
async screenshot(options = {}) {
|
|
231
|
-
const startTime = Date.now();
|
|
232
|
-
try {
|
|
233
|
-
const result = await this.cdpCommand('Page.captureScreenshot', {
|
|
234
|
-
format: 'png',
|
|
235
|
-
quality: options.quality,
|
|
236
|
-
clip: options.clip,
|
|
237
|
-
captureBeyondViewport: options.fullPage ?? false,
|
|
238
|
-
});
|
|
239
|
-
const screenshotData = Buffer.from(result.data, 'base64');
|
|
240
|
-
if (options.path) {
|
|
241
|
-
await writeFile(options.path, screenshotData);
|
|
242
|
-
}
|
|
243
|
-
return {
|
|
244
|
-
success: true,
|
|
245
|
-
data: {
|
|
246
|
-
buffer: screenshotData,
|
|
247
|
-
path: options.path,
|
|
248
|
-
},
|
|
249
|
-
durationMs: Date.now() - startTime,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
catch (err) {
|
|
253
|
-
return {
|
|
254
|
-
success: false,
|
|
255
|
-
error: err instanceof Error ? err.message : String(err),
|
|
256
|
-
durationMs: Date.now() - startTime,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Get page content.
|
|
262
|
-
*/
|
|
263
|
-
async getContent() {
|
|
264
|
-
const startTime = Date.now();
|
|
265
|
-
try {
|
|
266
|
-
const result = await this.evaluate('document.documentElement.outerHTML');
|
|
267
|
-
return {
|
|
268
|
-
success: true,
|
|
269
|
-
data: result.data,
|
|
270
|
-
durationMs: Date.now() - startTime,
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
catch (err) {
|
|
274
|
-
return {
|
|
275
|
-
success: false,
|
|
276
|
-
error: err instanceof Error ? err.message : String(err),
|
|
277
|
-
durationMs: Date.now() - startTime,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Get page title.
|
|
283
|
-
*/
|
|
284
|
-
async getTitle() {
|
|
285
|
-
const startTime = Date.now();
|
|
286
|
-
try {
|
|
287
|
-
const result = await this.evaluate('document.title');
|
|
288
|
-
return {
|
|
289
|
-
success: true,
|
|
290
|
-
data: result.data,
|
|
291
|
-
durationMs: Date.now() - startTime,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
catch (err) {
|
|
295
|
-
return {
|
|
296
|
-
success: false,
|
|
297
|
-
error: err instanceof Error ? err.message : String(err),
|
|
298
|
-
durationMs: Date.now() - startTime,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Get current URL.
|
|
304
|
-
*/
|
|
305
|
-
async getUrl() {
|
|
306
|
-
const startTime = Date.now();
|
|
307
|
-
try {
|
|
308
|
-
const result = await this.evaluate('window.location.href');
|
|
309
|
-
return {
|
|
310
|
-
success: true,
|
|
311
|
-
data: result.data,
|
|
312
|
-
durationMs: Date.now() - startTime,
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
catch (err) {
|
|
316
|
-
return {
|
|
317
|
-
success: false,
|
|
318
|
-
error: err instanceof Error ? err.message : String(err),
|
|
319
|
-
durationMs: Date.now() - startTime,
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Set cookie.
|
|
325
|
-
*/
|
|
326
|
-
async setCookie(cookie) {
|
|
327
|
-
const startTime = Date.now();
|
|
328
|
-
try {
|
|
329
|
-
await this.cdpCommand('Network.setCookie', cookie);
|
|
330
|
-
return {
|
|
331
|
-
success: true,
|
|
332
|
-
data: { name: cookie.name },
|
|
333
|
-
durationMs: Date.now() - startTime,
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
catch (err) {
|
|
337
|
-
return {
|
|
338
|
-
success: false,
|
|
339
|
-
error: err instanceof Error ? err.message : String(err),
|
|
340
|
-
durationMs: Date.now() - startTime,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Get cookies.
|
|
346
|
-
*/
|
|
347
|
-
async getCookies() {
|
|
348
|
-
const startTime = Date.now();
|
|
349
|
-
try {
|
|
350
|
-
const result = await this.cdpCommand('Network.getCookies');
|
|
351
|
-
return {
|
|
352
|
-
success: true,
|
|
353
|
-
data: result?.cookies ?? [],
|
|
354
|
-
durationMs: Date.now() - startTime,
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
catch (err) {
|
|
358
|
-
return {
|
|
359
|
-
success: false,
|
|
360
|
-
error: err instanceof Error ? err.message : String(err),
|
|
361
|
-
durationMs: Date.now() - startTime,
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Delete cookie.
|
|
367
|
-
*/
|
|
368
|
-
async deleteCookie(name, domain, path) {
|
|
369
|
-
const startTime = Date.now();
|
|
370
|
-
try {
|
|
371
|
-
await this.cdpCommand('Network.deleteCookies', {
|
|
372
|
-
name,
|
|
373
|
-
domain,
|
|
374
|
-
path,
|
|
375
|
-
});
|
|
376
|
-
return {
|
|
377
|
-
success: true,
|
|
378
|
-
data: { name },
|
|
379
|
-
durationMs: Date.now() - startTime,
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
catch (err) {
|
|
383
|
-
return {
|
|
384
|
-
success: false,
|
|
385
|
-
error: err instanceof Error ? err.message : String(err),
|
|
386
|
-
durationMs: Date.now() - startTime,
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Get local storage.
|
|
392
|
-
*/
|
|
393
|
-
async getLocalStorage() {
|
|
394
|
-
const startTime = Date.now();
|
|
395
|
-
try {
|
|
396
|
-
const result = await this.evaluate(`
|
|
397
|
-
JSON.stringify(Object.keys(localStorage).reduce((acc, key) => {
|
|
398
|
-
acc[key] = localStorage.getItem(key);
|
|
399
|
-
return acc;
|
|
400
|
-
}, {}))
|
|
401
|
-
`);
|
|
402
|
-
return {
|
|
403
|
-
success: true,
|
|
404
|
-
data: JSON.parse(result.data ?? '{}'),
|
|
405
|
-
durationMs: Date.now() - startTime,
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
catch (err) {
|
|
409
|
-
return {
|
|
410
|
-
success: false,
|
|
411
|
-
error: err instanceof Error ? err.message : String(err),
|
|
412
|
-
durationMs: Date.now() - startTime,
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Set local storage item.
|
|
418
|
-
*/
|
|
419
|
-
async setLocalStorage(key, value) {
|
|
420
|
-
const startTime = Date.now();
|
|
421
|
-
try {
|
|
422
|
-
await this.evaluate(`localStorage.setItem('${key}', '${value}')`);
|
|
423
|
-
return {
|
|
424
|
-
success: true,
|
|
425
|
-
data: { key, value },
|
|
426
|
-
durationMs: Date.now() - startTime,
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
catch (err) {
|
|
430
|
-
return {
|
|
431
|
-
success: false,
|
|
432
|
-
error: err instanceof Error ? err.message : String(err),
|
|
433
|
-
durationMs: Date.now() - startTime,
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Wait for element to appear.
|
|
439
|
-
*/
|
|
440
|
-
async waitForSelector(selector, timeout) {
|
|
441
|
-
const startTime = Date.now();
|
|
442
|
-
const waitTimeout = timeout ?? this.config.timeout ?? 30000;
|
|
443
|
-
try {
|
|
444
|
-
const startTime = Date.now();
|
|
445
|
-
while (Date.now() - startTime < waitTimeout) {
|
|
446
|
-
const element = await this.querySelector(selector);
|
|
447
|
-
if (element) {
|
|
448
|
-
return {
|
|
449
|
-
success: true,
|
|
450
|
-
data: element,
|
|
451
|
-
durationMs: Date.now() - startTime,
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
await this.sleep(100);
|
|
455
|
-
}
|
|
456
|
-
return {
|
|
457
|
-
success: false,
|
|
458
|
-
error: `Timeout waiting for selector: ${selector}`,
|
|
459
|
-
durationMs: Date.now() - startTime,
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
catch (err) {
|
|
463
|
-
return {
|
|
464
|
-
success: false,
|
|
465
|
-
error: err instanceof Error ? err.message : String(err),
|
|
466
|
-
durationMs: Date.now() - startTime,
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Close browser.
|
|
472
|
-
*/
|
|
473
|
-
async close() {
|
|
474
|
-
if (this.process) {
|
|
475
|
-
this.process.kill('SIGTERM');
|
|
476
|
-
this.process = null;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
// ─── Private Methods ─────────────────────────────────────────────────
|
|
480
|
-
async findChrome() {
|
|
481
|
-
const paths = [
|
|
482
|
-
// macOS
|
|
483
|
-
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
484
|
-
'/Applications/Chromium.app/Contents/MacOS/Chromium',
|
|
485
|
-
// Linux
|
|
486
|
-
'/usr/bin/google-chrome',
|
|
487
|
-
'/usr/bin/chromium-browser',
|
|
488
|
-
'/usr/bin/chromium',
|
|
489
|
-
// Windows
|
|
490
|
-
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
491
|
-
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
|
|
492
|
-
];
|
|
493
|
-
for (const path of paths) {
|
|
494
|
-
try {
|
|
495
|
-
await readFile(path);
|
|
496
|
-
return path;
|
|
497
|
-
}
|
|
498
|
-
catch {
|
|
499
|
-
// Continue
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
return null;
|
|
503
|
-
}
|
|
504
|
-
buildArgs() {
|
|
505
|
-
const args = [
|
|
506
|
-
`--remote-debugging-port=${this.cdpPort}`,
|
|
507
|
-
`--window-size=${this.config.viewport?.width ?? 1280},${this.config.viewport?.height ?? 720}`,
|
|
508
|
-
];
|
|
509
|
-
if (this.config.headless) {
|
|
510
|
-
args.push('--headless=new');
|
|
511
|
-
}
|
|
512
|
-
if (this.config.proxy) {
|
|
513
|
-
args.push(`--proxy-server=${this.config.proxy.server}`);
|
|
514
|
-
}
|
|
515
|
-
if (this.config.userAgent) {
|
|
516
|
-
args.push(`--user-agent=${this.config.userAgent}`);
|
|
517
|
-
}
|
|
518
|
-
if (this.config.args) {
|
|
519
|
-
args.push(...this.config.args);
|
|
520
|
-
}
|
|
521
|
-
return args;
|
|
522
|
-
}
|
|
523
|
-
async waitForCdp() {
|
|
524
|
-
const timeout = 10000;
|
|
525
|
-
const startTime = Date.now();
|
|
526
|
-
while (Date.now() - startTime < timeout) {
|
|
527
|
-
try {
|
|
528
|
-
const response = await fetch(`http://localhost:${this.cdpPort}/json/version`);
|
|
529
|
-
if (response.ok) {
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
catch {
|
|
534
|
-
// Continue
|
|
535
|
-
}
|
|
536
|
-
await this.sleep(100);
|
|
537
|
-
}
|
|
538
|
-
throw new Error('CDP not ready after timeout');
|
|
539
|
-
}
|
|
540
|
-
async cdpCommand(method, params) {
|
|
541
|
-
// Get WebSocket URL
|
|
542
|
-
const response = await fetch(`http://localhost:${this.cdpPort}/json`);
|
|
543
|
-
const targets = (await response.json());
|
|
544
|
-
const target = targets.find((t) => t.type === 'page');
|
|
545
|
-
if (!target) {
|
|
546
|
-
throw new Error('No page target found');
|
|
547
|
-
}
|
|
548
|
-
// Connect via WebSocket
|
|
549
|
-
const ws = new WebSocket(target.webSocketDebuggerUrl);
|
|
550
|
-
return new Promise((resolve, reject) => {
|
|
551
|
-
const timeout = setTimeout(() => {
|
|
552
|
-
ws.close();
|
|
553
|
-
reject(new Error('CDP command timeout'));
|
|
554
|
-
}, this.config.timeout ?? 30000);
|
|
555
|
-
ws.onopen = () => {
|
|
556
|
-
ws.send(JSON.stringify({
|
|
557
|
-
id: 1,
|
|
558
|
-
method,
|
|
559
|
-
params: params ?? {},
|
|
560
|
-
}));
|
|
561
|
-
};
|
|
562
|
-
ws.onmessage = (event) => {
|
|
563
|
-
const data = JSON.parse(event.data);
|
|
564
|
-
if (data.id === 1) {
|
|
565
|
-
clearTimeout(timeout);
|
|
566
|
-
ws.close();
|
|
567
|
-
if (data.error) {
|
|
568
|
-
reject(new Error(data.error.message));
|
|
569
|
-
}
|
|
570
|
-
else {
|
|
571
|
-
resolve(data.result);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
ws.onerror = (error) => {
|
|
576
|
-
clearTimeout(timeout);
|
|
577
|
-
reject(error);
|
|
578
|
-
};
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
async querySelector(selector) {
|
|
582
|
-
const result = await this.evaluate(`
|
|
583
|
-
(() => {
|
|
584
|
-
const el = document.querySelector('${selector}');
|
|
585
|
-
if (!el) return null;
|
|
586
|
-
return {
|
|
587
|
-
nodeId: el.nodeId,
|
|
588
|
-
nodeName: el.nodeName,
|
|
589
|
-
attributes: el.attributes,
|
|
590
|
-
};
|
|
591
|
-
})()
|
|
592
|
-
`);
|
|
593
|
-
return result.data;
|
|
594
|
-
}
|
|
595
|
-
async getBoundingBox(element) {
|
|
596
|
-
const result = await this.evaluate(`
|
|
597
|
-
(() => {
|
|
598
|
-
const el = document.querySelector('[data-node-id="${element.nodeId}"]');
|
|
599
|
-
if (!el) return null;
|
|
600
|
-
const rect = el.getBoundingClientRect();
|
|
601
|
-
return {
|
|
602
|
-
x: rect.x,
|
|
603
|
-
y: rect.y,
|
|
604
|
-
width: rect.width,
|
|
605
|
-
height: rect.height,
|
|
606
|
-
};
|
|
607
|
-
})()
|
|
608
|
-
`);
|
|
609
|
-
return result.data;
|
|
610
|
-
}
|
|
611
|
-
async focus(selector) {
|
|
612
|
-
await this.evaluate(`
|
|
613
|
-
(() => {
|
|
614
|
-
const el = document.querySelector('${selector}');
|
|
615
|
-
if (el) el.focus();
|
|
616
|
-
})()
|
|
617
|
-
`);
|
|
618
|
-
}
|
|
619
|
-
async waitForLoad(timeout) {
|
|
620
|
-
await this.cdpCommand('Page.enable');
|
|
621
|
-
await new Promise((resolve) => {
|
|
622
|
-
const timer = setTimeout(resolve, timeout);
|
|
623
|
-
this.cdpCommand('Page.loadEventFired').then(() => {
|
|
624
|
-
clearTimeout(timer);
|
|
625
|
-
resolve(null);
|
|
626
|
-
});
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
async waitForNetworkIdle(timeout) {
|
|
630
|
-
await this.cdpCommand('Network.enable');
|
|
631
|
-
await new Promise((resolve) => {
|
|
632
|
-
const timer = setTimeout(resolve, timeout);
|
|
633
|
-
let requestCount = 0;
|
|
634
|
-
const checkIdle = () => {
|
|
635
|
-
if (requestCount === 0) {
|
|
636
|
-
clearTimeout(timer);
|
|
637
|
-
resolve(null);
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
|
-
this.cdpCommand('Network.requestWillBeSent').then(() => {
|
|
641
|
-
requestCount++;
|
|
642
|
-
});
|
|
643
|
-
this.cdpCommand('Network.loadingFinished').then(() => {
|
|
644
|
-
requestCount--;
|
|
645
|
-
checkIdle();
|
|
646
|
-
});
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
sleep(ms) {
|
|
650
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
// ─── Singleton Instance ──────────────────────────────────────────────────
|
|
654
|
-
let browserInstance = null;
|
|
655
|
-
/**
|
|
656
|
-
* Get or create browser instance.
|
|
657
|
-
*/
|
|
658
|
-
export async function getBrowser(config) {
|
|
659
|
-
if (!browserInstance) {
|
|
660
|
-
browserInstance = new BrowserTool(config);
|
|
661
|
-
await browserInstance.launch();
|
|
662
|
-
}
|
|
663
|
-
return browserInstance;
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Close browser instance.
|
|
667
|
-
*/
|
|
668
|
-
export async function closeBrowser() {
|
|
669
|
-
if (browserInstance) {
|
|
670
|
-
await browserInstance.close();
|
|
671
|
-
browserInstance = null;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
// ─── Skill Integration ───────────────────────────────────────────────────
|
|
675
|
-
/**
|
|
676
|
-
* Execute a browser-based skill.
|
|
677
|
-
*/
|
|
678
|
-
export async function executeBrowserSkill(skillContent, options = {}) {
|
|
679
|
-
const browser = await getBrowser();
|
|
680
|
-
const startTime = Date.now();
|
|
681
|
-
try {
|
|
682
|
-
// Navigate to URL if provided
|
|
683
|
-
if (options.url) {
|
|
684
|
-
await browser.navigate({ url: options.url });
|
|
685
|
-
}
|
|
686
|
-
// Execute actions
|
|
687
|
-
const results = [];
|
|
688
|
-
for (const action of options.actions ?? []) {
|
|
689
|
-
let result;
|
|
690
|
-
switch (action.type) {
|
|
691
|
-
case 'click':
|
|
692
|
-
result = await browser.click(action.params);
|
|
693
|
-
break;
|
|
694
|
-
case 'type':
|
|
695
|
-
result = await browser.type(action.params);
|
|
696
|
-
break;
|
|
697
|
-
case 'screenshot':
|
|
698
|
-
result = await browser.screenshot(action.params);
|
|
699
|
-
break;
|
|
700
|
-
case 'evaluate':
|
|
701
|
-
result = await browser.evaluate(action.params.expression);
|
|
702
|
-
break;
|
|
703
|
-
default:
|
|
704
|
-
result = {
|
|
705
|
-
success: false,
|
|
706
|
-
error: `Unknown action type: ${action.type}`,
|
|
707
|
-
durationMs: 0,
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
results.push(result);
|
|
711
|
-
}
|
|
712
|
-
return {
|
|
713
|
-
success: true,
|
|
714
|
-
data: results,
|
|
715
|
-
durationMs: Date.now() - startTime,
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
catch (err) {
|
|
719
|
-
return {
|
|
720
|
-
success: false,
|
|
721
|
-
error: err instanceof Error ? err.message : String(err),
|
|
722
|
-
durationMs: Date.now() - startTime,
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
//# sourceMappingURL=browser-tool.js.map
|