{# 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 %}
{# ============ 1 · AGENTS (top, unchanged) — pick + configure agents ============ #} {# ============ 2 · METRICS (informational) — compact stat block ============ #} {# Moved here from the center vitals strip. Sized for a narrow column: small chips, not the big center cards. Numbers are derived server-side (main._metrics_view): active/pending handoffs + events/24h off /state, pending tasks off /board. A None counter shows '—'. #}
Metrics {% if selected_key %}{{ selected_key }}{% endif %} {# Drill-in link → swaps the CENTER to this project's detail view (full open handoffs + tasks lists). The Metrics block shows the counts; this opens the lists. Only rendered when a project is scoped. #} {% if selected_key %} {% endif %}
{{ metrics.active_tasks if metrics.active_tasks is not none else "—" }} Active tasks
{{ metrics.pending_tasks if metrics.pending_tasks is not none else "—" }} Pending tasks
{{ metrics.pending_handoffs if metrics.pending_handoffs is not none else "—" }} Pending handoffs
{{ metrics.events_24h if metrics.events_24h is not none else "—" }} Events · 24h
{# ============ 3 · ACTIVE EPIC (informational, bottom) ============ #} {# LIVE epic data from GET /epics (shaped server-side in main._epic_view — templates do no logic). mode='epics' → a compact stack of the project's epic(s), active/build epic FIRST: each shows epic_id · title · overall % bar · per-increment mini-bars (done=green / prog=teal / todo=empty). mode='continuous' → the 'continuous · no epics' line (continuous-backlog projects like Marketing/BPA, projects with no epics, OR a graceful-degrade when /epics is unreachable — never fabricated progress). `epic` = {mode, epics:[{epic_id,title,status,overall_pct,increments:[{label, pct,status,kind}],is_active,increment_count}], epic_count, label?} #}
Active Epic {% if epic.mode == 'epics' %} {{ epic.epic_count }} {% else %} continuous {% endif %}
{% if epic.mode == 'epics' %}
{% for e in epic.epics %}
{{ e.epic_id }} {{ e.title }} {{ e.overall_pct }}%
{% if e.increments %}
{% for inc in e.increments %} {% endfor %}
{% endif %}
{% endfor %}
{% else %}
{{ epic.label }}
{% endif %}
{# /.col2 #}