DEV Community

Cover image for Your AI bill says how much. Git knows what for.
Jose Daniel Leon Ruiz
Jose Daniel Leon Ruiz

Posted on

Your AI bill says how much. Git knows what for.

Most AI cost tools answer one question: how much did I spend? It's a useful number until someone asks a better one. What did the export the client asked for cost? What about the branch that got three afternoons of work and never merged?
Estela is an open source CLI that reads your local coding-agent logs and your git history. Since 0.4 it answers that second question: what each AI dollar delivered, per PR and per ticket. The report is the easy part. The interesting part is the join, and what to do when the join doesn't work.

Two sources and one missing link

Claude Code writes every session to disk, and each turn carries a timestamp, token counts and the git branch. Git knows which branches were merged, because a normal PR merge leaves a commit that says so: "Merge pull request #31 from …".
Put those together and a turn maps to a branch, a branch to a PR, and a PR to its hours and its cost. estela ai-cost --by item gives you that per ticket and PR, and --by branch per branch.

Two costs, because there are two questions

Every row carries two money figures, and they measure different things:

  • API price measures usage: what those tokens would have cost if you paid per token.- Your share of the subscription is money actually paid: the flat fee, divided according to real usage.They can disagree, and the disagreement is useful. On a light month the subscription can cost more than the API would have, which is worth knowing before you renew. The share has to be honest in aggregate too. In estela summary, the report meant for finance, a closed month adds up to exactly your subscription. Months follow your local clock, not UTC. ## Every row says why it was attributed A cost per PR is only as good as the reason it landed on that PR, so each row names its basis: the branch the agent recorded, a number in the branch name (feat/12-login), a #12 in a commit, a manual estela entry link, or the PR's merge commit. Whatever has no basis goes to "Unattributed", whole. We don't spread it across PRs so the totals look tidy. That line is information in its own right: it's how much of your spend you can't explain. ## Where the join breaks Most of the work went into the cases where the clean story above isn't true:
  • Squash merges leave no merge commit, so git alone can't tie the branch to its PR. If estela delivery has read the PR through gh, the squashed branch at least stops being counted as unmerged.- A session that changes branch used to land entirely on the last one. Now the block is split at the moment of the switch and each branch gets its own hours and cost. The day's total doesn't change.- GitLab numbers issues and merge requests separately, so issue #45 and MR !45 are different things. We were storing them under the same key, which could merge their costs. An MR is now !45.- Copilot doesn't store tokens, so its hours count but its cost is unknown, and the row is marked. Agents whose sessions we don't read yet, like Cursor, produce no AI cost at all.## Planned versus delivered estela delivery compares a plan, defined by a label or a milestone in GitHub or GitLab, with what actually shipped. You get three blocks, each with hours and AI cost: planned and delivered, planned and not delivered, and delivered without being planned. It reads the tracker through your own gh or glab, and --offline skips that call. One caveat: GitLab doesn't distinguish an issue closed as done from one closed as not done, so closed counts as delivered unless the issue moved to another project. estela delivery --by client does the same for client requests, using labels like cliente:acme. Work that served several clients isn't divided by guesswork. ## The uncomfortable number estela ai-cost --undelivered adds up, per project, the cost of sessions with no commit at all and of branches still unmerged after 14 days (configurable). It's a signal to review, not a verdict: exploring and investigating are work too. And what can't be known, like a deleted branch that may have been a squash, is shown apart and doesn't count. ## Try it npx estela setup needs Node 22.5 or later, with no account. Everything stays local by default, and the code is here: github.com/jdleonruiz/estela-cli When you look at your own AI spend, how much of it could you tie to something that shipped?

Top comments (0)