()
| 38 | } |
| 39 | |
| 40 | function listDevices(): DeviceListEntry[] { |
| 41 | // devicectl JSON output requires --json-output to a path. Use a tempfile. |
| 42 | const tmp = `/tmp/devicectl-list-${process.pid}-${Date.now()}.json`; |
| 43 | const r = spawnSync('xcrun', ['devicectl', 'list', 'devices', '--json-output', tmp], { |
| 44 | stdio: 'pipe', |
| 45 | timeout: 30_000, |
| 46 | }); |
| 47 | if (r.status !== 0) return []; |
| 48 | try { |
| 49 | const fs = require('fs'); |
| 50 | const raw = fs.readFileSync(tmp, 'utf-8'); |
| 51 | const obj = JSON.parse(raw); |
| 52 | fs.unlinkSync(tmp); |
| 53 | return (obj.result?.devices ?? []).map((d: { identifier: string; connectionProperties: { tunnelState: string }; deviceProperties: { name: string }; hardwareProperties: { productType: string } }) => ({ |
| 54 | identifier: d.identifier, |
| 55 | state: d.connectionProperties?.tunnelState ?? 'unknown', |
| 56 | name: d.deviceProperties?.name ?? 'unknown', |
| 57 | model: d.hardwareProperties?.productType ?? 'unknown', |
| 58 | })); |
| 59 | } catch { |
| 60 | return []; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | function isPaired(udid: string): boolean { |
| 65 | // devicectl device info processes returns a clean exit when paired. |
no test coverage detected