Turns time actually spent in Claude Code into client invoices, measured rather than remembered.
Own product, in live use. Every Claude Code session writes a transcript to disk, and every message in it records the real working directory and a millisecond timestamp. That is an accurate record of when work happened and which folder it happened in — it just is not in a form anyone can bill from.
Developers bill from memory, and memory rounds in whichever direction the week went. Timesheets filled in on Friday are fiction by Wednesday. Meanwhile the machine already holds a precise record of the work, going unused.
MILESTONES.md sitting in the project folder; ticking a milestone off is what triggers the invoice for the time since the last one.TypeScript monorepo (agent + web + shared core) · Next.js on Vercel · Neon Postgres · Google OAuth · PDF generation · Windows Scheduled Task.
Deciding what "active" means. Wall-clock time between the first and last event of a session is wrong — it counts lunch. The engine sums the gaps between events and discards any longer than the idle cap, so a long silence is a break rather than three billable hours. Rounding is then applied once per project per invoice line, not per interval, so rounding cannot accumulate into a number nobody can defend.
Reading someone's working transcripts is a privacy decision. The agent parses them locally and transmits only paths and durations. Nothing that was typed or generated ever leaves the machine.
Validated on a real machine: 427 transcripts parsed into 85 hours of idle-capped active time across 26 folders, with zero unparseable lines.
It bills real client work. The milestone file the agent reads sits in the A Story To Tell repository, with that engagement's milestones ticked and priced.
If something here is close to what you need, bring the problem and I will say how close. If it is not, I will say that instead.