Observed since 20 Oct, 20:20 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
aegon-rs
Observability for Claude Code agentic runs — live TUI dashboard for Claude Code sessions
Observability for Claude Code agentic runs.
Watches the JSONL session files Claude Code writes during a run, parses them into typed Rust structs, tracks live session state, and displays everything in a split terminal UI — a raw event feed on the left and an aggregated dashboard on the right.
https://github.com/user-attachments/assets/a34fd65b-3872-40b2-a0a4-ef012dcf0c0a
┌─ Aegon 1 session 247 events ──────────────────────────────────────────────────────────┐
│ │
│ Events (newest first) │ Session │
│ ───────────────────── │ Live session ● LIVE 247 events │
│ 14:22:01 TOOL▶ Bash cargo… │ ───────────────────────────────────────────────────── │
│ 14:22:00 THINK I should… │ Tokens ████████████░░░░░░░░░░ 42k / 200k │
│ 14:21:59 ASST Let me run… │ in=38420 out=3801 cache_r=71204 │
│ 14:21:55 TOOL◀ Finished `d… │ est. cost: $0.0321 │
│ 14:21:54 TOOL▶ Read src/… │ ───────────────────────────────────────────────────── │
│ 14:21:54 TOOL▶ Bash ls -la… │ Steps │
│ 14:21:53 ASST I'll check… │ ⠋ Bash [1.2s] │
│ 14:21:52 USER lets start… │ ✓ Read 312ms │
│ │ ✓ Write 89ms │
│ │ ───────────────────────────────────────────────────── │
│ │ Flow │
│ │ USER → THINK → [Bash ‖ Read] → ASST → Write → ASST │
│ q quit │ │
└─────────────────────────────────────────────────────────────────────────────────────────────┘
Left panel — raw event feed: every tool call, result, thinking block, and assistant message in arrival order, coloured by type, newest first.
Right panel — live dashboard:
[Bash ‖ Read]), and
human turns~/.claude/projects/**/*.jsonl
│
│ notify (OS file events: FSEvents / inotify)
▼
aegon-cli / watcher.rs
┌─ background thread ──────────────────────────────────┐
│ seek to last-read byte → read new lines │
│ ClaudeAdapter::parse_line() → Vec<LogEvent> │
│ tx.send(event) │
└──────────────────────────────────────────────────────┘
│ mpsc channel
▼
aegon-cli / main.rs (main thread)
App::push(event)
├─► events: Vec<LogEvent> raw feed buffer (500 events)
└─► SessionRegistry::ingest()
└─► SessionState::ingest()
├─ pending: HashMap<id, Step> running tool calls
├─ steps: Vec<Step> completed with timing
├─ flow: Vec<FlowNode> causal chain
└─ token_totals: TokenTotals cumulative usage
aegon-ui / tui.rs draws every 50ms:
left → raw event list
right → dashboard::draw(SessionState)
├─ gauge::draw() token progress bar + cost
├─ steps::draw() spinners + completed steps
└─ flow::draw() USER → THINK → [T1 ‖ T2] → ASST
| Crate | Role |
|---|---|
aegon-types | All domain types — LogEvent, EventKind, ToolCall, ToolResult, TokenUsage, Session, StreamId |
aegon-adapters | Claude JSONL → Vec<LogEvent>; lenient on unknown fields |
aegon-core | Pure session logic — SessionState, SessionRegistry, Step, FlowNode, TokenTotals |
aegon-ui | ratatui TUI — split event feed + dashboard |
aegon-cli | Binary entry point — file watcher + channel wiring |
Via pip (no Rust toolchain needed):
pip install aegon-rs
Via Cargo (Rust toolchain required):
cargo install aegon-cli
aegon run # TUI in the current terminal
aegon run --detached # open TUI in a new terminal window
aegon # same as aegon run
Press q or Esc to quit.
The watcher automatically picks up ~/.claude/projects/**/*.jsonl and
~/.claude/sessions/**/*.jsonl. Start a Claude Code session in another
terminal — events appear in real time.
From source (contributors):
just run # build + launch in one step
just demo # opens in a new Terminal window
just setup # first-time: installs system deps and Cargo tools
just --list # all available recipes
just ci # mirrors what CI runs (fmt + clippy + check + test + docs)
just build # cargo build --workspace
just test # cargo test --workspace
just audit-jsonl # scan ~/.claude/projects for JSONL structure insights
just demo # run the tool in a separate terminal for live demo
See CLAUDE.md for full design constraints, crate responsibilities, and the development workflow.
See CHANGELOG.md for release history and JOURNAL.md for design decisions and session notes.
All changes go through a branch → PR → squash-merge cycle. The full
loop is documented in CLAUDE.md and enforced by skills in
.claude/skills/. In short:
just branch feat/<name> # cut a branch from latest main
# ... make changes ...
just ci # must pass locally before pushing
just push # push and set upstream
just pr # open PR (gh will prompt for title + body)
just merge # squash-merge once CI is green
just cleanup feat/<name> # delete local branch + prune remote refs
main directly. Every change goes through a PR.just ci must pass before pushing. It runs fmt, clippy -D warnings,
check, test, and cargo doc -D warnings — exactly what CI runs.cargo doc -D warnings is an
error, not a warning.[Unreleased] in CHANGELOG for unreleased changes; add a dated
JOURNAL entry with achievements, caveats, and next steps.unwrap() or expect() in library crates outside tests.#[serde(deny_unknown_fields)] on top-level event
types — the Claude JSONL format evolves without notice.crates/aegon-adapters/src/<tool>/mod.rs and raw.rsAdapter trait from crates/aegon-adapters/src/lib.rsaegon-tests/fixtures/<tool>/aegon-cli via config or format detection@chinmaypandya is the default owner for all files. All PRs require
approval before merge.
Download counts and popularity will appear here as the collector receives them.
Declarations describe requirements; they are not a resolved dependency graph.
bdist_wheel · 1,707.84 KB · Python py3
bdist_wheel · 899.67 KB · Python py3
bdist_wheel · 956.26 KB · Python py3
bdist_wheel · 790.27 KB · Python py3
Observed since 20 Oct, 20:20 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:85772faf363ef4bb67c4309afc0b2d3f2fefd2336acede3c0a1ae58d1367a3ca