wiki-vault/Sources/Homelab/tokened.md

3.9 KiB

created path project tags type
2026-07-09 Sources/Homelab tokened
homelab
podman
traefik
observability
claude-code
tokens
project-plan

Goal

Visualize where the context window goes across Lovebug (herbyadmin) Claude Code sessions — turn the raw JSONL we've been hand-grepping into a standing, glanceable dashboard. Born from a session that hit 708k/1M and the question "where did it all go?"

Success criteria

  1. Up and reachabletokened.herbylab.dev resolves through Traefik, loads, no auth wall; container runs rootless as herbyadmin reading ~/.claude/projects read-only.
  2. Sees the real data — herbyadmin's sessions appear across all project folders (not just lovebug-instructions), including the 3-day marathons; session list populated and browsable.
  3. Numbers are trustworthy — dashboard's total for at least one known session roughly matches that session's /context reading, validating the message.id dedup. Separates "pretty" from "true."
  4. Answers the founding question — for any session, see token breakdown by category and spot heavy hitters (e.g. read_worker_transcript-heavy, Bash-heavy patterns) without touching a terminal.
  5. Cool graphs. Non-negotiable. Heatmaps and per-prompt cost charts render and are nice to look at. An unopened dashboard is a failed dashboard.

Build shape

  • Source: fork upstream nateherkai/token-dashboard into Gitea petal-power org; build from the fork, pinned commit. Fork is load-bearing (expect local patches), not cosmetic.
  • Runtime: rootless Podman, run as herbyadmin on herbys-dev. --userns=keep-id → container is herbyadmin, reads own files natively.
  • Mounts: ~/.claude/projects:ro. SQLite cache → named volume, writable, herbyadmin-owned.
  • Lifecycle: manual podman start (fish abbr for convenience). No systemd. Dies on reboot until poked — accepted for v1.
  • Ingress: Traefik file-provider route → tokened.herbylab.dev. Wildcard cert. No auth (private VLAN, behind server).
  • Container build: Lovebug writes the Containerfile — python:3.12-slim, stdlib-only app, no build step.
  • Deploy tree: /opt/projects/homelab/tokened/.
  • Stack fit: first Podman tool on herbys-dev (rest is Docker) — deliberate low-stakes sandbox for the rootless model.

Open questions — Lovebug resolves via survey before building

  1. Config surface — does the app take CLAUDE_PROJECTS_DIR / a cache-path / PORT / HOST via env, or are paths hardcoded to ~/.claude/projects/? Read the scanner source. Determines whether the mount path must match the app's expectation or can be redirected. Biggest "won't-just-work" risk.
  2. Bind address — app defaults to 127.0.0.1; inside the container it must bind 0.0.0.0 (container netns is the boundary) so Traefik can reach it. Confirm PORT/HOST are settable.
  3. Source-tagging — deferred to build time by design. Goal is to tag each session by source-agent (orchestrator / worker / interactive) using JSONL fields (agentType, parentToolUseId) — richer than folder-tagging. Survey whether upstream exposes this as a dimension or flattens it; if flattened, this is fork-patch #1. Work out during build.

Design principle

Static, on-demand tool — read when opened, no live streaming. Upstream's 30-second re-scan is unwanted; disable or ignore. Keep as many axes in the data as possible (source-agent, project-folder, tool-type, per-prompt cost, cache-hit, time) — slicing them is the point.

Validation checkpoint

Once up, sanity-check dashboard total vs /context for a known session (criterion 3). Rough agreement = dedup works, numbers trustworthy. Divergence = don't trust it, investigate. This is the fun part.

Out of scope / v2 negative-space

  • Reboot persistence (Quadlet / systemd-user lingering) — accepted manual for now, explore later.
  • Deep axis-slicing / custom graphs beyond upstream defaults — the fork roadmap, not v1.