Emip159/pitwall

Pitwall: an always-on-top note showing your Claude Code, Codex and Antigravity plan limits, cost, context windows and live agents. Native macOS and Windows, no dependencies, no telemetry.

C#

0

28 commits

updated Sep 18, 2026

See the code
ai-agents
antigravity
claude
claude-code
codex
developer-tools
macos
menu-bar-app
rate-limits
swift
usage-tracker
windows
wpf

See what people are saying (1)

SourceMessageScoreDate

I made this so anxiety is not the only thing you get when checking your Claude usage (r/SideProject)

So I kept hitting my limit, and I got used to just typing all the time the magic "/usage" command, sooo, I made a foating note that shows your limits, cost, context and live agents for Claude Code, Codex, and Antigravity. Mac and Windows, free and open source. Open to feedback.…

1

Sep 18, 2026

README

Pitwall

See how much of your AI coding plan is left, and what every agent is doing, without leaving your editor.

Pitwall is a small always-on-top note for people who work with Claude Code, Codex and Antigravity. It shows your plan limits and when they reset, what the provider says you have spent, how full each agent's context window is, and a live tree of every running agent and sub-agent. It appears when you open one of those tools and goes away when you close the last one.

Native macOS app (Swift) and native Windows app (C#/WPF). No Electron, no Python, no third-party packages, no telemetry. MIT licensed.

The Pitwall note on Windows: three Claude accounts, ChatGPT and two Antigravity accounts, each with plan limits, cost, context window and live agents

Demo mode (--demo), so every state is on screen at once. Real accounts look the same.

What you get

  • Plan limits with reset countdowns for Claude Pro / Max / Team (5-hour, weekly, and the weekly Fable limit), ChatGPT through Codex, and Gemini through Antigravity or the Gemini CLI. Several accounts side by side.
  • Cost the provider reports, never an estimate, plus Claude Code's own per-session cost split across its sub-agents.
  • Live agents. Each running claude, codex or agy session is a small ghost acting out its real state: working, thinking, using a tool, waiting for you, rate limited, done. Sub-agents hang under the session that launched them.
  • Context window per agent, with a warning before it fills.
  • It stays out of the way. Nothing on screen until a tool is open, only the accounts in use are listed, it never takes keyboard focus, and one click hides it.

Quick start

You need the CLIs you already use to be signed in (claude, codex login, agy). Pitwall has no login of its own: it reads the sign-ins those tools created, read-only.

Download it. Get the installer for your computer from the latest release: Pitwall-Setup-…-x64.exe for Windows (-arm64 for Windows on ARM), Pitwall-….dmg for macOS 14 or newer. The builds are not code signed, so the first launch needs one extra click: on Windows More info > Run anyway, on macOS System Settings > Privacy & Security > Open Anyway.

Or build it yourself, which takes about a minute and is how you avoid those warnings.

macOS (14 Sonoma or newer, with Xcode or xcode-select --install):

git clone https://github.com/Emip159/pitwall.git
cd pitwall/macos
./build-app.sh && cp -R build/Pitwall.app /Applications/
open /Applications/Pitwall.app

macOS asks whether Pitwall may read the Claude Code-credentials Keychain item, once per Claude sign-in. Choose Always Allow.

Windows (10 or 11, with the .NET 10 SDK: winget install Microsoft.DotNet.SDK.10):

git clone https://github.com/Emip159/pitwall.git
cd pitwall\windows
powershell -ExecutionPolicy Bypass -File .\build.ps1
.\publish\win-x64\Pitwall-Setup.exe

The Setup window installs for your user only (no administrator rights) and can start Pitwall when you sign in. The -ExecutionPolicy Bypass applies to that one command: Windows refuses to run any script by default.

Then just work. Open claude, codex or agy in any terminal and the note appears on its own.

You want toDo this
Check your limits with no tool openClick the ghost icon in the menu bar (macOS: Show Note) or the tray (Windows: left-click)
Put the note away for nowThe in its corner. It comes back with the next tool you open
Move or resize itDrag it, or drag any edge. It remembers where you put it
See an agent's task, model, context, tools and costClick its row
See plan details for an accountClick the card's name
Change theme, size, compact mode, accountsRight-click the note, or open Settings from the icon
Try it without any accountRun it with --demo

Is it safe to run? It reads the same local sign-ins your CLIs use and sends them only to the provider that issued them. The hosts are on a fixed allowlist, redirects are refused, nothing is written back, and there is no telemetry or update check. Security and privacy has the short version and SECURITY.md the whole boundary, including what it does not protect you from.

What it looks like

Compact layout: one line per limit and agents as badges
Compact layout, six accounts
The note on macOS, one column, with an agent's details open
macOS, one column, an agent's details open
Light theme
Light
Sticky note theme
Sticky note
Glass theme
Glass

The rest of this page is reference. Everything above is enough to install and use Pitwall.

Contents

  1. What it shows, in detail
  2. Requirements
  3. Install on macOS
  4. Install on Windows
  5. Signing in to each agent
  6. Using the note
  7. Settings
  8. How it works
  9. Security and privacy
  10. Troubleshooting
  11. Uninstall
  12. Contributing
  13. Known limitations
  14. License

What it shows, in detail

You are deep in a Claude Code session and you want to know, without breaking flow, whether you are about to hit your weekly limit. That is the whole idea. The note floats above your editor and answers it.

Plan limits and resets

  • Claude Pro / Max / Team: the 5-hour session window, the weekly all-models window, and the weekly Fable limit, each with a reset countdown. It covers every Claude Code sign-in on the machine, for example ~/.claude, ~/.claude-personal and ~/.claude-work.
  • ChatGPT, through the Codex CLI: the 5-hour and weekly plan limits.
  • Gemini: through Google Antigravity (agy), the 5-hour and weekly limits for Gemini models and for Claude and GPT models. Through the Gemini CLI, the Workspace / Code Assist quota.

Cost

  • The usage cost the provider reports, never an estimate. For Claude that is subscription credits for the billing period. A provider that reports no cost says so rather than guessing.
  • Cost per agent, read from Claude Code's own per-session figure in the transcript. See How it works for the two things this is careful about, because both are easy to get wrong.
  • Claude API (Console): today's and this month's cost, tokens and top models. Needs an Admin API key.

Live agents

Every running claude, codex or agy session appears as a small ghost that acts out its real state: working, thinking, using a tool, needs you, done, rate limited, error, queued or idle. Claude Code sub-agents appear as a tree under the session that launched them, with their task, model, context, tool calls and result on demand. A Pac-Man on each card eats through your quota as you use it.

Context window

How full each agent's context is, taken from the tokens of its latest request. Claude Code does not record the window size, so the maximum is assumed per model and labelled as such. Codex reports its own.

Requirements

macOSWindows
To runmacOS 14 Sonoma or newerWindows 10 or 11, x64 or ARM64
To buildXcode, or the command line tools (xcode-select --install).NET 10 SDK (winget install Microsoft.DotNet.SDK.10)
DependenciesNoneNone

Installers for both platforms are attached to every release, built by GitHub Actions from the tagged commit, with SHA-256 checksums. Building it yourself takes about a minute. Either way the Windows exe is self-contained, so the PC that runs it needs nothing installed. On macOS, git and the compiler come with the command line tools. On Windows you need git (winget install Git.Git) only if you clone rather than download the ZIP from GitHub.

A note on code signing. This project is not distributed with an Apple Developer ID or an Authenticode certificate, because those cost money and are tied to one person's identity. An app you build on your own machine runs normally. An app you copy to a different machine will be stopped by Gatekeeper or SmartScreen until you allow it. Both sections below explain how.

Install on macOS

git clone https://github.com/Emip159/pitwall.git
cd pitwall/macos
UNIVERSAL=1 ./build-dmg.sh

That writes macos/build/Pitwall-<version>.dmg, which runs on both Apple Silicon and Intel. Open it and drag Pitwall onto Applications, then launch it from Applications or Spotlight. The app has no Dock icon. Look for the small ghost in the menu bar, with your highest usage percentage beside it. The note itself stays away until a tool is open: see When the note appears.

Other build options:

CommandResult
./build-app.shbuild/Pitwall.app for this Mac's architecture only
UNIVERSAL=1 ./build-app.shUniversal app bundle, no DMG
./build-dmg.shDMG for this Mac's architecture only
SIGN_IDENTITY="-" ./build-app.shForce an ad-hoc signature, even if you have a certificate
swift testRun the unit tests

Quick install without a DMG: ./build-app.sh && cp -R "build/Pitwall.app" /Applications/

Code signing on macOS

build-app.sh signs automatically, picking the first identity it finds in this order:

  1. SIGN_IDENTITY, if you set it.
  2. A Developer ID Application certificate.
  3. An Apple Development certificate.
  4. Ad-hoc, with a warning printed at the end of the build.

A stable certificate matters for one specific reason. macOS remembers a Keychain "Always Allow" grant per signing identity, and an ad-hoc signature changes on every rebuild, so macOS will ask again every time. This is also why you should only ever grant "Always Allow" to a build signed with a real certificate, as SECURITY.md explains.

To share a build with another Mac you need to notarize it, which requires a paid Apple Developer account and a Developer ID certificate. Store the credentials once, then build:

xcrun notarytool store-credentials my-profile
NOTARY_PROFILE=my-profile UNIVERSAL=1 ./build-dmg.sh

Without notarization, the other Mac can allow the app once in System Settings > Privacy & Security > Open Anyway, or you can clear the quarantine flag: xattr -dr com.apple.quarantine "/Applications/Pitwall.app".

First launch on macOS

  • Keychain prompts. macOS asks whether Pitwall may use the Claude Code-credentials items, one per Claude Code config folder, and the antigravity item. Enter your Mac password and click Always Allow. If you click Deny, that account shows an error. Click Refresh on the note to be asked again.
  • Settings open automatically on first launch if no signed-in CLI was found.
  • Launch at login is in Settings > General. It works best when the app is in /Applications.

Install on Windows

Clone the repository to the PC, open PowerShell in the windows folder, and run:

.\build.ps1

If PowerShell refuses with "running scripts is disabled on this system", that is Windows' default execution policy, not a problem with the script. Run it as powershell -ExecutionPolicy Bypass -File .uild.ps1 instead, which lifts the policy for that one command only.

That produces two identical files in publish\win-x64\: Pitwall.exe and Pitwall-Setup.exe. Double-click the Setup one. The app is its own installer. A small window lets you tick Start when I sign in to Windows and Launch now, then it:

  1. Installs to %LOCALAPPDATA%\Programs\Pitwall\. No administrator rights needed.
  2. Adds a Start Menu shortcut and an entry in Settings > Apps > Installed apps, with an Uninstall button.
  3. Registers it to start at sign-in, if you ticked that.
  4. Launches it. A ghost-shaped icon carrying your highest usage percentage appears in the notification area. You may need to open the ^ overflow and drag the icon onto the taskbar. The note itself appears as soon as a claude, codex or agy session is open, top right the first time. See When the note appears.

Running the Setup exe again updates an existing installation. For scripted installs there is install.ps1:

powershell -ExecutionPolicy RemoteSigned -File .\install.ps1 -LaunchAtLogin
CommandResult
.\build.ps1Build only. Single self-contained file, about 150 MB (uncompressed on purpose: a compressed single file costs about 100 MB more memory while running)
.\build.ps1 -Runtime win-arm64Build for ARM64 PCs
.\build.ps1 -FrameworkDependentSmall exe, about 1 MB, needs the .NET 10 Desktop Runtime on the PC
.\install.ps1 -Runtime win-arm64Install the ARM64 build
.\install.ps1 -UninstallRemove the app, shortcut and login item, keeping settings
.\install.ps1 -Uninstall -PurgeAlso delete settings and saved keys
dotnet run --project ParserTestsParser checks. These also run on macOS and Linux

After a git pull, delete the publish folder, or run .\build.ps1 again, before running .\install.ps1, so it does not reinstall the old exe.

Building the Windows exe on a Mac. After brew install --cask dotnet-sdk:

cd windows
dotnet publish Pitwall/Pitwall.csproj -c Release -r win-x64 --self-contained true \
  -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=false \
  -o publish/win-x64

Copy publish/win-x64 to the PC and run install.ps1 there. It sees the existing exe and skips the build.

SmartScreen. An exe built on the same PC runs normally. An exe you download or copy from elsewhere may show "Windows protected your PC". Click More info, then Run anyway, or run Unblock-File .\publish\win-x64\Pitwall.exe before installing.

Signing in to each agent

Pitwall never asks for a password and has no login of its own. It only reads sign-ins that the official CLIs have already created, so log in with them first.

AgentLog in withWhat the note then shows
Claude Pro / Max / Teamclaude (Claude Code). For several accounts use separate config folders: CLAUDE_CONFIG_DIR=~/.claude-work claude5-hour session, weekly all-models, weekly per-model limits
ChatGPT Plus / Pro / Teamcodex login (OpenAI Codex CLI)5-hour and weekly limits, plus any extra model limits
Gemini, personal Google accountagy, then log in (Google Antigravity CLI)Gemini models 5h and weekly, Claude and GPT models 5h and weekly
Gemini, Workspace / Code Assistgemini (Gemini CLI)Per-model daily quota
Claude APIPaste an Admin API key in SettingsCost today and this month, tokens today, top models

Then click Rescan in Settings, or restart the app.

The Admin API key looks like sk-ant-admin01-..., and an organization admin creates it in the Console under Settings > Admin keys. Ordinary sk-ant-api... keys and individual, non-organization accounts cannot read usage.

Using the note

Moving and resizing

  • Move: drag it anywhere, including onto another monitor. It stays above other windows, on every desktop, and over full-screen apps.
  • Resize: drag any edge or corner, like a normal window. There is a grip in the bottom right. The cards rearrange to fit: one column when narrow, two by two at medium width, side by side when wide. Rows stretch to fill the height you set. Until you resize it, the note hugs its content and scrolls only if it would be taller than the screen. Right-click and choose Reset size to go back to hugging. On Windows, dropping the note near a screen edge snaps it flush.
  • Text size is in Settings, from 70% to 200%.

Reading a card

Each account gets a card in its agent's colours: Claude terracotta, ChatGPT green, Gemini blue to purple. A card with something that needs you gets an orange outline. Top to bottom:

  1. Name, plan badge (Max, Team, Plus and so on) and a status chip such as "2 working" or "2 blocked".
  2. Usage. The main window, usually the 5-hour session, is a Pac-Man track. The dots ahead are the quota you have left, and Pac-Man sits at the percentage used. He glides forward eating dots as usage rises, and chomps only while one of that account's agents is working. A barrier appears in front of him when the account is rate limited or at 100%. Other limits are thin bars with dotted trails. Colours turn orange at 70% and red at 90%, and a limit the provider flags as critical is red at any percentage.
  3. Usage cost, as reported by the provider.
  4. Cost per agent, read from Claude Code's transcript.
  5. Context window for the card's most urgent agent, for example 124k / 1M tokens, 62%, with what is left, the model, and whether the maximum is assumed or reported. It turns amber at the threshold in Settings, 80% by default.
  6. Live agents, one row per running session, most urgent first, with sub-agents nested underneath. Click a row for its details. Click the card's name for provider details.
  7. Sign-in problems replace the numbers with a panel naming the command to run, instead of a misleading 0%.

Live agent states

Every row names the project and spells out the status in words, so you never have to interpret the animation.

StatusWhat you seeWhere it comes from
WorkingGhost scoots around, bits of output fly offSession busy, writing a reply
ThinkingGhost floats, eyes wander, thought bubbleWaiting on the model
Running / Reading / Editing / BrowsingGhost next to its tool: terminal, magnifier, pencil, globe, wrenchAn unanswered tool call in the transcript
DelegatingGhost hands a package to a small sub-agent ghostAn Agent or Task tool call
Needs youGhost looks at you, orange question mark pulsesClaude Code is waiting for your input or permission
DoneA quick jump with sparks, then a tickA turn just finished without errors
Rate limitedGhost stuck behind a striped barrierA 429 from the API, or the plan window at 100%
RetryingGhost keeps going with spinning arrowsAn API error mid-turn that Claude Code is retrying
ErrorA short shake, dizzy eyes, red exclamationThe turn ended with an API error
IdleGhost dozesSession open, nothing running
QueuedGhost waits in a small queueA sub-agent launched but not yet producing output

Codex and Antigravity only report working and idle, plus Done, so their ghosts show only those states.

Sub-agents. Each Agent tool call that Claude Code runs as a separate agent gets its own row under its parent, read from the subagents transcripts. It shows Queued until its first reply, then the same states as a session, then Done and Idle once its turn ends. Finished sub-agents stay listed for 5 minutes, configurable in Settings, after which only a count remains. Nested sub-agents nest.

Accessibility and performance. The note never takes keyboard focus, since it is an always-on-top tool window, so expand and collapse rows with the mouse. Rows still expose their name and status to screen readers. Animations are Core Animation layers, so an animating note uses almost no CPU, and they pause while the note is hidden or covered. Under macOS Reduce Motion, or with Animate agents and Pac-Man turned off, still poses replace them and each state is still distinguishable.

When the note appears

The note follows your tools, so it is only on screen while there is something to watch.

  • Nothing open, no note. At login, and whenever no claude, codex or agy is running, the note stays away. The menu bar or tray icon keeps showing your highest usage.
  • Open a tool and the note appears by itself, listing only the accounts that have a tool open. With work and personal Claude accounts and only a work session running, you see the work card alone. Start agy and its card joins.
  • Close the last tool and the note leaves 30 seconds later, so quitting and resuming a session does not make it blink.
  • Hide it while you work with the ✕ button or the icon, and it stays away until the next time you go from nothing open to something open.
  • Peek with nothing running: Show Note from the icon (on Windows, a left-click) opens the note with every account, and the API card if you track it, so you can check your limits before you start. Opening a tool ends the peek.

To keep the note away for good, untick Show the note while a tool is open in Settings. Showing it from the icon turns that back on.

Right-click menu

Right-click the note for the menu below. Right-click a specific card to also get a Hide item for that account.

ItemWhat it does
Refresh NowFetch all accounts now
Hide accountHide this account. Bring it back from Accounts
AccountsTick which accounts appear on the note
Size (macOS) / Reset size (Windows)macOS: zoom presets. Windows: back to hugging the content
ThemeDark, Glass (translucent), Light, Sticky note
CompactOne line per limit
Show Live AgentsShow or hide the live agents section
Lock Position & SizeStops accidental dragging and hides the resize grip
SettingsOpen Settings
Hide NoteHide the note for now. It returns with the next tool, or from the menu bar or tray

The icon shows the highest current-window usage across your accounts. On macOS it is a monochrome ghost with the percentage beside it, which follows light and dark mode. On Windows the ghost is filled with the severity colour and the percentage sits inside it.

The menu lists every account and limit, plus Show/Hide Note, Lock Position, Click-Through, Refresh Now, Settings and Quit. On Windows, left-click the tray icon to show or hide the note. With no tool open, showing it is a peek at every account (see When the note appears).

Click-through makes mouse clicks pass straight through the note to whatever is under it, turning it into a true overlay. Turn it off from the menu bar or tray icon.

Settings

  • Subscriptions. Every sign-in that was found, each with its status. Untick an account to hide it. Rescan searches again after you log in to a new CLI. Paste a token instead covers a Claude OAuth token if you do not use Claude Code. On Windows, Add Claude config folder covers a Claude Code folder in an unusual location.
  • API usage (Claude Console). Paste an Admin API key.
  • Floating note. Whether it appears while a tool is open, theme, size, opacity, compact mode, sessions, lock, click-through, refresh interval from 1 to 30 minutes, the context-window warning threshold from 50% to 95%, and whether finished sub-agents stay listed.
  • General. Launch at login.

How it works

Everything is read locally and read-only. Pitwall never writes to any CLI's files and never writes a token back.

AccountSign-in read fromNetwork requestActive sessions
Claude CodemacOS: Keychain Claude Code-credentials, plus -<hash> per extra config folder. Windows: %USERPROFILE%\.claude*\.credentials.jsonGET https://api.anthropic.com/api/oauth/usage for windows, limits[] including the Fable limit, spend, and the weekly breakdown<config>/sessions/<pid>.json gives busy or idle, and only if the process is still alive. The transcript at projects/<slug>/<sessionId>.jsonl, appended bytes only, gives model, tokens and context. <sessionId>/subagents/**/agent-*.jsonl gives the sub-agents
Codex (ChatGPT)~/.codex/auth.jsonGET https://chatgpt.com/backend-api/wham/usage. If the token has expired, the last limits recorded in ~/.codex/sessions/**/rollout-*.jsonl are shown instead~/.codex/thread-writer-locks/*.lock. Working means a rollout was written in the last 20 seconds
AntigravitymacOS: Keychain item with account antigravity. Windows: Credential Manager entry gemini:antigravity. Fallback: ~/.gemini/antigravity-cli/antigravity-oauth-tokenPOST https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary, on the backend and quota project that agy's own log/cli-*.log shows it using, since each backend keeps its own quotaRunning agy processes. Working means a conversation file changed in the last 20 seconds. Model and workspace come from that launch's log
Gemini CLI~/.gemini/oauth_creds.jsonPOST .../v1internal:loadCodeAssist and :retrieveUserQuotaChat logs written in the last 15 minutes
Claude APIThe Admin key you pastedGET https://api.anthropic.com/v1/organizations/cost_report and /usage_report/messagesNot applicable

Timing. Session scanning is local and runs every 2 seconds. Usage is fetched on the refresh timer, when you click refresh, and when a session finishes working, at most once a minute per account.

Admin API costs are reported in cents and converted to dollars. "Today" means today in UTC, and the data lags by about 5 minutes.

How cost per agent is worked out

Claude Code prices each session in its own transcript, and the note reads that figure rather than inventing one. Two things it is careful about:

  • A session's cost covers its sub-agents. Its token count does not. The Agent SDK documents the same split: total_cost_usd counts sub-agent requests alongside the top-level loop, while the token usage counts only the top-level loop. So a sub-agent's cost is shown as a share of the session, never added on top of it.
  • Claude reports cost per model, not per agent. When an agent is the only one running its model, which is the usual case for a sub-agent, that model's figure simply is its cost, exactly. When agents share a model, the model's cost is split between them by weighted tokens: an output token counts 5x, a cache write 1.25x, a cache read 0.1x, so a cache-heavy agent is not charged like a writer. The row then says the figure was derived. Only those ratios are assumed. The rate itself comes from the cost Claude reported.

It is list-price arithmetic, not a bill. A session whose transcript carries no cost line says "Not reported for this session" rather than guessing.

The icon

The app icon is the same ghost the agents in the note are drawn from. swift macos/Tools/make-icons.swift redraws it and writes both macos/Resources/AppIcon.icns and windows/Pitwall/Pitwall.ico using CoreGraphics only, no packages. Both files are committed, so a normal build never runs it. Run it when the mark changes.

Security and privacy

Pitwall reads the sign-ins of AI coding CLIs on your machine, which is a sensitive thing for a program to do. SECURITY.md is the full account, including how to report a vulnerability. The short version:

  • No telemetry, no analytics, no crash reporting, no update check. Nothing is sent anywhere except the provider APIs listed above.
  • Network allowlist. The app can only contact api.anthropic.com, chatgpt.com, oauth2.googleapis.com and cloudcode-pa.googleapis.com, or the *-cloudcode-pa.googleapis.com backend your agy uses, and only for accounts you have enabled. Redirects are refused, so a token cannot be forwarded to another host.
  • No third-party dependencies on either platform, so there is no supply chain to compromise.
  • Other apps' sign-ins are only read, never written. Claude Code and Codex tokens are never refreshed, because Codex refresh tokens are single-use and refreshing one would log you out of Codex. Antigravity and Gemini CLI tokens expire hourly and are refreshed in memory only, using the OAuth client from your own installed agy or gemini. No Google client credentials are stored in this repository.
  • Your own secrets. A pasted Admin key or token goes into the macOS Keychain, readable only while the Mac is unlocked and never synced to iCloud. On Windows it is encrypted with DPAPI for your Windows account.
  • Files other programs write are treated as untrusted input. Session ids are validated before they become part of a path, reads are size-capped, and directory walks are bounded.

What it does not protect you from. Anything already running under your user account can read these tokens directly, with or without this app. On Windows in particular, because this project is open source, the DPAPI entropy constant is public, so secrets.json is protected against another Windows user but not against software running as you. SECURITY.md spells out the whole boundary.

Troubleshooting

SymptomFix
"Sign-in expired. Run any claude command"Claude Code's token expired while it was not in use. Run claude once. The note recovers on the next refresh.
"Keychain access was denied" (macOS)Click refresh on the note and choose Always Allow. You can also fix it in Keychain Access, under the item's Access Control.
Keychain asks again after every rebuildYou are building with an ad-hoc signature. Build with an Apple Development or Developer ID certificate.
An account is missingLog in with its CLI, then Settings > Rescan. Check it is ticked under Accounts.
Two cards show the same numbersTwo config folders are signed in to the same account. Hide one.
"From your last Codex session"The Codex token expired, so the numbers come from Codex's local log. Run codex to refresh.
Gemini CLI: "no longer supported for Gemini Code Assist for individuals"Google moved personal accounts to Antigravity. Log in with agy.
Antigravity: "Couldn't refresh the Antigravity sign-in"The stored token expired and the OAuth client could not be read from your installed agy. Run agy once, then refresh.
Settings and sign-ins look reset after updatingThe app used to be called Claude Usage Note, and its identity moved with the rename. It copies the old settings and stored keys across on first launch. If something did not come over, the old data is still there, since nothing is deleted. Please report it rather than re-entering keys.
Note disappearedIt leaves when no tool is open and returns with the next one. To see it now: menu bar or tray icon, then Show Note. If it is off-screen, delete the saved position: macOS defaults delete local.pitwall noteTopLeft, Windows remove NoteLeft and NoteTop from settings.json. Then restart.
Cannot click the noteClick-through is on. Turn it off from the menu bar or tray icon.
"Rate limited by the server"Pick a longer refresh interval in Settings.
Context window: "Unavailable from provider"Codex only reports it in sessions that logged a token_count with a window size. Antigravity and Gemini CLI never do. For Claude Code it appears once the transcript has an assistant reply.
Usage cost: "Not reported by ..."Only Claude reports a cost in its usage response. Antigravity and Codex do not, and the note never estimates one.
Cost: "Not reported for this session"Only Claude Code writes a per-session cost into its transcript, and only once the session has billed a request. That format is internal to Claude Code and changes between versions, so if a release stops writing that line the note says this rather than guessing.
A sub-agent's cost says "derived"It shares a model with another agent in the session, so that model's reported cost was split by weighted tokens. An agent that is its model's only user shows Claude's own figure instead.
More than one keychain item matches (macOS)Two generic passwords share the same service or account name. Pitwall refuses to guess which one is real. Remove the duplicate in Keychain Access.

Diagnostics

Neither dump command prints a secret.

macOS:

"/Applications/Pitwall.app/Contents/MacOS/Pitwall" --dump
"/Applications/Pitwall.app/Contents/MacOS/Pitwall" --dump --verbose   # also prints response structure, field names only
"/Applications/Pitwall.app/Contents/MacOS/Pitwall" --demo             # made-up accounts cycling through every state, reads and fetches nothing

Windows: crashes are logged to %APPDATA%\Pitwall\error.log.

& "$env:LOCALAPPDATA\Programs\Pitwall\Pitwall.exe" --dump
& "$env:LOCALAPPDATA\Programs\Pitwall\Pitwall.exe" --demo

Dump output does include folder and project names, so glance over it before pasting it into an issue.

Uninstall

macOS:

  1. Turn off Launch at login in Settings.

  2. Quit from the menu bar icon.

  3. Run:

    rm -rf "/Applications/Pitwall.app"
    defaults delete local.pitwall
    
  4. If you pasted an Admin key or token, delete the Pitwall items in Keychain Access.

Windows: Settings > Apps > Installed apps > Pitwall > Uninstall. It asks whether to keep your settings. Alternatively, from the windows folder, run .\install.ps1 -Uninstall -Purge.

Contributing

Issues and pull requests are welcome. A few things worth knowing first.

Repository layout

macos/                 Swift package: menu bar item plus floating note
  Sources/Pitwall/     App code
  Tests/PitwallTests/  Unit tests, run with `swift test`
  build-app.sh         Build and sign the .app
  build-dmg.sh         Build the .app, then package a DMG
windows/               .NET 10 WPF app: tray icon plus floating note
  Pitwall/             App code
  ParserTests/         Parser checks that run on any OS
  build.ps1            Build the exe and the self-installer
  install.ps1          Scripted install and uninstall
docs/                  Design notes and specs
SECURITY.md            What the app touches, what it sends, how to report a vulnerability

Running the tests

cd macos && swift test                                # unit tests
cd windows && dotnet run --project ParserTests        # parser checks, any OS

The Windows app itself also compiles on macOS and Linux, which is useful for checking a change before you get to a PC:

cd windows && dotnet build Pitwall/Pitwall.csproj

One parser check, sub id from path, fails when run on macOS or Linux and passes on Windows. It uses a Windows-style path, and Path.GetFileNameWithoutExtension does not treat a backslash as a separator off Windows. This is expected.

Cutting a release

  1. Set the same version in windows/Pitwall/Pitwall.csproj (<Version>) and macos/Resources/Info.plist (CFBundleShortVersionString and CFBundleVersion), and commit.
  2. Tag that commit and push the tag: git tag v1.2.0 && git push origin v1.2.0.

.github/workflows/release.yml then tests and builds both apps, and publishes a GitHub Release with the DMG, the x64 and ARM64 Windows installers and their checksums. It refuses a tag that does not match the two version numbers. A tag with a suffix, such as v1.2.0-rc1, becomes a pre-release. Versions follow MAJOR.MINOR.PATCH: a fix bumps the last number, a feature the middle one.

Things to keep in mind

  • No dependencies. Both apps deliberately have zero third-party packages. Please keep it that way. A pull request that adds a NuGet or SwiftPM dependency needs a strong reason.
  • The two apps are kept at parity. A feature added to one should land in the other. macos/PARITY.md records what the last port involved.
  • Never estimate a number. If a provider does not report something, the note says so. This is a core principle of the project, not a detail.
  • Treat local files as untrusted. Everything the app parses is written by another program. Validate ids before they become paths, cap reads, bound directory walks. See SECURITY.md.
  • Security issues should go through private vulnerability reporting, not a public issue.

Known limitations

  • The provider endpoints are not public APIs. The subscription endpoints for Claude, ChatGPT and Google Code Assist are the ones the official CLIs use. They are undocumented and may change without notice.
  • No code signing certificate. The release installers are unsigned, so Windows and macOS warn about them on first launch. A build you make yourself runs without a warning on the machine that built it.
  • The Glass theme on Windows is a translucent surface, not a true behind-window blur.
  • Windows agent sessions started by another user, or elevated, cannot be named. They show as agy.
  • Screenshots and screen sharing. The note shows an agent's task description and up to 160 characters of its latest reply, so that text appears in anything that captures your screen.

License

MIT. Copyright (c) 2026 Emilian Popescu.

Contributors

Emip159

28 commits

Emip159/pitwall

Pitwall: an always-on-top note showing your Claude Code, Codex and Antigravity plan limits, cost, context windows and live agents. Native macOS and Windows, no dependencies, no telemetry.

C#

0

28 commits

updated Sep 18, 2026

See the code
ai-agents
antigravity
claude
claude-code
codex
developer-tools
macos
menu-bar-app
rate-limits
swift
usage-tracker
windows
wpf

See what people are saying (1)

SourceMessageScoreDate

I made this so anxiety is not the only thing you get when checking your Claude usage (r/SideProject)

So I kept hitting my limit, and I got used to just typing all the time the magic "/usage" command, sooo, I made a foating note that shows your limits, cost, context and live agents for Claude Code, Codex, and Antigravity. Mac and Windows, free and open source. Open to feedback.…

1

Sep 18, 2026

README

Pitwall

See how much of your AI coding plan is left, and what every agent is doing, without leaving your editor.

Pitwall is a small always-on-top note for people who work with Claude Code, Codex and Antigravity. It shows your plan limits and when they reset, what the provider says you have spent, how full each agent's context window is, and a live tree of every running agent and sub-agent. It appears when you open one of those tools and goes away when you close the last one.

Native macOS app (Swift) and native Windows app (C#/WPF). No Electron, no Python, no third-party packages, no telemetry. MIT licensed.

The Pitwall note on Windows: three Claude accounts, ChatGPT and two Antigravity accounts, each with plan limits, cost, context window and live agents

Demo mode (--demo), so every state is on screen at once. Real accounts look the same.

What you get

  • Plan limits with reset countdowns for Claude Pro / Max / Team (5-hour, weekly, and the weekly Fable limit), ChatGPT through Codex, and Gemini through Antigravity or the Gemini CLI. Several accounts side by side.
  • Cost the provider reports, never an estimate, plus Claude Code's own per-session cost split across its sub-agents.
  • Live agents. Each running claude, codex or agy session is a small ghost acting out its real state: working, thinking, using a tool, waiting for you, rate limited, done. Sub-agents hang under the session that launched them.
  • Context window per agent, with a warning before it fills.
  • It stays out of the way. Nothing on screen until a tool is open, only the accounts in use are listed, it never takes keyboard focus, and one click hides it.

Quick start

You need the CLIs you already use to be signed in (claude, codex login, agy). Pitwall has no login of its own: it reads the sign-ins those tools created, read-only.

Download it. Get the installer for your computer from the latest release: Pitwall-Setup-…-x64.exe for Windows (-arm64 for Windows on ARM), Pitwall-….dmg for macOS 14 or newer. The builds are not code signed, so the first launch needs one extra click: on Windows More info > Run anyway, on macOS System Settings > Privacy & Security > Open Anyway.

Or build it yourself, which takes about a minute and is how you avoid those warnings.

macOS (14 Sonoma or newer, with Xcode or xcode-select --install):

git clone https://github.com/Emip159/pitwall.git
cd pitwall/macos
./build-app.sh && cp -R build/Pitwall.app /Applications/
open /Applications/Pitwall.app

macOS asks whether Pitwall may read the Claude Code-credentials Keychain item, once per Claude sign-in. Choose Always Allow.

Windows (10 or 11, with the .NET 10 SDK: winget install Microsoft.DotNet.SDK.10):

git clone https://github.com/Emip159/pitwall.git
cd pitwall\windows
powershell -ExecutionPolicy Bypass -File .\build.ps1
.\publish\win-x64\Pitwall-Setup.exe

The Setup window installs for your user only (no administrator rights) and can start Pitwall when you sign in. The -ExecutionPolicy Bypass applies to that one command: Windows refuses to run any script by default.

Then just work. Open claude, codex or agy in any terminal and the note appears on its own.

You want toDo this
Check your limits with no tool openClick the ghost icon in the menu bar (macOS: Show Note) or the tray (Windows: left-click)
Put the note away for nowThe in its corner. It comes back with the next tool you open
Move or resize itDrag it, or drag any edge. It remembers where you put it
See an agent's task, model, context, tools and costClick its row
See plan details for an accountClick the card's name
Change theme, size, compact mode, accountsRight-click the note, or open Settings from the icon
Try it without any accountRun it with --demo

Is it safe to run? It reads the same local sign-ins your CLIs use and sends them only to the provider that issued them. The hosts are on a fixed allowlist, redirects are refused, nothing is written back, and there is no telemetry or update check. Security and privacy has the short version and SECURITY.md the whole boundary, including what it does not protect you from.

What it looks like

Compact layout: one line per limit and agents as badges
Compact layout, six accounts
The note on macOS, one column, with an agent's details open
macOS, one column, an agent's details open
Light theme
Light
Sticky note theme
Sticky note
Glass theme
Glass

The rest of this page is reference. Everything above is enough to install and use Pitwall.

Contents

  1. What it shows, in detail
  2. Requirements
  3. Install on macOS
  4. Install on Windows
  5. Signing in to each agent
  6. Using the note
  7. Settings
  8. How it works
  9. Security and privacy
  10. Troubleshooting
  11. Uninstall
  12. Contributing
  13. Known limitations
  14. License

What it shows, in detail

You are deep in a Claude Code session and you want to know, without breaking flow, whether you are about to hit your weekly limit. That is the whole idea. The note floats above your editor and answers it.

Plan limits and resets

  • Claude Pro / Max / Team: the 5-hour session window, the weekly all-models window, and the weekly Fable limit, each with a reset countdown. It covers every Claude Code sign-in on the machine, for example ~/.claude, ~/.claude-personal and ~/.claude-work.
  • ChatGPT, through the Codex CLI: the 5-hour and weekly plan limits.
  • Gemini: through Google Antigravity (agy), the 5-hour and weekly limits for Gemini models and for Claude and GPT models. Through the Gemini CLI, the Workspace / Code Assist quota.

Cost

  • The usage cost the provider reports, never an estimate. For Claude that is subscription credits for the billing period. A provider that reports no cost says so rather than guessing.
  • Cost per agent, read from Claude Code's own per-session figure in the transcript. See How it works for the two things this is careful about, because both are easy to get wrong.
  • Claude API (Console): today's and this month's cost, tokens and top models. Needs an Admin API key.

Live agents

Every running claude, codex or agy session appears as a small ghost that acts out its real state: working, thinking, using a tool, needs you, done, rate limited, error, queued or idle. Claude Code sub-agents appear as a tree under the session that launched them, with their task, model, context, tool calls and result on demand. A Pac-Man on each card eats through your quota as you use it.

Context window

How full each agent's context is, taken from the tokens of its latest request. Claude Code does not record the window size, so the maximum is assumed per model and labelled as such. Codex reports its own.

Requirements

macOSWindows
To runmacOS 14 Sonoma or newerWindows 10 or 11, x64 or ARM64
To buildXcode, or the command line tools (xcode-select --install).NET 10 SDK (winget install Microsoft.DotNet.SDK.10)
DependenciesNoneNone

Installers for both platforms are attached to every release, built by GitHub Actions from the tagged commit, with SHA-256 checksums. Building it yourself takes about a minute. Either way the Windows exe is self-contained, so the PC that runs it needs nothing installed. On macOS, git and the compiler come with the command line tools. On Windows you need git (winget install Git.Git) only if you clone rather than download the ZIP from GitHub.

A note on code signing. This project is not distributed with an Apple Developer ID or an Authenticode certificate, because those cost money and are tied to one person's identity. An app you build on your own machine runs normally. An app you copy to a different machine will be stopped by Gatekeeper or SmartScreen until you allow it. Both sections below explain how.

Install on macOS

git clone https://github.com/Emip159/pitwall.git
cd pitwall/macos
UNIVERSAL=1 ./build-dmg.sh

That writes macos/build/Pitwall-<version>.dmg, which runs on both Apple Silicon and Intel. Open it and drag Pitwall onto Applications, then launch it from Applications or Spotlight. The app has no Dock icon. Look for the small ghost in the menu bar, with your highest usage percentage beside it. The note itself stays away until a tool is open: see When the note appears.

Other build options:

CommandResult
./build-app.shbuild/Pitwall.app for this Mac's architecture only
UNIVERSAL=1 ./build-app.shUniversal app bundle, no DMG
./build-dmg.shDMG for this Mac's architecture only
SIGN_IDENTITY="-" ./build-app.shForce an ad-hoc signature, even if you have a certificate
swift testRun the unit tests

Quick install without a DMG: ./build-app.sh && cp -R "build/Pitwall.app" /Applications/

Code signing on macOS

build-app.sh signs automatically, picking the first identity it finds in this order:

  1. SIGN_IDENTITY, if you set it.
  2. A Developer ID Application certificate.
  3. An Apple Development certificate.
  4. Ad-hoc, with a warning printed at the end of the build.

A stable certificate matters for one specific reason. macOS remembers a Keychain "Always Allow" grant per signing identity, and an ad-hoc signature changes on every rebuild, so macOS will ask again every time. This is also why you should only ever grant "Always Allow" to a build signed with a real certificate, as SECURITY.md explains.

To share a build with another Mac you need to notarize it, which requires a paid Apple Developer account and a Developer ID certificate. Store the credentials once, then build:

xcrun notarytool store-credentials my-profile
NOTARY_PROFILE=my-profile UNIVERSAL=1 ./build-dmg.sh

Without notarization, the other Mac can allow the app once in System Settings > Privacy & Security > Open Anyway, or you can clear the quarantine flag: xattr -dr com.apple.quarantine "/Applications/Pitwall.app".

First launch on macOS

  • Keychain prompts. macOS asks whether Pitwall may use the Claude Code-credentials items, one per Claude Code config folder, and the antigravity item. Enter your Mac password and click Always Allow. If you click Deny, that account shows an error. Click Refresh on the note to be asked again.
  • Settings open automatically on first launch if no signed-in CLI was found.
  • Launch at login is in Settings > General. It works best when the app is in /Applications.

Install on Windows

Clone the repository to the PC, open PowerShell in the windows folder, and run:

.\build.ps1

If PowerShell refuses with "running scripts is disabled on this system", that is Windows' default execution policy, not a problem with the script. Run it as powershell -ExecutionPolicy Bypass -File .uild.ps1 instead, which lifts the policy for that one command only.

That produces two identical files in publish\win-x64\: Pitwall.exe and Pitwall-Setup.exe. Double-click the Setup one. The app is its own installer. A small window lets you tick Start when I sign in to Windows and Launch now, then it:

  1. Installs to %LOCALAPPDATA%\Programs\Pitwall\. No administrator rights needed.
  2. Adds a Start Menu shortcut and an entry in Settings > Apps > Installed apps, with an Uninstall button.
  3. Registers it to start at sign-in, if you ticked that.
  4. Launches it. A ghost-shaped icon carrying your highest usage percentage appears in the notification area. You may need to open the ^ overflow and drag the icon onto the taskbar. The note itself appears as soon as a claude, codex or agy session is open, top right the first time. See When the note appears.

Running the Setup exe again updates an existing installation. For scripted installs there is install.ps1:

powershell -ExecutionPolicy RemoteSigned -File .\install.ps1 -LaunchAtLogin
CommandResult
.\build.ps1Build only. Single self-contained file, about 150 MB (uncompressed on purpose: a compressed single file costs about 100 MB more memory while running)
.\build.ps1 -Runtime win-arm64Build for ARM64 PCs
.\build.ps1 -FrameworkDependentSmall exe, about 1 MB, needs the .NET 10 Desktop Runtime on the PC
.\install.ps1 -Runtime win-arm64Install the ARM64 build
.\install.ps1 -UninstallRemove the app, shortcut and login item, keeping settings
.\install.ps1 -Uninstall -PurgeAlso delete settings and saved keys
dotnet run --project ParserTestsParser checks. These also run on macOS and Linux

After a git pull, delete the publish folder, or run .\build.ps1 again, before running .\install.ps1, so it does not reinstall the old exe.

Building the Windows exe on a Mac. After brew install --cask dotnet-sdk:

cd windows
dotnet publish Pitwall/Pitwall.csproj -c Release -r win-x64 --self-contained true \
  -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=false \
  -o publish/win-x64

Copy publish/win-x64 to the PC and run install.ps1 there. It sees the existing exe and skips the build.

SmartScreen. An exe built on the same PC runs normally. An exe you download or copy from elsewhere may show "Windows protected your PC". Click More info, then Run anyway, or run Unblock-File .\publish\win-x64\Pitwall.exe before installing.

Signing in to each agent

Pitwall never asks for a password and has no login of its own. It only reads sign-ins that the official CLIs have already created, so log in with them first.

AgentLog in withWhat the note then shows
Claude Pro / Max / Teamclaude (Claude Code). For several accounts use separate config folders: CLAUDE_CONFIG_DIR=~/.claude-work claude5-hour session, weekly all-models, weekly per-model limits
ChatGPT Plus / Pro / Teamcodex login (OpenAI Codex CLI)5-hour and weekly limits, plus any extra model limits
Gemini, personal Google accountagy, then log in (Google Antigravity CLI)Gemini models 5h and weekly, Claude and GPT models 5h and weekly
Gemini, Workspace / Code Assistgemini (Gemini CLI)Per-model daily quota
Claude APIPaste an Admin API key in SettingsCost today and this month, tokens today, top models

Then click Rescan in Settings, or restart the app.

The Admin API key looks like sk-ant-admin01-..., and an organization admin creates it in the Console under Settings > Admin keys. Ordinary sk-ant-api... keys and individual, non-organization accounts cannot read usage.

Using the note

Moving and resizing

  • Move: drag it anywhere, including onto another monitor. It stays above other windows, on every desktop, and over full-screen apps.
  • Resize: drag any edge or corner, like a normal window. There is a grip in the bottom right. The cards rearrange to fit: one column when narrow, two by two at medium width, side by side when wide. Rows stretch to fill the height you set. Until you resize it, the note hugs its content and scrolls only if it would be taller than the screen. Right-click and choose Reset size to go back to hugging. On Windows, dropping the note near a screen edge snaps it flush.
  • Text size is in Settings, from 70% to 200%.

Reading a card

Each account gets a card in its agent's colours: Claude terracotta, ChatGPT green, Gemini blue to purple. A card with something that needs you gets an orange outline. Top to bottom:

  1. Name, plan badge (Max, Team, Plus and so on) and a status chip such as "2 working" or "2 blocked".
  2. Usage. The main window, usually the 5-hour session, is a Pac-Man track. The dots ahead are the quota you have left, and Pac-Man sits at the percentage used. He glides forward eating dots as usage rises, and chomps only while one of that account's agents is working. A barrier appears in front of him when the account is rate limited or at 100%. Other limits are thin bars with dotted trails. Colours turn orange at 70% and red at 90%, and a limit the provider flags as critical is red at any percentage.
  3. Usage cost, as reported by the provider.
  4. Cost per agent, read from Claude Code's transcript.
  5. Context window for the card's most urgent agent, for example 124k / 1M tokens, 62%, with what is left, the model, and whether the maximum is assumed or reported. It turns amber at the threshold in Settings, 80% by default.
  6. Live agents, one row per running session, most urgent first, with sub-agents nested underneath. Click a row for its details. Click the card's name for provider details.
  7. Sign-in problems replace the numbers with a panel naming the command to run, instead of a misleading 0%.

Live agent states

Every row names the project and spells out the status in words, so you never have to interpret the animation.

StatusWhat you seeWhere it comes from
WorkingGhost scoots around, bits of output fly offSession busy, writing a reply
ThinkingGhost floats, eyes wander, thought bubbleWaiting on the model
Running / Reading / Editing / BrowsingGhost next to its tool: terminal, magnifier, pencil, globe, wrenchAn unanswered tool call in the transcript
DelegatingGhost hands a package to a small sub-agent ghostAn Agent or Task tool call
Needs youGhost looks at you, orange question mark pulsesClaude Code is waiting for your input or permission
DoneA quick jump with sparks, then a tickA turn just finished without errors
Rate limitedGhost stuck behind a striped barrierA 429 from the API, or the plan window at 100%
RetryingGhost keeps going with spinning arrowsAn API error mid-turn that Claude Code is retrying
ErrorA short shake, dizzy eyes, red exclamationThe turn ended with an API error
IdleGhost dozesSession open, nothing running
QueuedGhost waits in a small queueA sub-agent launched but not yet producing output

Codex and Antigravity only report working and idle, plus Done, so their ghosts show only those states.

Sub-agents. Each Agent tool call that Claude Code runs as a separate agent gets its own row under its parent, read from the subagents transcripts. It shows Queued until its first reply, then the same states as a session, then Done and Idle once its turn ends. Finished sub-agents stay listed for 5 minutes, configurable in Settings, after which only a count remains. Nested sub-agents nest.

Accessibility and performance. The note never takes keyboard focus, since it is an always-on-top tool window, so expand and collapse rows with the mouse. Rows still expose their name and status to screen readers. Animations are Core Animation layers, so an animating note uses almost no CPU, and they pause while the note is hidden or covered. Under macOS Reduce Motion, or with Animate agents and Pac-Man turned off, still poses replace them and each state is still distinguishable.

When the note appears

The note follows your tools, so it is only on screen while there is something to watch.

  • Nothing open, no note. At login, and whenever no claude, codex or agy is running, the note stays away. The menu bar or tray icon keeps showing your highest usage.
  • Open a tool and the note appears by itself, listing only the accounts that have a tool open. With work and personal Claude accounts and only a work session running, you see the work card alone. Start agy and its card joins.
  • Close the last tool and the note leaves 30 seconds later, so quitting and resuming a session does not make it blink.
  • Hide it while you work with the ✕ button or the icon, and it stays away until the next time you go from nothing open to something open.
  • Peek with nothing running: Show Note from the icon (on Windows, a left-click) opens the note with every account, and the API card if you track it, so you can check your limits before you start. Opening a tool ends the peek.

To keep the note away for good, untick Show the note while a tool is open in Settings. Showing it from the icon turns that back on.

Right-click menu

Right-click the note for the menu below. Right-click a specific card to also get a Hide item for that account.

ItemWhat it does
Refresh NowFetch all accounts now
Hide accountHide this account. Bring it back from Accounts
AccountsTick which accounts appear on the note
Size (macOS) / Reset size (Windows)macOS: zoom presets. Windows: back to hugging the content
ThemeDark, Glass (translucent), Light, Sticky note
CompactOne line per limit
Show Live AgentsShow or hide the live agents section
Lock Position & SizeStops accidental dragging and hides the resize grip
SettingsOpen Settings
Hide NoteHide the note for now. It returns with the next tool, or from the menu bar or tray

The icon shows the highest current-window usage across your accounts. On macOS it is a monochrome ghost with the percentage beside it, which follows light and dark mode. On Windows the ghost is filled with the severity colour and the percentage sits inside it.

The menu lists every account and limit, plus Show/Hide Note, Lock Position, Click-Through, Refresh Now, Settings and Quit. On Windows, left-click the tray icon to show or hide the note. With no tool open, showing it is a peek at every account (see When the note appears).

Click-through makes mouse clicks pass straight through the note to whatever is under it, turning it into a true overlay. Turn it off from the menu bar or tray icon.

Settings

  • Subscriptions. Every sign-in that was found, each with its status. Untick an account to hide it. Rescan searches again after you log in to a new CLI. Paste a token instead covers a Claude OAuth token if you do not use Claude Code. On Windows, Add Claude config folder covers a Claude Code folder in an unusual location.
  • API usage (Claude Console). Paste an Admin API key.
  • Floating note. Whether it appears while a tool is open, theme, size, opacity, compact mode, sessions, lock, click-through, refresh interval from 1 to 30 minutes, the context-window warning threshold from 50% to 95%, and whether finished sub-agents stay listed.
  • General. Launch at login.

How it works

Everything is read locally and read-only. Pitwall never writes to any CLI's files and never writes a token back.

AccountSign-in read fromNetwork requestActive sessions
Claude CodemacOS: Keychain Claude Code-credentials, plus -<hash> per extra config folder. Windows: %USERPROFILE%\.claude*\.credentials.jsonGET https://api.anthropic.com/api/oauth/usage for windows, limits[] including the Fable limit, spend, and the weekly breakdown<config>/sessions/<pid>.json gives busy or idle, and only if the process is still alive. The transcript at projects/<slug>/<sessionId>.jsonl, appended bytes only, gives model, tokens and context. <sessionId>/subagents/**/agent-*.jsonl gives the sub-agents
Codex (ChatGPT)~/.codex/auth.jsonGET https://chatgpt.com/backend-api/wham/usage. If the token has expired, the last limits recorded in ~/.codex/sessions/**/rollout-*.jsonl are shown instead~/.codex/thread-writer-locks/*.lock. Working means a rollout was written in the last 20 seconds
AntigravitymacOS: Keychain item with account antigravity. Windows: Credential Manager entry gemini:antigravity. Fallback: ~/.gemini/antigravity-cli/antigravity-oauth-tokenPOST https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary, on the backend and quota project that agy's own log/cli-*.log shows it using, since each backend keeps its own quotaRunning agy processes. Working means a conversation file changed in the last 20 seconds. Model and workspace come from that launch's log
Gemini CLI~/.gemini/oauth_creds.jsonPOST .../v1internal:loadCodeAssist and :retrieveUserQuotaChat logs written in the last 15 minutes
Claude APIThe Admin key you pastedGET https://api.anthropic.com/v1/organizations/cost_report and /usage_report/messagesNot applicable

Timing. Session scanning is local and runs every 2 seconds. Usage is fetched on the refresh timer, when you click refresh, and when a session finishes working, at most once a minute per account.

Admin API costs are reported in cents and converted to dollars. "Today" means today in UTC, and the data lags by about 5 minutes.

How cost per agent is worked out

Claude Code prices each session in its own transcript, and the note reads that figure rather than inventing one. Two things it is careful about:

  • A session's cost covers its sub-agents. Its token count does not. The Agent SDK documents the same split: total_cost_usd counts sub-agent requests alongside the top-level loop, while the token usage counts only the top-level loop. So a sub-agent's cost is shown as a share of the session, never added on top of it.
  • Claude reports cost per model, not per agent. When an agent is the only one running its model, which is the usual case for a sub-agent, that model's figure simply is its cost, exactly. When agents share a model, the model's cost is split between them by weighted tokens: an output token counts 5x, a cache write 1.25x, a cache read 0.1x, so a cache-heavy agent is not charged like a writer. The row then says the figure was derived. Only those ratios are assumed. The rate itself comes from the cost Claude reported.

It is list-price arithmetic, not a bill. A session whose transcript carries no cost line says "Not reported for this session" rather than guessing.

The icon

The app icon is the same ghost the agents in the note are drawn from. swift macos/Tools/make-icons.swift redraws it and writes both macos/Resources/AppIcon.icns and windows/Pitwall/Pitwall.ico using CoreGraphics only, no packages. Both files are committed, so a normal build never runs it. Run it when the mark changes.

Security and privacy

Pitwall reads the sign-ins of AI coding CLIs on your machine, which is a sensitive thing for a program to do. SECURITY.md is the full account, including how to report a vulnerability. The short version:

  • No telemetry, no analytics, no crash reporting, no update check. Nothing is sent anywhere except the provider APIs listed above.
  • Network allowlist. The app can only contact api.anthropic.com, chatgpt.com, oauth2.googleapis.com and cloudcode-pa.googleapis.com, or the *-cloudcode-pa.googleapis.com backend your agy uses, and only for accounts you have enabled. Redirects are refused, so a token cannot be forwarded to another host.
  • No third-party dependencies on either platform, so there is no supply chain to compromise.
  • Other apps' sign-ins are only read, never written. Claude Code and Codex tokens are never refreshed, because Codex refresh tokens are single-use and refreshing one would log you out of Codex. Antigravity and Gemini CLI tokens expire hourly and are refreshed in memory only, using the OAuth client from your own installed agy or gemini. No Google client credentials are stored in this repository.
  • Your own secrets. A pasted Admin key or token goes into the macOS Keychain, readable only while the Mac is unlocked and never synced to iCloud. On Windows it is encrypted with DPAPI for your Windows account.
  • Files other programs write are treated as untrusted input. Session ids are validated before they become part of a path, reads are size-capped, and directory walks are bounded.

What it does not protect you from. Anything already running under your user account can read these tokens directly, with or without this app. On Windows in particular, because this project is open source, the DPAPI entropy constant is public, so secrets.json is protected against another Windows user but not against software running as you. SECURITY.md spells out the whole boundary.

Troubleshooting

SymptomFix
"Sign-in expired. Run any claude command"Claude Code's token expired while it was not in use. Run claude once. The note recovers on the next refresh.
"Keychain access was denied" (macOS)Click refresh on the note and choose Always Allow. You can also fix it in Keychain Access, under the item's Access Control.
Keychain asks again after every rebuildYou are building with an ad-hoc signature. Build with an Apple Development or Developer ID certificate.
An account is missingLog in with its CLI, then Settings > Rescan. Check it is ticked under Accounts.
Two cards show the same numbersTwo config folders are signed in to the same account. Hide one.
"From your last Codex session"The Codex token expired, so the numbers come from Codex's local log. Run codex to refresh.
Gemini CLI: "no longer supported for Gemini Code Assist for individuals"Google moved personal accounts to Antigravity. Log in with agy.
Antigravity: "Couldn't refresh the Antigravity sign-in"The stored token expired and the OAuth client could not be read from your installed agy. Run agy once, then refresh.
Settings and sign-ins look reset after updatingThe app used to be called Claude Usage Note, and its identity moved with the rename. It copies the old settings and stored keys across on first launch. If something did not come over, the old data is still there, since nothing is deleted. Please report it rather than re-entering keys.
Note disappearedIt leaves when no tool is open and returns with the next one. To see it now: menu bar or tray icon, then Show Note. If it is off-screen, delete the saved position: macOS defaults delete local.pitwall noteTopLeft, Windows remove NoteLeft and NoteTop from settings.json. Then restart.
Cannot click the noteClick-through is on. Turn it off from the menu bar or tray icon.
"Rate limited by the server"Pick a longer refresh interval in Settings.
Context window: "Unavailable from provider"Codex only reports it in sessions that logged a token_count with a window size. Antigravity and Gemini CLI never do. For Claude Code it appears once the transcript has an assistant reply.
Usage cost: "Not reported by ..."Only Claude reports a cost in its usage response. Antigravity and Codex do not, and the note never estimates one.
Cost: "Not reported for this session"Only Claude Code writes a per-session cost into its transcript, and only once the session has billed a request. That format is internal to Claude Code and changes between versions, so if a release stops writing that line the note says this rather than guessing.
A sub-agent's cost says "derived"It shares a model with another agent in the session, so that model's reported cost was split by weighted tokens. An agent that is its model's only user shows Claude's own figure instead.
More than one keychain item matches (macOS)Two generic passwords share the same service or account name. Pitwall refuses to guess which one is real. Remove the duplicate in Keychain Access.

Diagnostics

Neither dump command prints a secret.

macOS:

"/Applications/Pitwall.app/Contents/MacOS/Pitwall" --dump
"/Applications/Pitwall.app/Contents/MacOS/Pitwall" --dump --verbose   # also prints response structure, field names only
"/Applications/Pitwall.app/Contents/MacOS/Pitwall" --demo             # made-up accounts cycling through every state, reads and fetches nothing

Windows: crashes are logged to %APPDATA%\Pitwall\error.log.

& "$env:LOCALAPPDATA\Programs\Pitwall\Pitwall.exe" --dump
& "$env:LOCALAPPDATA\Programs\Pitwall\Pitwall.exe" --demo

Dump output does include folder and project names, so glance over it before pasting it into an issue.

Uninstall

macOS:

  1. Turn off Launch at login in Settings.

  2. Quit from the menu bar icon.

  3. Run:

    rm -rf "/Applications/Pitwall.app"
    defaults delete local.pitwall
    
  4. If you pasted an Admin key or token, delete the Pitwall items in Keychain Access.

Windows: Settings > Apps > Installed apps > Pitwall > Uninstall. It asks whether to keep your settings. Alternatively, from the windows folder, run .\install.ps1 -Uninstall -Purge.

Contributing

Issues and pull requests are welcome. A few things worth knowing first.

Repository layout

macos/                 Swift package: menu bar item plus floating note
  Sources/Pitwall/     App code
  Tests/PitwallTests/  Unit tests, run with `swift test`
  build-app.sh         Build and sign the .app
  build-dmg.sh         Build the .app, then package a DMG
windows/               .NET 10 WPF app: tray icon plus floating note
  Pitwall/             App code
  ParserTests/         Parser checks that run on any OS
  build.ps1            Build the exe and the self-installer
  install.ps1          Scripted install and uninstall
docs/                  Design notes and specs
SECURITY.md            What the app touches, what it sends, how to report a vulnerability

Running the tests

cd macos && swift test                                # unit tests
cd windows && dotnet run --project ParserTests        # parser checks, any OS

The Windows app itself also compiles on macOS and Linux, which is useful for checking a change before you get to a PC:

cd windows && dotnet build Pitwall/Pitwall.csproj

One parser check, sub id from path, fails when run on macOS or Linux and passes on Windows. It uses a Windows-style path, and Path.GetFileNameWithoutExtension does not treat a backslash as a separator off Windows. This is expected.

Cutting a release

  1. Set the same version in windows/Pitwall/Pitwall.csproj (<Version>) and macos/Resources/Info.plist (CFBundleShortVersionString and CFBundleVersion), and commit.
  2. Tag that commit and push the tag: git tag v1.2.0 && git push origin v1.2.0.

.github/workflows/release.yml then tests and builds both apps, and publishes a GitHub Release with the DMG, the x64 and ARM64 Windows installers and their checksums. It refuses a tag that does not match the two version numbers. A tag with a suffix, such as v1.2.0-rc1, becomes a pre-release. Versions follow MAJOR.MINOR.PATCH: a fix bumps the last number, a feature the middle one.

Things to keep in mind

  • No dependencies. Both apps deliberately have zero third-party packages. Please keep it that way. A pull request that adds a NuGet or SwiftPM dependency needs a strong reason.
  • The two apps are kept at parity. A feature added to one should land in the other. macos/PARITY.md records what the last port involved.
  • Never estimate a number. If a provider does not report something, the note says so. This is a core principle of the project, not a detail.
  • Treat local files as untrusted. Everything the app parses is written by another program. Validate ids before they become paths, cap reads, bound directory walks. See SECURITY.md.
  • Security issues should go through private vulnerability reporting, not a public issue.

Known limitations

  • The provider endpoints are not public APIs. The subscription endpoints for Claude, ChatGPT and Google Code Assist are the ones the official CLIs use. They are undocumented and may change without notice.
  • No code signing certificate. The release installers are unsigned, so Windows and macOS warn about them on first launch. A build you make yourself runs without a warning on the machine that built it.
  • The Glass theme on Windows is a translucent surface, not a true behind-window blur.
  • Windows agent sessions started by another user, or elevated, cannot be named. They show as agy.
  • Screenshots and screen sharing. The note shows an agent's task description and up to 160 characters of its latest reply, so that text appears in anything that captures your screen.

License

MIT. Copyright (c) 2026 Emilian Popescu.

Contributors

Emip159

28 commits

Languages

C#

50.2%

Swift

48.9%