diff --git a/docs/wireframes/v2/agents.md b/docs/wireframes/v2/agents.md index f9b94c4..aa9ce43 100644 --- a/docs/wireframes/v2/agents.md +++ b/docs/wireframes/v2/agents.md @@ -13,6 +13,12 @@ | Mode filter | None | Dropdown: All / discuss / plan / detail / execute / verify / etc. | | Search | None | Text input filtering agent name | | Agent card context | Name + status + provider + mode + time only | Added context row: "Task: ..." or "Initiative: ..." with link | +| Agent card actions | Inline in card only | `[...]` dropdown menu (Stop / Dismiss / Delete) in card | +| Status dots | Static colored circles | Animated dots: pulsing (running), static (waiting), hollow (exited) | +| Agent list width | 320px fixed | 360px fixed — accommodates context rows + action menus | +| Output viewer | Basic dark panel | Full terminal: monospace font, ANSI support, auto-scroll, search | +| Output viewer header | Name only | Name + status badge + session count + token/cost counters | +| Exited agents | Disappear when dismissed | Remain with `neutral` styling; dismissal moves to Dismissed filter | | Loading state | 5 skeleton cards (basic) | 5 skeleton cards with shimmer animation | | Error state | AlertCircle + retry (exists) | Same (unchanged) | | Empty (filtered) | "No agents match this filter" | "No matching agents" + `[Clear filters]` link | @@ -23,38 +29,45 @@ ## Default State (with agents) ``` -+=============================================================================+ -| [CW] Initiatives [*Agents*] *3 Inbox (2) Settings [cmd-k] [sun] * | -+=============================================================================+ -| | -| Agents (7) [ Refresh ] | -| [search___________] [All providers v] [All modes v] | -| | -| Agent List 320px | Agent Output | -| -------------------------+-------------------------------------------------| -| +----------------------+ | | -| | * blue-fox-7 [...] | | Session 1 | -| | claude . execute | | > Analyzing codebase structure... | -| | Task: PKCE flow | | > Found 12 files matching pattern | -| | 2m ago | | > Creating src/auth/pkce.ts | -| +----------------------+ | > Writing test file... | -| | | -| +----------------------+ | | -| | - red-elk-3 [...] | | | -| | claude . plan | | | -| | Init: Auth Overhaul | | | -| | 1h ago | | | -| +----------------------+ | | -| | | -| +----------------------+ | | -| | ? green-bear-1 [...] | | | -| | codex . detail | | | -| | Task: DB schema | | | -| | 5m ago | | | -| +----------------------+ | | -+=============================================================================+ ++=====================================================================================+ +| [CW] Initiatives [*Agents*] *3 Inbox (2) Settings [cmd-k] [sun] * myws | ++=====================================================================================+ +| | +| Agents (7) [ Refresh ] | +| [search___________] [All providers v] [All modes v] | +| | +| Agent List 360px | Agent Output | +| ----------------------------+--------------------------------------------------------| +| +---------------------------+ | blue-fox-7 [RUNNING] Session 2 $0.42 12k▼ | +| | (*) blue-fox-7 [...] | | ───────────────────────────────────────────────── | +| | claude . execute | | | +| | Task: PKCE flow | | > Analyzing codebase structure... | +| | 2m ago | | > Found 12 files matching pattern | +| +---------------------------+ | > Creating src/auth/pkce.ts | +| | > Writing test file... | +| +---------------------------+ | | +| | (-) red-elk-3 [...] | | | [Tool Call] Write | +| | claude . plan | | | file_path: src/auth/pkce.ts | +| | Init: Auth Overhaul | | | +| | 1h ago | | | [Result] 42 lines written | +| +---------------------------+ | | +| | | +| +---------------------------+ | [search] [v] | +| | (?) green-bear-1 [...] | | | +| | codex . detail | | (*) Following | auto-scrolling to bottom | +| | Task: DB schema | | | +| | 5m ago | +-----------------------------------------------------+ +| | Answer questions -> | +| +---------------------------+ ++=====================================================================================+ ``` +### Key layout changes from v1 +- **Agent list: 360px** (up from 320px) to accommodate context rows, provider/mode badges, and the `[...]` action menu without truncation. +- **Output viewer header** now shows: agent name, status badge, session number, cumulative cost, and token count with a down-arrow indicator for input tokens. +- **Output viewer footer bar** has terminal search (`[search]`) and scroll-to-bottom (`[v]`). The `(*) Following` indicator replaces the ambiguous Follow/Pause toggle. +- **Status indicators** use `(*)` `(?)` `(-)` in ASCII but render as styled dots (see Status Dot section below). + --- ## Search + Filter Controls @@ -63,11 +76,21 @@ [search___________] [All providers v] [All modes v] ``` +### Filter order rationale + +Search is leftmost because it is the highest-frequency action: you already know +the agent name. Provider second because in a multi-provider setup (5+ accounts +across Claude/Codex/Gemini), narrowing by provider is the next most common +filter. Mode last because it is the most stable dimension (most users run +execute tasks predominantly). + ### Search input - Placeholder: "Search agents..." - Client-side filter on `agent.name` (case-insensitive substring match) +- Also matches task name and initiative name from the context row - Debounced 150ms - Clear button `[x]` appears when non-empty +- Keyboard shortcut: `/` focuses the search input (when no other input is focused) ### Provider filter dropdown `[All providers v]` @@ -75,15 +98,15 @@ [All providers v] +-----------------+ | All | - | claude | - | codex | - | gemini | - | ... | + | claude (4) | + | codex (2) | + | gemini (1) | +-----------------+ ``` Populated dynamically from `listProviderNames` tRPC query. Only shows providers -that have at least one registered account. +that have at least one registered account. Each option shows the count of +currently visible agents for that provider in parentheses. ### Mode filter dropdown `[All modes v]` @@ -91,11 +114,11 @@ that have at least one registered account. [All modes v] +-----------------+ | All | + | execute (3) | + | plan (2) | + | detail (1) | + | verify (1) | | discuss | - | plan | - | detail | - | execute | - | verify | | refine | | research | | merge | @@ -103,7 +126,14 @@ that have at least one registered account. +-----------------+ ``` -Static list of all task category values. +Static list of all task category values. Modes with active agents show counts; +modes with zero agents are dimmed (`text-muted-foreground`) but still selectable. + +### Active filter indicator + +When any filter is non-default, a small `[x Clear]` link appears after the last +dropdown to reset all filters at once. This supplements the per-input clear +button on search. --- @@ -112,101 +142,155 @@ Static list of all task category values. ### Running agent with task context ``` -+------------------------------+ -| * blue-fox-7 [...] | -| claude . execute | -| Task: PKCE flow | <-- clickable link to task/initiative -| 2m ago | -+------------------------------+ ++----------------------------------+ +| (*) blue-fox-7 [...] | +| claude . execute | +| Task: PKCE flow | <-- clickable, navigates to initiative Execution tab +| 2m ago $0.42 12k▼ | <-- cost + input token count ++----------------------------------+ ``` ### Running agent with initiative context (no specific task) ``` -+------------------------------+ -| * blue-fox-7 [...] | -| claude . plan | -| Init: Auth Overhaul | <-- clickable link to initiative -| 2m ago | -+------------------------------+ ++----------------------------------+ +| (*) blue-fox-7 [...] | +| claude . plan | +| Init: Auth Overhaul | <-- clickable, navigates to initiative detail +| 2m ago $0.18 4k▼ | ++----------------------------------+ ``` ### Waiting for input ``` -+------------------------------+ -| ? green-bear-1 [...] | -| codex . detail | -| Task: DB schema | -| 5m ago | -| Answer questions -> | <-- link to /inbox -+------------------------------+ ++----------------------------------+ +| (?) green-bear-1 [...] | +| codex . detail | +| Task: DB schema | +| 5m ago $0.31 8k▼ | +| Answer questions -> | <-- link to /inbox, filtered to this agent ++----------------------------------+ ``` -### Exited +### Exited (completed successfully) ``` -+------------------------------+ -| - red-elk-3 [...] | -| claude . plan | -| Init: Auth Overhaul | -| 1h ago | -+------------------------------+ ++----------------------------------+ +| (v) red-elk-3 [...] | +| claude . plan | +| Init: Auth Overhaul | +| 1h ago $1.24 31k▼ | ++----------------------------------+ ``` +### Exited (crashed) + +``` ++----------------------------------+ +| (!) pink-owl-9 [...] | +| gemini . execute | +| Task: API refactor | +| 3m ago $0.08 2k▼ | ++----------------------------------+ +``` + +### Card layout details + +- Row 1: status dot + agent name (`font-mono text-sm font-medium`) + `[...]` action menu +- Row 2: provider badge (`variant="outline" text-xs`) + dot separator + mode badge (`variant="secondary" text-xs`) +- Row 3: context row (Task/Init link) — see rules below +- Row 4: relative time (`text-xs text-muted-foreground`) left-aligned, cost + tokens right-aligned (`font-mono text-xs text-muted-foreground`) +- Row 5 (conditional): "Answer questions ->" for `waiting_for_input` status + ### Context row rules -- If agent has a `taskId`: show "Task: " linking to the initiative detail (Execution tab) -- Else if agent has an `initiativeId`: show "Init: " linking to the initiative detail -- Else: omit the context row entirely -- Context text: `text-xs text-muted-foreground`, clickable portion gets `hover:underline cursor-pointer` +- If agent has a `taskId`: show "Task: " as a `` to `/initiatives/$initiativeId?tab=execution` +- Else if agent has an `initiativeId`: show "Init: " as a `` to `/initiatives/$initiativeId` +- Else: omit the context row entirely (card is 3 rows instead of 4) +- Context text: `text-xs text-muted-foreground`, clickable portion gets `hover:underline hover:text-foreground cursor-pointer` +- Clicking the context link navigates to the target — it does NOT select the agent card. Use `e.stopPropagation()` on the link click handler. + +### Cost + token display +- Cost: `$X.XX` format, updates live via subscription data (from `session_end` events) +- Tokens: input token count with `▼` suffix (down-arrow = consumed), e.g. `12k▼` +- Both use `font-mono text-xs text-muted-foreground` +- Hidden when agent has no session data yet (first few seconds after spawn) + +### `[...]` Action menu (existing `` component) + +The three-dot menu renders a `` with context-aware items: + +``` + [...] + +-----------------------+ + | Go to Inbox | <-- only for waiting_for_input + | ───────────────── | + | Stop | <-- only for running / waiting_for_input + | ───────────────── | + | Dismiss | <-- only for stopped / crashed / idle (not yet dismissed) + | Delete | <-- destructive, Shift+click skips confirm dialog + +-----------------------+ +``` + +This matches the existing `AgentActions.tsx` implementation. Delete uses +`window.confirm()` with the Shift+click bypass pattern per project conventions. ### Status dot legend -- `*` green/active = `running` -- `?` orange/waiting = `waiting_for_input` -- `-` grey/exited = `stopped`, `crashed`, `idle`, `completed` + +| Dot | Color | Token | Animation | Status | +|-----|-------|-------|-----------|--------| +| `(*)` | Blue | `status-active-dot` | `animate-pulse` (subtle, 2s cycle) | `running` | +| `(?)` | Amber | `status-warning-dot` | None (static) | `waiting_for_input` | +| `(v)` | Green | `status-success-dot` | None (static) | `completed` | +| `(!)` | Red | `status-error-dot` | None (static) | `crashed` | +| `(-)` | Grey | `status-neutral-dot` | None (static) | `stopped`, `idle` | + +The pulsing animation on running agents provides immediate visual scanning — +you can spot which agents are active without reading any text. The pulse uses +`opacity` animation (0.4 to 1.0) rather than `scale` to avoid layout shifts +in the tight card layout. + +Crashed agents get a distinct red dot (not the same grey as stopped/idle). +This was missing in v1 where crashed and stopped were visually identical. --- ## Loading State (5 skeleton cards with shimmer) ``` -+=============================================================================+ -| | -| Agents [ Refresh ] | -| [search___________] [All providers v] [All modes v] | -| | -| Agent List 320px | Agent Output | -| -------------------------+-------------------------------------------------| -| +----------------------+ | | -| | [.] ░░░░░░░░░░░░ | | | -| | ░░░░░ . ░░░░░░ | | | -| | ░░░░░░░░░░░░░ | | | -| +----------------------+ | Select an agent | -| +----------------------+ | to view output | -| | [.] ░░░░░░░░░░░░ | | | -| | ░░░░░ . ░░░░░░ | | | -| | ░░░░░░░░░░░░░ | | | -| +----------------------+ | | -| +----------------------+ | | -| | [.] ░░░░░░░░░░░░ | | | -| | ░░░░░ . ░░░░░░ | | | -| | ░░░░░░░░░░░░░ | | | -| +----------------------+ | | -| +----------------------+ | | -| | [.] ░░░░░░░░░░░░ | | | -| | ░░░░░ . ░░░░░░ | | | -| | ░░░░░░░░░░░░░ | | | -| +----------------------+ | | -| +----------------------+ | | -| | [.] ░░░░░░░░░░░░ | | | -| | ░░░░░ . ░░░░░░ | | | -| | ░░░░░░░░░░░░░ | | | -| +----------------------+ | | -+=============================================================================+ ++=====================================================================================+ +| | +| Agents [ Refresh ] | +| [search___________] [All providers v] [All modes v] | +| | +| Agent List 360px | Agent Output | +| ----------------------------+--------------------------------------------------------| +| +---------------------------+ | | +| | [.] ░░░░░░░░░░░░ | | | +| | ░░░░░ . ░░░░░░ | | | +| | ░░░░░░░░░░░░░ | | | +| | ░░░░ ░░░ ░░░ | | Select an agent | +| +---------------------------+ | to view output | +| +---------------------------+ | | +| | [.] ░░░░░░░░░░░░ | | | +| | ░░░░░ . ░░░░░░ | | | +| | ░░░░░░░░░░░░░ | | | +| | ░░░░ ░░░ ░░░ | | | +| +---------------------------+ | | +| +---------------------------+ | | +| | [.] ░░░░░░░░░░░░ | | | +| | ░░░░░ . ░░░░░░ | | | +| | ░░░░░░░░░░░░░ | | | +| | ░░░░ ░░░ ░░░ | | | +| +---------------------------+ | | ++=====================================================================================+ ``` Skeleton cards mirror card anatomy: status dot placeholder, name line, provider/mode line, -context line. Shimmer animation sweeps left-to-right on a 1.5s loop. +context line, time + cost line. Shimmer animation sweeps left-to-right on a 1.5s loop. + +The output viewer right panel shows the "Select an agent" empty state even during +loading — it does not show its own skeleton. --- @@ -281,9 +365,267 @@ context line. Shimmer animation sweeps left-to-right on a 1.5s loop. --- +## Output Viewer (Terminal Panel) + +The right panel is a **terminal emulator** — it must look and feel like a real +terminal, not a log viewer. This is where operators spend 80% of their time on +this page. + +### Terminal header + +``` ++----------------------------------------------------------------------+ +| blue-fox-7 [RUNNING] Session 2/2 $0.42 12k▼ [Stop] | ++----------------------------------------------------------------------+ +``` + +- Agent name: `font-mono text-sm font-medium text-terminal-fg` +- Status badge: uses status token colors (blue/green/amber/red/grey) +- Session indicator: "Session N/M" where M = total sessions (for resumed agents) +- Cost: cumulative `$X.XX` from all `session_end` events +- Token count: cumulative input tokens with `▼` suffix +- `[Stop]` button: `variant="destructive" size="sm"`, only shown for `running` / `waiting_for_input` + +### Terminal body + +``` ++----------------------------------------------------------------------+ +| bg: --terminal-bg font-mono | +| | +| ── Session 1 ─────────────────────────────────────────────────── | +| [System] Starting task: PKCE flow | +| | +| > I'll examine the existing auth code to understand the current | +| > structure before implementing PKCE. | +| | +| | [Read] src/auth/index.ts | +| | import { Router } from 'express'; | +| | export function setupAuth(app: Application) { ... | +| | +| | [Write] src/auth/pkce.ts | +| | 42 lines written | +| | +| ── Session 2 ─────────────────────────────────────────────────── | +| [System] Resumed — continuing PKCE implementation | +| | +| > Now I'll add the verification endpoint... | +| | ++----------------------------------------------------------------------+ +``` + +### Terminal styling rules + +- **Font**: `font-mono` (Geist Mono) everywhere — no sans-serif text inside the terminal +- **Background**: `bg-terminal` — always dark, even in light mode (terminal aesthetic) +- **Text colors**: use `--terminal-*` tokens from theme.md, NOT raw Tailwind colors +- **Agent text**: `text-terminal-fg` (green-on-dark) +- **Tool calls**: left border `border-terminal-tool` (blue), tool name in `[ToolName]` badge +- **Tool results**: left border `border-terminal-result` (green), collapsible if > 10 lines +- **Errors**: left border `border-terminal-error` (red), `bg-red-900/10` tint +- **System messages**: `text-terminal-system` (dimmed), `[System]` prefix badge +- **Session dividers**: horizontal rule with "Session N" label, `border-terminal-border` +- **Whitespace**: `whitespace-pre-wrap` for agent text, `overflow-x-auto` for tool output + +### Scroll behavior + +- **Auto-scroll**: enabled by default. Terminal auto-scrolls to bottom on each new chunk. +- **User scroll-up**: when user scrolls up more than 50px from bottom, auto-scroll pauses. + A floating `[v Jump to bottom]` button appears at the bottom-right of the terminal. +- **Scroll indicator**: bottom bar shows `(*) Following` (green dot, auto-scrolling active) + or `(-) Paused` (grey dot, user scrolled up). Clicking toggles. +- **Keyboard**: `End` key scrolls to bottom and re-enables auto-follow. + +### Terminal footer bar + +``` ++----------------------------------------------------------------------+ +| (*) Following [Cmd+F search...] [v] | ++----------------------------------------------------------------------+ +``` + +- Left: follow status indicator (clickable toggle) +- Right: output search field + scroll-to-bottom button +- `Cmd+F` / `Ctrl+F` within the terminal panel opens an inline search bar + (NOT the browser's native find — the terminal content is a virtual scroll, + native find would miss off-screen content) +- Search highlights matches in `bg-terminal-selection/20` with the current match + in `bg-terminal-selection/40` +- `Enter` / `Shift+Enter` navigate between matches +- `Esc` closes the search bar + +### No agent selected (empty state) + +``` ++----------------------------------------------------------------------+ +| | +| | +| [Terminal] | +| Select an agent | +| to view its output | +| | +| (or press J/K to | +| navigate the list) | +| | ++----------------------------------------------------------------------+ +``` + +- `[Terminal]` icon: `Terminal` from Lucide, `h-8 w-8 text-terminal-muted` +- Background: `bg-terminal` (dark surface even in light mode) +- Text: `text-terminal-muted` + +--- + +## Keyboard Shortcuts + +| Key | Action | +|-----|--------| +| `J` / `Down` | Select next agent in list (when list is focused) | +| `K` / `Up` | Select previous agent in list | +| `/` | Focus search input | +| `Esc` | Clear search / close terminal search | +| `Cmd+F` | Open terminal output search (when output viewer is focused) | +| `End` | Scroll terminal to bottom, re-enable auto-follow | + +These shortcuts are only active when no text input is focused (except `Cmd+F` +which is always available within the terminal panel). + +--- + +## Agent Lifecycle Visibility + +Agents do NOT disappear from the list when they exit. The existing v1 filter +tabs (All / Running / Questions / Exited / Dismissed) handle lifecycle: + +| Status | Visible in "All" | Visible in filter | Styling | +|--------|-------------------|-------------------|---------| +| `running` | Yes | "Running" | Normal card, pulsing blue dot | +| `waiting_for_input` | Yes | "Questions" | Normal card, amber dot, "Answer questions ->" CTA | +| `completed` | Yes | "Exited" | Slightly dimmed (`opacity-80`), green dot | +| `stopped` | Yes | "Exited" | Slightly dimmed, grey dot | +| `crashed` | Yes | "Exited" | Slightly dimmed, red dot, red left-border accent | +| `idle` | Yes | "Exited" | Slightly dimmed, grey dot | +| Any + `userDismissedAt` | No | "Dismissed" | Full opacity but separated from active view | + +"All" filter excludes dismissed agents (matching current implementation). +Crashed agents get a subtle `border-l-2 border-status-error-dot` left accent +on the card to draw attention without being overbearing. + +--- + ## Source - `packages/web/src/routes/agents.tsx` - `packages/web/src/components/AgentOutputViewer.tsx` - `packages/web/src/components/AgentActions.tsx` - `packages/web/src/components/StatusDot.tsx` +- `packages/web/src/lib/parse-agent-output.ts` + +--- + +## Design Review Notes + +Findings from a design review against the mission-control aesthetic and the +existing implementation in `agents.tsx` / `AgentOutputViewer.tsx`. + +### 1. Agent list width: 320px was too tight (FIXED) + +Bumped to 360px. The original 320px was fine for name + status dot, but the v2 +card now has 4-5 rows: status+name+menu, provider+mode badges, context row, +time+cost. At 320px the `[...]` menu was colliding with the provider badge on +shorter names. 360px gives breathing room without eating too much from the +output viewer. The implementation already uses `lg:grid-cols-[320px_1fr]` — a +single value change. + +### 2. Output viewer was massively underspecified (FIXED) + +The original wireframe showed 4 lines of `> text` and nothing else. For a +screen where operators spend most of their time, that is unacceptable. Added: + +- **Terminal header** with agent name, status badge, session counter, cost, tokens +- **Terminal body** with explicit styling rules referencing `--terminal-*` tokens + from theme.md (the tokens existed but the wireframe never referenced them) +- **Terminal footer** with follow indicator, inline search, scroll-to-bottom +- **Scroll behavior** spec (auto-scroll, pause on scroll-up, 50px threshold) — + the implementation already has this logic but the wireframe didn't document it +- **Session dividers** — the implementation supports multi-session agents but the + wireframe showed only "Session 1" with no visual separator + +### 3. Agent actions were invisible in the wireframe (FIXED) + +The `[...]` three-dot menu existed in the ASCII art but was never documented. +The implementation (`AgentActions.tsx`) has a full dropdown with Stop/Dismiss/Delete +and Go to Inbox. Added explicit documentation of the menu items and their +visibility rules, including the Shift+click bypass pattern for Delete. + +### 4. Status dots were too ambiguous (FIXED) + +`*` `?` `-` as ASCII symbols mapped to 3 states, but the codebase has 5 distinct +agent statuses. The original spec collapsed `completed`, `stopped`, `crashed`, +and `idle` into one grey `-`. That is wrong — a crashed agent demands attention, +a completed agent is a success signal. Now: + +- `running` = pulsing blue dot (animation for scannability) +- `waiting_for_input` = static amber dot +- `completed` = static green dot (success signal) +- `crashed` = static red dot (error signal) +- `stopped` / `idle` = static grey dot + +The existing `StatusDot.tsx` already distinguishes `running` (blue), `crashed` +(red), `stopped` (grey). The wireframe was behind the implementation. + +### 5. Missing cost/token indicators (FIXED) + +For 10+ agents running in parallel, operators need to know which agents are +burning through tokens and which are idle. Added `$X.XX` cost and `Nk▼` token +indicators to both the card (row 4) and the output viewer header. Data comes +from `session_end` parsed messages which already include `meta.cost`. + +### 6. Context row links were not actionable (FIXED) + +The original spec said "clickable link to task/initiative" but didn't specify +the navigation target. Now explicit: Task links go to +`/initiatives/$initiativeId?tab=execution`, Initiative links go to +`/initiatives/$initiativeId`. Also added `e.stopPropagation()` note so clicking +the link doesn't simultaneously select the card. + +### 7. Search only matched agent name (FIXED) + +Searching for "PKCE" should find the agent working on the PKCE task. Extended +search to also match task name and initiative name from the context row. + +### 8. No keyboard navigation (FIXED) + +Mission control = keyboard-first. Added J/K for list navigation, `/` for search +focus, `Cmd+F` for terminal search, `End` for scroll-to-bottom. These match +conventions from tools operators already know (vim, less, tmux). + +### 9. Missing terminal search (FIXED) + +When an agent has been running for 30 minutes and produced 2000 lines of output, +you need to search it. Added `Cmd+F` inline search in the terminal footer with +match highlighting using `--terminal-selection` token. Browser native find +would fail because the terminal should eventually use virtualized scrolling for +performance. + +### 10. Agent lifecycle visibility was unspecified (FIXED) + +The wireframe never addressed what happens to exited agents. The implementation +has a 5-tab filter system (All/Running/Questions/Exited/Dismissed) that the +wireframe completely ignored. Documented the full lifecycle table including +styling differences (dimmed opacity for exited, red accent for crashed). + +### Still not addressed (future work) + +These items were considered but intentionally deferred: + +- **Split-view for comparing two agents' output**: High complexity, low frequency. + Most comparisons happen via task results, not raw output. If needed, operators + can open two browser tabs. Revisit if user feedback demands it. +- **CPU/memory resource indicators**: Requires a monitoring sidecar or proc + polling that doesn't exist in the backend. Token count + cost is the more + relevant resource metric for AI agents. System resource monitoring belongs in + infrastructure tooling, not the orchestrator UI. +- **Agent timeline / Gantt view**: Valuable for post-mortem analysis of parallel + execution. Deferred to v3 as it requires a new visualization component and + historical data aggregation that the current `agent_log_chunks` table doesn't + efficiently support. diff --git a/docs/wireframes/v2/app-layout.md b/docs/wireframes/v2/app-layout.md index 9f47e6e..7bbe8b9 100644 --- a/docs/wireframes/v2/app-layout.md +++ b/docs/wireframes/v2/app-layout.md @@ -22,11 +22,11 @@ ``` +=============================================================================+ -| [CW] Initiatives Agents *3 Inbox (2) Settings [cmd-k] [sun] * | +| [CW] Initiatives Agents [*3] Inbox [2] Settings [⌘K] [sun] * myws | +=============================================================================+ | | | | -| max-w-7xl padded content | +| full-width padded content (px-4 sm:px-6 lg:px-8) | | | | | | | @@ -37,11 +37,16 @@ +=============================================================================+ ``` +Note: `max-w-*` constraints are set per-page, not globally. Pages like Agents +and Initiative Detail use full-width layouts. The Initiatives list and Settings +may opt into `max-w-6xl` or similar. The root layout applies only horizontal +padding. + ## Active Tab Highlighted ``` +=============================================================================+ -| [CW] [*Initiatives*] Agents *3 Inbox (2) Settings [cmd-k] [sun] * | +| [CW] [*Initiatives*] Agents [*3] Inbox [2] Settings [⌘K] [sun] * myws | +=============================================================================+ | | | | @@ -49,13 +54,15 @@ +=============================================================================+ ``` -Active tab gets `bg-muted rounded-md` treatment. Text is bold. +Active tab gets `bg-muted rounded-md` treatment. Text is `font-medium` +(not bold — `font-medium` is 500 weight, sufficient contrast without +the heaviness of `font-bold` at these small sizes). ## Zero Badges (no running agents, no pending conversations) ``` +=============================================================================+ -| [CW] Initiatives Agents Inbox Settings [cmd-k] [sun] * | +| [CW] Initiatives Agents Inbox Settings [⌘K] [sun] * myws | +=============================================================================+ | | | | @@ -63,7 +70,7 @@ Active tab gets `bg-muted rounded-md` treatment. Text is bold. +=============================================================================+ ``` -Badges are completely hidden when count is 0 — no empty `()` or `*0`. +Badges are completely hidden when count is 0 — no empty brackets or `*0`. ## Health Dot States @@ -73,18 +80,143 @@ Badges are completely hidden when count is 0 — no empty `()` or `*0`. - ← red: WebSocket disconnected or server unreachable ``` -Tooltip on hover shows details: +The dot uses `status-success-dot`, `status-warning-dot`, or `status-error-dot` +tokens from the theme. The green state gets a subtle `animate-pulse` removed +after 3s of stable connection to avoid distraction. + +### Tooltip on hover + +Rich tooltip (not just `title` attr) with structured content: + ``` - * Connected (42ms) - ? Slow response (2.3s) - - Disconnected — retrying... ++-------------------------------+ +| ● Connected | +| Latency: 42ms | +| Uptime: 2h 14m | +| Last heartbeat: <1s ago | ++-------------------------------+ + ++-------------------------------+ +| ◐ Degraded | +| Latency: 2,340ms | +| Last heartbeat: 8s ago | +| Server may be under load | ++-------------------------------+ + ++-------------------------------+ +| ○ Disconnected | +| Lost connection 12s ago | +| Retrying... (attempt 3) | ++-------------------------------+ ``` +- Uses shadcn `` with `` +- Tooltip content is `text-xs font-mono` for data readability +- Status label uses matching status token color + +## Connection Banner + +When the WebSocket disconnects, a full-width banner slides down between the +header and page content. This is more aggressive than the dot alone — the dot +is for glanceable status, the banner is for "you need to know this NOW." + +### Reconnecting + +``` ++=============================================================================+ +| [CW] Initiatives Agents [*3] Inbox [2] Settings [⌘K] [sun] - myws | ++=============================================================================+ +| [spinner] Reconnecting to server... [Dismiss] | ++=============================================================================+ +| | +| | ++=============================================================================+ +``` + +- `bg-status-warning-bg border-b border-status-warning-border` +- Text: `text-status-warning-fg text-sm` +- Spinner: 14px animated, same as SaveIndicator +- Dismiss hides the banner but the health dot stays red/yellow + +### Offline (> 30s disconnected) + +``` ++=============================================================================+ +| [CW] Initiatives Agents [*3] Inbox [2] Settings [⌘K] [sun] - myws | ++=============================================================================+ +| [!] Server unreachable — data may be stale [Retry] [Dismiss] | ++=============================================================================+ +| | +| | ++=============================================================================+ +``` + +- `bg-status-error-bg border-b border-status-error-border` +- Text: `text-status-error-fg text-sm` +- Retry button: `text-status-error-fg underline font-medium` + +### Reconnected (success, auto-dismisses) + +``` ++=============================================================================+ +| [CW] Initiatives Agents [*3] Inbox [2] Settings [⌘K] [sun] * myws | ++=============================================================================+ +| [v] Reconnected | ++=============================================================================+ +``` + +- `bg-status-success-bg text-status-success-fg text-sm` +- Auto-dismisses after 3s with fade-out + +### Timing + +| Duration disconnected | Behavior | +|----------------------|----------| +| 0-3s | No banner (brief blips are silent, dot goes yellow) | +| 3-30s | "Reconnecting..." banner | +| >30s | "Server unreachable" banner with Retry | +| On reconnect | "Reconnected" for 3s, then dismiss | + +--- + +## Notification Indicators + +Important events must surface even when the user is on a different tab. +Three mechanisms work together: + +### 1. Tab badges (already specified above) + +`Agents [*3]` and `Inbox [2]` update in real-time via tRPC subscriptions. + +### 2. Toast notifications (sonner) + +Critical events fire a toast regardless of current page: + +| Event | Toast | Duration | +|-------|-------|----------| +| Agent crashed | `"blue-fox-7 crashed"` + link to Agents | Persistent (manual dismiss) | +| Task needs approval | `"Task ready for approval"` + link | Persistent | +| All tasks complete | `"Initiative complete — ready for review"` | 8s auto-dismiss | +| Account exhausted | `"Account X exhausted, switched to Y"` | 5s auto-dismiss | +| Agent asking question | `"blue-fox-7 has a question"` + link to Inbox | 8s auto-dismiss | + +Persistent toasts stack in bottom-right. Max 3 visible; older ones collapse +into a "+N more" indicator. + +### 3. Browser tab title + +When the app is backgrounded and events occur: +- `(2) Codewalk District` — number prefix for unread attention items +- Counts: crashed agents + pending approvals + unanswered inbox items +- Resets to `Codewalk District` when user returns to the tab + +--- + ## Collapsed Mobile View (not yet implemented) ``` +=============================================================================+ -| [CW] [cmd-k] [sun] * [☰] | +| [CW] [⌘K] [sun] * [☰ 2] | +=============================================================================+ | | | | @@ -94,12 +226,14 @@ Tooltip on hover shows details: Note: Mobile hamburger menu is not implemented. This is a placeholder for future work. At `< 768px`, nav tabs collapse into a hamburger `[☰]` dropdown. +The hamburger icon shows a combined badge count (crashed agents + unread inbox) +so that attention items are never hidden behind the collapsed menu. ## 404 Page ``` +=============================================================================+ -| [CW] Initiatives Agents Inbox Settings [cmd-k] [sun] * | +| [CW] Initiatives Agents Inbox Settings [⌘K] [sun] * myws | +=============================================================================+ | | | | @@ -116,13 +250,22 @@ future work. At `< 768px`, nav tabs collapse into a hamburger `[☰]` dropdown. ## 48px Header Anatomy +48px is tight. This works because: +- Logo is icon-only (24px, no wordmark) +- Nav tabs use `px-3 py-1.5` (compact hit targets, 36px tall inside 48px) +- Badges are inline pills, not separate elements +- Right cluster items are icon-sized (no text labels except ⌘K) + +If this still feels cramped at certain content widths, the Cmd+K button +drops its text label at `< 1024px` (see Responsive Notes below). + ``` +-----------------------------------------------------------------------------+ -| LEFT CLUSTER SPACER RIGHT CLUSTER | -| [CW] [Nav] [Nav *N] [Nav (N)] [Nav] -------- [cmd-k] [◐] [●] | +| LEFT CLUSTER SPACER RIGHT CLUSTER | +| [CW] [Nav] [Nav [N]] [Nav [N]] [Nav] ------- [⌘K] [◐] [●] [workspace] | +-----------------------------------------------------------------------------+ - ↑ ↑ ↑ ↑ - 16px icon Cmd+K btn Theme Health + ↑ ↑ ↑ ↑ ↑ + 24px icon Cmd+K Theme Health Workspace ``` ### Left cluster (nav) @@ -131,41 +274,118 @@ future work. At `< 768px`, nav tabs collapse into a hamburger `[☰]` dropdown. - Each tab is an `` with `gap-1.5` between label and optional badge - Active tab: `bg-muted text-foreground font-medium rounded-md px-3 py-1.5` - Inactive tab: `text-muted-foreground hover:text-foreground px-3 py-1.5` +- Keyboard: `1` / `2` / `3` / `4` navigate to tabs (when no input is focused) -### Badge rendering -- `Agents *N` — small filled circle + count, only when N > 0, green tint -- `Inbox (N)` — parenthetical count, only when N > 0, yellow tint for unresolved +### Badge rendering — unified `` component + +Both tabs use the same badge component for visual consistency: + +```tsx +// Unified pill badge: inline, compact, color-coded + + {count} + +``` + +| Tab | Badge color | Example | Semantics | +|-----|-------------|---------|-----------| +| Agents | `bg-status-active-bg text-status-active-fg` (blue) | `Agents [3]` | Running agent count | +| Inbox | `bg-status-warning-bg text-status-warning-fg` (amber) | `Inbox [2]` | Unresolved conversation count | + +Both badges: +- Hidden entirely when count is 0 +- Use `tabular-nums` so width doesn't shift when count changes (e.g., 9 -> 10) +- Pill shape: `rounded-full` with tight `px-1.5 py-0.5` +- Font: `text-[10px]` — small enough to not compete with the tab label + +**Attention escalation**: When an agent has crashed or a task needs approval, +the Agents badge switches to `bg-status-error-bg text-status-error-fg` (red) +to draw the eye. The count reflects crashed + running agents in this state. ### Right cluster (utilities) -- `[cmd-k]` — `Cmd+K` on Mac, `Ctrl+K` on Windows. Shows shortcut text as label. +- `[⌘K]` — Shows platform-aware shortcut hint as label: `⌘K` on Mac, + `Ctrl+K` on Windows/Linux. Rendered as a `` style pill: + `bg-muted text-muted-foreground text-xs font-mono px-2 py-1 rounded-md border border-border`. Clicking opens the CommandPalette overlay (see shared-components.md). - `[◐]` — ThemeToggle, 3-state segmented control (see shared-components.md) -- `[●]` — Health status dot, 8px circle with color +- `[●]` — Health status dot, 8px circle with color (see Health Dot States above) +- `[workspace]` — Workspace name, derived from `.cwrc` or directory basename. + `text-xs text-muted-foreground font-mono truncate max-w-[120px]`. + Tooltip shows full path on hover: `/Users/me/projects/my-app`. + Hidden at `< 1024px` to save space. + +### Workspace identity + +The workspace label solves a real problem: developers often run multiple +Codewalk instances for different projects. Without it, you can't tell which +instance you're looking at without checking the terminal. + +``` + Right cluster detail: + [⌘K] [sun|monitor|moon] ● codewalk-district + ^^^^^^^^^^^^^^^^^^ + text-xs font-mono text-muted-foreground + truncated at 120px, full path in tooltip +``` ### Spacing - Left cluster: `gap-1` between items - Between clusters: `flex-1` spacer pushes them apart -- Right cluster: `gap-3` between items +- Right cluster: `gap-2` between items (tightened from `gap-3` — the + workspace label needs room) --- ## Responsive Notes -| Breakpoint | Behavior | -|------------|----------| -| `>= 1024px` | Full header as shown | -| `768px - 1023px` | Cmd+K label shortens to icon only `[search]` | -| `< 768px` | Nav tabs collapse into hamburger (future) | +| Breakpoint | Header | Content | +|------------|--------|---------| +| `>= 1280px` | Full header as shown, workspace label visible | Page decides own `max-w-*` | +| `1024px - 1279px` | Workspace label hidden, ⌘K shows icon-only `[search]` | Page decides own `max-w-*` | +| `768px - 1023px` | Same as above, tab labels may truncate | Horizontal padding reduces | +| `< 768px` | Nav tabs collapse into hamburger (future) | Single-column, `px-4` | -Content area is always `max-w-7xl mx-auto px-4 sm:px-6 lg:px-8`. +Content area uses `px-4 sm:px-6 lg:px-8` horizontal padding only. There is +**no global** `max-w-7xl`. Each page sets its own max-width constraint (or +uses none for full-bleed layouts like the Agents split-pane view). + +### Per-page width strategy + +| Page | Width constraint | Rationale | +|------|-----------------|-----------| +| Initiatives list | `max-w-6xl mx-auto` | Card grid, doesn't benefit from extreme width | +| Initiative detail | Full width | Tab content (execution, agents) needs room | +| Agents | Full width | Split-pane: agent list + output viewer | +| Inbox | Full width | Split-pane: conversation list + detail | +| Settings | `max-w-4xl mx-auto` | Forms, narrow content | --- ## Global Components (rendered in root layout) -- `` (sonner) — bottom-right toast notifications +- `` (sonner) — bottom-right toast notifications, max 3 visible - `` — wraps the page outlet - `` — overlay, triggered by Cmd+K or header button +- `` — slides between header and content on disconnect +- `` — invisible, manages `document.title` with unread counts + +--- + +## Keyboard Shortcuts (global) + +These are registered at the root layout level, suppressed when an input/textarea +is focused: + +| Shortcut | Action | +|----------|--------| +| `⌘K` / `Ctrl+K` | Open command palette | +| `1` | Navigate to Initiatives | +| `2` | Navigate to Agents | +| `3` | Navigate to Inbox | +| `4` | Navigate to Settings | +| `?` | Show keyboard shortcut help overlay (future) | --- @@ -176,3 +396,92 @@ Content area is always `max-w-7xl mx-auto px-4 sm:px-6 lg:px-8`. - `packages/web/src/components/ThemeToggle.tsx` (proposed) - `packages/web/src/components/CommandPalette.tsx` (proposed) - `packages/web/src/components/HealthDot.tsx` (proposed) +- `packages/web/src/components/ConnectionBanner.tsx` (proposed) +- `packages/web/src/components/NavBadge.tsx` (proposed) +- `packages/web/src/hooks/useWorkspaceName.ts` (proposed) +- `packages/web/src/hooks/useBrowserTitle.ts` (proposed) + +--- + +## Design Review Notes + +Reviewed against MISSION CONTROL criteria (dense, status-at-a-glance, +keyboard-first, dark-mode-first). Changes applied inline above. + +### 1. 48px header — is it cramped? + +48px is fine IF the content is disciplined: icon-only logo, no wordmark, compact +tab padding, and small inline badges. Added an explicit note to the Header +Anatomy section explaining why 48px works and where the escape hatch is +(responsive breakpoints drop ⌘K text and workspace label). The real risk is +not height but **horizontal** crowding when all badges are showing and the +workspace name is long. The `truncate max-w-[120px]` on the workspace label +and responsive hiding address this. + +### 2. Badge inconsistency (`*N` vs `(N)`) + +This was a real problem. The v1 spec used `*N` for Agents and `(N)` for Inbox, +two completely different visual languages for the same concept (a count badge +on a nav tab). Unified both into a `` component — a colored pill +with just the number. Color differentiates meaning (blue=active, amber=pending), +not punctuation. Added `tabular-nums` to prevent layout shift on count changes. + +### 3. Health dot — too subtle? + +The dot alone was easy to miss, yes. But the right fix is NOT making the dot +bigger — it is adding a **second tier of communication**. The dot stays as a +glanceable ambient indicator (like a server rack LED). The new ConnectionBanner +handles the "you need to stop and pay attention" case. Added a rich tooltip +with latency, uptime, and heartbeat data for the "I want details" case. Three +tiers: dot (ambient) -> tooltip (on-demand) -> banner (urgent). + +### 4. Connection banner — missing + +Added full spec: Reconnecting (3-30s), Offline (>30s), Reconnected (success). +The 3s delay before showing the banner prevents flicker on brief WebSocket +reconnections. The banner is dismissible but the dot stays colored. See +"Connection Banner" section above. + +### 5. Workspace identity — missing + +Added workspace name to the right cluster. Derived from `.cwrc` config or +directory basename. This is essential for multi-instance users. Hidden below +1024px because it is useful but not critical — the browser tab title or terminal +provides fallback identification. + +### 6. Cmd+K shortcut hint + +Changed from `[cmd-k]` text to a ``-styled `[⌘K]` pill showing the +actual platform shortcut. This doubles as both a clickable trigger and a +discoverability hint. Users see the shortcut every time they glance at the +header, which builds muscle memory. On Windows/Linux it renders as `Ctrl+K`. + +### 7. Notification system — missing + +This was the biggest gap. Added three tiers: +- **Tab badges**: real-time counts (already existed, now specified with attention escalation) +- **Toast notifications**: critical events fire toasts regardless of current page. + Persistent for crashes/approvals, auto-dismiss for informational events. +- **Browser tab title**: `(2) Codewalk District` prefix when backgrounded with + unread attention items. Standard web app pattern. + +The attention escalation on the Agents badge (blue -> red when something crashes) +is important — it means you do not need to be on the Agents page to know +something went wrong. + +### 8. `max-w-7xl` constraint — wrong default + +Removed. A mission control tool should default to full-width and let pages +opt into narrower layouts. The split-pane views (Agents, Inbox) and the +Initiative Detail tabs lose significant usable space under `max-w-7xl` (1280px). +Replaced with per-page width strategy: forms/lists get `max-w-4xl`/`max-w-6xl`, +operational views get full width. The root layout only applies horizontal padding. + +### Open questions for next review + +- **Favicon badge**: Should the browser favicon show a red dot for attention + items, like Slack does? More noticeable than title prefix alone. +- **Sound**: Should critical events (agent crash) play a subtle notification + sound? Power users managing 10+ agents may not be watching the screen. +- **Keyboard shortcut overlay**: `?` to show all shortcuts is specced as + "future" — should it be in v2 scope given the keyboard-first stance? diff --git a/docs/wireframes/v2/content-tab.md b/docs/wireframes/v2/content-tab.md index 8ee27b4..3c296d1 100644 --- a/docs/wireframes/v2/content-tab.md +++ b/docs/wireframes/v2/content-tab.md @@ -10,64 +10,104 @@ | Aspect | v1 | v2 | |--------|----|----| | Breadcrumbs | None | `Root > Parent > Current` row above title, clickable | +| Deep breadcrumbs | N/A | Ellipsis collapse with dropdown: `Root > [...] > Parent > Current` | | Save indicator | Bare "Saving..." text, top-right, no success/fail states | `` component: spinner, checkmark (fade), error + retry | | Empty root page | Blank editor, no guidance | Tiptap placeholder: "Start writing... use / for commands" | | Root page creation | Only via tree context menu hover `[+]` on nodes | Additional `[+]` button in sidebar header for root-level pages | -| Deep breadcrumbs | N/A | Ellipsis collapse: `Root > ... > Parent > Current` | +| Sidebar width | 192px (`w-48`) | 240px (`w-60`) — accommodates deep nesting + truncation | +| Page tree search | None | Collapsible filter input in sidebar header | +| Drag-and-drop | None | Reorder + re-parent via dnd-kit | +| Keyboard nav (tree) | None | Arrow keys, Enter, Home/End | +| Refine panel layout | Above editor (banner) | Right column (360px) at >= 1280px viewport | +| Refine panel detail | Minimal (spinner + text) | Full state machine: idle, running (live output), questions, proposals, crashed | +| Read-only lockout | None | Visual indicator when agent is actively refining | +| Word count | None | Bottom-right of editor area | +| Slash command menu | Functional but not documented | Wireframed floating popover with all command options | --- ## Default State (with content) ``` -+=============================================================================+ -| Pages [+] | Root > Architecture > Current Page | -| --------------------------+ [✓] Saved | -| ├── Architecture | ------------------------------------------------| -| │ ├── Overview | | -| │ └── Decisions | # Authentication Architecture | -| ├── Requirements | | -| └── API Design | This document outlines the OAuth 2.0 | -| | implementation strategy for... | -| | | -| 192px | editor area (flex-1) | -| | | -+=============================================================================+ ++=================================================================================+ +| Pages [+] | Root > Architecture > Current Page | +| --------------------------+ [✓] Saved | +| ├── Architecture | ----------------------------------------------------| +| │ ├── Overview | | +| │ └── Decisions | # Authentication Architecture | +| ├── Requirements | | +| └── API Design | This document outlines the OAuth 2.0 | +| | implementation strategy for... | +| | | +| | ~1,240 words · 5m | +| 240px | editor area (flex-1) | +| | | ++=================================================================================+ ``` - `[+]` in sidebar header creates a new root-level child page - Breadcrumb segments are clickable links that call `onNavigate(pageId)` - `[✓] Saved` indicator fades after 2s via CSS opacity transition - Tree nodes still show hover `[+]` for nested child creation (unchanged from v1) +- Word count + reading time displayed bottom-right of editor, `text-xs text-muted-foreground` --- ## Empty Root Page (placeholder) ``` -+=============================================================================+ -| Pages [+] | Root | -| --------------------------+ | -| (empty tree) | ------------------------------------------------| -| | | -| | My Initiative Name | -| | ^^^^^^^^^^^^^^^^^^^^^^ | -| | 3xl bold title input | -| | | -| | Start writing... use / for commands | -| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -| | muted placeholder text (text-muted-foreground) | -| | | -| | | -| 192px | editor area (flex-1) | -| | | -+=============================================================================+ ++=================================================================================+ +| Pages [+] | Root | +| --------------------------+ | +| (empty tree) | ----------------------------------------------------| +| | | +| | My Initiative Name | +| | ^^^^^^^^^^^^^^^^^^^^^^ | +| | 3xl bold title input | +| | | +| | Start writing... use / for commands | +| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +| | muted placeholder text (text-muted-foreground) | +| | | +| | | +| 240px | editor area (flex-1) | +| | | ++=================================================================================+ ``` - Placeholder uses `@tiptap/extension-placeholder` with `emptyEditorClass` - Placeholder text disappears on focus/first keystroke - Root page title maps to `initiativeName` (edits update initiative, not page) +### Slash Command Menu Preview + +When user types `/` at the start of a line (or after a space), the command menu +appears as a floating popover anchored to the cursor position: + +``` +| | +| /___ | +| +--------------------------------------+ | +| | [H1] Heading 1 | <- highlighted +| | [H2] Heading 2 | +| | [H3] Heading 3 | +| | [¶] Bullet List | +| | [#] Numbered List | +| | ["] Blockquote | +| | [—] Divider | +| | [<>] Code Block | +| | [+] Subpage | <- creates child + inserts link +| +--------------------------------------+ | +| surface: popover, shadow-md, max-h-64 scroll | +``` + +- Appears on `/` keystroke; filters as user types (e.g., `/head` shows only headings) +- `Arrow Up` / `Arrow Down` to navigate; `Enter` to select; `Esc` to dismiss +- Each item: icon (16px, `text-muted-foreground`) + label (`text-sm`) +- Popover: `bg-popover border border-border rounded-md shadow-md` +- Max height: `max-h-64 overflow-y-auto` with scroll +- Highlighted item: `bg-accent text-accent-foreground` + --- ## Save Indicator States @@ -108,24 +148,182 @@ Three-state component positioned top-right of editor area, inline with breadcrum ## With Refine Panel Open (3-column layout) ``` -+=============================================================================+ -| Pages [+] | Root > Current Page [✓] Saved | Refine with Agent | -| ---------------+ | | -| ├── Arch | # Auth Architecture | [spinner] Architect | -| │ ├── Ovw | | is refining... | -| │ └── Dec | This document outlines the | | -| ├── Req | OAuth 2.0 implementation... | | -| └── API | | | -| | | | -| 192px | editor (flex-1) | 320px | -| | | | -+=============================================================================+ ++=================================================================================+ +| Pages [+] | Root > Current Page [✓] Saved | Refine with Agent | +| ---------------+ | ----------------------| +| ├── Arch | # Auth Architecture | [spinner] Architect | +| │ ├── Ovw | | is refining... | +| │ └── Dec | This document outlines the | | +| ├── Req | OAuth 2.0 implementation... | (see panel detail | +| └── API | | below) | +| | | | +| 240px | editor (flex-1) | 360px | +| | | | ++=================================================================================+ ``` - Refine panel sits above editor in v1 source (not beside it) - v2 proposal: move to right column when viewport >= 1280px - Below 1280px, refine panel stays above editor (current v1 behavior) -- Panel width: 320px fixed, editor remains `flex-1` +- Panel width: **360px** fixed (`w-[360px]`), editor remains `flex-1` +- **Save indicator placement**: in the 3-column layout, the save indicator stays + inline with the breadcrumb row, right-aligned within the editor column (middle + column). It does NOT extend into the refine panel column. The breadcrumb row is + `flex justify-between` within the editor column only. + +--- + +## Refine Panel — Internal Layout + +The refine panel is a right-side column with its own state machine. The wireframe +must show all states, since this is where the agent-human interaction happens. + +### State: Idle (no active agent) + +``` ++-----------------------------------+ +| Refine with Agent | +| ---------------------------------| +| | +| [sparkle icon] | +| An agent will review all pages | +| and suggest improvements. | +| | +| What should it focus on? | +| +-------------------------------+| +| | (optional instruction) || +| +-------------------------------+| +| | +| [ Start Refine ] | +| | ++-----------------------------------+ +``` + +- Panel header: `text-sm font-semibold`, top-left +- CTA button: `