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
nisse-ui
The status page (architecture X6): a read-only view of what the agents did and how, for studying context, compaction and memory in practice.
It reads each agent's state store and the call record beside it (L7), and never writes to either. It runs no model and holds no credentials.
uv run nisse-ui --source dev=/var/lib/nisse-dev/state.db \
--source review=/var/lib/nisse-review/state.db \
--runs /path/to/kept-runs
--source NAME=STATE_DB: an agent's state store. Its call record is<stem>.calls.dbbeside it.--runs DIR: runs the benchmark kept (scripts/benchmark.py run --keep-runs DIR). Each folder holding astate.dbis a source.
It listens on 127.0.0.1:8765, because it shows everything the models saw, including what other people wrote. Until it sits behind Caddy and Authelia (M6.6d), reach it through an SSH tunnel:
ssh -L 8765:localhost:8765 <this VM>
then open http://localhost:8765/.
What it shows: for each work item, its steps (what people and the orchestrator said, and each run), each run's turns, and for each turn:
- the request exactly as sent, message by message, beside the log events each came from and what rendering did to them;
- what changed since the turn before, and where prompt reuse had to stop, next to the server's own count;
- the reply, with its reasoning;
- the raw JSON.
Runs going in circles are flagged (nisse_core.loop.circles).
Safety: everything is escaped, and the page sends a Content Security
Policy that runs no script at all. Files are opened through
nisse_core.state.readonly, which never creates or locks anything.