Skip to content

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

tasktrace

Where your Claude Code sessions actually spent their time.

You know the feeling: a change took twenty minutes and you could not say where the twenty minutes went. tasktrace reads Claude Code's own session transcripts and tells you — how much was a command genuinely running, how much was the model between calls, how much was a stall nobody noticed, and how much was the session sitting finished while it waited for you.

It runs entirely on your machine. There is no network call anywhere in the program.

The tasktrace terminal explorer, listing six sessions with elapsed time, active time, tools time, think time, call counts and a colour-coded bar showing where each session's time went


Install

Pick whichever fits. It is one Python file tree with no dependencies — Python 3.8 or newer and nothing else.

As a Claude Code plugin (gives Claude the skill, so you can just ask):

/plugin marketplace add seyonv/tasktrace
/plugin install tasktrace

That gives you two ways in, and they do different things:

  • Type /tasktrace and it asks the same three questions the CLI menu asks — how far back, which project, what output — then writes the HTML report and opens it, prints the summary inline, or hands you a picture of the explorer.
  • Or ask in words — "where did the time go in my sessions this week?" — and it skips the questions, infers the scope, and reads you the answer as text.

The navigable explorer only exists in a real terminal. It can be executed anywhere — --svg does exactly that, and photographs the result — but nothing outside a terminal can drive it: a tool call is request and response, so a keypress has no path into the running process. So /tasktrace substitutes Claude Code's own picker for the menu, and offers you a snapshot of the explorer's first screen rather than a screen you can move around in. To sort, drill in and scroll, use the command line install below.

A plugin install does not put a tasktrace command on your PATH. The tasktrace … examples further down this page therefore do not work from a plugin install alone — Claude runs the tool on your behalf instead. If you also want to run it yourself, add the command line install below; the two coexist fine.

As a skill only:

git clone https://github.com/seyonv/tasktrace
cp -r tasktrace/plugins/tasktrace/skills/tasktrace ~/.claude/skills/

As a plain command line tool, no Claude Code required:

git clone https://github.com/seyonv/tasktrace
tasktrace/bin/tasktrace --demo

bin/tasktrace works from wherever the clone lives. To type tasktrace from anywhere, symlink it onto your PATH:

ln -s "$PWD/tasktrace/bin/tasktrace" /usr/local/bin/tasktrace

Try it on data that isn't yours

tasktrace --demo

Six synthetic sessions with plausible shapes, including the two failures worth seeing: a call that hung for half an hour, and a session that finished and then waited overnight for a person. Every screenshot in this README was made from them, so nothing of anyone's real work is on this page.


Run it

Bare, it asks three questions. Move with ↑/↓, choose with ↵ — or type the number, which still works:

The tasktrace menu asking how far back to look, with seven options and last week selected, and a hint line reading up-down move, enter select

Each answer collapses to the line that records it, so by the end the menu reads back as what you chose rather than what you were offered:

The three menu questions after answering, each showing only the selected option: last 30 days, checkout-api, write an HTML report and open it

Where there is no terminal to draw on — a pipe, a CI job, another program — it falls back to printing the list and reading a number, so the menu never becomes the reason a script hangs.

Or skip the menu entirely:

tasktrace --days 7                       # last week, terminal explorer
tasktrace --days 30 --html out.html      # a shareable report
tasktrace --here --plain                 # this directory's sessions, as text
tasktrace --days 90 --project api        # one project

Either way it shows you what it is doing, in five named steps:

A progress bar at 48 percent with five steps: discover complete, parse in progress at 263 of 412, then segment, measure and render still pending


Every table sorts

This is the part that matters most, and it is why there are tables rather than prose. A trace read in order tells you what happened. The same trace ordered by duration tells you what it cost. Those are different questions, and a tool that only answers the first one leaves you doing the second by eye.

So every table opens chronological — the trace as it happened — and re-sorts on any column. In the terminal, s cycles the sort column and r flips the direction. In the HTML report, click any heading.

The same six sessions, by when they happened and then by how long they took:

The same session table re-sorted by elapsed time, longest first

It works at every level — sessions, the phases inside a session, and the individual calls inside a phase.


The two views

The terminal explorer

Three levels: sessions → phases → the per-call ledger. j/k to move, enter to drill in, esc back, / to filter, q to quit.

Phases are runs of similar work, inferred from the tool mix and the gaps — reading the code, changing it, running the tests, shipping it, and the two that are not work at all: a stall, and waiting on a person.

The phases inside one session: explore, implement, test, explore, implement, test, ship, each with its duration, tools time, think time, call count and an activity bar

The ledger is every call, with the gap before it and the time it took. a toggles between the notable calls and all of them.

The per-call ledger showing time, think gap, execution time, context size, output tokens, tool and label for each call in one phase

There is also --plain, which prints the whole thing as text — the right choice when you are piping it somewhere or reading it in a diff.

Plain text output showing headline numbers, findings, and a per-session phase breakdown with bar charts

The HTML report

