npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tiny-tracking-ui

v0.1.0

Published

See what your AI coding agents are doing. Reads the transcripts Claude Code and Codex already write. Read-only.

Readme

Tiny Tracking UI

See what your AI coding agents are doing.

npx ttu

Opens a browser at localhost:4317 with five views: a Timeline of sub-jobs over time, Metrics on what they delivered and cost, Machine — what they are doing to your computer — Habits, which nudges you to do something good while they work, and Flows, a drawing of how a conversation ran — what it handed to its sub-jobs, and what came back. Click what a turn changed and you get Changes: the diff itself, live.

It reads the transcripts Claude Code and Codex already write, plus your process table. It writes no files, installs no hooks, and never disturbs a running agent. The one thing it can end is a Leftover — a process whose agents are already gone, and only when you press the button.


What it shows

Timeline — a row for every turn: what you asked, what it used, what it changed on your disk, how long it worked, and the sub-jobs it started. Fan-out, overlap, and which one everyone waited for.

A job is open far longer than it works — typically four times longer. So a turn's bar is drawn in pieces, breaking wherever the job stopped and waited on you. That waiting is not a footnote: it is 39.6% of everything that happens inside a turn, and it is drawn, not hidden.

Each turn gets its own time axis. On one shared axis a 25-minute turn inside a two-day job is about thirteen pixels, which is how long it took to notice the bars were unreadable.

Click a turn to read what you asked, what the agent said back, what it cost, and the tools it used. Sub-jobs open in their own panel.

Every row also says what it changed: 5 files +129 −102. A replaced line counts once on each side, the same as git diff. A whole file written is counted apart and marked, because a new file and an overwrite of a 900-line one look identical on disk and there is nothing to diff against. A failed edit never counts — 1.3% of them come back an error, and the number waits for the result.

Click a Team's name to open it: its members in the order they started, each told apart by the one line of its own prompt that no sibling has — the difference between nineteen rows reading Source Extractor and nineteen rows you can actually read. Beside them, the plan the batch was run to carry out, and the work it handed along: a node per pull request, commit or source, with who made it and who picked it up.

The plan says when it does not know. Members are attached to phases only when they line up one-for-one, which is 6 of 18 batches here. The rest show the route and say plainly that no placement is claimed, because a phase panel is a shape you cannot check — a wrong one looks exactly like a right one.

Changes — the only part that answers what, where everything else answers how much.

Click a turn's 5 files +129 −102 and it opens: the writes that turn made, and the diff itself. The real one — the harness's own record, not a summary. From there, Everything widens to a live feed of every file your agents are writing across the whole machine, newest first, arriving within two seconds. A breadcrumb takes you back.

It is not a tab, on purpose. It is the answer to a question the Timeline raises, so it is reached by clicking the question.

The feed never yanks the page. If you are reading a diff or have scrolled down, new writes wait behind a 3 new button you press when you are ready. Watching and reading are different activities.

It shows both engines, and they are not equally forthcoming. Claude records its own diff for a job and nothing at all for a sub-job — only that the write succeeded. Since sub-jobs do 44% of all the editing, leaving them out would hide nearly half of it, so their diff is rebuilt from the instruction that produced it. Measured against the harness's own diff on 2,047 edits where both exist, that rebuild is exact 1,935 times and wrong 112 — always by a line or two at the edges. Good enough to read; not good enough to count. So a sub-job's row shows its diff, is marked as asked, and carries no line counts at all.

Metrics — what it all cost, per day and in total. Sub-jobs started vs finished (the burn chart), where delegated work goes by role, the most expensive sub-jobs, and cost per Skill — Claude only.

A job never "finishes" — the state needs a parent to report to, and a job has none — so the burn chart is about sub-jobs, and says so.

Machine — one row per Project, sortable by any column: how much CPU its agents are burning, how much memory at most, which ports they hold, and what they have left behind.

Sorting is the point. The same rows answer three different questions depending on the column you click: which project is eating my machine (CPU), which server is on which port (Ports), and what is still running that shouldn't be (Leftovers).

Open a row to see the individual processes, click a port to open it, and end a Leftover if you want it gone.

Habits — the only part of this tool that is about you.

When an agent has been working for five minutes and nothing has just asked you a question, it plays a soft tone and puts one small suggestion on the page: stand up, drink water, look away from the screen. You press Did it or Skip. A grid shows the week, and +1 on any row records one you did on your own — which is the only way a long Habit is ever counted. An arrow steps back through earlier weeks; a finished week is shown exactly as it happened and cannot be changed.

It knows when you are free, which an ordinary reminder app cannot. For the half hour after a job starts waiting on you, it stays quiet — then you are the bottleneck, not idle. After that it assumes you have parked that job on purpose, because a session left open overnight sits in Needs you until you come back to it.

It ships with those three and nothing else. No exercise, no numbers about your body. Everything beyond them is a Habit you wrote yourself, and the tool never suggests changing one.

Calls — the tool tells you when an agent wants you, instead of waiting for you to look.

A line appears in the terminal you started it from, and a strip appears at the top of the page, the moment a job stops and needs you, finishes, stops without finishing, or one turn suddenly costs far more than usual for that job. If the page is open and you have turned sound on, a soft tone also rings — at most once every three minutes, standing for everything since. The interruption is batched; the record is complete.

It rings for every job on the machine, not just the one you are looking at. It stays quiet while you are looking at the page, and it never claims a job is waiting on you when it only inferred that the job is alive.


Words

