Files
agentic-mobile-control/openspec/changes/cloud-console/tasks.md
T

3.4 KiB

1. Repository: bounded task listing

  • 1.1 Add list_tasks(*, status, limit, offset) and count_tasks(status) to the CloudRepository Protocol in repository.py
  • 1.2 Implement both methods in sql_repository.py using the existing SQLAlchemy query builder (no dialect-specific SQL), ordered most-recent-first
  • 1.3 Add unit/integration tests covering status filtering, pagination bounds, and empty results against both SQLite and PostgreSQL

2. Platform SDK API: task listing & attempt history

  • 2.1 Add response models (task summary list item, task attempt) to cloud/sdk/models.py
  • 2.2 Implement GET /v1/tasks in cloud/sdk/api.py: tasks:read scope, optional status query param, limit (default 50, max 100) / offset query params, calling the new repository methods
  • 2.3 Implement GET /v1/tasks/{task_id}/attempts in cloud/sdk/api.py: tasks:read scope, 404 on unknown task id, calling list_task_attempts
  • 2.4 Add tests for both endpoints: filtered/unfiltered listing, page-size-exceeds-max rejection, attempts for known/unknown task id, and scope enforcement (401/403)

3. Python SDK client parity

  • 3.1 Add list_tasks(...) and get_task_attempts(task_id) methods to CloudClient in cloud/sdk/client.py
  • 3.2 Add client tests asserting parity with direct HTTP calls to the two new endpoints

4. Cloud API CORS configuration

  • 4.1 Add a cors_allowed_origins field (env CLOUD_CONSOLE_CORS_ORIGINS, comma-separated, default empty) to CloudControlConfig/load_control_config()
  • 4.2 Wire CORSMiddleware into apps/cloud-api/cloud_api/app.py's create_app(), added only when the allow-list is non-empty
  • 4.3 Add a config/app test confirming CORS headers are absent by default and present only for a configured origin

5. Cloud console frontend (independent SPA)

  • 5.1 Scaffold an independent Vue 3 + Vite SPA project at cloud-console/ (own package.json/build tooling, sibling to console/)
  • 5.2 Implement the token-entry screen and an API client wrapper that stores the bearer token in sessionStorage and attaches it to every request, clearing it and returning to the entry screen on 401/403
  • 5.3 Implement the task view: filterable/paginated list against GET /v1/tasks, and a detail view with attempt history against GET /v1/tasks/{id}/attempts
  • 5.4 Implement the device pool and host registry views against GET /v1/devices and GET /v1/hosts
  • 5.5 Implement the plugin registry view (list) and registration form against GET /v1/plugins and POST /v1/plugins, surfacing validation/conflict/authorization errors from the API
  • 5.6 Document how to run the frontend dev server against a Cloud API base URL (env config) and the CORS origin it needs configured

6. Documentation

  • 6.1 Add a section to docs/CLOUD_DEPLOYMENT.md covering: running the console, provisioning an operator bearer token (least-privilege scopes), and configuring CLOUD_CONSOLE_CORS_ORIGINS

7. Verification

  • 7.1 Run the full backend test suite (uv run --all-packages pytest -m "not integration") and confirm no regressions
  • 7.2 Run the PostgreSQL-backed repository/integration tests for the new listing methods
  • 7.3 Manually verify end-to-end: submit a task via the existing SDK, confirm it appears in the console's task list, transitions status, and its attempt history renders; confirm device/host/plugin views render against a running Host Agent