A calm menu bar companion for working with AI coding agents.
It watches your Claude Code and Codex limits, your screen time and your token costs, on your own computer, and never touches any of them.
| Question | What Observatory shows |
|---|---|
| Am I near my limits? | Claude Code and Codex, each window (5-hour and weekly): percent left, reset time and the pace you are using it at. The menu bar title is the lowest one. |
| Where did my time go? | Screen time today and over time, by app and category, from ActivityWatch. |
| What did it cost? | Tokens today and over time, and what they would cost at public API prices. |
Observatory is monitor-only. It never starts, stops or answers an agent, and it never changes the tools it reads.
You need Node.js 22.13 or later on a Mac or a Windows PC. On a Mac, also install the Xcode Command Line Tools with xcode-select --install. For screen time, install and run ActivityWatch. Everything else is optional: a source that is missing shows Unknown and the rest keep working.
git clone https://github.com/ScribleSean/observatory.gitcd observatorynpm run setupThat is the whole install. Setup writes a settings file with every source on, builds the dashboard and a small menu bar app (a tray app on Windows) inside the folder you cloned, and starts it now and at login. There is no account and no installer, and nothing goes into Applications or Program Files. Because the app is built on your own computer, there is no downloaded-app warning to click through.
Click the number in the menu bar, then Open dashboard. The dashboard runs at http://127.0.0.1:5601 in your normal browser.
- Preview first:
npm run setup -- --dry-runlists what setup would do and changes nothing. - Update:
git pull, thennpm run setupagain. - Remove:
npm run setup -- --removestops the app and removes the login item. Then delete the cloned folder, and the data folder if you want the history gone:~/Library/Application Support/Observatoryon a Mac,%LOCALAPPDATA%\Observatoryon Windows. - npm warning about
fsevents: npm may say an install script forfseventswas not run. That package is only used by the development server, and setup does not need it. - Hidden menu bar item: on a MacBook with a notch and a busy menu bar, hold Command and drag the item to the right.
If you work on a Mac and a Windows PC, they can share one view. The Mac reads the PC's numbers over your own SSH connection every five minutes and writes the combined view back, so both menus and both dashboards show both computers. Limits are never added, and sums of time and tokens are labeled "not deduplicated". See Two computers.
Observatory reads records that your tools already keep on your computer. It sends nothing to any server of its own or anyone else's, and it has no telemetry.
| Source | What is read | What is kept |
|---|---|---|
| ActivityWatch | App usage events from its local server on 127.0.0.1 | Seconds per app and category, by day and hour. No window titles. |
Claude Code logs (~/.claude/projects) |
Token counts per request | Tokens per day, hour and model. No prompts or responses. |
Codex logs (~/.codex) |
Token counts, settings and tool calls per session | Tokens per day and model, effort and speed settings, tool call counts by name. No prompts, responses or arguments. |
| Limits | Asked from the Claude Code and Codex clients you already have | Percent left and reset time per window. |
- To read your limits, Observatory asks the installed Claude Code and Codex clients, which fetch your own account's limits from their provider with your existing sign-in. Observatory never sees or stores credentials.
- The dashboard listens on 127.0.0.1 only, serves one data file and has no way to change anything.
- With a second computer, the only other connection is SSH from your Mac to your own PC.
- The tests plant prompts, messages, paths and fake keys in sample files and check that none of them reach the saved data.
Turn any source off by setting it to false in observatory.config.json and running npm run setup again. See security for details.
Settings are in observatory.config.json, next to package.json. Setup writes it the first time.
{
"device": { "name": "Studio Mac" },
"sources": {
"screenTime": true,
"codex": true,
"codexLimits": true,
"claudeCode": true,
"claudeLimits": true
}
}A source is read only while it is true. An older settings file that still lists agents keeps working, and that key is ignored. Optional settings are dashboard.port (default 5601), dataFolder, and codexPath if Codex is installed somewhere unusual.
- Unknown means a value was not read. It never means zero.
- A limit percentage comes from the provider. A dollar figure is an estimate at public API prices, not a bill.
- Days are counted in your computer's own time zone.
The images in this README use fictional data from npm run preview. To retake them, run npm run build, then npm run preview, and open http://127.0.0.1:5602 for two computers (set PREVIEW_ONE=1 for one). They are taken at 1280 pixels wide and 2x scale.
Shots already in the repository:
docs/images/dashboard-one-computer-light.png: one computer, Limits page, light.docs/images/dashboard-{limits,activity,tokens}-{light,dark}.png: every page in both appearances.docs/images/menu-bar-menu.png: the real Mac menu bar app showing the same fictional data.PREVIEW_OUT=<file> npm run previewwrites that data as acombined.jsonfor the app to read.
Shots still to take:
- Windows tray icon with its number, and the tray menu open.
- The dashboard beside a terminal running Claude Code.
npm testnpm run lintnpm run tick runs one collection by hand. The design notes maps the code to the design, and the intro storyboard describes a short product video.
| Part | Files |
|---|---|
| Settings | lib/config.mjs, lib/timezone.mjs |
| Readers | scripts/read-settings.mjs, scripts/read-claude-usage.mjs, scripts/mac-activity.mjs, scripts/windows-aggregate-activity.ps1, scripts/collect-quota.mjs, scripts/claude-limits.mjs |
| Collect and combine | scripts/collect.mjs, lib/combine.mjs, scripts/tick.mjs |
| Second computer | scripts/hub.mjs, scripts/hub-transport.mjs |
| Dashboard | serve-local.mjs, app/viewer, lib/panel-data.mjs |
| Menu bar and tray | glance/mac/Glance.swift, glance/windows/Glance.cs |
| Setup | scripts/setup.mjs |
Bug reports and small fixes are welcome. Use synthetic examples and never attach real usage records. Read AGENTS.md first.

