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.
52 lines
1.5 KiB
Django/Jinja
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 %}
|