## ADDED Requirements ### Requirement: Device discovery and listing The system SHALL provide a Device Manager that can list all known iPhone devices and their current status (`idle`, `busy`, `offline`, `error`). #### Scenario: Listing devices returns current status - **WHEN** a caller requests the device list - **THEN** the system returns each known device's id, status, and driver connection info (e.g. WDA port) without contacting the physical device for every field #### Scenario: No devices connected - **WHEN** a caller requests the device list and no physical devices are reachable - **THEN** the system returns an empty list rather than raising an error ### Requirement: Device connect and disconnect lifecycle The system SHALL allow a caller to connect to and disconnect from a specific device by id, transitioning its tracked status accordingly. #### Scenario: Successful connect - **WHEN** a caller connects to a device id that is currently `idle` and reachable - **THEN** the Device Manager marks the device `busy`, and it becomes usable for capability calls #### Scenario: Connect to unreachable device - **WHEN** a caller connects to a device id that cannot be reached (WDA not responding) - **THEN** the Device Manager marks the device `offline` and returns an error to the caller instead of hanging indefinitely #### Scenario: Disconnect releases the device - **WHEN** a caller disconnects from a device it previously connected to - **THEN** the Device Manager releases the underlying driver connection and marks the device `idle` ### Requirement: Driver-independent capability interface The system SHALL define a single `Driver` interface (`connect`, `disconnect`, `screenshot`, `tap`, `swipe`, `input`, `launch`, `terminate`, `tree`, `home`, `lock`, `unlock`) that any concrete driver implementation (e.g. WDA, and in future Android) must satisfy identically, so callers above the driver layer never depend on a specific automation framework. #### Scenario: Capability call is dispatched through the interface - **WHEN** a higher layer (tools/) invokes a capability such as `tap(x, y)` on a connected device - **THEN** the call is routed through the `Driver` interface to the concrete driver instance for that device, with no framework-specific (e.g. Appium/WDA) types or errors surfacing to the caller ### Requirement: WDA driver implementation The system SHALL provide a concrete `WDADriver` implementing the `Driver` interface using WebDriverAgent (via Appium Python client), supporting at minimum: screenshot capture, tap, swipe, text input, app launch, app terminate, UI tree retrieval, home button, and device lock/unlock. #### Scenario: Screenshot via WDA driver - **WHEN** `screenshot()` is called on a device backed by `WDADriver` - **THEN** the driver returns image bytes/path representing the current physical screen contents #### Scenario: Launch app via WDA driver - **WHEN** `launch(bundle_id_or_name)` is called on a device backed by `WDADriver` - **THEN** the driver starts the requested app on the physical device and the call returns once the app process is confirmed running (or raises a clear error if launch fails) ### Requirement: Stateless driver Driver implementations SHALL NOT persist task-level or business state (e.g. current task id, plan progress); any such state SHALL be owned by the Agent Runtime / Task Memory layers, not the driver. #### Scenario: Driver restart does not lose task progress - **WHEN** a driver connection is dropped and re-established mid-task - **THEN** the in-progress task's plan, step history, and timeline remain intact because they were never stored in the driver, only the live device connection needs to be re-established