@kritchoff/agent-browser 0.9.2

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.
Files changed (88) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +903 -0
  3. package/README.sdk.md +77 -0
  4. package/bin/agent-browser-linux-x64 +0 -0
  5. package/bin/agent-browser.js +109 -0
  6. package/dist/actions.d.ts +17 -0
  7. package/dist/actions.d.ts.map +1 -0
  8. package/dist/actions.js +1427 -0
  9. package/dist/actions.js.map +1 -0
  10. package/dist/browser.d.ts +474 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +1566 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/cdp-client.d.ts +103 -0
  15. package/dist/cdp-client.d.ts.map +1 -0
  16. package/dist/cdp-client.js +223 -0
  17. package/dist/cdp-client.js.map +1 -0
  18. package/dist/daemon.d.ts +60 -0
  19. package/dist/daemon.d.ts.map +1 -0
  20. package/dist/daemon.js +401 -0
  21. package/dist/daemon.js.map +1 -0
  22. package/dist/dualmode-config.d.ts +37 -0
  23. package/dist/dualmode-config.d.ts.map +1 -0
  24. package/dist/dualmode-config.js +44 -0
  25. package/dist/dualmode-config.js.map +1 -0
  26. package/dist/dualmode-fetcher.d.ts +60 -0
  27. package/dist/dualmode-fetcher.d.ts.map +1 -0
  28. package/dist/dualmode-fetcher.js +449 -0
  29. package/dist/dualmode-fetcher.js.map +1 -0
  30. package/dist/dualmode-types.d.ts +183 -0
  31. package/dist/dualmode-types.d.ts.map +1 -0
  32. package/dist/dualmode-types.js +8 -0
  33. package/dist/dualmode-types.js.map +1 -0
  34. package/dist/ios-actions.d.ts +11 -0
  35. package/dist/ios-actions.d.ts.map +1 -0
  36. package/dist/ios-actions.js +228 -0
  37. package/dist/ios-actions.js.map +1 -0
  38. package/dist/ios-manager.d.ts +266 -0
  39. package/dist/ios-manager.d.ts.map +1 -0
  40. package/dist/ios-manager.js +1073 -0
  41. package/dist/ios-manager.js.map +1 -0
  42. package/dist/protocol.d.ts +26 -0
  43. package/dist/protocol.d.ts.map +1 -0
  44. package/dist/protocol.js +832 -0
  45. package/dist/protocol.js.map +1 -0
  46. package/dist/snapshot.d.ts +83 -0
  47. package/dist/snapshot.d.ts.map +1 -0
  48. package/dist/snapshot.js +653 -0
  49. package/dist/snapshot.js.map +1 -0
  50. package/dist/stream-server.d.ts +117 -0
  51. package/dist/stream-server.d.ts.map +1 -0
  52. package/dist/stream-server.js +305 -0
  53. package/dist/stream-server.js.map +1 -0
  54. package/dist/types.d.ts +742 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/docker-compose.sdk.yml +45 -0
  59. package/package.json +85 -0
  60. package/scripts/benchmark.sh +80 -0
  61. package/scripts/build-all-platforms.sh +68 -0
  62. package/scripts/check-version-sync.js +39 -0
  63. package/scripts/copy-native.js +36 -0
  64. package/scripts/fast_reset.sh +108 -0
  65. package/scripts/postinstall.js +235 -0
  66. package/scripts/publish_images.sh +55 -0
  67. package/scripts/snapshot_manager.sh +293 -0
  68. package/scripts/start-android-agent.sh +49 -0
  69. package/scripts/sync-version.js +69 -0
  70. package/scripts/vaccine-run +26 -0
  71. package/sdk.sh +153 -0
  72. package/skills/agent-browser/SKILL.md +217 -0
  73. package/skills/agent-browser/references/authentication.md +202 -0
  74. package/skills/agent-browser/references/commands.md +259 -0
  75. package/skills/agent-browser/references/proxy-support.md +188 -0
  76. package/skills/agent-browser/references/session-management.md +193 -0
  77. package/skills/agent-browser/references/snapshot-refs.md +194 -0
  78. package/skills/agent-browser/references/video-recording.md +173 -0
  79. package/skills/agent-browser/templates/authenticated-session.sh +97 -0
  80. package/skills/agent-browser/templates/capture-workflow.sh +69 -0
  81. package/skills/agent-browser/templates/form-automation.sh +62 -0
  82. package/skills/skill-creator/LICENSE.txt +202 -0
  83. package/skills/skill-creator/SKILL.md +356 -0
  84. package/skills/skill-creator/references/output-patterns.md +82 -0
  85. package/skills/skill-creator/references/workflows.md +28 -0
  86. package/skills/skill-creator/scripts/init_skill.py +303 -0
  87. package/skills/skill-creator/scripts/package_skill.py +113 -0
  88. package/skills/skill-creator/scripts/quick_validate.py +95 -0
