|
| 1 | +# session-stats |
| 2 | + |
| 3 | +Session statistics for ZCode: turns/steps, model vs tool time, TTFT, TPS (average + |
| 4 | +latest request), token usage and cache hit rate. Zero third-party dependencies. |
| 5 | + |
| 6 | +## Components |
| 7 | + |
| 8 | +- **MCP tool `get_stats`** — statistics for the current session (including subagents, |
| 9 | + aggregated via `session.parent_id`) or today's aggregate across sessions. |
| 10 | +- **MCP App side panel** (`ui.surfaces`) — stat pills with a details popup |
| 11 | + (timings, token buckets, cache hit, per-model breakdown), auto-refresh every 5 s, |
| 12 | + follows session switching and the live theme. |
| 13 | +- **`/stats` command** — text card rendering of the same numbers. |
| 14 | +- **SessionStart hook** — writes the current session id into the plugin data dir so |
| 15 | + the server can resolve "current session" without extra round-trips. |
| 16 | + |
| 17 | +## Data source and metric definitions |
| 18 | + |
| 19 | +Everything is read **read-only** from the local session database |
| 20 | +`~/.zcode/cli/db/db.sqlite` (SQLite URI `mode=ro`, `busy_timeout=5000`, WAL-safe). |
| 21 | +Measured against ZCode 3.17.1: |
| 22 | + |
| 23 | +| Metric | Definition | |
| 24 | +| --- | --- | |
| 25 | +| Turns | distinct `turn_id` of the main session | |
| 26 | +| Steps | distinct `logical_request_id` (retries excluded; failed/cancelled counted) | |
| 27 | +| Model time | Σ `duration_ms` | |
| 28 | +| Tool time | Σ `tool_usage.duration_ms` | |
| 29 | +| TTFT avg | AVG(`time_to_first_token_ms`) | |
| 30 | +| TPS | Σ output ÷ Σ(completed_at − first_token_at); "live" TPS = latest completed request | |
| 31 | +| Tokens | Σ input + Σ output (`input_tokens` already includes cache reads — measured) | |
| 32 | +| Cache hit | cache_read ÷ input | |
| 33 | + |
| 34 | +The database schema is an implementation detail of the host (not a stable API) and |
| 35 | +usage rows are retained for 30 days; queries degrade gracefully when columns are |
| 36 | +missing. |
| 37 | + |
| 38 | +## Side effects |
| 39 | + |
| 40 | +- Reads the local session database (read-only). |
| 41 | +- Starts a loopback-only HTTP service (`127.0.0.1:31710`) that serves the statistics |
| 42 | + JSON and the panel's dynamic script to ZCode's renderer. It answers only requests |
| 43 | + without a cross-origin `Origin` header (i.e. the app's own `file://` pages); other |
| 44 | + origins get 403. |
| 45 | +- The SessionStart hook writes one small file (`current_session`) into the |
| 46 | + plugin-owned data directory. |
| 47 | +- No network access, no credentials, no telemetry. |
| 48 | + |
| 49 | +## Install |
| 50 | + |
| 51 | +ZCode Desktop → **Plugin Marketplace** → add the marketplace that carries this plugin |
| 52 | +(the official `zcode-plugins` marketplace after review, or a local directory) → |
| 53 | +**Install session-stats** → restart or open a new session → run `/stats` or open the |
| 54 | +"Session Stats" side panel. |
| 55 | + |
| 56 | +## Optional composer pills (host patch, experimental) |
| 57 | + |
| 58 | +A stats strip centered under the composer input can be enabled with a patch to the |
| 59 | +host `app.asar` (see the upstream project's `patches/` directory). The patch is |
| 60 | +idempotent, backs up the host file per version and supports restore; it must be |
| 61 | +re-applied after ZCode updates. This is **not** part of the marketplace plugin and |
| 62 | +is purely optional. |
| 63 | + |
| 64 | +## License |
| 65 | + |
| 66 | +MIT |
0 commit comments