View
Project 04 — Antfarm
Antfarm

Antfarm

Desktop application + Systems design

Palette
07090B
12171B
232A32
76858F
D9843C
Client
Self-initiated
Year
2026
Role
Solo — Rust + front end
Sector
Developer tools

Agents never write to the brain. If they could, the notes would stop being evidence.

Antfarm started as “watch your agents work through glass” and is turning into “dispatch the work and get tapped on the shoulder when it needs you”. It reads the project brain, files every Claude Code and Cowork session against the right project, and shows cost, git state and status in one place.

Every number comes from the local filesystem, the process table and Claude Code hooks. There are no API calls, nothing phones home, and the only directories the app writes to are its own.

  • 01Rust backend — project scan, session providers, usage rollup, git metrics
  • 02Push-based status via Claude Code lifecycle hooks, not polling
  • 03Per-model cost rollup with cache-read and cache-write multipliers
  • 04Headless dispatch with git-worktree isolation and terminal takeover
  • 05Tolerant parsers — a malformed transcript degrades, never crashes

The product, and the claim it has to keep — the whole pitch is on the first screen

Observe first. Dispatch second.
Antfarm — campaign line

Introduction

I knew going in that I had a visibility problem and I assumed it was a dashboard problem. I had eleven projects, a folder of notes I actually maintain by hand, and some number of agent sessions running at any moment across two different clients. What I wanted was a pane of glass.

What I did not know was that the interesting constraint would show up in the first hour. The obvious feature — let the agents write their findings back into the brain — is the one that quietly destroys the thing. The brain is the notes I reason from. The moment an agent can edit them, I am reading my own tools’ output back to myself and calling it evidence.

That is the pattern that bothered me about every tool in this space: they all want to be the source of truth. Antfarm is built the other way round. It is observe-first, it holds no opinions your files did not already contain, and the write path back to the brain does not exist in the codebase — not disabled, not gated, absent.

Cheers,
C.D.

Phase 01The problem, in real units.

Eleven projects. Two clients writing session transcripts in two different undocumented formats. Somewhere between four and nine live sessions on a working day, each one either running, idle, finished, or sitting on a permission prompt waiting for me to notice.

The last state is the expensive one. An agent blocked on approval costs nothing and produces nothing, and I would routinely find one twenty minutes after it stopped. There was no way to know without checking every terminal, which is exactly the work the agents were supposed to remove.

So the first real feature was not a chart. It was knowing, without looking, that something needs a person.

Phase 02Push, not poll. Zero API calls.

Status could have been a timer that stats a directory every few seconds. It is not. Claude Code exposes lifecycle hooks — Stop, Notification, SessionStart, SessionEnd — and a small shell script appends each event to a local JSONL file the app tails. Status changes arrive when they happen, and idle machines stay idle.

The hook is observability only and always exits clean, which is not a style choice: a hook that can fail is a hook that can block an agent loop, and an observability tool that interferes with the thing it observes has failed at the only job it has.

The same rule governs cost. Token counts are read from each message’s own usage block and priced per model, with cache-read and cache-write multipliers applied separately, because a rollup that ignores cache pricing is off by a factor that makes it decorative. No request leaves the machine to produce any of it.

Phase 03What shipped, and what it is built on.

Tauri 2 with a Rust backend and a Vite + React + TypeScript front end, dark theme, not Next.js. The Rust side does the project scan, the session providers, the usage rollup, the git metrics and the event tail; dispatch lives in its own module.

v1 shipped projects, sessions, usage, git metrics, uncommitted-file tracking ordered oldest first, push status and dispatch. Dispatch fires a headless run at any project from a prompt box: it can isolate itself in a git worktree, runs in acceptEdits or dontAsk, streams a live log, and offers a one-click takeover that resumes that session in a real terminal.

The parsers are deliberately forgiving. Session and transcript formats are undocumented and change between releases, so a malformed file degrades to “details unavailable” for that one row. It never takes down a list, and it never lands in a total.

Phase 04Limitations, honestly.

The cost figures are estimates and will drift. They depend on a per-model price table I maintain by hand, and on transcript formats that were never promised to me. When either changes, the number is wrong before the app knows it is wrong — which is why the card says “est.” and why skipped sessions are counted in the open.

Liveness is inferred from a running process plus a recent transcript mtime. That is a heuristic, and it will call a wedged session “running”. Detecting the difference between working and stuck is genuinely hard and I have not solved it.

And it is a personal tool: unpackaged, unsigned, and it assumes my directory layout. The registry file that maps project slugs to repositories is the seam where that assumption lives, but it is still an assumption.

Closing remarks.

The pane of glass turned out to be the easy half. The half worth keeping is the rule underneath it — that the app reads your work and never edits it — because it is the only reason I still trust what the notes say after a month of agents running against them. v2 is a tabbed workspace with real terminals in it. The rule does not change.

The one rule the product is built on, turned slowly in the dark. If an agent could edit the notes it reasons from, the notes stop being evidence — so the write path does not exist in the codebase.
Fig 1: The one rule the product is built on, set as the whole message. If an agent could edit the notes it reasons from, the notes stop being evidence — so the write path does not exist in the codebase.
Fig 2: The claim is a promise about restraint, not capability. “Zero API calls” is the second line because for this buyer it is the whole argument.
Fig 3: The mark is a cross-section — a soil line with tunnels branching under it, which is also exactly the shape of a file tree. One glyph that means both things at once, blind-debossed so it reads as a tool rather than a product.
Next projectLexx