Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

558 Commits

Repository files navigation

agentistics

agentistics

Track · Analyze · Improve
Local-first analytics for AI coding assistants — one machine, or a whole team

Latest releaseBuild statusMIT LicensePlatform: Linux | WindowsBun

Install → · Team Mode → · Security model → · CLI →

The agentistics dashboard

Every screenshot and recording in this README is produced from a synthetic demo fleet (packages/server/scripts/seed-demo.ts) — real numbers, fictional names. See Reproducing the media.


What is agentistics?

agentistics reads what your AI coding assistants already write to disk and turns it into tokens, costs, sessions and activity you can actually reason about. Nothing is uploaded: on a single machine it never opens an outbound connection at all, and in Team Mode a machine sends computed metrics only — never chat.

It tracks six harnesses side by side:

HarnessRead fromTokens & costAgent metricsNotes
Claude Code~/.claude/The deepest source — agent invocations, git line counts, workflow runs
Codex CLI~/.codex/sessions/
Gemini CLI~/.gemini/tmp/Local files carry no token data
GitHub Copilot CLI~/.copilot/session-state/MCP tool calls counted
Antigravity (agy)~/.gemini/antigravity-cli/Decoded from its own protobuf blobs; edit deltas for lines changed
Kimi Code~/.kimi-code/sessions/Routes to other providers; priced by the routed model

A metric a harness genuinely cannot produce renders as N/A, never as a confident 0HARNESS_CAPABILITIES in @agentistics/core is the single source of truth for which is which.


Install

Linux / WSL — one line

curl -fsSL https://agentop.openvibes.tech/cli | bash

Then just run it:

agentop

Bare agentop on a terminal opens the control center — one full-screen application in the terminal's alternate buffer, so it adds nothing to your scrollback.

The agentop control center

Its tabs are Services (start / stop / restart this machine, a central, or the Docker machine; connect to or leave a central; enable a boot service), Setup, Logs, Commands, Help and Contribute. Screens change with /, panes with tab, and the footer always names the keys that work in the current focus.

Open the dashboard at http://localhost:47292 (the API + MCP endpoint stays on 47291).

Windows

Download the latest .msi or .exe from the Releases page. On first launch agentistics detects your Claude Code data path automatically (Windows native or WSL).

SmartScreen warning? "More info → Run anyway". The binary is not code-signed yet.

From source

git clone https://github.com/blpsoares/agentistics.git
cd agentistics && bun install
bun run dev # API (47291) + UI dev server (47292)
ScriptWhat it does
bun run devAPI + Vite dev server in parallel
bun run watchOTel daemon only
bun run watch:cliTerminal TUI
bun testUnit tests
bun run build:binaryFull build → release/agentop

The terminal dashboard

agentop tui is a live dashboard that needs no browser — Overview, Projects, Sessions, Costs and Harnesses, switched with the digits or tab.

agentop tui


The dashboard

Pages

PageRouteWhat it answers
Home/KPIs, activity over time, heatmap, hourly usage, highlights
Costs/costsSpend by model and date, budget and forecast, cache efficiency
Projects/projectsPer-project breakdown and comparison
Repositories/repositoriesGrouped by git remote, so one repo unifies across people, paths and machines
Actions/repositories/actionsSessions produced by CI runners
Tags/tagsSaved, named groupings — "what did Client X cost this month"
Tools/toolsTool-call ranking and token attribution
Compare/compareEvery harness side by side
Custom/customDrag-and-drop layout builder

Comparing harnesses

The compare page

Repositories

Metrics group by normalized git remote (host/org/repo), independent of where the repo is checked out or which machine produced the work. A repo's detail page carries Overview, Members, Sessions, an Actions tab when it has CI runs, and a Dynamic Workflows tab that renders each multi-agent Workflow run as a phase-by-phase timeline.

Repositories and repo detail

Tags

A tag is a saved grouping of sources — repositories, projects, machines, teams or accounts — optionally pinned to a date window. Tag responses are aggregate-only: counts and sums, never session rows or transcripts, with any key the viewer cannot see collapsed into an "other" bucket.

Tags

Custom layouts

The custom layout builder

On a phone

The whole dashboard is responsive and installs as a PWA.

The dashboard on mobile


Team Mode

One machine runs as a central and aggregates usage from many members. Members push computed metrics only — raw chat is never stored centrally (it is fetched on demand over a reverse WebSocket, from the machine that holds it).

Every machine has a role: solo (local only, the default), central (the aggregator, a Docker service on port 48080), or member. A machine may be a member of several centrals at once, with different sharing rules for each.

# host a central
agentop central init && agentop central up
# join one
agentop member connect --endpoint http://<central-host>:48080 --token <token>

Accounts, teams and roles

A central is not a shared password. First boot prints a one-time setup token and asks you to create the owner account; everyone else is invited. Accounts carry argon2id passwords, optional TOTP two-factor, and a role. A team is a scope key, not a label — being in a team is seeing it.

Signing in to a central

Step-up authentication gates escalation, not paperwork: editing an account, deleting a team and changing a password ask for a second proof. Enrolling a machine, a token or a repository does not — a prompt people meet daily is a prompt they clear without reading.

The central dashboard

What a machine shares — and what it withholds

Each connection carries its own rules across two dimensions (repositories and projects) in one of two modes: denylist (share everything except these) or allowlist (share only these). The rules never travel: the central is told nothing about them beyond a per-dimension count.

