PRD-002-2 — Pages, Routes & View States¶
| Field | Value |
|---|---|
| Document ID | PRD-002-2 |
| Version | 1.0 |
| Status | DRAFT |
| Date | March 2026 |
| Parent Doc | PRD-002 |
Part of: PRD-002-1 Design System · PRD-002-3 Interactions & A11y
1. Route Table¶
| Path | Component | Auth Required | Redirect Behavior |
|---|---|---|---|
/login |
LoginPage |
No | If authenticated → redirect to /dashboard |
/ |
— | — | Always redirect to /dashboard |
/dashboard |
DashboardPage |
Yes | If not authenticated → redirect to /login |
/settings |
SettingsPage |
Yes | If not authenticated → redirect to /login |
* |
NotFoundPage |
No | — |
2. Page: Login (/login)¶
Wireframe¶
╔══════════════════════════════════════════════════════════════════════╗
║ ║
║ ║
║ ║
║ ┌──────────────────────────────┐ ║
║ │ │ ║
║ │ [AgentOps Logo] │ ║
║ │ AgentOps │ ║
║ │ │ ║
║ │ Jira for AI agents. │ ║
║ │ Supervise, steer, and trust │ ║
║ │ your multi-agent workflows. │ ║
║ │ │ ║
║ │ ┌────────────────────────┐ │ ║
║ │ │ 🐙 Continue with │ │ ║
║ │ │ GitHub │ │ ║
║ │ └────────────────────────┘ │ ║
║ │ │ ║
║ └──────────────────────────────┘ ║
║ ║
║ AgentOps Dashboard · v1.0 · Open Source ║
║ ║
╚══════════════════════════════════════════════════════════════════════╝
Exact copy:
- Tagline:
"Jira for AI agents. Supervise, steer, and trust your multi-agent workflows." - Button label:
"Continue with GitHub"
States¶
Idle (default): As shown above.
Loading:
║ ┌────────────────────────┐ ║
║ │ ⟳ Connecting to │ ║
║ │ GitHub... │ ║
║ └────────────────────────┘ ║
Button disabled, spinner replaces GitHub icon, text changes to "Connecting to GitHub...".
Error — OAuth denied:
║ ┌──────────────────────────────┐ ║
║ │ ⚠ Access denied by GitHub │ ║ ← red inline message
║ └──────────────────────────────┘ ║
║ ┌────────────────────────┐ ║
║ │ 🐙 Continue with │ ║
║ │ GitHub │ ║
║ └────────────────────────┘ ║
Error message: "Access denied. Please authorise the AgentOps app on GitHub to continue."
Error — server error:
Error message: "Something went wrong. Please try again." + retry button below the message.
Auth Flow¶
[Click button] → GET /auth/login → GitHub OAuth consent → GET /auth/callback
→ Backend sets httpOnly cookie → redirect to /dashboard
3. Page: Dashboard (/dashboard)¶
3a. Full Layout Skeleton¶
┌─────────────────────────────────────────────────────────────────────────────┐ ← 48px topbar
│ AgentOps ● Connected [⧉] [@user ▾] │
├─────────────────┬───────────────────────────────────────┬───────────────────┤
│ Zone 1 │ Zone 2 │ Zone 3 │
│ 280px fixed │ flex (fills remaining ≈ 640px+) │ 320px fixed │
│ │ │ │
│ Job Queue │ Live Workspace │ Output Panel │
│ Sidebar │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
└─────────────────┴───────────────────────────────────────┴───────────────────┘
↑ 280px ↑ flex ↑ 320px
Full app height = 100vh - 48px (topbar). All three zones scroll independently.
3b. Topbar (always rendered)¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ [◈] AgentOps ● Connected [⧉ LangFlow] [@user ▾] │
└─────────────────────────────────────────────────────────────────────────────┘
| Section | Contents |
|---|---|
| Left | App logo icon + "AgentOps" wordmark |
| Center | Connection status pill: "● Connected" (green) or "○ Disconnected" (gray) |
| Right | LangFlow icon link (external) + user avatar + "@login ▾" dropdown chevron |
Avatar dropdown:
Separator between "Settings" and "Log out". Clicking outside or pressing Escape closes it.
3c. Zone 1 — Job Queue Sidebar¶
┌─────────────────────────────────┐
│ [Status ▾] [Repo ▾] [↕] [+ New Job] │
├─────────────────────────────────┤
│ ┌─────────────────────────────┐ │
│ │ ● RUNNING #1042 │ │ ← selected (left accent border)
│ │ Auth token expiry causes │ │
│ │ 500 on /api/me │ │
│ │ github.com/org/repo │ │
│ │ 4 min ago 3 agents active │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ ● WAITING #1098 │ │
│ │ Null pointer in payment │ │
│ │ checkout flow │ │
│ │ github.com/org/payments-svc │ │
│ │ 9 min ago Needs your input │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ ● QUEUED #1103 │ │
│ │ Redis connection pool │ │
│ │ exhausted at peak load │ │
│ │ github.com/org/infra │ │
│ │ just now │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ ● DONE #1031 │ │
│ │ Login page flickers on │ │
│ │ Safari 16 │ │
│ │ github.com/org/frontend │ │
│ │ Completed 22 min ago │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────┘
Filter row: Status dropdown, Repo dropdown, sort toggle (newest/oldest). All three are compact controls in a single row above the list.
Empty state (no jobs):
┌─────────────────────────────────┐
│ [Status ▾] [Repo ▾] [↕] [+ New Job] │
├─────────────────────────────────┤
│ │
│ │
│ No jobs yet. │
│ Submit your first issue → │
│ │
│ │
└─────────────────────────────────┘
Faint muted text, centered vertically in the available list area.
3d. Zone 2 — Live Workspace¶
State 1 — Empty (no job selected)¶
┌─────────────────────────────────────────────────────┐
│ │
│ │
│ │
│ [◈ icon, faint] │
│ │
│ Select a job from the queue, │
│ or submit a new one. │
│ │
│ [+ New Job] │
│ │
│ │
└─────────────────────────────────────────────────────┘
Icon and text in --color-text-muted. "+ New Job" is a ghost button, centered.
State 2 — Running¶
┌─────────────────────────────────────────────────────┐
│ #1042 Auth token expiry causes 500 on /api/me │ ← workspace header
│ github.com/org/repo · @user · 2 hours ago │
│ ● RUNNING [↪ Redirect] [⏸ Pause] [✕ Kill] │
├─────────────────────────────────────────────────────┤
│ ●────────●────────◌────────◌────────◌ │ ← execution timeline
│ START inv✓ cs_search human writer │
│ 12s (18s...) │
├─────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────┐ │
│ │ 🔍 INVESTIGATOR AGENT ● DONE (12s) │ │
│ ├───────────────────────────────────────────────┤ │
│ │ Reading issue body... │ │
│ │ Identified error: HTTP 500 on auth endpoint │ │
│ │ Hypothesis: JWT validation or middleware │ │
│ │ │ │
│ │ → Passed to: Codebase Searcher │ │
│ └───────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────┐ │
│ │ 🔎 CODEBASE SEARCH AGENT ● RUNNING │ │
│ ├───────────────────────────────────────────────┤ │
│ │ Searching for JWT middleware... │ │
│ │ 🔧 search_codebase — "JWT expiry check"... │ │
│ │ Found: auth/middleware.py:142▌ │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Control bar shows: [↪ Redirect] (ghost), [⏸ Pause] (secondary), [✕ Kill] (destructive).
State 3 — HITL / Waiting¶
┌─────────────────────────────────────────────────────┐
│ #1042 Auth token expiry causes 500 on /api/me │ ← workspace header
│ github.com/org/repo · @user · 2 hours ago │
│ ● WAITING Awaiting your response… │
├─────────────────────────────────────────────────────┤
│ ●────────●────────◌────────◌────────◌ │ ← timeline: human_input = amber spinner
│ START inv✓ cs_search⚠ human writer │
│ amber↑ │
├─────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────┐ │ ← amber border + glow
│ │ ⚠ SUPERVISOR NEEDS YOUR INPUT ● WAITING │ │
│ ├───────────────────────────────────────────────┤ │
│ │ The error appears in two code paths: │ │
│ │ │ │
│ │ (A) auth/middleware.py — JWT validation │ │
│ │ (B) db/session.py — DB connection pooling │ │
│ │ │ │
│ │ Which should agents prioritize? │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────┐ │ │
│ │ │ Type your answer here... │ │ │
│ │ └───────────────────────────────────────────┘ │ │
│ │ [Continue →] │ │
│ └───────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────┐ │ ← frozen, no cursor
│ │ 🔎 CODEBASE SEARCH AGENT ● DONE (18s) │ │
│ ├───────────────────────────────────────────────┤ │
│ │ Found relevant files in auth/middleware.py │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
- Control bar replaced by
"Awaiting your response…"label (amber text). - QuestionCard pinned above AgentCards.
- AgentCards below are frozen (no streaming cursor, no new tokens).
- Timeline
human_inputnode shown as amber spinner.
State 4 — Pausing¶
┌─────────────────────────────────────────────────────┐
│ #1042 Auth token expiry causes 500 on /api/me │
│ github.com/org/repo · @user · 2 hours ago │
│ ● PAUSING [↪ Redirect] [⟳ Pausing…] [✕ Kill] │ ← Pause replaced by spinner
├─────────────────────────────────────────────────────┤
│ ●────────●────────◌────────◌────────◌ │
├─────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────┐ │
│ │ 🔎 CODEBASE SEARCH AGENT ● RUNNING │ │ ← still streaming
│ ├───────────────────────────────────────────────┤ │
│ │ Searching for JWT middleware... │ │
│ │ Found: auth/middleware.py▌ │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
- Pause button replaced with
"⟳ Pausing…"(disabled, spinner). - Kill button remains active.
- Status badge shows
PAUSINGin static blue (no pulse). - Agents continue streaming (pause has not taken effect yet).
State 5 — Done¶
┌─────────────────────────────────────────────────────┐
│ #1042 Auth token expiry causes 500 on /api/me │
│ github.com/org/repo · @user · 2 hours ago │
│ ● DONE Job complete · 4m 32s │ ← control bar replaced
├─────────────────────────────────────────────────────┤
│ ●────────●────────●────────●────────● │ ← fully green timeline
│ START inv✓ cs_search✓ human✓ writer✓ │
├─────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────┐ │
│ │ 🔍 INVESTIGATOR AGENT ● DONE (12s) │ │
│ └───────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────┐ │
│ │ 🔎 CODEBASE SEARCH AGENT ● DONE (18s) │ │
│ └───────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────┐ │
│ │ ✍ WRITER AGENT ● DONE (31s) │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
- Control bar hidden; replaced by
"Job complete · {elapsed time}"label. - All AgentCards show ✓ DONE with elapsed time.
- Timeline fully green.
- Zone 3 fully populated.
3e. Zone 3 — Output Panel¶
State 1 — Accumulating (streaming)¶
┌───────────────────────────────────┐
│ OUTPUT PANEL │
├───────────────────────────────────┤
│ TRIAGE REPORT │
│ ░░░░░░░░░░░░░░░░░░░░░ │ ← SkeletonBlock
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░ │
├───────────────────────────────────┤
│ GITHUB COMMENT │
│ ░░░░░░░░░░░░░░░░░░░░░ │ ← SkeletonBlock
│ ░░░░░░░░░ │
├───────────────────────────────────┤
│ TICKET DRAFT │
│ ░░░░░░░░░░░░░░░░░░░░░ │ ← SkeletonBlock
├───────────────────────────────────┤
│ [Post Comment] [Create Issue] │ ← all disabled
│ [Copy Report] [View LangSmith] │
└───────────────────────────────────┘
SkeletonBlock placeholders until first output.token arrives per section. Each section activates independently as its tokens stream in. Action buttons disabled until job.done SSE received.
State 2 — Done¶
┌───────────────────────────────────┐
│ TRIAGE REPORT │
│ ┌────────────────────────────┐ │
│ │ Severity: 🔴 HIGH │ │
│ │ Category: Auth / Tokens │ │
│ │ Confidence: 87% │ │
│ │ │ │
│ │ Root Cause: │ │
│ │ JWT expiry check in │ │
│ │ auth/middleware.py:L142 │ │
│ │ does not account for │ │
│ │ timezone offset. │ │
│ │ │ │
│ │ Relevant Files: │ │
│ │ · auth/middleware.py │ │
│ │ · tests/test_auth.py │ │
│ │ · config/jwt_settings.py │ │
│ │ │ │
│ │ Similar Past Issues: │ │
│ │ · #891 — Fixed 2024-11 │ │
│ └────────────────────────────┘ │
├───────────────────────────────────┤
│ GITHUB COMMENT │
│ ┌────────────────────────────┐ │
│ │ ## AgentOps Triage #1042 │ │
│ │ **Severity:** High │ │
│ │ **Root Cause:** JWT bug... │ │ ← editable textarea
│ │ │ │
│ └────────────────────────────┘ │
│ [Preview] 1,247 chars │
├───────────────────────────────────┤
│ TICKET DRAFT │
│ Title: [Bug] JWT expiry fails... │
│ Labels: [bug] [auth] [high-pri] │
│ Assignee: @backend-team │
│ Effort: M (2-4 hours) │
├───────────────────────────────────┤
│ [Post Comment ↗] [Create Issue] │
│ [Copy Report] [View LangSmith↗] │
└───────────────────────────────────┘
Action buttons:
| Button | Variant |
|---|---|
| Post Comment | primary |
| Create Issue | secondary |
| Copy Report | ghost |
| View in LangSmith | ghost + external link icon |
State 3 — Write-back pending¶
├───────────────────────────────────┤
│ [⟳ Posting…] [Create Issue] │ ← all buttons disabled
│ [Copy Report] [View LangSmith] │
└───────────────────────────────────┘
"Post Comment" button shows spinner + "Posting…". All other buttons disabled.
After success:
├───────────────────────────────────┤
│ [✓ Posted · View on GitHub →] │ ← link replaces button
│ [Create Issue] │
│ [Copy Report] [View LangSmith] │
└───────────────────────────────────┘
4. Page: Settings (/settings)¶
Single-column centered layout, max-width: 600px.
┌─────────────────────────────────────────────────────────────────────┐
│ [topbar — same as dashboard] │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Settings │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ GitHub Account │ │
│ │ │ │
│ │ [avatar] @octocat │ │
│ │ Connected since Jan 12 2026 │ │
│ │ │ │
│ │ [Disconnect GitHub] │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Session │ │
│ │ │ │
│ │ @octocat │ │
│ │ │ │
│ │ [Log out] │ │
│ └──────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
After GitHub disconnect:
│ ┌──────────────────────────────────────────────┐ │
│ │ GitHub Account │ │
│ │ │ │
│ │ [○ gray circle] Not connected │ │
│ │ │ │
│ │ ⚠ Write-back disabled until reconnected. │ │
│ │ │ │
│ │ [Connect GitHub] │ │
│ └──────────────────────────────────────────────┘ │
- Avatar replaced with gray empty circle.
- "Disconnect GitHub" button replaced with "Connect GitHub" link (triggers OAuth flow).
- Inline warning shown in amber text.
5. Page: 404¶
╔══════════════════════════════════════════════════════════════════════╗
║ ║
║ ║
║ 404 ║ ← H1, mono, muted
║ ║
║ This page doesn't exist. ║
║ ║
║ ← Back to dashboard ║ ← link
║ ║
╚══════════════════════════════════════════════════════════════════════╝
"404" rendered in H1 mono-data style at --color-text-muted. "This page doesn't exist." in body style. Link navigates to /dashboard.