The words on screen are the words in the code. There is no translation layer.

| | | |---|---| | Job | One run of an agent, from your instruction until it stops | | Sub-job | A Job that another Job started | | Turn | One instruction you gave, and everything done in reply | | Stretch | One unbroken piece of a turn's work. A turn holds about two | | Team | Sub-jobs started together as one batch, and the plan they were started to carry out | | Phase | One named stage of a Team's plan — a route, not a schedule | | Brief | What a Job was actually told to do | | Working · Needs you · Finished · Stopped | The four states | | Host | The app a Job is open in — the window you would go back to | | Project | The folder agents are working in — and what owns a Footprint | | Process | Something an agent started to do the work. Holds the port | | Service | The agent's own machinery — an MCP server. Never offered for ending | | Leftover | A Process still running when its Project has no agents left | | At most | The memory figure, named as the ceiling it is — see below |

"Needs you" is the one worth watching. It means an agent is sitting open with nothing to do, waiting on you — the state where you are the bottleneck. It lives as a count in the header, so it reaches you even while you are deep inside one job's timeline.

A waiting Job also carries a button that takes you to it. In VS Code, Cursor and Windsurf it lands on the window already holding that project; anywhere else it brings the app forward, and the button says which before you press it. It opens the folder, never a file, so no stray tab appears — and it creates no window. macOS only; elsewhere the button offers the command that reopens the Job. Terminal tabs are not found yet.


Things worth knowing

Roles are guessed. Nothing on disk records what a sub-job was hired to do — across 2,510 Claude agents, 72% are just labelled general-purpose. So the role is inferred from the task wording, and the screen says so. Codex records real names; Claude does not.

Only writes the tools recorded, and deletions depend on which tool. Codex names every file it deletes — 82 across 40 sessions here — and those are counted and shown. Claude records none: no Claude tool deletes a file, it happens inside a shell command, and reading shell text for it is guesswork. A regex for rm over 9,785 Bash calls flagged 132, of which the samples were pkill -f and cat > file. The screen says whose deletions are missing rather than showing a zero that looks like a fact. The same gap covers any file changed inside a shell command: it is not there at all.

A change is what an agent did, not what is on your disk now. A later write, a git checkout, or your own edit undoes it, and nothing here re-checks. Changes is a record of actions.

Cost is an estimate at list prices, and the rate is always shown next to it. Money is the headline because token counts hide where the spend goes: cache is about 89% of the cost and output about 10%, and as raw counts those are not comparable. Jobs and sub-jobs spend differently — a job puts 57% of its money into re-reading its own growing context, where a sub-job puts 36% into writing a fresh one. Work whose model was never recorded is counted as Unpriced, never as zero. If you are on a subscription you did not pay this per token — treat it as a weight, not a bill.

A cache write has two prices, and both are charged. Keeping context for an hour costs 2x the input rate; keeping it five minutes costs 1.25x. 60% of what your agents store is the hourly kind — so charging it all at the cheap rate, which this tool did until 2026-08-06, understated the bill by 10% ($29,407 reported against $32,359 over 30 days here). Codex does not record a cache-write figure at all, so this correction is Claude's alone.

"Working" is sometimes proven and otherwise inferred. A claude process names the session it is running only when that session was resumed — on this machine, 4 of 35 running processes. For the rest, and for Codex, "working" means agents are running and this job's own transcript was written seconds ago. The header marks the count with a ? when any of it is inferred, and says which is which. An inferred job can be working or stopped, but never needs you: waiting for you and being gone look identical in the file.

"At most" is a ceiling, not a measurement. Adding memory across a group of processes counts every shared page once per process — and agent trees are all Node processes sharing one runtime. Measured: six of them reported 200 MB while really using 38. macOS offers no better number, so the limitation is in the name rather than in a footnote. The per-process figures need no such caveat; the error is in the adding.

A Leftover is a question, not an accusation. It means a process with no living parent that was already running before anything currently working in that folder. Nothing observable separates a server you forgot from one you are deliberately keeping — so the tool asks, shows you exactly what will end, and never decides on its own. Services are never offered, and neither is anything it could not trace to one of your projects.

Unreadable files are skipped and counted, never fatal. Click the count in the header to see what was skipped and why.


Options

| | | |---|---| | PORT=8080 | Use a different port (default 4317; takes the next free one if busy) | | --no-open | Print the URL instead of opening a browser | | TTU_LIVE_HOURS | How far back the live view looks (default 200) | | TTU_HISTORY_HOURS | How far back the timeline reaches (default 720) |

Running it a second time opens the instance you already have rather than starting another.

To stop it, press "Stop" in the header. That matters more than it sounds: because a second launch opens the instance already running, an old one left up will serve you a new page over its old API after you upgrade — and the screen goes blank with nothing to explain it. The page now spots that and tells you, but stopping it properly is the fix.

It listens on 127.0.0.1 only — never on your network. What it serves is everything you have ever typed at an agent, so there is no flag to open it up and there is a test that fails if someone adds one.

Requires Node 20+. No dependencies, no build step, nothing installed.

npx tiny-tracking-ui works too — ttu is the same tool under a shorter name.


How it was designed

Every decision has a written rationale and the evidence behind it, under .scratch/live-agent-tracker/ — a map, nine resolved tickets, and a spec.

The map also keeps a Pivots table: eleven times a confident belief turned out wrong, and what proved it. The design changed. The way to detect a dead agent moved out of the files entirely. The cost headline turned out to be 9% of the story.