One self-contained file. No fonts, no scripts, no images fetched from anywhere — you can mail it, commit it, or open it on a plane.

The HTML report: headline stat tiles for elapsed, tools, thinking, stalls, waiting, tool calls, output and sessions; a stacked bar showing the split; and a findings list

Open a session for its phases and its full ledger. Both sort on any column.

An expanded session in the HTML report, showing its phases table and its every-call table

A generated one is committed at docs/demo-report.html — clone and open it to click around before running anything.


What it can't tell you

Read this part. It is short, and it is the difference between using the numbers and misusing them.

  • Why a gap was slow. A gap is wall-clock between two log lines. Inference, queueing, rate limits and your network are indistinguishable inside it. Treat "think time" as an upper bound on inference, never as a measurement of it.
  • What anything cost in money. No pricing is bundled, and none is guessed.
  • Anything outside Claude Code. Your editor, your build server, and your own thinking are all invisible here.
  • Anything about a transcript that is no longer on disk. If a session was cleared, that time is simply not in the record, and nothing marks the hole. Every total is a floor.
  • Whether the time was well spent. It shows you where time went. What that means about the work is a judgement it does not make.
  • Durations under about a second, precisely. Timestamps are per-message, so short calls carry the log's own granularity as error.

tasktrace --capabilities prints all of this, plus what it does measure.


Privacy

Your transcripts contain your prompts, your commands, your file contents and your tool output. So extraction is lossy on purpose: it derives a label and a duration, and throws the content away in the same pass.

Kept per call: a timestamp, a tool name, a duration, token counts, an error flag, and a short label. Labels are deliberately narrow —

Tool What survives
Bash the program name only: pytest, git, make. Wrappers and their flag values are peeled off first, so sudo -u root pytest is pytest, not root
Read / Write / Edit the file's basename, never a directory
Grep / Glob the literal word pattern — that a search happened, never what for
Agent the subagent type, never the prompt
WebFetch the URL's host, never the path or query
assistant text a character count, never the text

Never kept: prompts, command arguments, file contents, tool output, absolute paths, search patterns.

A generated report is shareable as it stands. The test suite asserts this the blunt way: it plants secrets in a synthetic transcript — a credential, a home path, a password argument, a prompt, tool output — generates the full HTML report, and greps the whole file for every one of them.

Two flags move the line, in opposite directions:

  • --anonymize goes further, replacing file basenames with stable pseudonyms (file-03.ts) and project names with project-a. Stability is the point: the same file gets the same name every time, so this one file was rewritten eleven times is still visible. Use it when a filename is itself the thing you cannot share.
  • --include-detail goes the other way and keeps raw tool inputs. It prints a warning, and output made with it is exactly as sensitive as the transcript.

How the numbers are made

Everything comes from two subtractions between message timestamps:

exec   assistant message requests a tool  →  the tool_result comes back
gap    the previous event ends            →  this assistant message arrives

From those: think is every gap under five minutes, stall is every gap over it with nothing running, human is time between the assistant finishing and a person replying, and active is exec + think + stall. Within one session they add up — exec + think + stall + human ≤ elapsed, always.

Across several sessions they deliberately do not. Sessions overlap (two agents on two branches, a subagent alongside its parent), so the totals are sums while the headline wall clock is a union — overlap counted once. Adding the elapsed times instead would claim the afternoon was nine hours long. When the sums exceed the clock, the output says so in as many words rather than quietly reconciling them.

reference.md in the skill has the full definitions, the phase-detection rules, the classification tables, and every threshold.


Options

Flag Does
--days N only sessions active in the last N days
--project NAME substring match on the project name
--here only sessions started in this directory
--html [FILE] write a self-contained HTML report
--json FILE write the redacted trace as JSON
--svg [FILE] photograph the explorer's first screen as an SVG
--plain print a text summary instead of the explorer
--open open the report when it is written
--anonymize replace file and project names with stable pseudonyms
--include-detail keep raw tool inputs (disables redaction)
--demo / --demo-scale N run against generated sample data
--menu force the interactive menu
--capabilities what this can and cannot tell you

Development

python3 -m unittest discover -s plugins/tasktrace/skills/tasktrace/tests
python3 docs/shot.py       # regenerate every screenshot in this README

docs/shot.py runs tasktrace in a real pty, plays the bytes through a small terminal emulator, and writes the screen out as SVG. The pictures above are therefore what the program printed, not mockups — which means they cannot quietly drift from the code that made them.


Related

padawan-no-more reads the same transcripts to answer the neighbouring question: not where the time went, but how often the agent stopped and asked you something, and which piece of configuration caused each stop. tasktrace measures the clock; padawan-no-more measures the interruptions.


MIT © Seyon Vasantharajan. Not affiliated with Anthropic.

About

Where your Claude Code sessions actually spent their time — tool execution vs model think-time vs stalls vs waiting on you. Terminal explorer and a shareable HTML report. Reads local transcripts only; nothing leaves your machine.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages