Skip to content

Repository files navigation

atlas

An operating system for the agents you already run.

A local console that reads two things you already have — your Claude Code transcripts and your markdown vault — and turns them into the dashboard you keep wishing existed: what you actually spent, what you actually worked on, and a short list of things worth doing about it. Then it lets you act on all of it: read and follow your notes, search every word you have written, and run the agent in any project without leaving the page.

Nothing is mocked. Every number on the screen is computed from a file on your disk, and the ones that can't be computed say so.

the console

git clone https://github.com/openwarehq/atlas
cd atlas
npm install
npm run dev            # http://localhost:4338

That's the whole setup. It finds ~/.claude/projects and ~/ObsidianVault on its own; point it somewhere else with ATLAS_VAULT and ATLAS_TRANSCRIPTS.

Never run Claude Code? Five empty panels look broken rather than empty, so there is a seeder:

node seed/demo.mjs
ATLAS_TRANSCRIPTS=./demo/transcripts ATLAS_VAULT=./vault-example npm run dev

That is what the screenshot above is — a synthetic month across six invented projects. It is also how the screenshot avoids being a list of everything the author is building and what they paid for it, which is what this dashboard is when you point it at yourself.


What you can do with it

⌘K search every note — titles rank above bodies, matches are highlighted
click any note read it rendered, with backlinks and outgoing links
click a wikilink follow it, with a back stack, like a browser
⌘2 write a prompt, pick a project, run the agent, watch it stream
⌘1 ⌘3 ⌘4 command centre, vault, notices
a suggestion expand it to see exactly which notes it means, and open them

Running the agent

The Run tab spawns claude -p in a project and streams stdout back live. Three things about that are deliberate:

  • No shell. spawn gets an argv array, so a prompt containing ; or backticks is one argument and not a second command. There is no string in that file that ever reaches sh.
  • The working directory is an allowlist, not a parameter — it has to be a directory atlas already saw in your own transcripts, or the vault.
  • ATLAS_RUN=off turns the whole thing off. atlas binds to localhost, but behind a tunnel this route is remote code execution, and that switch is how you close it.

Stop actually stops: aborting the request kills the process, and closing the tab does too.


Filming it

A dashboard sitting still reads as a screenshot, and a screenshot does not hold anyone for ten seconds. So there is a reel: the console builds itself, the headline figures count up to their real values, the charts draw in, and the suggestions arrive one at a time. Ten seconds, then a beat and a half of stillness — a reel that cuts on its final motion feels clipped.

mid-reel

2.9s in: the counters are still climbing — $165 on its way to $177, 89% on its way to 96% — and the charts are half drawn.

http://localhost:4338/?reel=1          play once
http://localhost:4338/?reel=loop       loop, for recording
http://localhost:4338/?reel=portrait   loop, framed for a 9:16 crop

⌘⌥⇧A starts or stops the reel without a reload, so triggering it never appears in the take. Esc cancels.

⌘⇧A fires it too, but Chrome binds that to Search Tabs at the browser level where a page cannot intercept it — so Option is the one to use while recording. The browser has no claim on that chord.

Portrait mode is the one worth knowing about. A wide console cropped to 9:16 is a wall of six-pixel type, so ?reel=portrait drops the side rails, stacks the paired panels into one column, and scales the figures that carry the shot up to 44px. Record the browser at 1080×1920 and it needs no cropping.

Nothing in the reel is fabricated. Every number it counts towards is the number that was already on screen — the motion is the only thing being added.


What it actually reads

Your transcripts. Claude Code writes one JSONL record per API request, and every one carries a usage block. atlas parses all of them — 35,000 turns in about four seconds cold, 40ms warm — and gets you token spend by day and by model, cache hit rate, hour-of-day working pattern, longest sitting, and what the whole thing would have cost at list price.

Your vault. Any folder of markdown. Wikilinks resolved by basename the way Obsidian does it, so the note count and link count agree with what Obsidian shows you. Out of that: folders, backlinks, orphans, broken links, and a local graph.

Both are read-only. atlas writes exactly one file — atlas.db — and the only things in it are which suggestions you dismissed.


The banner

the banner

Real pixel art, generated — and then made real arithmetically, because asking a model for pixel art gets you a smooth illustration of pixel art. The render is box-averaged down onto a 200-cell grid, every cell quantised to a fixed 25-colour palette taken from this console's own CSS variables, then scaled back up with nearest-neighbour so each cell is a hard square. 21 colours survive.

Averaging on the way down matters: nearest-neighbour point-samples one arbitrary pixel per cell, which on a dithered source picks the checkerboard at random and turns the whole image into noise.

The result is 18KB instead of 1.1MB, and image-rendering: pixelated keeps the browser from smoothing the edges back off. Swap it by replacing public/banner.png — 5:1 fits the hero exactly.


Four decisions worth knowing about

Sittings, not sessions. A Claude Code session id survives --resume, so one id can span three weeks. Reporting that gives you "longest session: 58h 29m", which is the age of an identifier, not a fact about your day. atlas cuts turns into sittings at any gap over thirty minutes. The same fix makes the session list useful instead of showing four rows with a thousand turns each.

An unpriced model is never priced at zero. Models come out faster than public price lists get updated. A model with no rate is excluded from the cost figure and counted, and the console tells you how many turns that was. A model matched only by family prefix is flagged as inferred. The headline is either right or visibly incomplete — it is never quietly short.

Cache is priced at three different rates. A read is a tenth of a fresh input token; a five-minute write is 1.25x; a one-hour write is 2x. The transcript breaks the two writes out separately, so atlas prices them separately. This is most of why the number is what it is.

Confidence is computed, not assigned. Every suggestion shows the numbers it came from. 0.95 ESCALATE · 2 blocked notes · oldest 43d is a rule reading your frontmatter, not a model's opinion. And when no rule fires, the column is empty — an empty suggestions panel is a real answer, and padding it with filler is how you train someone to stop reading it.


What it doesn't do

  • It doesn't schedule anything. Runs happen when you press Run. There is no cron, no queue, no background agent.
  • It doesn't write to your vault. The reader is read-only; the one file atlas writes is atlas.db.
  • Context window is inferred, not read — the transcript doesn't record it. atlas picks the smallest standard window your week's peak actually fits in.
  • Prices are list prices as of writing and live in src/lib/pricing.ts. Verify them against the published rates before you quote anyone.
  • "List price" is not your bill. On a subscription the marginal cost of a turn is zero. It answers "what would this have cost on the API", which is the only version of that question with an answer.
  • One machine. No sync, no accounts, no telemetry, no network calls at all.

Configuration

variable default
ATLAS_VAULT ~/ObsidianVault, then ~/Documents/Lattice, then vault-example/
ATLAS_TRANSCRIPTS ~/.claude/projects
ATLAS_DB ./atlas.db
PORT 4338
ATLAS_RUN on — set to off to disable running agents entirely
ATLAS_AGENT_BIN claude — the binary the Run tab spawns

Docker, with both sources mounted read-only:

ATLAS_VAULT=~/ObsidianVault docker compose up --build

Development

npm test          # 164 tests
npm run typecheck
npm run build

The tests are on the parsing and the arithmetic, because that is where being wrong is invisible — a mis-bucketed day or a double-counted resumed session looks exactly like a correct dashboard.


MIT.

About

An operating system for the agents you already run — a local console over your Claude Code transcripts and your markdown vault. Real numbers, no mocks.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages