@alumnium/xcode 0.0.0-stage → 0.24.0-alpha.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.
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../xcode/src/Alumni.ts", "../../xcode/src/drivers/XcodeDriver.ts", "../../xcode/src/drivers/XcodeSession.ts", "../../xcode/src/accessibility/XcodeAccessibilityTree.ts"],
4
+ "sourcesContent": [
5
+ "import { Alumni as BaseAlumni } from \"@alumnium/core\";\nimport { XcodeDriver } from \"./drivers/XcodeDriver.ts\";\nimport { XcodeSession } from \"./drivers/XcodeSession.ts\";\n\n/** Alumni driving an `XcodeSession`. */\nexport class Alumni extends BaseAlumni<XcodeDriver> {\n constructor(driver: XcodeSession, options: Alumni.Options = {}) {\n super(new XcodeDriver(driver), options);\n }\n\n /** Whether the given object is a native driver this Alumni accepts. */\n static accepts(driver: unknown): driver is Alumni.Driver {\n return driver instanceof XcodeSession;\n }\n}\n\nexport namespace Alumni {\n export type Driver = XcodeSession;\n\n export type Options = BaseAlumni.Options;\n\n export type VisionOptions = BaseAlumni.VisionOptions;\n\n export type CheckOptions = BaseAlumni.CheckOptions;\n\n export type CheckAssert = BaseAlumni.CheckAssert;\n}\n",
6
+ "import {\n AppId,\n BaseDriver,\n ClickTool,\n DragAndDropTool,\n DragSliderTool,\n type Keys,\n NavigateBackTool,\n PressKeyTool,\n ScrollTool,\n sleep,\n Telemetry,\n type ToolClass,\n TypeTool,\n} from \"@alumnium/core/internal\";\nimport { XcodeAccessibilityTree } from \"../accessibility/XcodeAccessibilityTree.ts\";\nimport type { XcodeSession } from \"./XcodeSession.ts\";\n\nconst { tracer } = Telemetry.get(\"packages/typescript/xcode/src/drivers/XcodeDriver.ts\");\nconst { span } = tracer.dec();\nconst stateful = BaseDriver.stateful;\n\nexport class XcodeDriver extends BaseDriver<never> {\n kind = \"xcode\" as const;\n platform = \"ios\" as const;\n supportedTools: Set<ToolClass> = new Set([\n ClickTool,\n DragAndDropTool,\n DragSliderTool,\n NavigateBackTool,\n PressKeyTool,\n ScrollTool,\n TypeTool,\n ]);\n delay = 0;\n readonly session: XcodeSession;\n\n constructor(session: XcodeSession) {\n super();\n this.session = session;\n }\n\n @span(\"driver.fetch_accessibility_tree\", BaseDriver.spanAttrs)\n protected async fetchAccessibilityTree(): Promise<XcodeAccessibilityTree> {\n if (this.delay > 0) await sleep(this.delay * 1000);\n return (await this.session.capture()).tree;\n }\n\n @span(\"driver.click\", BaseDriver.spanAttrs)\n @stateful\n async click(id: number): Promise<void> {\n const node = await this.#resolve(id);\n const point = this.#pointOf(node);\n await this.#perform(`t ${point.x} ${point.y}`, node.activationBundleId);\n }\n\n @span(\"driver.type\", BaseDriver.spanAttrs)\n @stateful\n async type(id: number, text: string): Promise<void> {\n const node = await this.#resolve(id);\n const point = this.#pointOf(node);\n await this.#perform(`t ${point.x} ${point.y}`, node.activationBundleId);\n // XCTest types into the focused control. Delete its current value before replacing it.\n const focused = await this.#resolveNode(node);\n const value =\n focused.value === focused.attributes[\"placeholderValue\"]\n ? \"\"\n : (focused.value ?? \"\");\n\n const input = \"\\b\".repeat([...value].length) + text;\n if (input) {\n await this.#perform(`sender keyboard kbd ${this.#encodeText(input)}`);\n }\n }\n\n @span(\"driver.press_key\", BaseDriver.spanAttrs)\n @stateful\n async pressKey(key: Keys.Key): Promise<void> {\n const keys: Record<Keys.Key, string> = {\n Backspace: \"\\b\",\n Enter: \"\\n\",\n Tab: \"\\t\",\n Escape: \"\\u001b\",\n Space: \" \",\n // XCUIKeyboardKey arrow values (NS*ArrowFunctionKey).\n ArrowUp: \"\\uf700\",\n ArrowDown: \"\\uf701\",\n ArrowLeft: \"\\uf702\",\n ArrowRight: \"\\uf703\",\n };\n await this.#perform(`sender keyboard kbd ${this.#encodeText(keys[key])}`);\n }\n\n @span(\"driver.drag_and_drop\", BaseDriver.spanAttrs)\n @stateful\n async dragAndDrop(fromId: number, toId: number): Promise<void> {\n const previous = await this.#tree();\n const from = previous.elementById(fromId);\n const to = previous.elementById(toId);\n if (from.activationBundleId !== to.activationBundleId)\n throw new Error(\"Xcode cannot drag between applications\");\n const fresh = (\n await this.session.capture(undefined, from.activationBundleId)\n ).tree;\n const start = fresh.resolve(from);\n const end = fresh.resolve(to);\n if (start.activationBundleId !== end.activationBundleId)\n throw new Error(\"Xcode cannot drag between applications\");\n const a = this.#pointOf(start);\n const b = this.#pointOf(end);\n await this.#perform(\n `drag ${a.x} ${a.y} ${b.x} ${b.y}`,\n start.activationBundleId,\n );\n }\n\n @span(\"driver.drag_slider\", BaseDriver.spanAttrs)\n @stateful\n async dragSlider(id: number, value: number): Promise<void> {\n if (value < 0 || value > 100)\n throw new Error(\"Slider value must be between 0 and 100\");\n const node = await this.#resolve(id);\n if (node.type !== \"Slider\" || !node.frame)\n throw new Error(\"Xcode target must be a slider with a frame\");\n const start = this.#pointOf(node);\n const end = node.frame.x + (node.frame.width * value) / 100;\n await this.#perform(\n `drag ${start.x} ${start.y} ${end} ${start.y}`,\n node.activationBundleId,\n );\n }\n\n @span(\"driver.scroll_to\", BaseDriver.spanAttrs)\n @stateful\n async scrollTo(id: number): Promise<void> {\n const target = (await this.#tree()).elementById(id);\n for (let attempt = 0; attempt < 10; attempt++) {\n const tree = (await this.session.capture()).tree;\n const node = tree.resolve(target);\n if (node.hitPoint) return;\n let container = node.parent;\n while (\n container &&\n ![\"ScrollView\", \"Table\", \"CollectionView\", \"Window\"].includes(\n container.type,\n )\n )\n container = container.parent;\n if (!container?.frame || !node.frame)\n throw new Error(\n \"Xcode cannot determine a scroll container for this element\",\n );\n const frame = container.frame;\n const x = frame.x + frame.width / 2;\n const top = frame.y + frame.height * 0.25;\n const bottom = frame.y + frame.height * 0.75;\n const up = node.frame.y > frame.y + frame.height / 2;\n await this.#perform(\n `t ${x} ${up ? bottom : top} f ${x} ${up ? top : bottom} 0.3`,\n node.activationBundleId,\n );\n }\n throw new Error(\"Xcode element did not become hittable after scrolling\");\n }\n\n @span(\"driver.back\", BaseDriver.spanAttrs)\n @stateful\n async back(): Promise<void> {\n const tree = (await this.session.capture()).tree;\n const bar = tree.find((node) => node.type === \"NavigationBar\");\n const back = bar?.children.find(\n (node) =>\n node.type === \"Button\" &&\n node.hitPoint &&\n (/^back$/i.test(node.label ?? \"\") ||\n /^(back|back-button|backButton)$/i.test(node.identifier ?? \"\")),\n );\n if (!back) {\n const window = tree.find((node) => node.type === \"Window\");\n if (!bar || !window?.frame)\n throw new Error(\"Xcode could not find a navigation back button\");\n // UIKit often labels Back with the previous screen's title. Use its edge gesture then.\n const frame = window.frame;\n const y = frame.y + frame.height / 2;\n await this.#perform(\n `t ${frame.x + 1} ${y} f ${frame.x + frame.width * 0.75} ${y} 0.3`,\n window.activationBundleId,\n );\n return;\n }\n const point = this.#pointOf(back);\n await this.#perform(`t ${point.x} ${point.y}`, back.activationBundleId);\n }\n\n @span(\"driver.wait\", BaseDriver.spanAttrs)\n @stateful\n async wait(seconds: number): Promise<void> {\n await this.#perform(`w ${Math.max(1, Math.min(30, seconds))}`);\n }\n\n @span(\"driver.screenshot\", BaseDriver.spanAttrs)\n screenshot(): Promise<string> {\n return this.session.screenshot();\n }\n\n @span(\"driver.quit\", BaseDriver.spanAttrs)\n quit(): Promise<void> {\n return this.session.close();\n }\n\n app(): AppId {\n return AppId.parse(this.session.appId);\n }\n\n title(): string {\n return \"\";\n }\n\n url(): string {\n return \"\";\n }\n\n checkNavigationPolicy(): void {}\n\n //#region Unsupported\n\n findElement(): Promise<never> {\n throw new Error(\"Element handles are not supported on Xcode\");\n }\n\n visit(): Promise<void> {\n throw new Error(\"Opening URLs is not supported by Xcode MCP\");\n }\n\n executeScript(): Promise<void> {\n throw new Error(\"Executing JavaScript is not supported on Xcode\");\n }\n\n switchToNextTab(): Promise<void> {\n throw new Error(\"Tab switching is not supported on Xcode\");\n }\n\n switchToPreviousTab(): Promise<void> {\n throw new Error(\"Tab switching is not supported on Xcode\");\n }\n\n waitForSelector(): Promise<void> {\n throw new Error(\"CSS selectors are not supported on Xcode\");\n }\n\n printToPdf(): Promise<void> {\n throw new Error(\"Printing to PDF is not supported on Xcode\");\n }\n\n //#endregion\n\n async #tree(): Promise<XcodeAccessibilityTree> {\n return (await this.getAccessibilityTree()) as XcodeAccessibilityTree;\n }\n\n async #resolve(id: number): Promise<XcodeAccessibilityTree.Node> {\n return this.#resolveNode((await this.#tree()).elementById(id));\n }\n\n async #resolveNode(\n target: XcodeAccessibilityTree.Node,\n ): Promise<XcodeAccessibilityTree.Node> {\n // Activating another app can move its windows; resolve only after activation.\n return (\n await this.session.capture(undefined, target.activationBundleId)\n ).tree.resolve(target);\n }\n\n async #perform(command: string, bundleId?: string): Promise<void> {\n try {\n await this.session.capture(command, bundleId);\n } finally {\n this.resetAccessibilityTree();\n }\n }\n\n #pointOf(node: XcodeAccessibilityTree.Node): XcodeAccessibilityTree.Point {\n if (!node.hitPoint || node.attributes[\"enabled\"] === \"false\") {\n throw new Error(\n `Xcode element ${node.identifier || node.label || node.type} is not hittable`,\n );\n }\n return node.hitPoint;\n }\n\n #encodeText(text: string): string {\n // Encode every character, including literal backslashes, so user text cannot become commands.\n return [...text]\n .map((character) => `\\\\u{${character.codePointAt(0)!.toString(16)}}`)\n .join(\"\");\n }\n}\n",
7
+ "import { randomUUID } from \"node:crypto\";\nimport { cp, mkdtemp, readFile, rm } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { z } from \"zod\";\nimport {\n ALUMNIUM_VERSION,\n Env,\n exec,\n Logger,\n SimulatorWindow,\n sleep,\n} from \"@alumnium/core/internal\";\nimport { XcodeAccessibilityTree } from \"../accessibility/XcodeAccessibilityTree.ts\";\n\nexport namespace XcodeSession {\n export interface Props {\n appId?: string | undefined;\n /** Local simulator app bundle, Xcode project, or Xcode workspace. */\n appPath?: string | undefined;\n /** Reinstall the app to clear its data before launch. Defaults to false. */\n appReset?: boolean | undefined;\n device?: string | undefined;\n /** Hide the macOS Simulator window. Defaults to false. */\n headless?: boolean | undefined;\n launchArgs?: string[] | undefined;\n launchEnv?: Record<string, string> | undefined;\n }\n\n export interface Capture {\n tree: XcodeAccessibilityTree;\n screenshotPath: string;\n }\n}\n\nconst OpenWorkspace = z.object({\n workspaceIdentifier: z.string(),\n activeScheme: z.string().nullable().optional(),\n});\n\nconst Schemes = z.object({\n activeSchemeName: z.string().nullable().optional(),\n});\n\nconst BuildSettings = z.array(\n z.object({\n buildSettings: z.object({\n PRODUCT_TYPE: z.string().optional(),\n PRODUCT_BUNDLE_IDENTIFIER: z.string().optional(),\n }),\n }),\n);\n\nconst Session = z.object({\n interactionSessionKey: z.string(),\n deviceUUID: z.string(),\n deviceIsSimulator: z.boolean(),\n});\n\nconst PermissionStatus = z.object({\n permission: z.object({\n projectAccessAttempts: z\n .array(\n z.object({\n agent: z.object({ name: z.string() }),\n endpoints: z.array(z.string()),\n }),\n )\n .default([]),\n }),\n});\n\nconst Capture = z.object({\n hierarchyPath: z.string().optional(),\n screenshotPath: z.string(),\n});\n\nconst logger = Logger.get(\"packages/typescript/xcode/src/drivers/XcodeSession.ts\");\n\n/** A simulator interaction session served by Apple's `xcrun mcpbridge`. */\nexport class XcodeSession {\n static readonly TOOL_TIMEOUT_MS = 5 * 60_000;\n static readonly APPROVE_INTERVAL_MS = 1_000;\n\n readonly #client = new Client({\n name: \"alumnium\",\n version: ALUMNIUM_VERSION,\n });\n readonly #props: XcodeSession.Props;\n #key: string | undefined;\n #appId: string;\n readonly #simulatorWindow = new SimulatorWindow();\n #approving = false;\n\n constructor(props: XcodeSession.Props) {\n this.#props = props;\n this.#appId = props.appId ?? \"\";\n }\n\n get appId(): string {\n return this.#appId;\n }\n\n static async start(props: XcodeSession.Props): Promise<XcodeSession> {\n const session = new XcodeSession(props);\n try {\n await session.#start();\n return session;\n } catch (error) {\n await session.close().catch(() => {});\n throw error;\n }\n }\n\n async #start(): Promise<void> {\n const { appPath, appReset, device, launchArgs, launchEnv } = this.#props;\n const workspace =\n appPath && /\\.(xcodeproj|xcworkspace)[\\\\/]?$/i.test(appPath)\n ? appPath\n : undefined;\n if (\n !appPath &&\n !this.#appId &&\n (appReset || launchArgs?.length || Object.keys(launchEnv ?? {}).length)\n )\n throw new Error(\n \"An app is required to reset or launch with arguments or environment variables\",\n );\n this.#startAutoApprove();\n await this.#connect();\n const sessionIdentifier = `Alumnium ${randomUUID()}`;\n let workspaceIdentifier: string | undefined;\n let activeScheme: string | null | undefined;\n if (workspace) {\n const opened = OpenWorkspace.parse(\n await this.#call(\"XcodeOpenWorkspace\", { path: workspace }),\n );\n workspaceIdentifier = opened.workspaceIdentifier;\n activeScheme = opened.activeScheme;\n }\n const result = Session.parse(\n await this.#call(\n workspace\n ? \"DeviceInteractionStartWorkspaceSession\"\n : \"DeviceInteractionStartSession\",\n {\n sessionIdentifier,\n ...(workspace ? { workspaceIdentifier } : {}),\n ...(workspace\n ? device && { deviceIdentifier: device }\n : { deviceIdentifier: device ?? \"iPhone Simulator\" }),\n },\n ),\n );\n this.#key = result.interactionSessionKey;\n if (!result.deviceIsSimulator)\n throw new Error(\n \"XcodeDriver supports iOS simulators only; select a simulator using the device option\",\n );\n await this.#simulatorWindow.open(result.deviceUUID, this.#props.headless);\n if (workspace) {\n await this.#call(\"DeviceInteractionInstallAndRun\", {\n interactionSessionKey: this.#key,\n workspaceIdentifier,\n ...(launchArgs && { commandLineArguments: launchArgs }),\n ...(launchEnv && { environmentVariables: launchEnv }),\n });\n await this.#resolveWorkspaceApp(\n workspace,\n workspaceIdentifier!,\n result.deviceUUID,\n activeScheme,\n );\n } else {\n await this.#installApp(result.deviceUUID);\n }\n if (appReset) await this.#resetApp(result.deviceUUID);\n if (!workspace || appReset) await this.#launchApp(result.deviceUUID);\n await this.capture(undefined, this.#appId || undefined);\n }\n\n #startAutoApprove() {\n if (!Env.ALUMNIUM_XCODE_AUTO_APPROVE || this.#approving) return;\n\n this.#approving = true;\n this.#autoApprove();\n }\n\n async #autoApprove(): Promise<void> {\n let lastError: string | undefined;\n while (this.#approving) {\n try {\n if (await this.#approvePending()) break;\n } catch (error) {\n // Retry on the next iteration, the status may be unavailable while Xcode starts.\n const message = error instanceof Error ? error.message : String(error);\n if (message !== lastError)\n logger.warn(`Xcode auto approve failed: ${message}`);\n lastError = message;\n }\n await sleep(XcodeSession.APPROVE_INTERVAL_MS);\n }\n this.#approving = false;\n }\n\n async #approvePending(): Promise<boolean> {\n const { stdout } = await exec(\"xcrun\", [\n \"mcp-server\",\n \"status\",\n \"--format\",\n \"json\",\n ]);\n const { permission } = PermissionStatus.parse(JSON.parse(stdout));\n const ids = permission.projectAccessAttempts\n .filter(({ agent }) => agent.name === \"alumnium\")\n .flatMap(({ endpoints }) => endpoints);\n if (!ids.length) return false;\n\n logger.info(`Approving Xcode access requests: ${ids.join(\", \")}`);\n await exec(\"sudo\", [\n \"xcrun\",\n \"mcp-server\",\n \"approve\",\n ...ids,\n \"--for-24-hours\",\n ]);\n return true;\n }\n\n async #connect(): Promise<void> {\n try {\n await this.#client.connect(\n new StdioClientTransport({\n command: \"xcrun\",\n args: [\"mcpbridge\"],\n env: Object.fromEntries(\n // oxlint-disable-next-line node/no-process-env\n Object.entries(process.env).filter(\n (entry): entry is [string, string] => entry[1] !== undefined,\n ),\n ),\n stderr: \"pipe\",\n }),\n );\n } catch (error) {\n // The bridge reports why it cannot start (e.g. Xcode MCP access is disabled)\n // outside of JSON-RPC, so the client only sees \"Connection closed\".\n throw (await this.#bridgeFailure(error)) ?? error;\n }\n }\n\n async #bridgeFailure(cause: unknown): Promise<Error | undefined> {\n try {\n await exec(\"xcrun\", [\"mcpbridge\"], { timeout: 10_000 });\n } catch (error) {\n const output = (error instanceof Error ? error.message : \"\")\n .replace(/^.*? exited with status \\S+:\\s*/s, \"\")\n .trim();\n let message = output;\n try {\n const parsed = z\n .object({ error: z.object({ message: z.string() }) })\n .parse(JSON.parse(output));\n message = parsed.error.message;\n } catch {\n // Not a JSON-RPC error, use the raw output.\n }\n if (message)\n return new Error(`Xcode mcpbridge failed: ${message}`, { cause });\n }\n }\n\n async #resolveWorkspaceApp(\n workspace: string,\n workspaceIdentifier: string,\n device: string,\n activeScheme: string | null | undefined,\n ): Promise<void> {\n const scheme =\n activeScheme ||\n Schemes.parse(\n await this.#call(\"XcodeListSchemes\", { workspaceIdentifier }),\n ).activeSchemeName;\n if (!scheme) throw new Error(\"Xcode workspace has no active scheme\");\n\n const { stdout } = await exec(\n \"xcrun\",\n [\n \"xcodebuild\",\n /\\.xcodeproj[\\\\/]?$/i.test(workspace) ? \"-project\" : \"-workspace\",\n workspace,\n \"-scheme\",\n scheme,\n \"-destination\",\n `id=${device}`,\n \"-showBuildSettings\",\n \"-json\",\n ],\n { timeout: XcodeSession.TOOL_TIMEOUT_MS },\n );\n // Screen captures can belong to SpringBoard or a permission dialog, not the built app.\n const apps = BuildSettings.parse(JSON.parse(stdout)).filter(\n ({ buildSettings }) =>\n buildSettings.PRODUCT_TYPE === \"com.apple.product-type.application\" &&\n (!this.#appId ||\n buildSettings.PRODUCT_BUNDLE_IDENTIFIER === this.#appId),\n );\n if (apps.length !== 1)\n throw new Error(\n \"Xcode could not uniquely identify the active scheme's app\",\n );\n this.#appId = z\n .string()\n .trim()\n .min(1)\n .parse(apps[0]!.buildSettings.PRODUCT_BUNDLE_IDENTIFIER);\n }\n\n async #installApp(device: string): Promise<void> {\n const { appPath } = this.#props;\n if (appPath) {\n const { stdout } = await exec(\"/usr/libexec/PlistBuddy\", [\n \"-c\",\n \"Print :CFBundleIdentifier\",\n path.join(appPath, \"Info.plist\"),\n ]);\n this.#appId = z.string().trim().min(1).parse(stdout);\n await exec(\"xcrun\", [\"simctl\", \"install\", device, appPath], {\n timeout: XcodeSession.TOOL_TIMEOUT_MS,\n });\n }\n }\n\n async #resetApp(device: string): Promise<void> {\n if (!this.#appId)\n throw new Error(\n \"Xcode could not determine the app bundle id for appReset\",\n );\n if (this.#appId.toLowerCase() === \"com.apple.springboard\")\n throw new Error(\"Xcode cannot reset SpringBoard\");\n\n const { stdout } = await exec(\"xcrun\", [\n \"simctl\",\n \"get_app_container\",\n device,\n this.#appId,\n \"app\",\n ]);\n const appPath = z.string().trim().min(1).parse(stdout);\n const directory = await mkdtemp(\n path.join(os.tmpdir(), \"alumnium-xcode-reset-\"),\n );\n const savedApp = path.join(directory, path.basename(appPath));\n try {\n // Uninstall also removes the installed bundle, so preserve it for bundle-id sessions.\n await cp(appPath, savedApp, { recursive: true });\n await exec(\"xcrun\", [\"simctl\", \"uninstall\", device, this.#appId]);\n await exec(\"xcrun\", [\"simctl\", \"install\", device, savedApp], {\n timeout: XcodeSession.TOOL_TIMEOUT_MS,\n });\n } finally {\n await rm(directory, { recursive: true, force: true });\n }\n }\n\n async #launchApp(device: string): Promise<void> {\n const { launchArgs = [], launchEnv = {} } = this.#props;\n if (!this.#appId) return;\n\n await exec(\n \"xcrun\",\n [\n \"simctl\",\n \"launch\",\n \"--terminate-running-process\",\n device,\n this.#appId,\n ...launchArgs,\n ],\n {\n env: {\n // oxlint-disable-next-line node/no-process-env\n ...process.env,\n ...Object.fromEntries(\n Object.entries(launchEnv).map(([key, value]) => [\n `SIMCTL_CHILD_${key}`,\n value,\n ]),\n ),\n },\n },\n );\n }\n\n async capture(\n command?: string,\n activationBundleId?: string,\n ): Promise<XcodeSession.Capture> {\n if (!this.#key) throw new Error(\"Xcode session is not started\");\n\n const result = Capture.parse(\n await this.#call(\"DeviceInteractionSynthesize\", {\n interactSessionKey: this.#key,\n ...(command !== undefined && { interactionCommand: command }),\n ...(activationBundleId && { activationBundleId }),\n }),\n );\n\n // Missing hierarchies are transient. Retry the capture, never replay the interaction.\n if (!result.hierarchyPath) return this.#recapture();\n\n return this.#readCapture(result);\n }\n\n async #recapture(): Promise<XcodeSession.Capture> {\n const result = Capture.parse(\n await this.#call(\"DeviceInteractionSynthesize\", {\n interactSessionKey: this.#key,\n }),\n );\n\n if (!result.hierarchyPath)\n throw new Error(\"Xcode could not capture the accessibility hierarchy\");\n\n return this.#readCapture(result);\n }\n\n async #readCapture(\n result: z.infer<typeof Capture>,\n ): Promise<XcodeSession.Capture> {\n if (!result.hierarchyPath)\n throw new Error(\"Xcode could not capture the accessibility hierarchy\");\n\n const source = await readFile(result.hierarchyPath, \"utf-8\");\n const tree = new XcodeAccessibilityTree(source);\n if (!this.#props.appId && !this.#props.appPath)\n this.#appId ||=\n tree.find((node) => node.type === \"Application\")?.activationBundleId ??\n \"\";\n\n return { tree, screenshotPath: result.screenshotPath };\n }\n\n async screenshot(): Promise<string> {\n const { screenshotPath } = await this.capture();\n return (await readFile(screenshotPath)).toString(\"base64\");\n }\n\n async close(): Promise<void> {\n this.#approving = false;\n try {\n if (this.#key) {\n const key = this.#key;\n this.#key = undefined;\n await this.#call(\"DeviceInteractionEndSession\", {\n interactionSessionKey: key,\n });\n }\n } finally {\n try {\n await this.#client.close();\n } finally {\n await this.#simulatorWindow.close();\n }\n }\n }\n\n async #call(name: string, args: Record<string, unknown>): Promise<unknown> {\n const result = await this.#client.callTool(\n { name, arguments: args },\n undefined,\n {\n timeout: XcodeSession.TOOL_TIMEOUT_MS,\n },\n );\n const content = z\n .array(z.object({ type: z.string(), text: z.string().optional() }))\n .parse(result.content);\n const text = content\n .filter((item) => item.type === \"text\")\n .map((item) => item.text ?? \"\")\n .join(\"\\n\");\n if (result.isError) throw new Error(`Xcode ${name} failed: ${text}`);\n return result.structuredContent ?? JSON.parse(text);\n }\n}\n",
8
+ "import { Element } from \"domhandler\";\nimport { z } from \"zod\";\nimport {\n type AccessibilityElement,\n BaseAccessibilityTree,\n XmlRenderer,\n} from \"@alumnium/core/internal\";\n\nexport namespace XcodeAccessibilityTree {\n export interface Point {\n x: number;\n y: number;\n }\n\n export interface Frame extends Point {\n width: number;\n height: number;\n }\n\n export interface Node extends AccessibilityElement {\n id: number;\n type: string;\n identifier?: string | undefined;\n hitPoint?: Point | undefined;\n frame?: Frame | undefined;\n activationBundleId: string;\n attributes: Record<string, string>;\n children: Node[];\n parent?: Node | undefined;\n }\n}\n\n/** Xcode's indented XCTest debug description, with geometry kept outside the model's XML. */\nexport class XcodeAccessibilityTree extends BaseAccessibilityTree<string> {\n readonly #roots: XcodeAccessibilityTree.Node[];\n readonly #nodes: XcodeAccessibilityTree.Node[];\n\n protected override get kind(): string {\n return \"xcode\";\n }\n\n constructor(source: string, roots?: XcodeAccessibilityTree.Node[]) {\n super(source);\n this.#roots = roots ?? parseHierarchy(source);\n this.#nodes = this.#roots.flatMap(flatten);\n }\n\n toStr(): string {\n return (this.xml ??= XmlRenderer.render(this.#roots.map(toXml), {\n compactAttrs: false,\n }));\n }\n\n elementById(id: number): XcodeAccessibilityTree.Node {\n const node = this.#nodes.find((candidate) => candidate.id === id);\n if (!node) throw new Error(`No element with raw_id=${id} found`);\n return node;\n }\n\n override scopeToArea(id: number): XcodeAccessibilityTree {\n const node = this.#nodes.find((candidate) => candidate.id === id);\n return node ? new XcodeAccessibilityTree(this.toStr(), [node]) : this;\n }\n\n /** Resolve a previous target in a fresh capture, ignoring IDs, values, and coordinates. */\n resolve(target: XcodeAccessibilityTree.Node): XcodeAccessibilityTree.Node {\n let matches = this.#nodes.filter((candidate) =>\n sameIdentity(candidate, target),\n );\n if (!target.identifier || matches.length > 1) {\n const context = ancestorIdentity(target);\n matches = matches.filter(\n (candidate) => ancestorIdentity(candidate) === context,\n );\n }\n\n // XCTest can expose the same control twice through separate wrapper views.\n const first = matches[0];\n if (\n first?.hitPoint &&\n matches.every(\n (candidate) => actionIdentity(candidate) === actionIdentity(first),\n )\n ) {\n return first;\n }\n\n if (matches.length !== 1) {\n throw new Error(\n `Xcode element ${target.identifier || target.label || target.type} is ${matches.length ? \"ambiguous\" : \"no longer present\"}; fetch a fresh accessibility tree`,\n );\n }\n\n return matches[0]!;\n }\n\n find(\n predicate: (node: XcodeAccessibilityTree.Node) => boolean,\n ): XcodeAccessibilityTree.Node | undefined {\n return this.#nodes.find(predicate);\n }\n}\n\nconst NUMBER = \"(-?\\\\d+(?:\\\\.\\\\d+)?)\";\nconst FRAME = new RegExp(\n `\\\\{\\\\{${NUMBER},\\\\s*${NUMBER}\\\\},\\\\s*\\\\{${NUMBER},\\\\s*${NUMBER}\\\\}\\\\}`,\n);\nconst HIT_POINT = new RegExp(`hitPoint:\\\\s*\\\\{${NUMBER},\\\\s*${NUMBER}\\\\}`);\nconst QUOTED_ATTRIBUTE =\n /(?:^|,\\s*)(identifier|label|value|title|placeholderValue):\\s*'((?:\\\\.|[^']|'(?!,\\s|$))*)'(?=,\\s|$)/g;\nconst BOOLEAN_ATTRIBUTE =\n /(?:^|,\\s*)(enabled|selected|focused|isEnabled|isSelected|isFocused|isRemoteLeafPlaceholder):\\s*(true|false|YES|NO|0|1)(?=,\\s|$)/g;\nconst POINT = z.tuple([z.coerce.number().finite(), z.coerce.number().finite()]);\nconst RECT = z.tuple([\n z.coerce.number().finite(),\n z.coerce.number().finite(),\n z.coerce.number().finite(),\n z.coerce.number().finite(),\n]);\n\nfunction parseHierarchy(source: string): XcodeAccessibilityTree.Node[] {\n const roots: XcodeAccessibilityTree.Node[] = [];\n const stack: { indent: number; node: XcodeAccessibilityTree.Node }[] = [];\n let bundleId = \"\";\n let id = 0;\n for (const line of source.split(/\\r?\\n/)) {\n const application = /^Application bundle identifier:\\s*(.+)$/.exec(line);\n if (application) {\n bundleId = application[1]!.trim();\n stack.length = 0;\n continue;\n }\n const match = /^(\\s*)([A-Z][A-Za-z0-9]*)(?=,|\\s|$)(.*)$/.exec(line);\n if (\n !match ||\n /^(Device|Application UI|Application pid|Application is)/.test(line)\n )\n continue;\n const [, whitespace, type, description] = match;\n if (type !== \"Application\" && !stack.length) continue;\n const attributes: Record<string, string> = {};\n for (const attr of description!.matchAll(QUOTED_ATTRIBUTE)) {\n attributes[attr[1]!] = attr[2]!.replace(/\\\\(['\\\\])/g, \"$1\");\n }\n // XCTest quotes labels/identifiers, but usually emits values without quotes.\n const value =\n /(?:^|,\\s*)value:\\s*(.*?)(?=,\\s*(?:(?:hitPoint|activationBundleId|enabled|selected|focused|is\\w+):|(?:Disabled|Selected|Focused|Keyboard Focused)(?:,|$))|$)/.exec(\n description!,\n );\n if (value && attributes[\"value\"] === undefined)\n attributes[\"value\"] = value[1]!.trim();\n for (const attr of description!.matchAll(BOOLEAN_ATTRIBUTE)) {\n const name = attr[1]!.replace(/^is(?=[A-Z])/, \"\");\n const normalized = name[0]!.toLowerCase() + name.slice(1);\n attributes[normalized] = [\"true\", \"YES\", \"1\"].includes(attr[2]!)\n ? \"true\"\n : \"false\";\n }\n for (const [flag, attr] of [\n [\"Disabled\", \"enabled\"],\n [\"Selected\", \"selected\"],\n [\"Focused\", \"focused\"],\n [\"Keyboard Focused\", \"focused\"],\n ]) {\n if (new RegExp(`(?:^|,\\\\s*)${flag}(?=,|$)`).test(description!))\n attributes[attr!] = flag === \"Disabled\" ? \"false\" : \"true\";\n }\n const frameMatch = FRAME.exec(description!);\n const hitMatch = HIT_POINT.exec(description!);\n const frame = frameMatch\n ? RECT.parse(frameMatch.slice(1).map(Number))\n : undefined;\n const hitPoint = hitMatch\n ? POINT.parse(hitMatch.slice(1).map(Number))\n : undefined;\n const indent = whitespace!.length;\n while (stack.length && stack.at(-1)!.indent >= indent) stack.pop();\n const parent = stack.at(-1)?.node;\n const node: XcodeAccessibilityTree.Node = {\n id: ++id,\n type: type!,\n identifier: attributes[\"identifier\"],\n name: attributes[\"identifier\"] || attributes[\"label\"],\n label: attributes[\"label\"],\n value: attributes[\"value\"],\n frame: frame && {\n x: frame[0],\n y: frame[1],\n width: frame[2],\n height: frame[3],\n },\n hitPoint: hitPoint && { x: hitPoint[0], y: hitPoint[1] },\n activationBundleId:\n /activationBundleId:\\s*([^,\\s]+)/.exec(description!)?.[1] ?? bundleId,\n attributes,\n children: [],\n parent,\n };\n (parent?.children ?? roots).push(node);\n stack.push({ indent, node });\n }\n if (!roots.length)\n throw new Error(\n \"Xcode returned no application accessibility hierarchy; capture the device again\",\n );\n return roots;\n}\n\nfunction flatten(\n node: XcodeAccessibilityTree.Node,\n): XcodeAccessibilityTree.Node[] {\n return [node, ...node.children.flatMap(flatten)];\n}\n\nfunction toXml(node: XcodeAccessibilityTree.Node): Element {\n const attributes = {\n raw_id: String(node.id),\n name: node.name ?? \"\",\n ...node.attributes,\n };\n const element = new Element(node.type, attributes);\n element.children = node.children.map(toXml);\n for (const child of element.children) child.parent = element;\n return element;\n}\n\nfunction sameIdentity(\n candidate: XcodeAccessibilityTree.Node,\n target: XcodeAccessibilityTree.Node,\n): boolean {\n return (\n candidate.type === target.type &&\n candidate.activationBundleId === target.activationBundleId &&\n (target.identifier\n ? candidate.identifier === target.identifier\n : candidate.label === target.label)\n );\n}\n\nfunction ancestorIdentity(node: XcodeAccessibilityTree.Node): string {\n const identities: string[] = [];\n for (let parent = node.parent; parent; parent = parent.parent) {\n identities.push(\n JSON.stringify([\n parent.type,\n parent.identifier || parent.label || \"\",\n // SwiftUI list cells often have no label; their text identifies the row.\n parent.type === \"Cell\"\n ? flatten(parent)\n .filter((child) => child.type === \"StaticText\")\n .map((child) => child.label ?? \"\")\n .sort()\n : [],\n ]),\n );\n }\n return identities.join(\"/\");\n}\n\nfunction actionIdentity(node: XcodeAccessibilityTree.Node): string {\n return JSON.stringify([node.attributes, node.frame, node.hitPoint]);\n}\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "EFBBB991D7E2833564756E2164756E21",
12
+ "names": []
13
+ }