package/dist/daemon.js ADDED
@@ -0,0 +1,401 @@
1
+ import 'dotenv/config';
2
+ import * as net from 'net';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import * as os from 'os';
6
+ import { BrowserManager } from './browser.js';
7
+ import { IOSManager } from './ios-manager.js';
8
+ import { parseCommand, serializeResponse, errorResponse } from './protocol.js';
9
+ import { executeCommand } from './actions.js';
10
+ import { executeIOSCommand } from './ios-actions.js';
11
+ import { StreamServer } from './stream-server.js';
12
+ // Platform detection
13
+ const isWindows = process.platform === 'win32';
14
+ // Session support - each session gets its own socket/pid
15
+ let currentSession = process.env.AGENT_BROWSER_SESSION || 'default';
16
+ // Stream server for browser preview
17
+ let streamServer = null;
18
+ // Default stream port (can be overridden with AGENT_BROWSER_STREAM_PORT)
19
+ const DEFAULT_STREAM_PORT = 9223;
20
+ /**
21
+ * Set the current session
22
+ */
23
+ export function setSession(session) {
24
+ currentSession = session;
25
+ }
26
+ /**
27
+ * Get the current session
28
+ */
29
+ export function getSession() {
30
+ return currentSession;
31
+ }
32
+ /**
33
+ * Get port number for TCP mode (Windows)
34
+ * Uses a hash of the session name to get a consistent port
35
+ */
36
+ function getPortForSession(session) {
37
+ let hash = 0;
38
+ for (let i = 0; i < session.length; i++) {
39
+ hash = (hash << 5) - hash + session.charCodeAt(i);
40
+ hash |= 0;
41
+ }
42
+ // Port range 49152-65535 (dynamic/private ports)
43
+ return 49152 + (Math.abs(hash) % 16383);
44
+ }
45
+ /**
46
+ * Get the base directory for socket/pid files.
47
+ * Priority: AGENT_BROWSER_SOCKET_DIR > XDG_RUNTIME_DIR > ~/.agent-browser > tmpdir
48
+ */
49
+ export function getAppDir() {
50
+ // 1. XDG_RUNTIME_DIR (Linux standard)
51
+ if (process.env.XDG_RUNTIME_DIR) {
52
+ return path.join(process.env.XDG_RUNTIME_DIR, 'agent-browser');
53
+ }
54
+ // 2. Home directory fallback (like Docker Desktop's ~/.docker/run/)
55
+ const homeDir = os.homedir();
56
+ if (homeDir) {
57
+ return path.join(homeDir, '.agent-browser');
58
+ }
59
+ // 3. Last resort: temp dir
60
+ return path.join(os.tmpdir(), 'agent-browser');
61
+ }
62
+ export function getSocketDir() {
63
+ // Allow explicit override for socket directory
64
+ if (process.env.AGENT_BROWSER_SOCKET_DIR) {
65
+ return process.env.AGENT_BROWSER_SOCKET_DIR;
66
+ }
67
+ return getAppDir();
68
+ }
69
+ /**
70
+ * Get the socket path for the current session (Unix) or port (Windows)
71
+ */
72
+ export function getSocketPath(session) {
73
+ const sess = session ?? currentSession;
74
+ if (isWindows) {
75
+ return String(getPortForSession(sess));
76
+ }
77
+ return path.join(getSocketDir(), `${sess}.sock`);
78
+ }
79
+ /**
80
+ * Get the port file path for Windows (stores the port number)
81
+ */
82
+ export function getPortFile(session) {
83
+ const sess = session ?? currentSession;
84
+ return path.join(getSocketDir(), `${sess}.port`);
85
+ }
86
+ /**
87
+ * Get the PID file path for the current session
88
+ */
89
+ export function getPidFile(session) {
90
+ const sess = session ?? currentSession;
91
+ return path.join(getSocketDir(), `${sess}.pid`);
92
+ }
93
+ /**
94
+ * Check if daemon is running for the current session
95
+ */
96
+ export function isDaemonRunning(session) {
97
+ const pidFile = getPidFile(session);
98
+ if (!fs.existsSync(pidFile))
99
+ return false;
100
+ try {
101
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
102
+ // Check if process exists (works on both Unix and Windows)
103
+ process.kill(pid, 0);
104
+ return true;
105
+ }
106
+ catch {
107
+ // Process doesn't exist, clean up stale files
108
+ cleanupSocket(session);
109
+ return false;
110
+ }
111
+ }
112
+ /**
113
+ * Get connection info for the current session
114
+ * Returns { type: 'unix', path: string } or { type: 'tcp', port: number }
115
+ */
116
+ export function getConnectionInfo(session) {
117
+ const sess = session ?? currentSession;
118
+ if (isWindows) {
119
+ return { type: 'tcp', port: getPortForSession(sess) };
120
+ }
121
+ return { type: 'unix', path: path.join(getSocketDir(), `${sess}.sock`) };
122
+ }
123
+ /**
124
+ * Clean up socket and PID file for the current session
125
+ */
126
+ export function cleanupSocket(session) {
127
+ const pidFile = getPidFile(session);
128
+ const streamPortFile = getStreamPortFile(session);
129
+ try {
130
+ if (fs.existsSync(pidFile))
131
+ fs.unlinkSync(pidFile);
132
+ if (fs.existsSync(streamPortFile))
133
+ fs.unlinkSync(streamPortFile);
134
+ if (isWindows) {
135
+ const portFile = getPortFile(session);
136
+ if (fs.existsSync(portFile))
137
+ fs.unlinkSync(portFile);
138
+ }
139
+ else {
140
+ const socketPath = getSocketPath(session);
141
+ if (fs.existsSync(socketPath))
142
+ fs.unlinkSync(socketPath);
143
+ }
144
+ }
145
+ catch {
146
+ // Ignore cleanup errors
147
+ }
148
+ }
149
+ /**
150
+ * Get the stream port file path
151
+ */
152
+ export function getStreamPortFile(session) {
153
+ const sess = session ?? currentSession;
154
+ return path.join(getSocketDir(), `${sess}.stream`);
155
+ }
156
+ /**
157
+ * Start the daemon server
158
+ * @param options.streamPort Port for WebSocket stream server (0 to disable)
159
+ * @param options.provider Provider type ('ios' for iOS Simulator, undefined for desktop)
160
+ */
161
+ export async function startDaemon(options) {
162
+ // Ensure socket directory exists
163
+ const socketDir = getSocketDir();
164
+ if (!fs.existsSync(socketDir)) {
165
+ fs.mkdirSync(socketDir, { recursive: true });
166
+ }
167
+ // Clean up any stale socket
168
+ cleanupSocket();
169
+ // Determine provider from options or environment
170
+ const provider = options?.provider ?? process.env.AGENT_BROWSER_PROVIDER;
171
+ const isIOS = provider === 'ios';
172
+ // Create appropriate manager
173
+ const manager = isIOS ? new IOSManager() : new BrowserManager();
174
+ let shuttingDown = false;
175
+ // Start stream server if port is specified (or use default if env var is set)
176
+ // Note: Stream server only works with BrowserManager (desktop), not iOS
177
+ const streamPort = options?.streamPort ??
178
+ (process.env.AGENT_BROWSER_STREAM_PORT
179
+ ? parseInt(process.env.AGENT_BROWSER_STREAM_PORT, 10)
180
+ : 0);
181
+ if (streamPort > 0 && !isIOS && manager instanceof BrowserManager) {
182
+ streamServer = new StreamServer(manager, streamPort);
183
+ await streamServer.start();
184
+ // Write stream port to file for clients to discover
185
+ const streamPortFile = getStreamPortFile();
186
+ fs.writeFileSync(streamPortFile, streamPort.toString());
187
+ }
188
+ const server = net.createServer((socket) => {
189
+ let buffer = '';
190
+ let httpChecked = false;
191
+ socket.on('data', async (data) => {
192
+ buffer += data.toString();
193
+ // Security: Detect and reject HTTP requests to prevent cross-origin attacks.
194
+ // Browsers using fetch() must send HTTP headers (e.g., "POST / HTTP/1.1"),
195
+ // while legitimate clients send raw JSON starting with "{".
196
+ if (!httpChecked) {
197
+ httpChecked = true;
198
+ const trimmed = buffer.trimStart();
199
+ if (/^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|CONNECT|TRACE)\s/i.test(trimmed)) {
200
+ socket.destroy();
201
+ return;
202
+ }
203
+ }
204
+ // Process complete lines
205
+ while (buffer.includes('\n')) {
206
+ const newlineIdx = buffer.indexOf('\n');
207
+ const line = buffer.substring(0, newlineIdx);
208
+ buffer = buffer.substring(newlineIdx + 1);
209
+ if (!line.trim())
210
+ continue;
211
+ try {
212
+ const parseResult = parseCommand(line);
213
+ if (!parseResult.success) {
214
+ const resp = errorResponse(parseResult.id ?? 'unknown', parseResult.error);
215
+ socket.write(serializeResponse(resp) + '\n');
216
+ continue;
217
+ }
218
+ // Handle device_list specially - it works without a session and always uses IOSManager
219
+ if (parseResult.command.action === 'device_list') {
220
+ const iosManager = new IOSManager();
221
+ try {
222
+ const devices = await iosManager.listAllDevices();
223
+ const response = {
224
+ id: parseResult.command.id,
225
+ success: true,
226
+ data: { devices },
227
+ };
228
+ socket.write(serializeResponse(response) + '\n');
229
+ }
230
+ catch (err) {
231
+ const message = err instanceof Error ? err.message : String(err);
232
+ socket.write(serializeResponse(errorResponse(parseResult.command.id, message)) + '\n');
233
+ }
234
+ continue;
235
+ }
236
+ // Auto-launch if not already launched and this isn't a launch/close command
237
+ if (!manager.isLaunched() &&
238
+ parseResult.command.action !== 'launch' &&
239
+ parseResult.command.action !== 'close') {
240
+ if (isIOS && manager instanceof IOSManager) {
241
+ // Auto-launch iOS Safari
242
+ // Check for device in command first (for reused daemons), then fall back to env vars
243
+ const cmd = parseResult.command;
244
+ const iosDevice = cmd.iosDevice || process.env.AGENT_BROWSER_IOS_DEVICE;
245
+ await manager.launch({
246
+ device: iosDevice,
247
+ udid: process.env.AGENT_BROWSER_IOS_UDID,
248
+ });
249
+ }
250
+ else if (manager instanceof BrowserManager) {
251
+ // Auto-launch desktop browser
252
+ const extensions = process.env.AGENT_BROWSER_EXTENSIONS
253
+ ? process.env.AGENT_BROWSER_EXTENSIONS.split(',')
254
+ .map((p) => p.trim())
255
+ .filter(Boolean)
256
+ : undefined;
257
+ // Parse args from env (comma or newline separated)
258
+ const argsEnv = process.env.AGENT_BROWSER_ARGS;
259
+ const args = argsEnv
260
+ ? argsEnv
261
+ .split(/[,\n]/)
262
+ .map((a) => a.trim())
263
+ .filter((a) => a.length > 0)
264
+ : undefined;
265
+ // Parse proxy from env
266
+ const proxyServer = process.env.AGENT_BROWSER_PROXY;
267
+ const proxyBypass = process.env.AGENT_BROWSER_PROXY_BYPASS;
268
+ const proxy = proxyServer
269
+ ? {
270
+ server: proxyServer,
271
+ ...(proxyBypass && { bypass: proxyBypass }),
272
+ }
273
+ : undefined;
274
+ const ignoreHTTPSErrors = process.env.AGENT_BROWSER_IGNORE_HTTPS_ERRORS === '1';
275
+ const allowFileAccess = process.env.AGENT_BROWSER_ALLOW_FILE_ACCESS === '1';
276
+ await manager.launch({
277
+ id: 'auto',
278
+ action: 'launch',
279
+ headless: process.env.AGENT_BROWSER_HEADED !== '1',
280
+ executablePath: process.env.AGENT_BROWSER_EXECUTABLE_PATH,
281
+ extensions: extensions,
282
+ profile: process.env.AGENT_BROWSER_PROFILE,
283
+ storageState: process.env.AGENT_BROWSER_STATE,
284
+ args,
285
+ userAgent: process.env.AGENT_BROWSER_USER_AGENT,
286
+ proxy,
287
+ ignoreHTTPSErrors: ignoreHTTPSErrors,
288
+ allowFileAccess: allowFileAccess,
289
+ });
290
+ }
291
+ }
292
+ // Handle close command specially - shuts down daemon
293
+ if (parseResult.command.action === 'close') {
294
+ const response = isIOS && manager instanceof IOSManager
295
+ ? await executeIOSCommand(parseResult.command, manager)
296
+ : await executeCommand(parseResult.command, manager);
297
+ socket.write(serializeResponse(response) + '\n');
298
+ if (!shuttingDown) {
299
+ shuttingDown = true;
300
+ setTimeout(() => {
301
+ server.close();
302
+ cleanupSocket();
303
+ process.exit(0);
304
+ }, 100);
305
+ }
306
+ return;
307
+ }
308
+ // Execute command with appropriate handler
309
+ const response = isIOS && manager instanceof IOSManager
310
+ ? await executeIOSCommand(parseResult.command, manager)
311
+ : await executeCommand(parseResult.command, manager);
312
+ socket.write(serializeResponse(response) + '\n');
313
+ }
314
+ catch (err) {
315
+ const message = err instanceof Error ? err.message : String(err);
316
+ socket.write(serializeResponse(errorResponse('error', message)) + '\n');
317
+ }
318
+ }
319
+ });
320
+ socket.on('error', () => {
321
+ // Client disconnected, ignore
322
+ });
323
+ });
324
+ const pidFile = getPidFile();
325
+ // Write PID file before listening
326
+ fs.writeFileSync(pidFile, process.pid.toString());
327
+ if (isWindows) {
328
+ // Windows: use TCP socket on localhost
329
+ const port = getPortForSession(currentSession);
330
+ const portFile = getPortFile();
331
+ fs.writeFileSync(portFile, port.toString());
332
+ server.listen(port, '127.0.0.1', () => {
333
+ // Daemon is ready on TCP port
334
+ });
335
+ }
336
+ else {
337
+ // Unix: use Unix domain socket
338
+ const socketPath = getSocketPath();
339
+ server.listen(socketPath, () => {
340
+ // Daemon is ready
341
+ });
342
+ }
343
+ server.on('error', (err) => {
344
+ console.error('Server error:', err);
345
+ cleanupSocket();
346
+ process.exit(1);
347
+ });
348
+ // Handle shutdown signals
349
+ const shutdown = async () => {
350
+ if (shuttingDown)
351
+ return;
352
+ shuttingDown = true;
353
+ // Stop stream server if running
354
+ if (streamServer) {
355
+ await streamServer.stop();
356
+ streamServer = null;
357
+ // Clean up stream port file
358
+ const streamPortFile = getStreamPortFile();
359
+ try {
360
+ if (fs.existsSync(streamPortFile))
361
+ fs.unlinkSync(streamPortFile);
362
+ }
363
+ catch {
364
+ // Ignore cleanup errors
365
+ }
366
+ }
367
+ await manager.close();
368
+ server.close();
369
+ cleanupSocket();
370
+ process.exit(0);
371
+ };
372
+ process.on('SIGINT', shutdown);
373
+ process.on('SIGTERM', shutdown);
374
+ process.on('SIGHUP', shutdown);
375
+ // Handle unexpected errors - always cleanup
376
+ process.on('uncaughtException', (err) => {
377
+ console.error('Uncaught exception:', err);
378
+ cleanupSocket();
379
+ process.exit(1);
380
+ });
381
+ process.on('unhandledRejection', (reason) => {
382
+ console.error('Unhandled rejection:', reason);
383
+ cleanupSocket();
384
+ process.exit(1);
385
+ });
386
+ // Cleanup on normal exit
387
+ process.on('exit', () => {
388
+ cleanupSocket();
389
+ });
390
+ // Keep process alive
391
+ process.stdin.resume();
392
+ }
393
+ // Run daemon if this is the entry point
394
+ if (process.argv[1]?.endsWith('daemon.js') || process.env.AGENT_BROWSER_DAEMON === '1') {
395
+ startDaemon().catch((err) => {
396
+ console.error('Daemon error:', err);
397
+ cleanupSocket();
398
+ process.exit(1);
399
+ });
400
+ }
401
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Configuration for DualMode / WootzApp engine
3
+ *
4
+ * Reads environment variables and provides configuration for switching
5
+ * between Playwright and WootzApp engines.
6
+ */
7
+ /**
8
+ * DualMode engine configuration
9
+ */
10
+ export interface DualModeConfig {
11
+ /** Engine to use: 'playwright' or 'wootzapp' */
12
+ engine: 'playwright' | 'wootzapp';
13
+ /** CDP host (for WootzApp) */
14
+ cdpHost: string;
15
+ /** CDP port (for WootzApp) */
16
+ cdpPort: number;
17
+ /** CDP connection timeout in milliseconds */
18
+ cdpTimeout: number;
19
+ /** Whether DualMode engine is enabled */
20
+ enabled: boolean;
21
+ }
22
+ /**
23
+ * Get DualMode configuration from environment variables
24
+ */
25
+ export declare function getDualModeConfig(): DualModeConfig;
26
+ /**
27
+ * Check if WootzApp engine is enabled
28
+ */
29
+ export declare function isWootzAppEnabled(): boolean;
30
+ /**
31
+ * Get CDP endpoint URL
32
+ */
33
+ export declare function getCDPEndpoint(): {
34
+ host: string;
35
+ port: number;
36
+ };
37
+ //# sourceMappingURL=dualmode-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dualmode-config.d.ts","sourceRoot":"","sources":["../src/dualmode-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,MAAM,EAAE,YAAY,GAAG,UAAU,CAAC;IAElC,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAEhB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAEhB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IAEnB,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAoBlD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAM/D"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Configuration for DualMode / WootzApp engine
3
+ *
4
+ * Reads environment variables and provides configuration for switching
5
+ * between Playwright and WootzApp engines.
6
+ */
7
+ /**
8
+ * Get DualMode configuration from environment variables
9
+ */
10
+ export function getDualModeConfig() {
11
+ const rawEngine = process.env.AGENT_BROWSER_ENGINE;
12
+ const engine = (rawEngine?.toLowerCase() || 'playwright');
13
+ const config = {
14
+ engine,
15
+ cdpHost: process.env.AGENT_BROWSER_CDP_HOST || 'localhost',
16
+ cdpPort: parseInt(process.env.AGENT_BROWSER_CDP_PORT || '9224', 10),
17
+ cdpTimeout: parseInt(process.env.AGENT_BROWSER_CDP_TIMEOUT || '30000', 10),
18
+ enabled: engine === 'wootzapp',
19
+ };
20
+ console.log('[DualMode Config] Retrieved configuration:', {
21
+ rawEnv: rawEngine,
22
+ processedEngine: engine,
23
+ enabled: config.enabled,
24
+ cdpEndpoint: `${config.cdpHost}:${config.cdpPort}`
25
+ });
26
+ return config;
27
+ }
28
+ /**
29
+ * Check if WootzApp engine is enabled
30
+ */
31
+ export function isWootzAppEnabled() {
32
+ return getDualModeConfig().enabled;
33
+ }
34
+ /**
35
+ * Get CDP endpoint URL
36
+ */
37
+ export function getCDPEndpoint() {
38
+ const config = getDualModeConfig();
39
+ return {
40
+ host: config.cdpHost,
41
+ port: config.cdpPort,
42
+ };
43
+ }
44
+ //# sourceMappingURL=dualmode-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dualmode-config.js","sourceRoot":"","sources":["../src/dualmode-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IACnD,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,YAAY,CAA8B,CAAC;IAEvF,MAAM,MAAM,GAAG;QACb,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,WAAW;QAC1D,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,MAAM,EAAE,EAAE,CAAC;QACnE,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,OAAO,EAAE,EAAE,CAAC;QAC1E,OAAO,EAAE,MAAM,KAAK,UAAU;KAC/B,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE;QACxD,MAAM,EAAE,SAAS;QACjB,eAAe,EAAE,MAAM;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE;KACnD,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,iBAAiB,EAAE,CAAC,OAAO,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,OAAO;QACpB,IAAI,EAAE,MAAM,CAAC,OAAO;KACrB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * DualMode Accessibility Tree Fetcher
3
+ *
4
+ * Fetches enhanced accessibility tree from WootzApp Android browser via CDP.
5
+ * Transforms flat node list into hierarchical tree structure with refs.
6
+ */
7
+ import type { DualModeTree, GetDualModeAXTreeResponse, DualModeSnapshotOptions, DualModeEnhancedSnapshot } from './dualmode-types.js';
8
+ /**
9
+ * DualMode AXTree fetcher
10
+ */
11
+ export declare class DualModeAXTreeFetcher {
12
+ private host;
13
+ private port;
14
+ constructor(host?: string, port?: number);
15
+ /**
16
+ * Clear Chrome app data using pm clear command
17
+ */
18
+ private clearBrowserData;
19
+ /**
20
+ * Fetch DualMode AXTree for a URL
21
+ */
22
+ fetchTree(url: string): Promise<GetDualModeAXTreeResponse>;
23
+ /**
24
+ * Convert standard CDP accessibility tree to DualMode format
25
+ */
26
+ private convertStandardTreeToDualMode;
27
+ /**
28
+ * Parse node ID (handle string or number)
29
+ */
30
+ private parseNodeId;
31
+ /**
32
+ * Fetch tree for current page (no navigation)
33
+ */
34
+ fetchCurrentPageTree(): Promise<GetDualModeAXTreeResponse>;
35
+ /**
36
+ * Build hierarchical tree from flat node list
37
+ */
38
+ buildTree(response: GetDualModeAXTreeResponse): DualModeTree;
39
+ /**
40
+ * Check if role is interactive
41
+ */
42
+ private isInteractiveRole;
43
+ /**
44
+ * Generate selector for node (best effort)
45
+ */
46
+ private generateSelector;
47
+ /**
48
+ * Generate text tree representation
49
+ */
50
+ generateTextTree(tree: DualModeTree, options?: DualModeSnapshotOptions): string;
51
+ /**
52
+ * Get enhanced snapshot with refs
53
+ */
54
+ getEnhancedSnapshot(url: string, options?: DualModeSnapshotOptions): Promise<DualModeEnhancedSnapshot>;
55
+ /**
56
+ * Get current page snapshot (no navigation)
57
+ */
58
+ getCurrentPageSnapshot(options?: DualModeSnapshotOptions): Promise<DualModeEnhancedSnapshot>;
59
+ }
60
+ //# sourceMappingURL=dualmode-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dualmode-fetcher.d.ts","sourceRoot":"","sources":["../src/dualmode-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,GAAE,MAAoB,EAAE,IAAI,GAAE,MAAa;IAK3D;;OAEG;YACW,gBAAgB;IAmB9B;;OAEG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAuEhE;;OAEG;IACH,OAAO,CAAC,6BAA6B;IA6ErC;;OAEG;IACH,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,yBAAyB,CAAC;IA6BhE;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,yBAAyB,GAAG,YAAY;IA6D5D;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkCxB;;OAEG;IACH,gBAAgB,CACd,IAAI,EAAE,YAAY,EAClB,OAAO,GAAE,uBAA4B,GACpC,MAAM;IA0FT;;OAEG;IACG,mBAAmB,CACvB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,wBAAwB,CAAC;IA8BpC;;OAEG;IACG,sBAAsB,CAC1B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,wBAAwB,CAAC;CA6CrC"}