hedge-local

module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: MIT

README

hcli: Local-only Telemetry TUI for Coding Agents

CI Release Go Reference

hcli collects OpenTelemetry (OTEL) telemetry from coding agents (Claude Code, OpenCode) into a local SQLite database and visualizes cost, tokens, tool usage, and latency in a terminal UI. Single Go binary, no cloud, no account, no telemetry home.

hcli TUI demo

Quickstart

curl -fsSL https://github.com/justinmaks/hedge-local/releases/latest/download/install.sh | sh
hcli setup claude
source ~/.hedge/env.sh
hcli

Start coding, and telemetry appears in the TUI within 60 seconds.

What It Does

  • Collects OTEL telemetry from Claude Code and OpenCode via OTLP/HTTP
  • Stores it in a local SQLite database (WAL mode, no external services)
  • Visualizes cost, tokens, tools, models, projects, and live activity in a 7-view TUI
  • Pulse: a live EKG of your coding session — token waveform, tool activity lane, burn rate ($/hr), and session rhythm, updating in real time
  • Exports data as CSV, JSON, or Markdown
  • Local-only: no usage data leaves your machine

Screenshots

Sample data shown.

Overview Cost
Overview Cost
Tools Models
Tools Models
Projects Live Pulse
Projects Pulse

Install

Shell installer (macOS + Linux)
curl -fsSL https://github.com/justinmaks/hedge-local/releases/latest/download/install.sh | sh
Debian/Ubuntu (.deb)

Download the .deb for your architecture from the latest release, then:

sudo dpkg -i hcli_*_linux_amd64.deb
Fedora/RHEL (.rpm)

Download the .rpm for your architecture from the latest release, then:

sudo rpm -i hcli_*_linux_amd64.rpm
go install
go install github.com/justinmaks/hedge-local/cmd/hcli@latest
Direct binary download

Download the archive for your platform from GitHub Releases, extract, and add hcli to your PATH.

Uninstall
# 1. Stop the daemon if running, then remove data and config
hcli stop
hcli uninstall        # removes ~/.hedge (prompts first; --dry-run to preview)

# 2. Remove the binary (location depends on how you installed)
sudo rm -f /usr/local/bin/hcli          # shell installer
rm -f "$(go env GOPATH)/bin/hcli"       # go install
# or: sudo dpkg -r hcli   /   sudo rpm -e hcli   (.deb / .rpm)

# 3. Remove the telemetry env line you added to your shell rc (~/.bashrc or ~/.zshrc):
#    source ~/.hedge/env.sh

For OpenCode, also remove @devtheops/opencode-plugin-otel from the plugin array in your opencode.json if you no longer want it.

Setup

Claude Code
hcli setup claude
source ~/.hedge/env.sh

Writes OTEL env vars to ~/.hedge/env.sh. Add source ~/.hedge/env.sh to your shell rc (~/.bashrc or ~/.zshrc) to make it permanent.

OpenCode
hcli setup opencode
source ~/.hedge/opencode-env.sh

Adds the @devtheops/opencode-plugin-otel plugin to your OpenCode config and writes its env vars. Source the file in the shell you run opencode from.

Per-project attribution

For Claude Code this is automatic: hcli setup claude installs a SessionStart hook that attributes each session to the directory you start claude in. OpenCode sessions still need a small shell wrapper; see Per-project attribution.

Usage

Embedded mode (zero config)
hcli

Starts the OTLP receiver and TUI together in one process. Press q to quit.

hcli service install     # run the collector as an OS-managed user service
hcli service status      # is it installed and listening?
hcli service uninstall   # stop and remove it

OTLP exporters don't buffer: whenever no collector is listening, that telemetry is lost. The service (systemd --user on Linux, launchd on macOS) keeps the collector running across crashes, logouts, and reboots, so your cost history has no holes. Open hcli tui whenever you want to look.

Daemon mode (portable fallback)
hcli collect -d       # start receiver in background
hcli tui              # open TUI (reads from DB)
hcli status           # collector + daemon health
hcli stop             # stop daemon
hcli logs             # tail daemon logs
hcli logs -f          # follow daemon logs
Headless export
hcli export --range 7d --format csv --out ~/hcli-export.csv
hcli export --range 30d --format json --out -
hcli export --data sessions --range 7d --format markdown --out report.md

