arborist-viz/arborist_viz/templates/sessions_list.jinja2
russell@unturf.com 60e8640d86
sessions: list / tree / FTS5 search views via arborist.read.SessionsView
Mounts the sessions shard (~/.arborist/sessions.db by default) as a
read-only data source alongside the corpus shards. Imports stay
behind the arborist.read seam — viz never touches the schema directly.

Wire:
- storage.py: get_sessions(path) — process-cached SessionsView,
  parallel structure to get_shards(paths). close_all() now closes
  both caches.
- __init__.py: ARBORIST_VIZ_SESSIONS_DB env (or arborist.sessions_db
  ini) → request.sessions request property. Defaults to
  ~/.arborist/sessions.db.
- routes.py: /sessions (list), /sessions/{sid} (tree),
  /sessions/find (FTS5 search) + matching /api/sessions/... JSON.
- views/sessions.py: HTML + JSON handlers.
- templates/sessions_{list,tree,find}.jinja2: minimal views — table
  for list, recursive tree macro for tree, table for find results.
- static/css/viz.css: cmd-table / cmd-tree / cmd-audit-* styles.

Endpoint summary:
  /sessions                   list every session
  /sessions/{sid}             one session's tree (synthetic root
                              collapsed, cross-session children show
                              [from <sid>] tag)
  /sessions/find?q=...&limit= FTS5 across all sessions
  /api/sessions                       JSON list
  /api/sessions/{sid}                 JSON tree
  /api/sessions/find?q=...            JSON search

Audit_mode is rendered as a colored chip (strict/hybrid/ungrounded/
canonical_projection); cited titles surface as inline pills. Privacy
contract from base.jinja2 inherits unchanged — sessions shard is
local-private per ticket #000069 §14.
2026-06-01 17:41:24 -04:00

52 lines
1.5 KiB
Django/Jinja

{% extends "base.jinja2" %}
{% block body %}
<section class="cmd-panel">
<header class="cmd-panel-head">
<h1>Sessions</h1>
<p class="cmd-panel-sub">
Merkle conversation forest — single shard,
{% if sessions_stats.open %}
{{ sessions_stats.n_sessions }} session(s) ·
{{ sessions_stats.n_nodes }} node(s) ·
{{ sessions_stats.n_audit_events }} audit event(s) ·
<code>{{ sessions_stats.path }}</code>
{% else %}
no sessions shard configured
{% endif %}
</p>
<form action="/sessions/find" method="get" class="cmd-inline-form">
<input type="text" name="q" placeholder="search across all sessions (FTS5)" autocomplete="off">
<button type="submit">find</button>
</form>
</header>
{% if rows %}
<table class="cmd-table">
<thead>
<tr>
<th>sid</th>
<th>nodes</th>
<th>session_root</th>
<th>current_bates</th>
<th>updated</th>
<th>label</th>
</tr>
</thead>
<tbody>
{% for s in rows %}
<tr>
<td><a href="/sessions/{{ s.sid }}"><code>{{ s.sid }}</code></a></td>
<td>{{ s.n_nodes }}</td>
<td><code class="cmd-hash">{{ s.session_root }}</code></td>
<td><code>{{ s.current_bates }}</code></td>
<td>{{ s.updated_at }}</td>
<td>{{ s.label or '' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="cmd-empty">No sessions yet. Run <code>make session</code> to start one.</p>
{% endif %}
</section>
{% endblock %}