UI Specification¶
Single-screen, prompt-driven dashboard for aaiclick operators. SPA served by
the FastAPI backend with 2 s REST polling (v0). Tech stack and build details:
docs/frontend.md.
Implementation: aaiclick/server/app.py — see STATIC_DIR and the
StaticFiles mount (SPA served when aaiclick/server/static/ exists);
src/App.tsx — prompt router; src/prompt.ts — parsePrompt + URL sync.
Layout¶
All modes share a fixed layout:
┌──────────────────────────────────────────┐
│ [aaiclick] [ prompt input.............. ]│ ← fixed header
├──────────────────────────────────────────┤
│ │
│ dynamic content area │ ← updates based on prompt
│ │
└──────────────────────────────────────────┘
- Header: always visible, contains app logo and editable prompt input
- Content area: fills remaining viewport, updates reactively based on prompt value
Navigation¶
Clicking interactive elements updates the prompt, which drives what is displayed:
(empty prompt) ──────▶ Help / command reference
@jobs ──────▶ Jobs list
@job <name> ──────▶ Job detail (tasks table)
@task <id> ──────▶ Task detail (status + logs)
Modes¶
Home (empty prompt)¶
Prompt: (empty)
Displays a help/command reference showing available commands and their descriptions.
Implementation: src/views/Home.tsx — see Home component.
Jobs List (@jobs)¶
Prompt: @jobs
Table of jobs sorted by created_at descending. Auto-refreshes via REST polling (2 s).
Implementation: src/views/Jobs.tsx — see Jobs component; aaiclick/server/routers/jobs.py — see list_jobs; aaiclick/orchestration/view_models.py — see JobView (total_tasks, completed_tasks).
| Column | Source field | Notes |
|---|---|---|
| Name | name |
Clickable — sets prompt to @job <name> |
| Status | status |
Colored badge |
| Progress | computed | completed_tasks / total_tasks |
| Created | created_at |
Relative time (e.g., "2m ago") |
| Duration | computed | started_at to completed_at or now |
Status badges¶
| Status | Color |
|---|---|
PENDING |
gray |
RUNNING |
blue |
COMPLETED |
green |
FAILED |
red |
CANCELLED |
yellow |
Job Detail (@job <name>)¶
Prompt: @job <name>
Header with job info, followed by a table of tasks. Auto-refreshes via REST polling (2 s).
Implementation: src/views/JobDetail.tsx — see JobDetail component; aaiclick/server/routers/jobs.py — see get_job.
Job header: name, status badge, created/started/completed times, error (if any).
Tasks table:
| Column | Source field | Notes |
|---|---|---|
| Name | name |
Clickable — sets prompt to @task <id> |
| Status | status |
Colored badge |
| Entrypoint | entrypoint |
|
| Attempt | attempt |
attempt / max_retries |
| Started | started_at |
Relative time |
| Duration | computed | started_at to completed_at or now |
Task statuses use the same color scheme as job statuses, plus:
| Status | Color |
|---|---|
CLAIMED |
purple |
Task Detail (@task <id>)¶
Prompt: @task <id>
Top section: status bar with task metadata — name, status badge, entrypoint, job name, worker ID, attempt info, timestamps, error (if any).
Main section: log viewer filling the remaining screen with vertical scroll. Logs poll every 2 s in v0; real-time SSE is deferred. Log source is log_path on the task record. Returns available=false when the file is missing or cross-host.
Implementation: src/views/TaskDetail.tsx — see TaskDetail component; src/components/LogViewer.tsx — see LogViewer; aaiclick/server/routers/tasks.py — see get_task_logs; aaiclick/internal_api/tasks.py — see get_task_logs.
Tech stack & real-time¶
v0 uses 2 s REST polling (refetchInterval). SSE and LISTEN/NOTIFY fanout
are deferred — see docs/future.md.
For framework choices, project layout, and build workflow, see docs/frontend.md.