Flags: --range (today, 7d, 30d, custom:YYYY-MM-DD:YYYY-MM-DD), --format (csv, json, markdown), --data (sessions, llm_calls, tool_calls, events, weekly_report), --out (file path or - for stdout).

SQL query (power users)

Run read-only SQL against the local database with hcli query. See SQL query.

Data retention
hcli prune --older-than 90d --dry-run   # preview what would be deleted
hcli prune --older-than 90d             # delete spans/sessions older than 90 days
hcli prune --older-than 12w --vacuum    # also reclaim disk space

Set retention_days in the config file to give hcli prune a default window. hcli status shows the current database size.

Pricing management
hcli pricing list                    # list local pricing
hcli pricing import /path/to/pricing.json  # import pricing JSON
hcli pricing fetch                   # fetch latest pricing from GitHub

Configuration

Optional, at ~/.hedge/config.toml (flags override the file):

db_path = "/custom/path/hedge.db"  # default ~/.hedge/hedge.db
otlp_port = 4318                   # OTLP/HTTP listen port
with_logs = false                  # capture log events (full prompts)
retention_days = 90                # default window for hcli prune

Unknown keys produce a warning (typo detection), and a path passed via --config must exist.

TUI Keybindings

Key Action
1-7 Jump to tab
Tab / Shift+Tab Cycle tabs
e Date range filter
r Refresh
? Help
q / Ctrl+C Quit
↑↓ Scroll
Enter Focused detail
Esc Return to table
t Live tab: toggle pulse/table

Architecture

Agent (Claude Code / OpenCode)
  → OTLP/HTTP (port 4318)
  → Receiver (protobuf parsing)
  → Normalizer (per-agent adapter)
  → Writer (cost computation + SQLite insert)
  → TUI (Bubble Tea views reading from SQLite)

Single Go binary, no CGO, pure-Go SQLite via modernc.org/sqlite.

See ARCHITECTURE.md for component details and the non-obvious bits, especially how cost is attributed and derived.

Local-Only Guarantee

hcli makes no outbound network calls during normal operation. The only exception is hcli pricing fetch, which is an explicit user-initiated command that downloads pricing data from GitHub. All telemetry data stays on your machine.

Local data lives in ~/.hedge/ and is stored owner-only: the directory is created 0700 and the SQLite database and daemon logs 0600, so other users on a shared machine can't read your captured telemetry.

Troubleshooting

No telemetry appearing
  • Verify env vars are set: echo $OTEL_EXPORTER_OTLP_ENDPOINT (should be http://localhost:4318)
  • Check daemon is running: hcli status
  • Check daemon logs: hcli logs
OpenCode: no telemetry appearing
  • The telemetry env vars must be set in the shell that launches opencode. Run source ~/.hedge/opencode-env.sh in that shell (or add it to your shell rc). If OPENCODE_ENABLE_TELEMETRY is unset, the plugin stays disabled and sends nothing.
  • Verify the @devtheops/opencode-plugin-otel plugin is in your opencode.json.
  • Let the session finish normally. The plugin batches telemetry and flushes it on a timer / on exit; a very short opencode run that exits instantly can race the final flush. Interactive sessions and runs that do real work flush reliably.
Port 4318 already in use
  • Another OTLP collector may be running. Stop it or use hcli collect --port 4319.
  • If a stale daemon is running: hcli stop then hcli collect -d.
Database locked
  • WAL mode makes this rare. If it happens, stop the daemon (hcli stop), wait 5 seconds, restart.
Pricing missing
  • Bundled pricing is seeded automatically by hcli collect. If cost shows $0, run hcli pricing list to verify, then hcli pricing fetch to update.
Stale PID file
  • If hcli status shows "stale PID file", run hcli stop to clean it up, then hcli collect -d.

License

MIT

Directories

Path Synopsis
cmd
hcli command
dist
internal
cli
tui

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL