Files
agentic-mobile-control/cloud-console/README.md
T
q792602257andClaude Opus 4.6 2169bb03d9 feat(cloud-console): task listing, attempt history, CORS, and console SPA
Implements the cloud-console OpenSpec change: adds GET /v1/tasks (filterable,
bounded pagination, tasks:read) and GET /v1/tasks/{id}/attempts (404 on unknown
task) to the platform SDK, with matching CloudClient methods and a closed-by-
default CLOUD_CONSOLE_CORS_ORIGINS allow-list wired through CloudControlConfig.
Ships an independent Vue 3 + Vite SPA at cloud-console/ that authenticates with
an operator-supplied bearer token held in sessionStorage, renders tasks with
attempt history, device pool, host registry, and the plugin registry with a
registration form.

Backend test suite: 438 passed (-m "not integration"); cloud-console typecheck
and production build both succeed. PostgreSQL-backed repository tests and
manual end-to-end verification remain pending external infrastructure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 14:00:23 +08:00

96 lines
3.5 KiB
Markdown

# Cloud Console
Independent Vue 3 + Vite single-page app for the Cloud Control Plane
(`apps/cloud-api`). Operators authenticate by pasting a pre-issued scoped
bearer token; the console stores it in `sessionStorage`, attaches
`Authorization: Bearer <token>` to every request, and clears it whenever the
Cloud API responds `401` or `403`.
The app talks only to the platform SDK surface (`/v1/...`) and consumes the
two listing endpoints added by the `cloud-console` change (`GET /v1/tasks`,
`GET /v1/tasks/{task_id}/attempts`) alongside the existing
`/v1/devices`, `/v1/hosts`, `/v1/plugins`, and `POST /v1/plugins` routes.
## Prerequisites
- Node.js 20+ (matching the existing `console/` SPA project)
- A running Cloud API (`apps/cloud-api`) reachable from your browser
- A bearer token issued via `CLOUD_PUBLIC_CREDENTIALS_JSON` whose scopes cover
what you intend to do from the console. Recommended least-privilege set:
- `tasks:read` — task list and attempt history views
- `pool:read` — device and host views
- `plugins:read` — plugin list
- Add `tasks:submit`/`plugins:admin` only if you need the write actions from
the same tab.
## Configure the backend CORS allow-list
The Cloud API has no CORS middleware by default. Before a browser can call it
cross-origin, set `CLOUD_CONSOLE_CORS_ORIGINS` to a comma-separated allow-list
that includes the exact origin your dev server prints (scheme + host + port —
no trailing slash):
```bash
# Example: allow the default Vite dev origin
export CLOUD_CONSOLE_CORS_ORIGINS="http://127.0.0.1:5173"
```
Restart `apps/cloud-api` after changing this env. Tokens are still required —
the allow-list only says which browser origins may send them.
## Run the dev server
```bash
cd cloud-console
cp .env.example .env.local
# Edit .env.local if your Cloud API is not at http://127.0.0.1:8001
npm install
npm run dev
```
Vite prints a local URL (default `http://127.0.0.1:5173`). Open it, paste a
bearer token, and the task/device/host/plugin dashboards become available.
`.env.local` overrides the default base URL via `VITE_CLOUD_API_BASE_URL`
(defaults to `http://127.0.0.1:8001`).
## Build for production
```bash
npm run build # type-checks with vue-tsc, then emits dist/
npm run preview # serves the built bundle locally
```
`dist/` is a static bundle — host it behind any static file server or CDN and
point it at a deployed Cloud API via `VITE_CLOUD_API_BASE_URL` set at build
time.
## Token handling
- The token is held in `sessionStorage` only. Closing the tab discards it.
- Every API request attaches `Authorization: Bearer <token>` and targets only
the configured `VITE_CLOUD_API_BASE_URL`.
- A `401`/`403` response clears the stored token and returns the operator to
the token-entry screen with the API's error detail.
## Project layout
```
cloud-console/
├── src/
│ ├── api.ts # API client wrapper (token storage, fetch, errors)
│ ├── types.ts # TS interfaces mirroring the REST models
│ ├── App.vue # Shell: token gate, nav, view router
│ ├── main.ts # Vue bootstrap
│ ├── style.css # Dark theme styles
│ └── views/
│ ├── TokenScreen.vue
│ ├── TasksView.vue # list + detail with attempt history
│ ├── DevicesView.vue # device pool + host registry
│ └── PluginsView.vue # registry list + registration form
├── index.html
├── package.json
├── tsconfig.json / tsconfig.node.json
└── vite.config.ts
```