import { devices, getDevice, listSelectableDeviceModels, type DeviceModel, } from 'sootsim-engine/settings' import { rnxExit } from '../run-rnx' import { callInBridge, createBridgeFromParsed, parseBridgeCliArgs, type ParsedBridgeCliArgs, } from '../ws-bridge' interface DeviceCommandOptions { port?: number } type CurrentDeviceSnapshot = { model: string width: number height: number scale: number name: string } | null function usage() { console.log(` rnx device — inspect or change the live device preset for a sim usage: rnx device rnx device get rnx device set [--sim ] rnx device list examples: rnx device rnx device set iphone-16 rnx device set iphone-16-pro-max --sim a7 `) } function printDevice(model: DeviceModel) { const spec = getDevice(model) console.log( ` ${model.padEnd(14)} ${String(spec.width).padStart(4)}x${String(spec.height).padEnd(4)} pt ${String(spec.width * spec.scale).padStart(4)}x${String(spec.height * spec.scale).padEnd(4)} px ${spec.name}`, ) } async function readCurrentDevice( parsed: ParsedBridgeCliArgs, ): Promise { const bridge = createBridgeFromParsed(parsed) try { const settings = (await callInBridge | null>( bridge, 'SootSim.bridges.settings.get', )) ?? { deviceModel: null } const model = typeof settings.deviceModel === 'string' ? settings.deviceModel : null if (!model || !(model in devices)) return null const spec = getDevice(model as DeviceModel) return { model, width: spec.width, height: spec.height, scale: spec.scale, name: spec.name, } } finally { bridge.close() } } export async function runDeviceCommand(args: string[], opts: DeviceCommandOptions) { if (args.includes('--help') || args.includes('-h')) { usage() rnxExit(0) } const subcommand = args[0] if (!subcommand || subcommand === 'get') { const parsed = parseBridgeCliArgs(args, { port: opts.port }) const current = await readCurrentDevice(parsed) if (!current) { console.error(' error: could not read current device from the target sim') rnxExit(1) } console.log( ` ${current.model} ${current.width}x${current.height} pt ${current.width * current.scale}x${current.height * current.scale} px ${current.name}`, ) return } if (subcommand === 'list') { console.log(' available devices:\n') for (const model of listSelectableDeviceModels()) printDevice(model) return } if (subcommand === 'set') { const model = args[1] if (!model) { console.error(' error: device set expects a model') rnxExit(1) } if (!(model in devices)) { console.error(` error: unknown device "${model}"`) console.error(' run `rnx device list` to see valid models') rnxExit(1) } const parsed = parseBridgeCliArgs(args, { port: opts.port }) const bridge = createBridgeFromParsed(parsed) try { const changed = await callInBridge( bridge, 'SootSim.bridges.settings.set', 'deviceModel', model, ) const spec = getDevice(model as DeviceModel) console.log( ` ${changed ? 'set' : 'kept'} device: ${model} (${spec.width}x${spec.height} pt, ${spec.width * spec.scale}x${spec.height * spec.scale} px)${changed ? ' — reloading sim' : ''}`, ) } finally { bridge.close() } return } usage() console.error(` unknown subcommand: ${subcommand}`) rnxExit(1) }