Files
agentic-mobile-control/openspec/changes/apex-agent-mvp/specs/device-management/spec.md
T

53 lines
3.6 KiB
Markdown

## 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