When several of your machines share one account, they tell each other what they withhold over a sealed machine-to-machine channel (X25519 → HKDF → AES-256-GCM, sender and recipient bound into the authenticated header, keys pinned on first sight and every new pin announced). That is what makes two things possible:

  • A warning at the point of decision: before you start sharing a repository, the picker names the sibling machines that withhold it. It warns, never blocks — and it always says that an absent warning is not proof, because a machine knows only what its siblings announced.
  • A proposal: a sibling can offer its rules, and applying one may only ever narrow what this machine shares. Never replace, never widen.

Presence, self-healing and CI

  • Presence is WebSocket-authoritative — online while the socket is live, offline within ~8s.
  • Auto-reconciliation: if the central's database is wiped, a token is rotated or an endpoint changes, a member notices and re-pushes its full history. A revoked machine resets itself to solo.
  • GitHub Actions: an ephemeral runner pushes its metrics with agentop ci-push, authenticated by keyless GitHub OIDC against a registered-repos allowlist. The central stamps the repository itself, so a runner cannot mis-report which repo it ran for. See docs/github-actions.md.

docs/architecture.md · docs/DEPLOY.md · docs/security.md


Exposing a central on the internet

A central can be published behind a tunnel. AGENTISTICS_EXPOSURE selects a profile — local | lan | public — and public permanently revokes every route that touches the host (shell, local chat, raw transcripts, MCP admin) and requires a second factor of every owner. The profile is the only thing that decides a capability; no opt-in re-enables host power on public.

agentop doctor --exposed # run this BEFORE opening a tunnel

A check that could not be verified reports fail, never a reassuring pass.

docs/exposure.md · SECURITY.md


The CLI — agentop

The commands cheat sheet

CommandPurpose
(bare) / startThe control center
setupFirst-run wizard (solo / central / member)
serverWeb + API + MCP + daemon. --central runs a central natively (no Docker), --bg detaches
restartBounce a mode; --rebuild rebuilds first (a full, cacheless rebuild — --cache opts out)
statusServices + health
tuiThe live terminal dashboard
watchThe OTel daemon only
centralup / init / down / logs / status / restart / pull
memberconnect / leave / status / list
ci-pushOne-shot push of a CI runner's metrics
autostartStart a mode with the system (systemd user service)
doctorExposure preflight; --exposed checks against the strict public bar
setup-tokenReissue the one-time owner setup token
reset-passwordThe way back in for a locked-out last owner
upgrade · check-updateUpdate, or print a notice when one is due

Full reference:docs/cli.md


Costs, and where the prices come from

Costs are computed per session from a pricing table with three layered sources, merged in order of trust: the built-in table (compiled in — the floor), the LiteLLM community dataset, and the vendors' own pages. A source that fails or returns junk costs freshness, never the ability to price anything; community rows that imply a unit change or sit more than tenfold from the built-in figure are dropped.

Settings → Pricing lists every model this machine has actually used, each with its origin (official / community / builtin) — so a model nobody can price is visible rather than silently guessed at.


Keeping history that the harnesses delete

Claude Code deletes session transcripts older than cleanupPeriodDays (30 by default) on every startup. agentistics asks once, on first run, what to do about that:

ModeWhat it keeps
consolidate(recommended)One small JSON of computed metrics per session — survives the cleanup, no chat duplicated
fullAdditionally mirrors the raw transcripts, chat included. Grows without bound
offNothing — ~/.claude only

Revived sessions appear in lists and agent metrics but never inflate aggregate totals.


Nay, and the MCP server

Nay is a chat panel that answers questions about your own data by calling the MCP tools. It runs claude --print under the hood, so it spends your Claude subscription quota.

The MCP server exposes the same analytics as structured tools (summary, harnesses, projects, sessions, costs, layout building, PDF export) and registers itself at user scope on first start — so any Claude Code session can use them, not just Nay.

claude mcp list # should show "agentistics"

docs/nay.md · docs/mcp.md


Also in the box

  • OpenTelemetry export for Grafana, Datadog or any OTLP collector — docs/opentelemetry.md
  • Live sessions — which assistants are running right now, detected from host processes. When detection is impossible (not Linux, no /proc, a container that cannot see the host) it says so instead of rendering an honest-looking zero
  • PDF export of any combination of sections, period and theme
  • PT-BR + EN, light and dark, throughout — CLI, TUI and web

Documentation

DocContents
docs/cli.mdEvery agentop command, flag and example
docs/architecture.mdStructure, request lifecycle, build pipeline
docs/security.mdThreat model, trust boundaries, the limits of each control
docs/exposure.mdPublishing a central safely
docs/DEPLOY.mdCentral deployment, central.sh, env vars
docs/github-actions.mdCI ingest, OIDC, repo-bound tokens
docs/harness-contract.mdWhat each metric must MEAN across harnesses
docs/data-sources.mdData sources, JSONL parsing, SessionMeta
docs/metrics.mdPricing table, cost formula, streak, cache
docs/nay.md · docs/mcp.mdThe chat assistant and the MCP tools

Reproducing the media

The GIFs above are recorded from a demo fleet, never from a real machine — a published recording cannot be taken back, and a real project name or repository in one is a leak.

# 1. a pseudonymized fleet, derived from this machine's computed metrics# (never from transcripts, so chat cannot reach it by construction)
bun run packages/server/scripts/seed-demo.ts --split 3 --force
# 2. run them
HOME=~/.agentistics-demo-home-1 PORT=47391 ./release/agentop server &# 3. record
packages/server/scripts/record-all.sh # terminal → .cast + .gif
bun run packages/server/scripts/record-web.ts # web → .gif

Terminal recordings are asciinema casts (casts/*.cast, embeddable as a real player with selectable text) rendered to GIF with agg.


Contributing

See CONTRIBUTING.md. Everything in this project is in English — code, comments, commits, docs.


Star History

Star History Chart


Made with ♥ for the vibe coding community

Releases

Packages

Contributors

Languages