Files
nisse/nisse-ui/src/nisse_ui/templates/overview.html
T
dongarandClaude Opus 5.5 d02f8c1fbb
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 2m35s
CI / e2e (pull_request) Successful in 4m6s
The status page's overview (M6.6c)
The home page now shows, per agent: the run under way (or idle since
when, and runs a crash may have left open), the active item, nisse-dev's
queue in its own order with items on a blocked build VM held out, parked
items with their wait and note, blocked items and VM blocks, review PRs
by position, and the last ten closed. Kept benchmark runs follow.

Item data is read tolerantly (nisse-dev's own parser refuses unknown
fields); contract tests write items with the agents' own code. Links to
issues, PRs and threads come from --config NAME=YAML, reading only the
Gitea address, the Matrix room and each project's repo and build VM.
The page reloads every minute by meta refresh; ?refresh=0 stops it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
2026-10-26 04:45:38 +00:00

104 lines
5.2 KiB
HTML

{% extends "base.html" %}
{% from "macros.html" import src_link, item_href %}
{% block title %}Overview{% endblock %}
{% block head %}{% if refresh %}<meta http-equiv="refresh" content="{{ refresh }}">{% endif %}{% endblock %}
{% macro links(source, row) %}{% for l in row.links %}{% if l.href %}<a class="out" href="{{ l.href }}" rel="noreferrer">{{ l.text }}</a>{% else %}<span class="out">{{ l.text }}</span>{% endif %}{% endfor %}{% endmacro %}
{% macro item_row(source, row) %}
<tr{% if row.held %} class="held"{% endif %}>
<td><a href="{{ item_href(source, row.item.id) }}">{{ row.item.title or row.item.id }}</a><div class="muted path">{{ row.item.id }}</div></td>
<td>{% if row.mark %}<span class="tag{% if row.held %} warn{% endif %}">{{ row.mark }}</span> {% endif %}{{ row.what }}
{% for d in row.details %}<div class="why">{{ d|clip(300) }}</div>{% endfor %}</td>
<td>{{ links(source, row) }}</td>
<td title="{{ row.item.updated_at|when }}">{{ row.item.updated_at|ago }}</td>
</tr>
{% endmacro %}
{% block main %}
<h1>Overview</h1>
<p class="meta">As of {{ now.isoformat()|when }} UTC.
{% if refresh %}Reloads every {{ refresh }} s · <a href="/?refresh=0">stop reloading</a>{% else %}Not reloading · <a href="/">reload every minute</a>{% endif %}</p>
{% if not agents and not rows %}<p class="muted">No sources. Start with <code>--source NAME=STATE_DB</code> or <code>--runs DIR</code>.</p>{% endif %}
{% for a in agents %}
<section class="agent" id="agent-{{ a.source.name }}">
<h2>{{ src_link(a.source) }}{% if a.kind %} <span class="tag">{{ "nisse-dev" if a.kind == "dev" else "nisse-review" }}</span>{% endif %}</h2>
{% if a.problem %}
<p class="bad">Couldn't read its store: {{ a.problem }}</p>
{% else %}
<div class="now">
{% for r in a.running %}
<p class="running"><span class="tag">running</span> {{ r.run.kind }} · {{ r.run.role }}
{% if r.run.work_item %} on <a href="{{ item_href(a.source, r.run.work_item) }}">{{ r.run.work_item }}</a>{% else %} (agent level){% endif %}
· {{ r.turns }} turn{{ "" if r.turns == 1 else "s" }} · since {{ r.run.started_at|when }}
{% if r.last_call %} · <a href="/s/{{ a.source.name|u }}/call/{{ r.last_call }}">latest turn</a> {{ r.last_at|ago }}{% endif %}</p>
{% endfor %}
{% if not a.running %}<p>Idle{% if a.last_activity %} since {{ a.last_activity|when }} ({{ a.last_activity|ago }}){% endif %}.</p>{% endif %}
{% for r in a.interrupted %}
<p class="muted"><span class="tag warn">maybe interrupted</span> {{ r.run.kind }} · {{ r.run.role }}
{% if r.run.work_item %} on <a href="{{ item_href(a.source, r.run.work_item) }}">{{ r.run.work_item }}</a>{% endif %}
· never ended; last heard {{ r.last_at|when }} ({{ r.last_at|ago }})</p>
{% endfor %}
{% if a.record_note %}<p class="muted">{{ a.record_note }}</p>{% endif %}
{% if a.active %}<p>Active item: <a href="{{ item_href(a.source, a.active.item.id) }}">{{ a.active.item.title or a.active.item.id }}</a> · {{ a.active.what }}</p>{% endif %}
</div>
{% if a.blocks %}
<h3>Blocked build VMs</h3>
<table>
<thead><tr><th>VM</th><th>Why</th><th>Found by</th><th>Since</th></tr></thead>
<tbody>
{% for b in a.blocks %}
<tr class="held"><td class="path">{{ b.host }}</td><td><span class="tag warn">{{ b.cause }}</span> {{ b.reason|clip(300) }}</td>
<td>{% if b.work_item %}<a href="{{ item_href(a.source, b.work_item) }}">{{ b.work_item }}</a>{% endif %}</td>
<td title="{{ b.since|when }}">{{ b.since|ago }}</td></tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% for g in a.groups if g.rows %}
<h3>{{ g.title }} <span class="muted">({{ g.rows|length }})</span></h3>
<table class="items">
<thead><tr><th>Item</th><th>Where, and why</th><th>Links</th><th>Changed</th></tr></thead>
<tbody>{% for row in g.rows %}{{ item_row(a.source, row) }}{% endfor %}</tbody>
</table>
{% endfor %}
{% if not a.groups|selectattr("rows")|list %}<p class="muted">No open work items.</p>{% endif %}
{% if a.closed %}
<details class="closed">
<summary>Recently closed ({{ a.closed|length }})</summary>
<table class="items">
<thead><tr><th>Item</th><th>Outcome</th><th>Links</th><th>Closed</th></tr></thead>
<tbody>
{% for row in a.closed %}
<tr><td><a href="{{ item_href(a.source, row.item.id) }}">{{ row.item.title or row.item.id }}</a></td>
<td>{{ row.what }}</td><td>{{ links(a.source, row) }}</td>
<td title="{{ (row.item.closed_at or row.item.updated_at)|when }}">{{ (row.item.closed_at or row.item.updated_at)|ago }}</td></tr>
{% endfor %}
</tbody>
</table>
</details>
{% endif %}
<p class="meta"><a href="/s/{{ a.source.name|u }}/">All its work items</a> · <a href="{{ item_href(a.source, none) }}">agent-level log</a></p>
{% endif %}
</section>
{% endfor %}
{% if rows %}
<h2>Recorded runs</h2>
<table>
<thead><tr><th>Run</th><th>Work items</th><th>Call record</th><th>State store</th></tr></thead>
<tbody>
{% for r in rows %}
<tr>
<td>{{ src_link(r.source) }}</td>
<td>{% if r.count is not none %}{{ r.count }}{% else %}<span class="bad">{{ r.note }}</span>{% endif %}</td>
<td>{{ "yes" if r.record else "none" }}</td>
<td class="path">{{ r.source.state_db }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %}