@metamask/device-mcp 0.3.2 → 0.3.3

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 (44) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/dist/backends/adb-backend.cjs +1 -0
  3. package/dist/backends/adb-backend.cjs.map +1 -1
  4. package/dist/backends/adb-backend.d.cts +1 -0
  5. package/dist/backends/adb-backend.d.cts.map +1 -1
  6. package/dist/backends/adb-backend.d.mts +1 -0
  7. package/dist/backends/adb-backend.d.mts.map +1 -1
  8. package/dist/backends/adb-backend.mjs +1 -0
  9. package/dist/backends/adb-backend.mjs.map +1 -1
  10. package/dist/backends/appium-backend.cjs +1 -0
  11. package/dist/backends/appium-backend.cjs.map +1 -1
  12. package/dist/backends/appium-backend.d.cts +1 -0
  13. package/dist/backends/appium-backend.d.cts.map +1 -1
  14. package/dist/backends/appium-backend.d.mts +1 -0
  15. package/dist/backends/appium-backend.d.mts.map +1 -1
  16. package/dist/backends/appium-backend.mjs +1 -0
  17. package/dist/backends/appium-backend.mjs.map +1 -1
  18. package/dist/backends/idb-backend.cjs +1 -0
  19. package/dist/backends/idb-backend.cjs.map +1 -1
  20. package/dist/backends/idb-backend.d.cts +1 -0
  21. package/dist/backends/idb-backend.d.cts.map +1 -1
  22. package/dist/backends/idb-backend.d.mts +1 -0
  23. package/dist/backends/idb-backend.d.mts.map +1 -1
  24. package/dist/backends/idb-backend.mjs +1 -0
  25. package/dist/backends/idb-backend.mjs.map +1 -1
  26. package/dist/backends/index.cjs +3 -0
  27. package/dist/backends/index.cjs.map +1 -1
  28. package/dist/backends/index.d.cts.map +1 -1
  29. package/dist/backends/index.d.mts.map +1 -1
  30. package/dist/backends/index.mjs +3 -0
  31. package/dist/backends/index.mjs.map +1 -1
  32. package/dist/backends/types.cjs.map +1 -1
  33. package/dist/backends/types.d.cts +6 -0
  34. package/dist/backends/types.d.cts.map +1 -1
  35. package/dist/backends/types.d.mts +6 -0
  36. package/dist/backends/types.d.mts.map +1 -1
  37. package/dist/backends/types.mjs.map +1 -1
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +1 -1
  40. package/dist/index.d.cts.map +1 -1
  41. package/dist/index.d.mts +1 -1
  42. package/dist/index.d.mts.map +1 -1
  43. package/dist/index.mjs.map +1 -1
  44. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.3]
