{# COLUMN 2 — the project-scoped left column, stacked top → bottom: 1. Agents (active/interactive: pick + configure agents) — FIRST, scrolls 2. Metrics (informational: compact stat block for the project) 3. Active Epic (informational: best-effort epic summary) — BOTTOM Agents data (from /runtime, falling back to /roster) is grouped Interactive (Lead) vs AI Workers server-side (main._group_agents). Metrics + epic are also derived server-side (main._metrics_view / _epic_view); these templates are pure presentation. `selected` : the selected project record (for the scope chip) `selected_key` : project key `agent_groups` : {"interactive": [view, ...], "autonomous": [view, ...]} `agent_count` : total agents `metrics` : {active_tasks, pending_tasks, pending_handoffs, events_24h} `epic` : {mode, epics[], epic_count, label?} — LIVE from GET /epics (main._epic_view). mode='epics' renders the epic stack; 'continuous' renders the 'continuous · no epics' line. Each agent view: name, display_name, initials, role, model, harness, thinking, writer_scope, capabilities[], row_sub, is_test, interactive, cpo_tag, designation_override. Classification is OVERRIDE-FIRST (main._classify_interactive): a console `designation` override ("interactive"/"autonomous", set per agent in the Settings → Configure card) wins; absent that, the registry-derived heuristic (role/capability cpo/lead markers) decides. `cpo_tag` flags an Interactive agent whose effective role reads as lead (renders a small "Lead" tag). #} {# One agent row. The whole row is a button: clicking it swaps the CENTER (#center-region) to this agent's detail view (GET /agents/{key}/{name}) and highlights the row. The col-2 column itself is NOT re-rendered, so the highlight is re-applied client-side (console.html syncAgent) off the swapped center's data-selected-agent marker; we also flip .is-open optimistically on click so the press feels instant. #} {% macro agent_row(a, det) %} {% endmacro %}