## ADDED Requirements ### Requirement: List device status The system SHALL expose `GET /console/devices` returning every registered device's id, name, status (`idle`/`busy`/`offline`/`error`), and driver type, reusing `DeviceManager.list_devices()`. #### Scenario: Devices are registered - **WHEN** an operator calls `GET /console/devices` while one or more devices are registered - **THEN** the response is a `200` with a JSON array containing one entry per device with its current `status` #### Scenario: No devices registered - **WHEN** an operator calls `GET /console/devices` while no devices are registered - **THEN** the response is a `200` with an empty JSON array ### Requirement: List tasks The system SHALL expose `GET /console/tasks` returning all tasks known to `TaskMetadataStore`, most recently created first, with optional `device_id` and `status` query filters. #### Scenario: List all tasks - **WHEN** an operator calls `GET /console/tasks` with no query parameters - **THEN** the response is a `200` with a JSON array of tasks ordered by `created_at` descending #### Scenario: Filter by device - **WHEN** an operator calls `GET /console/tasks?device_id=` - **THEN** the response contains only tasks whose `device_id` matches `` #### Scenario: Filter by status - **WHEN** an operator calls `GET /console/tasks?status=running` - **THEN** the response contains only tasks whose `status` equals `running` ### Requirement: Task detail The system SHALL expose `GET /console/tasks/{task_id}` returning the full task record, or a `404` if the task does not exist. #### Scenario: Task exists - **WHEN** an operator calls `GET /console/tasks/{task_id}` for a known task id - **THEN** the response is a `200` with the task's goal, device_id, status, timestamps, and failure_reason (if any) #### Scenario: Task does not exist - **WHEN** an operator calls `GET /console/tasks/{task_id}` for an unknown task id - **THEN** the response is a `404` ### Requirement: Task timeline replay The system SHALL expose `GET /console/tasks/{task_id}/timeline` returning the ordered list of execution steps recorded for the task, each including its scene, prompt, tool call, result, timestamp, and a base64-encoded screenshot when one was captured for that step. #### Scenario: Task has recorded steps - **WHEN** an operator calls `GET /console/tasks/{task_id}/timeline` for a task that executed at least one step - **THEN** the response is a `200` with a JSON array ordered by step `index` ascending, each entry including `image_base64` when a screenshot was captured for that step #### Scenario: Task has no recorded steps - **WHEN** an operator calls `GET /console/tasks/{task_id}/timeline` for a task with no timeline history (e.g. it failed before its first step) - **THEN** the response is a `200` with an empty JSON array