11
+
12
+ ### Changed
13
+
14
+ - feat: add public `kind` discriminator to DeviceBackend ([#21](https://github.com/MetaMask/device-mcp/pull/21))
15
+
10
16
  ## [0.3.2]
11
17
 
12
18
  ### Changed
@@ -55,7 +61,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55
61
  - `.device-session` file for attaching to existing Appium sessions or creating new ones
56
62
  - 16 MCP tools: `device_snapshot`, `device_screenshot`, `device_info`, `device_tap_element`, `device_tap_coordinates`, `device_type`, `device_swipe`, `device_long_press`, `device_wait_for`, `device_app_state`, `device_open_app`, `device_close_app`, `device_press_button`, `device_dismiss_keyboard`, `device_dismiss_alert`, `device_logs`
57
63
 
58
- [Unreleased]: https://github.com/MetaMask/device-mcp/compare/v0.3.2...HEAD
64
+ [Unreleased]: https://github.com/MetaMask/device-mcp/compare/v0.3.3...HEAD
65
+ [0.3.3]: https://github.com/MetaMask/device-mcp/compare/v0.3.2...v0.3.3
59
66
  [0.3.2]: https://github.com/MetaMask/device-mcp/compare/v0.3.1...v0.3.2
60
67
  [0.3.1]: https://github.com/MetaMask/device-mcp/compare/v0.3.0...v0.3.1
61
68
  [0.3.0]: https://github.com/MetaMask/device-mcp/compare/v0.2.0...v0.3.0
@@ -24,6 +24,7 @@ const output_path_js_1 = require("../utils/output-path.cjs");
24
24
  class AdbBackend {
25
25
  constructor(serial) {
26
26
  _AdbBackend_instances.add(this);
27
+ this.kind = 'adb';
27
28
  this.platform = 'android';
28
29
  _AdbBackend_serial.set(this, void 0);
29
30
  _AdbBackend_recordingProcess.set(this, null);
@@ -1 +1 @@
1
- {"version":3,"file":"adb-backend.cjs","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\n\nimport type {\n DeviceBackend,\n DeviceButton,\n DeviceInfo,\n SnapshotResult,\n ScreenshotResult,\n ScreenshotFileResult,\n ScreenshotOptions,\n LogsResult,\n TapResult,\n AppStateResult,\n ElementQuery,\n UIElement,\n WindowSize,\n} from './types.js';\nimport { ACCEPT_LABELS, DENY_LABELS } from '../utils/alert-labels.js';\nimport {\n findElement,\n describeElement,\n computeSwipeEnd,\n} from '../utils/element.js';\nimport { execStrict, isCommandAvailable } from '../utils/exec.js';\nimport {\n hardenArtifactFile,\n resolveArtifactPath,\n} from '../utils/output-path.js';\n\nexport class AdbBackend implements DeviceBackend {\n readonly platform = 'android' as const;\n\n readonly #serial: string;\n\n #recordingProcess: ChildProcess | null = null;\n\n #recordingPath: string | null = null;\n\n readonly #recordingRemotePath = '/sdcard/device-mcp-recording.mp4';\n\n constructor(serial: string) {\n this.#serial = serial;\n }\n\n async #adb(args: string[]): Promise<string> {\n return execStrict('adb', ['-s', this.#serial, ...args]);\n }\n\n async ensureConnected(): Promise<void> {\n if (!(await isCommandAvailable('adb'))) {\n throw new Error(\n 'adb is not installed or not on $PATH.\\n' +\n 'Install Android SDK platform-tools.',\n );\n }\n const state = await this.#adb(['get-state']);\n if (state.trim() !== 'device') {\n throw new Error(\n `Device ${this.#serial} is not ready (state: ${state.trim()})`,\n );\n }\n }\n\n async getDeviceInfo(): Promise<DeviceInfo> {\n const [model, version] = await Promise.all([\n this.#adb(['shell', 'getprop', 'ro.product.model']),\n this.#adb(['shell', 'getprop', 'ro.build.version.release']),\n ]);\n return {\n platform: 'android',\n deviceId: this.#serial,\n name: model.trim(),\n osVersion: version.trim(),\n state: 'device',\n };\n }\n\n async snapshot(): Promise<SnapshotResult> {\n const raw = await this.#dumpUiHierarchy();\n const hierarchy = parseAndroidHierarchy(raw);\n return {\n platform: 'android',\n hierarchy,\n raw,\n timestamp: Date.now(),\n };\n }\n\n async tapElement(query: ElementQuery): Promise<TapResult> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const x = Math.round(element.frame.x + element.frame.width / 2);\n const y = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(x, y);\n\n return {\n success: true,\n x,\n y,\n targetDescription: describeElement(element),\n };\n }\n\n async getElementText(query: ElementQuery): Promise<string> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return element.label ?? element.value ?? '';\n }\n\n async tapCoordinates(x: number, y: number): Promise<void> {\n await this.#adb(['shell', 'input', 'tap', String(x), String(y)]);\n }\n\n async typeText(text: string): Promise<void> {\n // Android keyevent 29+shift = Ctrl+A (select all), 67 = DEL\n await this.#adb(['shell', 'input', 'keyevent', 'KEYCODE_MOVE_HOME']);\n await this.#adb([\n 'shell',\n 'input',\n 'keyevent',\n '--longpress',\n 'KEYCODE_SHIFT_LEFT',\n 'KEYCODE_MOVE_END',\n ]);\n await this.#adb(['shell', 'input', 'keyevent', '67']);\n // Android input text requires escaping spaces and special chars\n const escaped = text.replace(/ /gu, '%s').replace(/[&|;<>]/gu, '\\\\$&');\n await this.#adb(['shell', 'input', 'text', escaped]);\n }\n\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n startX?: number,\n startY?: number,\n distance?: number,\n ): Promise<void> {\n const d = distance ?? 500;\n const sx = startX ?? 540;\n const sy = startY ?? 960;\n const [endX, endY] = computeSwipeEnd(sx, sy, direction, d);\n const durationMs = 300;\n\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(sx),\n String(sy),\n String(endX),\n String(endY),\n String(durationMs),\n ]);\n }\n\n async waitForElement(\n query: ElementQuery,\n timeoutMs = 10_000,\n intervalMs = 500,\n ): Promise<UIElement> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (element) {\n return element;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(\n `Timed out waiting for element: ${JSON.stringify(query)} (${timeoutMs}ms)`,\n );\n }\n\n async getAppState(bundleId: string): Promise<AppStateResult> {\n const raw = await this.#adb(['shell', 'dumpsys', 'activity', 'processes']);\n\n const pidMatch = raw.match(\n new RegExp(`PID #(\\\\d+):.*${bundleId.replace(/\\./gu, '\\\\.')}`, 'u'),\n );\n\n if (pidMatch) {\n return {\n bundleId,\n state: 'Running',\n pid: parseInt(pidMatch[1], 10),\n };\n }\n\n const pmResult = await this.#adb([\n 'shell',\n 'pm',\n 'list',\n 'packages',\n bundleId,\n ]);\n if (pmResult.includes(bundleId)) {\n return { bundleId, state: 'Installed (not running)' };\n }\n\n return { bundleId, state: 'Not Installed' };\n }\n\n async #dumpUiHierarchy(): Promise<string> {\n const remotePath = '/sdcard/window_dump.xml';\n await this.#adb(['shell', 'uiautomator', 'dump', remotePath]);\n const xml = await this.#adb(['shell', 'cat', remotePath]);\n await this.#adb(['shell', 'rm', '-f', remotePath]);\n return xml;\n }\n\n screenshot(\n outputPath?: string,\n options?: { encode?: true },\n ): Promise<ScreenshotResult>;\n\n screenshot(\n outputPath: string | undefined,\n options: { encode: false },\n ): Promise<ScreenshotFileResult>;\n\n screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult>;\n\n async screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult> {\n const localPath = resolveArtifactPath(outputPath, 'screenshot');\n await this.#adb(['shell', 'screencap', '-p', '/sdcard/screenshot.png']);\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n '/sdcard/screenshot.png',\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', '/sdcard/screenshot.png']);\n hardenArtifactFile(localPath);\n if (options?.encode === false) {\n return { data: undefined, format: 'png', path: localPath };\n }\n const data = await readFile(localPath, 'base64');\n return { data, format: 'png', path: localPath };\n }\n\n async openApp(bundleId: string): Promise<void> {\n await this.#adb([\n 'shell',\n 'monkey',\n '-p',\n bundleId,\n '-c',\n 'android.intent.category.LAUNCHER',\n '1',\n ]);\n }\n\n async closeApp(bundleId: string): Promise<void> {\n await this.#adb(['shell', 'am', 'force-stop', bundleId]);\n }\n\n async pressButton(button: DeviceButton): Promise<void> {\n // Android keyevent codes\n const keyMap: Record<DeviceButton, string> = {\n home: '3',\n back: '4',\n enter: '66',\n lock: '26',\n };\n await this.#adb(['shell', 'input', 'keyevent', keyMap[button]]);\n }\n\n async dismissKeyboard(): Promise<void> {\n await this.#adb(['shell', 'input', 'keyevent', '111']);\n }\n\n async dismissAlert(accept: boolean): Promise<void> {\n const snap = await this.snapshot();\n const candidates = accept ? ACCEPT_LABELS : DENY_LABELS;\n\n for (const label of candidates) {\n const element = findElement(snap.hierarchy, { text: label });\n if (element) {\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(cx, cy);\n return;\n }\n }\n\n throw new Error(`No alert button found. Tried: ${candidates.join(', ')}`);\n }\n\n async getLogs(durationSeconds = 30, filter?: string): Promise<LogsResult> {\n const args = ['shell', 'logcat', '-d', '-t', String(durationSeconds)];\n if (filter) {\n args.push('-e', filter);\n }\n const raw = await this.#adb(args);\n const entries = raw\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const match = line.match(/^(\\d{2}-\\d{2}\\s+\\S+)\\s+(\\w)\\/.*?:\\s*(.*)/u);\n if (match) {\n return {\n timestamp: match[1],\n level: match[2],\n message: match[3],\n };\n }\n return { timestamp: '', level: 'info', message: line };\n });\n return { entries, source: 'logcat' };\n }\n\n async longPress(query: ElementQuery, durationMs = 1000): Promise<TapResult> {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(cx),\n String(cy),\n String(cx),\n String(cy),\n String(durationMs),\n ]);\n\n return {\n success: true,\n x: cx,\n y: cy,\n targetDescription: describeElement(element),\n };\n }\n\n async scrollToElement(\n query: ElementQuery,\n direction: 'up' | 'down' = 'down',\n maxAttempts = 10,\n ): Promise<UIElement> {\n let previousRaw = '';\n\n for (let i = 0; i < maxAttempts; i++) {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (element) {\n return element;\n }\n if (snap.raw === previousRaw) {\n break;\n }\n previousRaw = snap.raw;\n await this.swipe(direction);\n }\n throw new Error(\n `Element not found after scrolling: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n async getAlertText(): Promise<string> {\n const snap = await this.snapshot();\n const texts = collectAndroidAlertTexts(snap.hierarchy);\n if (texts.length === 0) {\n throw new Error(\n 'No alert is currently displayed.\\n' +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return texts.join('\\n');\n }\n\n async getWindowSize(): Promise<WindowSize> {\n const raw = await this.#adb(['shell', 'wm', 'size']);\n const match = raw.match(/(\\d+)x(\\d+)/u);\n if (match) {\n return {\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n };\n }\n throw new Error(`Unable to parse window size from: ${raw.trim()}`);\n }\n\n async getContexts(): Promise<string[]> {\n return ['NATIVE_APP'];\n }\n\n async setContext(context: string): Promise<void> {\n if (context === 'NATIVE_APP') {\n return;\n }\n throw new Error(\n 'Context switching requires Appium backend. ADB only supports NATIVE_APP.',\n );\n }\n\n async getClipboard(): Promise<string> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async setClipboard(_text: string): Promise<void> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async startScreenRecording(outputPath?: string): Promise<void> {\n if (this.#recordingProcess) {\n throw new Error('Screen recording is already in progress');\n }\n this.#recordingPath = resolveArtifactPath(outputPath, 'recording');\n this.#recordingProcess = spawn('adb', [\n '-s',\n this.#serial,\n 'shell',\n 'screenrecord',\n this.#recordingRemotePath,\n ]);\n this.#recordingProcess.on('error', () => {\n this.#recordingProcess = null;\n this.#recordingPath = null;\n });\n }\n\n async stopScreenRecording(): Promise<string> {\n if (!this.#recordingProcess || !this.#recordingPath) {\n throw new Error('No screen recording in progress');\n }\n const localPath = this.#recordingPath;\n this.#recordingProcess.kill('SIGINT');\n await new Promise((resolve) => setTimeout(resolve, 2000));\n this.#recordingProcess = null;\n this.#recordingPath = null;\n\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n this.#recordingRemotePath,\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', this.#recordingRemotePath]);\n hardenArtifactFile(localPath);\n return localPath;\n }\n}\n\nfunction collectAndroidAlertTexts(elements: UIElement[]): string[] {\n const texts: string[] = [];\n for (const el of elements) {\n const isDialog =\n el.type.includes('Dialog') || el.type.includes('AlertDialog');\n if (isDialog) {\n collectTextValues(el.children ?? [], texts);\n return texts;\n }\n if (el.children) {\n const found = collectAndroidAlertTexts(el.children);\n if (found.length > 0) {\n return found;\n }\n }\n }\n return texts;\n}\n\nfunction collectTextValues(elements: UIElement[], texts: string[]): void {\n for (const el of elements) {\n if (el.type.includes('TextView') && el.value) {\n texts.push(el.value);\n }\n if (el.children) {\n collectTextValues(el.children, texts);\n }\n }\n}\n\nexport function parseAndroidHierarchy(xml: string): UIElement[] {\n const stack: UIElement[][] = [[]];\n\n // Matches all <node ...>, </node>, and <node .../> tags in document order\n const tagRegex = /<(\\/?)node(?:\\s+([^>]*?))?\\s*(\\/?)>/gu;\n let match: RegExpExecArray | null;\n\n while ((match = tagRegex.exec(xml)) !== null) {\n const isClosing = match[1] === '/';\n const attrs = match[2];\n const isSelfClosing = match[3] === '/';\n\n if (isClosing) {\n if (stack.length > 1) {\n stack.pop();\n }\n } else if (isSelfClosing && attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n stack[stack.length - 1].push(element);\n }\n } else if (attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n element.children = [];\n stack[stack.length - 1].push(element);\n stack.push(element.children);\n }\n }\n }\n\n return stack[0];\n}\n\nexport function parseNodeAttributes(attrs: string): UIElement | null {\n const get = (name: string): string | undefined => {\n const attrMatch = attrs.match(new RegExp(`${name}=\"([^\"]*)\"`, 'u'));\n return attrMatch?.[1] || undefined;\n };\n\n const boundsStr = get('bounds');\n if (!boundsStr) {\n return null;\n }\n\n // bounds format: [x1,y1][x2,y2]\n const boundsMatch = boundsStr.match(/\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]/u);\n if (!boundsMatch) {\n return null;\n }\n\n const x1 = parseInt(boundsMatch[1], 10);\n const y1 = parseInt(boundsMatch[2], 10);\n const x2 = parseInt(boundsMatch[3], 10);\n const y2 = parseInt(boundsMatch[4], 10);\n\n return {\n type: get('class') ?? 'Unknown',\n label: get('content-desc') || undefined,\n value: get('text') || undefined,\n identifier: get('resource-id') || undefined,\n frame: { x: x1, y: y1, width: x2 - x1, height: y2 - y1 },\n enabled: get('enabled') !== 'false',\n };\n}\n"]}
1
+ {"version":3,"file":"adb-backend.cjs","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\n\nimport type {\n DeviceBackend,\n DeviceButton,\n DeviceInfo,\n SnapshotResult,\n ScreenshotResult,\n ScreenshotFileResult,\n ScreenshotOptions,\n LogsResult,\n TapResult,\n AppStateResult,\n ElementQuery,\n UIElement,\n WindowSize,\n} from './types.js';\nimport { ACCEPT_LABELS, DENY_LABELS } from '../utils/alert-labels.js';\nimport {\n findElement,\n describeElement,\n computeSwipeEnd,\n} from '../utils/element.js';\nimport { execStrict, isCommandAvailable } from '../utils/exec.js';\nimport {\n hardenArtifactFile,\n resolveArtifactPath,\n} from '../utils/output-path.js';\n\nexport class AdbBackend implements DeviceBackend {\n readonly kind = 'adb' as const;\n\n readonly platform = 'android' as const;\n\n readonly #serial: string;\n\n #recordingProcess: ChildProcess | null = null;\n\n #recordingPath: string | null = null;\n\n readonly #recordingRemotePath = '/sdcard/device-mcp-recording.mp4';\n\n constructor(serial: string) {\n this.#serial = serial;\n }\n\n async #adb(args: string[]): Promise<string> {\n return execStrict('adb', ['-s', this.#serial, ...args]);\n }\n\n async ensureConnected(): Promise<void> {\n if (!(await isCommandAvailable('adb'))) {\n throw new Error(\n 'adb is not installed or not on $PATH.\\n' +\n 'Install Android SDK platform-tools.',\n );\n }\n const state = await this.#adb(['get-state']);\n if (state.trim() !== 'device') {\n throw new Error(\n `Device ${this.#serial} is not ready (state: ${state.trim()})`,\n );\n }\n }\n\n async getDeviceInfo(): Promise<DeviceInfo> {\n const [model, version] = await Promise.all([\n this.#adb(['shell', 'getprop', 'ro.product.model']),\n this.#adb(['shell', 'getprop', 'ro.build.version.release']),\n ]);\n return {\n platform: 'android',\n deviceId: this.#serial,\n name: model.trim(),\n osVersion: version.trim(),\n state: 'device',\n };\n }\n\n async snapshot(): Promise<SnapshotResult> {\n const raw = await this.#dumpUiHierarchy();\n const hierarchy = parseAndroidHierarchy(raw);\n return {\n platform: 'android',\n hierarchy,\n raw,\n timestamp: Date.now(),\n };\n }\n\n async tapElement(query: ElementQuery): Promise<TapResult> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const x = Math.round(element.frame.x + element.frame.width / 2);\n const y = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(x, y);\n\n return {\n success: true,\n x,\n y,\n targetDescription: describeElement(element),\n };\n }\n\n async getElementText(query: ElementQuery): Promise<string> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return element.label ?? element.value ?? '';\n }\n\n async tapCoordinates(x: number, y: number): Promise<void> {\n await this.#adb(['shell', 'input', 'tap', String(x), String(y)]);\n }\n\n async typeText(text: string): Promise<void> {\n // Android keyevent 29+shift = Ctrl+A (select all), 67 = DEL\n await this.#adb(['shell', 'input', 'keyevent', 'KEYCODE_MOVE_HOME']);\n await this.#adb([\n 'shell',\n 'input',\n 'keyevent',\n '--longpress',\n 'KEYCODE_SHIFT_LEFT',\n 'KEYCODE_MOVE_END',\n ]);\n await this.#adb(['shell', 'input', 'keyevent', '67']);\n // Android input text requires escaping spaces and special chars\n const escaped = text.replace(/ /gu, '%s').replace(/[&|;<>]/gu, '\\\\$&');\n await this.#adb(['shell', 'input', 'text', escaped]);\n }\n\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n startX?: number,\n startY?: number,\n distance?: number,\n ): Promise<void> {\n const d = distance ?? 500;\n const sx = startX ?? 540;\n const sy = startY ?? 960;\n const [endX, endY] = computeSwipeEnd(sx, sy, direction, d);\n const durationMs = 300;\n\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(sx),\n String(sy),\n String(endX),\n String(endY),\n String(durationMs),\n ]);\n }\n\n async waitForElement(\n query: ElementQuery,\n timeoutMs = 10_000,\n intervalMs = 500,\n ): Promise<UIElement> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (element) {\n return element;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(\n `Timed out waiting for element: ${JSON.stringify(query)} (${timeoutMs}ms)`,\n );\n }\n\n async getAppState(bundleId: string): Promise<AppStateResult> {\n const raw = await this.#adb(['shell', 'dumpsys', 'activity', 'processes']);\n\n const pidMatch = raw.match(\n new RegExp(`PID #(\\\\d+):.*${bundleId.replace(/\\./gu, '\\\\.')}`, 'u'),\n );\n\n if (pidMatch) {\n return {\n bundleId,\n state: 'Running',\n pid: parseInt(pidMatch[1], 10),\n };\n }\n\n const pmResult = await this.#adb([\n 'shell',\n 'pm',\n 'list',\n 'packages',\n bundleId,\n ]);\n if (pmResult.includes(bundleId)) {\n return { bundleId, state: 'Installed (not running)' };\n }\n\n return { bundleId, state: 'Not Installed' };\n }\n\n async #dumpUiHierarchy(): Promise<string> {\n const remotePath = '/sdcard/window_dump.xml';\n await this.#adb(['shell', 'uiautomator', 'dump', remotePath]);\n const xml = await this.#adb(['shell', 'cat', remotePath]);\n await this.#adb(['shell', 'rm', '-f', remotePath]);\n return xml;\n }\n\n screenshot(\n outputPath?: string,\n options?: { encode?: true },\n ): Promise<ScreenshotResult>;\n\n screenshot(\n outputPath: string | undefined,\n options: { encode: false },\n ): Promise<ScreenshotFileResult>;\n\n screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult>;\n\n async screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult> {\n const localPath = resolveArtifactPath(outputPath, 'screenshot');\n await this.#adb(['shell', 'screencap', '-p', '/sdcard/screenshot.png']);\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n '/sdcard/screenshot.png',\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', '/sdcard/screenshot.png']);\n hardenArtifactFile(localPath);\n if (options?.encode === false) {\n return { data: undefined, format: 'png', path: localPath };\n }\n const data = await readFile(localPath, 'base64');\n return { data, format: 'png', path: localPath };\n }\n\n async openApp(bundleId: string): Promise<void> {\n await this.#adb([\n 'shell',\n 'monkey',\n '-p',\n bundleId,\n '-c',\n 'android.intent.category.LAUNCHER',\n '1',\n ]);\n }\n\n async closeApp(bundleId: string): Promise<void> {\n await this.#adb(['shell', 'am', 'force-stop', bundleId]);\n }\n\n async pressButton(button: DeviceButton): Promise<void> {\n // Android keyevent codes\n const keyMap: Record<DeviceButton, string> = {\n home: '3',\n back: '4',\n enter: '66',\n lock: '26',\n };\n await this.#adb(['shell', 'input', 'keyevent', keyMap[button]]);\n }\n\n async dismissKeyboard(): Promise<void> {\n await this.#adb(['shell', 'input', 'keyevent', '111']);\n }\n\n async dismissAlert(accept: boolean): Promise<void> {\n const snap = await this.snapshot();\n const candidates = accept ? ACCEPT_LABELS : DENY_LABELS;\n\n for (const label of candidates) {\n const element = findElement(snap.hierarchy, { text: label });\n if (element) {\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(cx, cy);\n return;\n }\n }\n\n throw new Error(`No alert button found. Tried: ${candidates.join(', ')}`);\n }\n\n async getLogs(durationSeconds = 30, filter?: string): Promise<LogsResult> {\n const args = ['shell', 'logcat', '-d', '-t', String(durationSeconds)];\n if (filter) {\n args.push('-e', filter);\n }\n const raw = await this.#adb(args);\n const entries = raw\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const match = line.match(/^(\\d{2}-\\d{2}\\s+\\S+)\\s+(\\w)\\/.*?:\\s*(.*)/u);\n if (match) {\n return {\n timestamp: match[1],\n level: match[2],\n message: match[3],\n };\n }\n return { timestamp: '', level: 'info', message: line };\n });\n return { entries, source: 'logcat' };\n }\n\n async longPress(query: ElementQuery, durationMs = 1000): Promise<TapResult> {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(cx),\n String(cy),\n String(cx),\n String(cy),\n String(durationMs),\n ]);\n\n return {\n success: true,\n x: cx,\n y: cy,\n targetDescription: describeElement(element),\n };\n }\n\n async scrollToElement(\n query: ElementQuery,\n direction: 'up' | 'down' = 'down',\n maxAttempts = 10,\n ): Promise<UIElement> {\n let previousRaw = '';\n\n for (let i = 0; i < maxAttempts; i++) {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (element) {\n return element;\n }\n if (snap.raw === previousRaw) {\n break;\n }\n previousRaw = snap.raw;\n await this.swipe(direction);\n }\n throw new Error(\n `Element not found after scrolling: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n async getAlertText(): Promise<string> {\n const snap = await this.snapshot();\n const texts = collectAndroidAlertTexts(snap.hierarchy);\n if (texts.length === 0) {\n throw new Error(\n 'No alert is currently displayed.\\n' +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return texts.join('\\n');\n }\n\n async getWindowSize(): Promise<WindowSize> {\n const raw = await this.#adb(['shell', 'wm', 'size']);\n const match = raw.match(/(\\d+)x(\\d+)/u);\n if (match) {\n return {\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n };\n }\n throw new Error(`Unable to parse window size from: ${raw.trim()}`);\n }\n\n async getContexts(): Promise<string[]> {\n return ['NATIVE_APP'];\n }\n\n async setContext(context: string): Promise<void> {\n if (context === 'NATIVE_APP') {\n return;\n }\n throw new Error(\n 'Context switching requires Appium backend. ADB only supports NATIVE_APP.',\n );\n }\n\n async getClipboard(): Promise<string> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async setClipboard(_text: string): Promise<void> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async startScreenRecording(outputPath?: string): Promise<void> {\n if (this.#recordingProcess) {\n throw new Error('Screen recording is already in progress');\n }\n this.#recordingPath = resolveArtifactPath(outputPath, 'recording');\n this.#recordingProcess = spawn('adb', [\n '-s',\n this.#serial,\n 'shell',\n 'screenrecord',\n this.#recordingRemotePath,\n ]);\n this.#recordingProcess.on('error', () => {\n this.#recordingProcess = null;\n this.#recordingPath = null;\n });\n }\n\n async stopScreenRecording(): Promise<string> {\n if (!this.#recordingProcess || !this.#recordingPath) {\n throw new Error('No screen recording in progress');\n }\n const localPath = this.#recordingPath;\n this.#recordingProcess.kill('SIGINT');\n await new Promise((resolve) => setTimeout(resolve, 2000));\n this.#recordingProcess = null;\n this.#recordingPath = null;\n\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n this.#recordingRemotePath,\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', this.#recordingRemotePath]);\n hardenArtifactFile(localPath);\n return localPath;\n }\n}\n\nfunction collectAndroidAlertTexts(elements: UIElement[]): string[] {\n const texts: string[] = [];\n for (const el of elements) {\n const isDialog =\n el.type.includes('Dialog') || el.type.includes('AlertDialog');\n if (isDialog) {\n collectTextValues(el.children ?? [], texts);\n return texts;\n }\n if (el.children) {\n const found = collectAndroidAlertTexts(el.children);\n if (found.length > 0) {\n return found;\n }\n }\n }\n return texts;\n}\n\nfunction collectTextValues(elements: UIElement[], texts: string[]): void {\n for (const el of elements) {\n if (el.type.includes('TextView') && el.value) {\n texts.push(el.value);\n }\n if (el.children) {\n collectTextValues(el.children, texts);\n }\n }\n}\n\nexport function parseAndroidHierarchy(xml: string): UIElement[] {\n const stack: UIElement[][] = [[]];\n\n // Matches all <node ...>, </node>, and <node .../> tags in document order\n const tagRegex = /<(\\/?)node(?:\\s+([^>]*?))?\\s*(\\/?)>/gu;\n let match: RegExpExecArray | null;\n\n while ((match = tagRegex.exec(xml)) !== null) {\n const isClosing = match[1] === '/';\n const attrs = match[2];\n const isSelfClosing = match[3] === '/';\n\n if (isClosing) {\n if (stack.length > 1) {\n stack.pop();\n }\n } else if (isSelfClosing && attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n stack[stack.length - 1].push(element);\n }\n } else if (attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n element.children = [];\n stack[stack.length - 1].push(element);\n stack.push(element.children);\n }\n }\n }\n\n return stack[0];\n}\n\nexport function parseNodeAttributes(attrs: string): UIElement | null {\n const get = (name: string): string | undefined => {\n const attrMatch = attrs.match(new RegExp(`${name}=\"([^\"]*)\"`, 'u'));\n return attrMatch?.[1] || undefined;\n };\n\n const boundsStr = get('bounds');\n if (!boundsStr) {\n return null;\n }\n\n // bounds format: [x1,y1][x2,y2]\n const boundsMatch = boundsStr.match(/\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]/u);\n if (!boundsMatch) {\n return null;\n }\n\n const x1 = parseInt(boundsMatch[1], 10);\n const y1 = parseInt(boundsMatch[2], 10);\n const x2 = parseInt(boundsMatch[3], 10);\n const y2 = parseInt(boundsMatch[4], 10);\n\n return {\n type: get('class') ?? 'Unknown',\n label: get('content-desc') || undefined,\n value: get('text') || undefined,\n identifier: get('resource-id') || undefined,\n frame: { x: x1, y: y1, width: x2 - x1, height: y2 - y1 },\n enabled: get('enabled') !== 'false',\n };\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import type { DeviceBackend, DeviceButton, DeviceInfo, SnapshotResult, ScreenshotResult, ScreenshotFileResult, ScreenshotOptions, LogsResult, TapResult, AppStateResult, ElementQuery, UIElement, WindowSize } from "./types.cjs";
2
2
  export declare class AdbBackend implements DeviceBackend {
3
3
  #private;
4
+ readonly kind: "adb";
4
5
  readonly platform: "android";
5
6
  constructor(serial: string);
6
7
  ensureConnected(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"adb-backend.d.cts","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adb-backend.d.cts","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { DeviceBackend, DeviceButton, DeviceInfo, SnapshotResult, ScreenshotResult, ScreenshotFileResult, ScreenshotOptions, LogsResult, TapResult, AppStateResult, ElementQuery, UIElement, WindowSize } from "./types.mjs";
2
2
  export declare class AdbBackend implements DeviceBackend {
3
3
  #private;
4
+ readonly kind: "adb";
4
5
  readonly platform: "android";
5
6
  constructor(serial: string);
6
7
  ensureConnected(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"adb-backend.d.mts","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adb-backend.d.mts","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@ import { hardenArtifactFile, resolveArtifactPath } from "../utils/output-path.mj
19
19
  export class AdbBackend {
20
20
  constructor(serial) {
21
21
  _AdbBackend_instances.add(this);
22
+ this.kind = 'adb';
22
23
  this.platform = 'android';
23
24
  _AdbBackend_serial.set(this, void 0);
24
25
  _AdbBackend_recordingProcess.set(this, null);
@@ -1 +1 @@
1
- {"version":3,"file":"adb-backend.mjs","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\n\nimport type {\n DeviceBackend,\n DeviceButton,\n DeviceInfo,\n SnapshotResult,\n ScreenshotResult,\n ScreenshotFileResult,\n ScreenshotOptions,\n LogsResult,\n TapResult,\n AppStateResult,\n ElementQuery,\n UIElement,\n WindowSize,\n} from './types.js';\nimport { ACCEPT_LABELS, DENY_LABELS } from '../utils/alert-labels.js';\nimport {\n findElement,\n describeElement,\n computeSwipeEnd,\n} from '../utils/element.js';\nimport { execStrict, isCommandAvailable } from '../utils/exec.js';\nimport {\n hardenArtifactFile,\n resolveArtifactPath,\n} from '../utils/output-path.js';\n\nexport class AdbBackend implements DeviceBackend {\n readonly platform = 'android' as const;\n\n readonly #serial: string;\n\n #recordingProcess: ChildProcess | null = null;\n\n #recordingPath: string | null = null;\n\n readonly #recordingRemotePath = '/sdcard/device-mcp-recording.mp4';\n\n constructor(serial: string) {\n this.#serial = serial;\n }\n\n async #adb(args: string[]): Promise<string> {\n return execStrict('adb', ['-s', this.#serial, ...args]);\n }\n\n async ensureConnected(): Promise<void> {\n if (!(await isCommandAvailable('adb'))) {\n throw new Error(\n 'adb is not installed or not on $PATH.\\n' +\n 'Install Android SDK platform-tools.',\n );\n }\n const state = await this.#adb(['get-state']);\n if (state.trim() !== 'device') {\n throw new Error(\n `Device ${this.#serial} is not ready (state: ${state.trim()})`,\n );\n }\n }\n\n async getDeviceInfo(): Promise<DeviceInfo> {\n const [model, version] = await Promise.all([\n this.#adb(['shell', 'getprop', 'ro.product.model']),\n this.#adb(['shell', 'getprop', 'ro.build.version.release']),\n ]);\n return {\n platform: 'android',\n deviceId: this.#serial,\n name: model.trim(),\n osVersion: version.trim(),\n state: 'device',\n };\n }\n\n async snapshot(): Promise<SnapshotResult> {\n const raw = await this.#dumpUiHierarchy();\n const hierarchy = parseAndroidHierarchy(raw);\n return {\n platform: 'android',\n hierarchy,\n raw,\n timestamp: Date.now(),\n };\n }\n\n async tapElement(query: ElementQuery): Promise<TapResult> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const x = Math.round(element.frame.x + element.frame.width / 2);\n const y = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(x, y);\n\n return {\n success: true,\n x,\n y,\n targetDescription: describeElement(element),\n };\n }\n\n async getElementText(query: ElementQuery): Promise<string> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return element.label ?? element.value ?? '';\n }\n\n async tapCoordinates(x: number, y: number): Promise<void> {\n await this.#adb(['shell', 'input', 'tap', String(x), String(y)]);\n }\n\n async typeText(text: string): Promise<void> {\n // Android keyevent 29+shift = Ctrl+A (select all), 67 = DEL\n await this.#adb(['shell', 'input', 'keyevent', 'KEYCODE_MOVE_HOME']);\n await this.#adb([\n 'shell',\n 'input',\n 'keyevent',\n '--longpress',\n 'KEYCODE_SHIFT_LEFT',\n 'KEYCODE_MOVE_END',\n ]);\n await this.#adb(['shell', 'input', 'keyevent', '67']);\n // Android input text requires escaping spaces and special chars\n const escaped = text.replace(/ /gu, '%s').replace(/[&|;<>]/gu, '\\\\$&');\n await this.#adb(['shell', 'input', 'text', escaped]);\n }\n\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n startX?: number,\n startY?: number,\n distance?: number,\n ): Promise<void> {\n const d = distance ?? 500;\n const sx = startX ?? 540;\n const sy = startY ?? 960;\n const [endX, endY] = computeSwipeEnd(sx, sy, direction, d);\n const durationMs = 300;\n\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(sx),\n String(sy),\n String(endX),\n String(endY),\n String(durationMs),\n ]);\n }\n\n async waitForElement(\n query: ElementQuery,\n timeoutMs = 10_000,\n intervalMs = 500,\n ): Promise<UIElement> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (element) {\n return element;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(\n `Timed out waiting for element: ${JSON.stringify(query)} (${timeoutMs}ms)`,\n );\n }\n\n async getAppState(bundleId: string): Promise<AppStateResult> {\n const raw = await this.#adb(['shell', 'dumpsys', 'activity', 'processes']);\n\n const pidMatch = raw.match(\n new RegExp(`PID #(\\\\d+):.*${bundleId.replace(/\\./gu, '\\\\.')}`, 'u'),\n );\n\n if (pidMatch) {\n return {\n bundleId,\n state: 'Running',\n pid: parseInt(pidMatch[1], 10),\n };\n }\n\n const pmResult = await this.#adb([\n 'shell',\n 'pm',\n 'list',\n 'packages',\n bundleId,\n ]);\n if (pmResult.includes(bundleId)) {\n return { bundleId, state: 'Installed (not running)' };\n }\n\n return { bundleId, state: 'Not Installed' };\n }\n\n async #dumpUiHierarchy(): Promise<string> {\n const remotePath = '/sdcard/window_dump.xml';\n await this.#adb(['shell', 'uiautomator', 'dump', remotePath]);\n const xml = await this.#adb(['shell', 'cat', remotePath]);\n await this.#adb(['shell', 'rm', '-f', remotePath]);\n return xml;\n }\n\n screenshot(\n outputPath?: string,\n options?: { encode?: true },\n ): Promise<ScreenshotResult>;\n\n screenshot(\n outputPath: string | undefined,\n options: { encode: false },\n ): Promise<ScreenshotFileResult>;\n\n screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult>;\n\n async screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult> {\n const localPath = resolveArtifactPath(outputPath, 'screenshot');\n await this.#adb(['shell', 'screencap', '-p', '/sdcard/screenshot.png']);\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n '/sdcard/screenshot.png',\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', '/sdcard/screenshot.png']);\n hardenArtifactFile(localPath);\n if (options?.encode === false) {\n return { data: undefined, format: 'png', path: localPath };\n }\n const data = await readFile(localPath, 'base64');\n return { data, format: 'png', path: localPath };\n }\n\n async openApp(bundleId: string): Promise<void> {\n await this.#adb([\n 'shell',\n 'monkey',\n '-p',\n bundleId,\n '-c',\n 'android.intent.category.LAUNCHER',\n '1',\n ]);\n }\n\n async closeApp(bundleId: string): Promise<void> {\n await this.#adb(['shell', 'am', 'force-stop', bundleId]);\n }\n\n async pressButton(button: DeviceButton): Promise<void> {\n // Android keyevent codes\n const keyMap: Record<DeviceButton, string> = {\n home: '3',\n back: '4',\n enter: '66',\n lock: '26',\n };\n await this.#adb(['shell', 'input', 'keyevent', keyMap[button]]);\n }\n\n async dismissKeyboard(): Promise<void> {\n await this.#adb(['shell', 'input', 'keyevent', '111']);\n }\n\n async dismissAlert(accept: boolean): Promise<void> {\n const snap = await this.snapshot();\n const candidates = accept ? ACCEPT_LABELS : DENY_LABELS;\n\n for (const label of candidates) {\n const element = findElement(snap.hierarchy, { text: label });\n if (element) {\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(cx, cy);\n return;\n }\n }\n\n throw new Error(`No alert button found. Tried: ${candidates.join(', ')}`);\n }\n\n async getLogs(durationSeconds = 30, filter?: string): Promise<LogsResult> {\n const args = ['shell', 'logcat', '-d', '-t', String(durationSeconds)];\n if (filter) {\n args.push('-e', filter);\n }\n const raw = await this.#adb(args);\n const entries = raw\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const match = line.match(/^(\\d{2}-\\d{2}\\s+\\S+)\\s+(\\w)\\/.*?:\\s*(.*)/u);\n if (match) {\n return {\n timestamp: match[1],\n level: match[2],\n message: match[3],\n };\n }\n return { timestamp: '', level: 'info', message: line };\n });\n return { entries, source: 'logcat' };\n }\n\n async longPress(query: ElementQuery, durationMs = 1000): Promise<TapResult> {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(cx),\n String(cy),\n String(cx),\n String(cy),\n String(durationMs),\n ]);\n\n return {\n success: true,\n x: cx,\n y: cy,\n targetDescription: describeElement(element),\n };\n }\n\n async scrollToElement(\n query: ElementQuery,\n direction: 'up' | 'down' = 'down',\n maxAttempts = 10,\n ): Promise<UIElement> {\n let previousRaw = '';\n\n for (let i = 0; i < maxAttempts; i++) {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (element) {\n return element;\n }\n if (snap.raw === previousRaw) {\n break;\n }\n previousRaw = snap.raw;\n await this.swipe(direction);\n }\n throw new Error(\n `Element not found after scrolling: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n async getAlertText(): Promise<string> {\n const snap = await this.snapshot();\n const texts = collectAndroidAlertTexts(snap.hierarchy);\n if (texts.length === 0) {\n throw new Error(\n 'No alert is currently displayed.\\n' +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return texts.join('\\n');\n }\n\n async getWindowSize(): Promise<WindowSize> {\n const raw = await this.#adb(['shell', 'wm', 'size']);\n const match = raw.match(/(\\d+)x(\\d+)/u);\n if (match) {\n return {\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n };\n }\n throw new Error(`Unable to parse window size from: ${raw.trim()}`);\n }\n\n async getContexts(): Promise<string[]> {\n return ['NATIVE_APP'];\n }\n\n async setContext(context: string): Promise<void> {\n if (context === 'NATIVE_APP') {\n return;\n }\n throw new Error(\n 'Context switching requires Appium backend. ADB only supports NATIVE_APP.',\n );\n }\n\n async getClipboard(): Promise<string> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async setClipboard(_text: string): Promise<void> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async startScreenRecording(outputPath?: string): Promise<void> {\n if (this.#recordingProcess) {\n throw new Error('Screen recording is already in progress');\n }\n this.#recordingPath = resolveArtifactPath(outputPath, 'recording');\n this.#recordingProcess = spawn('adb', [\n '-s',\n this.#serial,\n 'shell',\n 'screenrecord',\n this.#recordingRemotePath,\n ]);\n this.#recordingProcess.on('error', () => {\n this.#recordingProcess = null;\n this.#recordingPath = null;\n });\n }\n\n async stopScreenRecording(): Promise<string> {\n if (!this.#recordingProcess || !this.#recordingPath) {\n throw new Error('No screen recording in progress');\n }\n const localPath = this.#recordingPath;\n this.#recordingProcess.kill('SIGINT');\n await new Promise((resolve) => setTimeout(resolve, 2000));\n this.#recordingProcess = null;\n this.#recordingPath = null;\n\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n this.#recordingRemotePath,\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', this.#recordingRemotePath]);\n hardenArtifactFile(localPath);\n return localPath;\n }\n}\n\nfunction collectAndroidAlertTexts(elements: UIElement[]): string[] {\n const texts: string[] = [];\n for (const el of elements) {\n const isDialog =\n el.type.includes('Dialog') || el.type.includes('AlertDialog');\n if (isDialog) {\n collectTextValues(el.children ?? [], texts);\n return texts;\n }\n if (el.children) {\n const found = collectAndroidAlertTexts(el.children);\n if (found.length > 0) {\n return found;\n }\n }\n }\n return texts;\n}\n\nfunction collectTextValues(elements: UIElement[], texts: string[]): void {\n for (const el of elements) {\n if (el.type.includes('TextView') && el.value) {\n texts.push(el.value);\n }\n if (el.children) {\n collectTextValues(el.children, texts);\n }\n }\n}\n\nexport function parseAndroidHierarchy(xml: string): UIElement[] {\n const stack: UIElement[][] = [[]];\n\n // Matches all <node ...>, </node>, and <node .../> tags in document order\n const tagRegex = /<(\\/?)node(?:\\s+([^>]*?))?\\s*(\\/?)>/gu;\n let match: RegExpExecArray | null;\n\n while ((match = tagRegex.exec(xml)) !== null) {\n const isClosing = match[1] === '/';\n const attrs = match[2];\n const isSelfClosing = match[3] === '/';\n\n if (isClosing) {\n if (stack.length > 1) {\n stack.pop();\n }\n } else if (isSelfClosing && attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n stack[stack.length - 1].push(element);\n }\n } else if (attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n element.children = [];\n stack[stack.length - 1].push(element);\n stack.push(element.children);\n }\n }\n }\n\n return stack[0];\n}\n\nexport function parseNodeAttributes(attrs: string): UIElement | null {\n const get = (name: string): string | undefined => {\n const attrMatch = attrs.match(new RegExp(`${name}=\"([^\"]*)\"`, 'u'));\n return attrMatch?.[1] || undefined;\n };\n\n const boundsStr = get('bounds');\n if (!boundsStr) {\n return null;\n }\n\n // bounds format: [x1,y1][x2,y2]\n const boundsMatch = boundsStr.match(/\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]/u);\n if (!boundsMatch) {\n return null;\n }\n\n const x1 = parseInt(boundsMatch[1], 10);\n const y1 = parseInt(boundsMatch[2], 10);\n const x2 = parseInt(boundsMatch[3], 10);\n const y2 = parseInt(boundsMatch[4], 10);\n\n return {\n type: get('class') ?? 'Unknown',\n label: get('content-desc') || undefined,\n value: get('text') || undefined,\n identifier: get('resource-id') || undefined,\n frame: { x: x1, y: y1, width: x2 - x1, height: y2 - y1 },\n enabled: get('enabled') !== 'false',\n };\n}\n"]}
1
+ {"version":3,"file":"adb-backend.mjs","sourceRoot":"","sources":["../../src/backends/adb-backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\n\nimport type {\n DeviceBackend,\n DeviceButton,\n DeviceInfo,\n SnapshotResult,\n ScreenshotResult,\n ScreenshotFileResult,\n ScreenshotOptions,\n LogsResult,\n TapResult,\n AppStateResult,\n ElementQuery,\n UIElement,\n WindowSize,\n} from './types.js';\nimport { ACCEPT_LABELS, DENY_LABELS } from '../utils/alert-labels.js';\nimport {\n findElement,\n describeElement,\n computeSwipeEnd,\n} from '../utils/element.js';\nimport { execStrict, isCommandAvailable } from '../utils/exec.js';\nimport {\n hardenArtifactFile,\n resolveArtifactPath,\n} from '../utils/output-path.js';\n\nexport class AdbBackend implements DeviceBackend {\n readonly kind = 'adb' as const;\n\n readonly platform = 'android' as const;\n\n readonly #serial: string;\n\n #recordingProcess: ChildProcess | null = null;\n\n #recordingPath: string | null = null;\n\n readonly #recordingRemotePath = '/sdcard/device-mcp-recording.mp4';\n\n constructor(serial: string) {\n this.#serial = serial;\n }\n\n async #adb(args: string[]): Promise<string> {\n return execStrict('adb', ['-s', this.#serial, ...args]);\n }\n\n async ensureConnected(): Promise<void> {\n if (!(await isCommandAvailable('adb'))) {\n throw new Error(\n 'adb is not installed or not on $PATH.\\n' +\n 'Install Android SDK platform-tools.',\n );\n }\n const state = await this.#adb(['get-state']);\n if (state.trim() !== 'device') {\n throw new Error(\n `Device ${this.#serial} is not ready (state: ${state.trim()})`,\n );\n }\n }\n\n async getDeviceInfo(): Promise<DeviceInfo> {\n const [model, version] = await Promise.all([\n this.#adb(['shell', 'getprop', 'ro.product.model']),\n this.#adb(['shell', 'getprop', 'ro.build.version.release']),\n ]);\n return {\n platform: 'android',\n deviceId: this.#serial,\n name: model.trim(),\n osVersion: version.trim(),\n state: 'device',\n };\n }\n\n async snapshot(): Promise<SnapshotResult> {\n const raw = await this.#dumpUiHierarchy();\n const hierarchy = parseAndroidHierarchy(raw);\n return {\n platform: 'android',\n hierarchy,\n raw,\n timestamp: Date.now(),\n };\n }\n\n async tapElement(query: ElementQuery): Promise<TapResult> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const x = Math.round(element.frame.x + element.frame.width / 2);\n const y = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(x, y);\n\n return {\n success: true,\n x,\n y,\n targetDescription: describeElement(element),\n };\n }\n\n async getElementText(query: ElementQuery): Promise<string> {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return element.label ?? element.value ?? '';\n }\n\n async tapCoordinates(x: number, y: number): Promise<void> {\n await this.#adb(['shell', 'input', 'tap', String(x), String(y)]);\n }\n\n async typeText(text: string): Promise<void> {\n // Android keyevent 29+shift = Ctrl+A (select all), 67 = DEL\n await this.#adb(['shell', 'input', 'keyevent', 'KEYCODE_MOVE_HOME']);\n await this.#adb([\n 'shell',\n 'input',\n 'keyevent',\n '--longpress',\n 'KEYCODE_SHIFT_LEFT',\n 'KEYCODE_MOVE_END',\n ]);\n await this.#adb(['shell', 'input', 'keyevent', '67']);\n // Android input text requires escaping spaces and special chars\n const escaped = text.replace(/ /gu, '%s').replace(/[&|;<>]/gu, '\\\\$&');\n await this.#adb(['shell', 'input', 'text', escaped]);\n }\n\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n startX?: number,\n startY?: number,\n distance?: number,\n ): Promise<void> {\n const d = distance ?? 500;\n const sx = startX ?? 540;\n const sy = startY ?? 960;\n const [endX, endY] = computeSwipeEnd(sx, sy, direction, d);\n const durationMs = 300;\n\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(sx),\n String(sy),\n String(endX),\n String(endY),\n String(durationMs),\n ]);\n }\n\n async waitForElement(\n query: ElementQuery,\n timeoutMs = 10_000,\n intervalMs = 500,\n ): Promise<UIElement> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (element) {\n return element;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(\n `Timed out waiting for element: ${JSON.stringify(query)} (${timeoutMs}ms)`,\n );\n }\n\n async getAppState(bundleId: string): Promise<AppStateResult> {\n const raw = await this.#adb(['shell', 'dumpsys', 'activity', 'processes']);\n\n const pidMatch = raw.match(\n new RegExp(`PID #(\\\\d+):.*${bundleId.replace(/\\./gu, '\\\\.')}`, 'u'),\n );\n\n if (pidMatch) {\n return {\n bundleId,\n state: 'Running',\n pid: parseInt(pidMatch[1], 10),\n };\n }\n\n const pmResult = await this.#adb([\n 'shell',\n 'pm',\n 'list',\n 'packages',\n bundleId,\n ]);\n if (pmResult.includes(bundleId)) {\n return { bundleId, state: 'Installed (not running)' };\n }\n\n return { bundleId, state: 'Not Installed' };\n }\n\n async #dumpUiHierarchy(): Promise<string> {\n const remotePath = '/sdcard/window_dump.xml';\n await this.#adb(['shell', 'uiautomator', 'dump', remotePath]);\n const xml = await this.#adb(['shell', 'cat', remotePath]);\n await this.#adb(['shell', 'rm', '-f', remotePath]);\n return xml;\n }\n\n screenshot(\n outputPath?: string,\n options?: { encode?: true },\n ): Promise<ScreenshotResult>;\n\n screenshot(\n outputPath: string | undefined,\n options: { encode: false },\n ): Promise<ScreenshotFileResult>;\n\n screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult>;\n\n async screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult> {\n const localPath = resolveArtifactPath(outputPath, 'screenshot');\n await this.#adb(['shell', 'screencap', '-p', '/sdcard/screenshot.png']);\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n '/sdcard/screenshot.png',\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', '/sdcard/screenshot.png']);\n hardenArtifactFile(localPath);\n if (options?.encode === false) {\n return { data: undefined, format: 'png', path: localPath };\n }\n const data = await readFile(localPath, 'base64');\n return { data, format: 'png', path: localPath };\n }\n\n async openApp(bundleId: string): Promise<void> {\n await this.#adb([\n 'shell',\n 'monkey',\n '-p',\n bundleId,\n '-c',\n 'android.intent.category.LAUNCHER',\n '1',\n ]);\n }\n\n async closeApp(bundleId: string): Promise<void> {\n await this.#adb(['shell', 'am', 'force-stop', bundleId]);\n }\n\n async pressButton(button: DeviceButton): Promise<void> {\n // Android keyevent codes\n const keyMap: Record<DeviceButton, string> = {\n home: '3',\n back: '4',\n enter: '66',\n lock: '26',\n };\n await this.#adb(['shell', 'input', 'keyevent', keyMap[button]]);\n }\n\n async dismissKeyboard(): Promise<void> {\n await this.#adb(['shell', 'input', 'keyevent', '111']);\n }\n\n async dismissAlert(accept: boolean): Promise<void> {\n const snap = await this.snapshot();\n const candidates = accept ? ACCEPT_LABELS : DENY_LABELS;\n\n for (const label of candidates) {\n const element = findElement(snap.hierarchy, { text: label });\n if (element) {\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(cx, cy);\n return;\n }\n }\n\n throw new Error(`No alert button found. Tried: ${candidates.join(', ')}`);\n }\n\n async getLogs(durationSeconds = 30, filter?: string): Promise<LogsResult> {\n const args = ['shell', 'logcat', '-d', '-t', String(durationSeconds)];\n if (filter) {\n args.push('-e', filter);\n }\n const raw = await this.#adb(args);\n const entries = raw\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const match = line.match(/^(\\d{2}-\\d{2}\\s+\\S+)\\s+(\\w)\\/.*?:\\s*(.*)/u);\n if (match) {\n return {\n timestamp: match[1],\n level: match[2],\n message: match[3],\n };\n }\n return { timestamp: '', level: 'info', message: line };\n });\n return { entries, source: 'logcat' };\n }\n\n async longPress(query: ElementQuery, durationMs = 1000): Promise<TapResult> {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.#adb([\n 'shell',\n 'input',\n 'swipe',\n String(cx),\n String(cy),\n String(cx),\n String(cy),\n String(durationMs),\n ]);\n\n return {\n success: true,\n x: cx,\n y: cy,\n targetDescription: describeElement(element),\n };\n }\n\n async scrollToElement(\n query: ElementQuery,\n direction: 'up' | 'down' = 'down',\n maxAttempts = 10,\n ): Promise<UIElement> {\n let previousRaw = '';\n\n for (let i = 0; i < maxAttempts; i++) {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (element) {\n return element;\n }\n if (snap.raw === previousRaw) {\n break;\n }\n previousRaw = snap.raw;\n await this.swipe(direction);\n }\n throw new Error(\n `Element not found after scrolling: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n async getAlertText(): Promise<string> {\n const snap = await this.snapshot();\n const texts = collectAndroidAlertTexts(snap.hierarchy);\n if (texts.length === 0) {\n throw new Error(\n 'No alert is currently displayed.\\n' +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return texts.join('\\n');\n }\n\n async getWindowSize(): Promise<WindowSize> {\n const raw = await this.#adb(['shell', 'wm', 'size']);\n const match = raw.match(/(\\d+)x(\\d+)/u);\n if (match) {\n return {\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n };\n }\n throw new Error(`Unable to parse window size from: ${raw.trim()}`);\n }\n\n async getContexts(): Promise<string[]> {\n return ['NATIVE_APP'];\n }\n\n async setContext(context: string): Promise<void> {\n if (context === 'NATIVE_APP') {\n return;\n }\n throw new Error(\n 'Context switching requires Appium backend. ADB only supports NATIVE_APP.',\n );\n }\n\n async getClipboard(): Promise<string> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async setClipboard(_text: string): Promise<void> {\n throw new Error(\n 'Clipboard access via ADB is not supported on modern Android. ' +\n 'Use the Appium backend for clipboard operations.',\n );\n }\n\n async startScreenRecording(outputPath?: string): Promise<void> {\n if (this.#recordingProcess) {\n throw new Error('Screen recording is already in progress');\n }\n this.#recordingPath = resolveArtifactPath(outputPath, 'recording');\n this.#recordingProcess = spawn('adb', [\n '-s',\n this.#serial,\n 'shell',\n 'screenrecord',\n this.#recordingRemotePath,\n ]);\n this.#recordingProcess.on('error', () => {\n this.#recordingProcess = null;\n this.#recordingPath = null;\n });\n }\n\n async stopScreenRecording(): Promise<string> {\n if (!this.#recordingProcess || !this.#recordingPath) {\n throw new Error('No screen recording in progress');\n }\n const localPath = this.#recordingPath;\n this.#recordingProcess.kill('SIGINT');\n await new Promise((resolve) => setTimeout(resolve, 2000));\n this.#recordingProcess = null;\n this.#recordingPath = null;\n\n await execStrict('adb', [\n '-s',\n this.#serial,\n 'pull',\n this.#recordingRemotePath,\n localPath,\n ]);\n await this.#adb(['shell', 'rm', '-f', this.#recordingRemotePath]);\n hardenArtifactFile(localPath);\n return localPath;\n }\n}\n\nfunction collectAndroidAlertTexts(elements: UIElement[]): string[] {\n const texts: string[] = [];\n for (const el of elements) {\n const isDialog =\n el.type.includes('Dialog') || el.type.includes('AlertDialog');\n if (isDialog) {\n collectTextValues(el.children ?? [], texts);\n return texts;\n }\n if (el.children) {\n const found = collectAndroidAlertTexts(el.children);\n if (found.length > 0) {\n return found;\n }\n }\n }\n return texts;\n}\n\nfunction collectTextValues(elements: UIElement[], texts: string[]): void {\n for (const el of elements) {\n if (el.type.includes('TextView') && el.value) {\n texts.push(el.value);\n }\n if (el.children) {\n collectTextValues(el.children, texts);\n }\n }\n}\n\nexport function parseAndroidHierarchy(xml: string): UIElement[] {\n const stack: UIElement[][] = [[]];\n\n // Matches all <node ...>, </node>, and <node .../> tags in document order\n const tagRegex = /<(\\/?)node(?:\\s+([^>]*?))?\\s*(\\/?)>/gu;\n let match: RegExpExecArray | null;\n\n while ((match = tagRegex.exec(xml)) !== null) {\n const isClosing = match[1] === '/';\n const attrs = match[2];\n const isSelfClosing = match[3] === '/';\n\n if (isClosing) {\n if (stack.length > 1) {\n stack.pop();\n }\n } else if (isSelfClosing && attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n stack[stack.length - 1].push(element);\n }\n } else if (attrs) {\n const element = parseNodeAttributes(attrs);\n if (element) {\n element.children = [];\n stack[stack.length - 1].push(element);\n stack.push(element.children);\n }\n }\n }\n\n return stack[0];\n}\n\nexport function parseNodeAttributes(attrs: string): UIElement | null {\n const get = (name: string): string | undefined => {\n const attrMatch = attrs.match(new RegExp(`${name}=\"([^\"]*)\"`, 'u'));\n return attrMatch?.[1] || undefined;\n };\n\n const boundsStr = get('bounds');\n if (!boundsStr) {\n return null;\n }\n\n // bounds format: [x1,y1][x2,y2]\n const boundsMatch = boundsStr.match(/\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]/u);\n if (!boundsMatch) {\n return null;\n }\n\n const x1 = parseInt(boundsMatch[1], 10);\n const y1 = parseInt(boundsMatch[2], 10);\n const x2 = parseInt(boundsMatch[3], 10);\n const y2 = parseInt(boundsMatch[4], 10);\n\n return {\n type: get('class') ?? 'Unknown',\n label: get('content-desc') || undefined,\n value: get('text') || undefined,\n identifier: get('resource-id') || undefined,\n frame: { x: x1, y: y1, width: x2 - x1, height: y2 - y1 },\n enabled: get('enabled') !== 'false',\n };\n}\n"]}
@@ -21,6 +21,7 @@ const output_path_js_1 = require("../utils/output-path.cjs");
21
21
  class AppiumBackend {
22
22
  constructor(config) {
23
23
  _AppiumBackend_instances.add(this);
24
+ this.kind = 'appium';
24
25
  _AppiumBackend_client.set(this, null);
25
26
  _AppiumBackend_config.set(this, void 0);
26
27
  _AppiumBackend_recording.set(this, false);