Documentation
From install to internals,
in one page.
How to install it, how to use the five menu bar tabs (Active / Usage / History / Update / Diag) and the Graph window, the mechanisms that keep it light, privacy, and the FAQ. The comparison with CodexBar's problems is on the .
01 · Install
Install
The DMG from GitHub Releases is recommended. It is Developer ID signed and notarized by Apple. Building from source produces the same app.
- macOS
- 14 (Sonoma) or later. Apple Silicon and Intel (universal binary)
- Building from source
- Xcode 16 / Swift 6 (the command line tools alone are not enough)
- Dependencies
- None (SwiftPM only)
DMG download
RecommendedReleases page. Download AgentBar-<version>.dmg, open the DMG, and drag AgentBar.app into Applications. On launch it stays in both the menu bar and the Dock.
Build from source
AvailableClone the repository and run swift run. The build needs a Swift 6 toolchain from Xcode 16 or later (CI verifies with Xcode 16.x on a macOS 15 runner).
git clone https://github.com/tsuvic/agentbar
cd agentbar
swift build
# 実行。ウィンドウは開きません。
# メニューバー(時計の左)にゲージアイコンが現れます。
swift run AgentBar
# テスト。プロセス非起動の回帰テストを含みます(172 テスト)。
swift testHomebrew Cask
PlannedThe cask definition lives in the repository at distribution/agentbar.rb, but no public tap exists yet. Use the DMG until then.
# 公開準備ができ次第アナウンスします。
brew install --cask agentbarMenuBarExtra popover for glancing at usage and pending approvals; clicking the Dock icon opens the Graph window.To uninstall, drag AgentBar.app to the Trash. The only leftover is ~/Library/Preferences/com.tsuvic.agentbar.plist, which holds the refresh interval settings; delete it if needed. Everyday operation is covered in Usage.
02 · Usage
Usage
Clicking the gauge icon in the menu bar opens a 320pt popover. The five tabs are Active / Usage / History / Update / Diag, and Active is shown when it opens. The label next to the icon shows Claude's weekly quota when there is one, otherwise today's total tokens.
Live activity monitor
Watches session directories by file polling and re-reads the trace when something changes (10-second throttle). Each agent's current state is shown as running / awaiting approval / awaiting input / done / failed.
Runs awaiting approval or input are pinned to the top as Needs attention. For Claude, a pending approval is detected from unfinished tool_use and result records at the end of the raw JSONL. Codex, Qwen, and Cursor use best-effort estimates from conversation turns.
Opening the Graph window from the header shows the call relationships between agents as an indented tree. The mechanics are covered in the Architecture section.
Usage monitor
Rows for the eight registered providers (Claude, Codex, Qwen, Gemini, Cursor, Command Code, OpenCode, Hermes), each with today's tokens, the 7-day total, and the age of the last fetch.
Tokens are broken down into input / output / cache read / cache creation / reasoning. Per-model totals are shown too.
Quota bars use the accent color below 80%, warning at 80% and above, and danger at 100%. Claude reads its 5-hour / weekly limits from ~/.claude/usage-watch/rate-limits.json.
The refresh interval is chosen from the footer menu (Manual / 5 / 15 / 30 / 60 minutes). The 5-minute floor is deliberate: 1-minute refresh was one of the settings that caused problems in CodexBar.
When a fetch fails, the last good data stays on screen with the fetch timestamp (stale-while-revalidate).
History and conversation detail
Sessions from the last 60 days, up to 500 per provider. Each row packs project, model, tokens, message count, time, and estimated cost, with a provider filter.
Selecting a session shows its conversation turns (user / assistant / tool) directly, with model and token counts.
Tool updater
Detects AI tools regardless of how they were installed.
| Method | Detection | Update |
|---|---|---|
| npm global | package.json under npm root -g | npm install -g <pkg>@latest |
| Homebrew formula | brew list --versions | brew upgrade <formula> |
| Homebrew cask | brew list --cask | brew upgrade --cask <cask> |
| App bundle | Info.plist in /Applications/*.app | package manager only |
| Binary | check ~/.local/bin and similar with --version | package manager only |
Checks and updates run only when you trigger them. There is no periodic polling. Every command has a hard timeout (SIGTERM, a grace period, then SIGKILL).
Self-diagnostics
Reports AgentBar's own behavior for the most recent usage fetch.
- Wall time and CPU time
- Memory (RSS)
- Files read / records parsed
- Forbidden processes spawned (should always be 0)
- Exit reason (success / timedOut / circuitOpen / forbiddenProcess)
This monitoring exists so AgentBar never becomes the thing it is replacing. A provider that crosses a threshold is suspended automatically.
From session list to conversation turns
The History tab reads the same local files as daily usage, broken down per session. From a cross-provider list (project, git branch, message count, tokens, main model, last activity) you can drill down into individual conversation turns (user / assistant / tool, with timestamps, model, and per-turn tokens).
- agentbarmain1.24Mtokensclaude128 msgsclaude-sonnet2h ago
- sitefeat/docs310.4ktokenscodex42 msgsgpt-5-codex5h ago
- pixeldexdevelop890.2ktokensqwen67 msgsqwen-maxyesterday
- resume—cursor23 msgscomposer3d ago
Triage 200 CodexBar issues and summarize the design-level causes.
Confirmed. The root cause is a design that spawns a full-stack CLI just to read usage; the auto-update traffic in #2052 and the browser launches in #1844 all derive from it…
The per-model token breakdown also feeds a cost estimate (USD). It is always an estimate. Usage covered by a subscription plan may not be billable, and sources that report only totals are priced at the highest output rate, so the number skews high. Do not use it for billing.
03 · Architecture
Why it stays light
The default usage data is read from files the agents already write to disk. A normal fetch is four steps (timer, open files, parse, render), with no subprocess and no network involved.
Disk
Files the agents write themselves
Claude
~/.claude/projects/**/*.jsonl
Codex
~/.codex/sessions/YYYY/MM/DD/*.jsonl
Qwen
~/.qwen/projects/<project>/chats/*.jsonl
Cursor
…/Cursor/User/globalStorage/state.vscdb
ProviderCoordinator
An actor. Every fetch goes through here
Single-flight / While a fetch for a provider is running, no new fetch starts; waiters share the in-flight result.
Hard timeout / Slow fetches are killed. Default 10 seconds.
Circuit breaker / Three consecutive failures suspend the provider for 15 minutes.
CPU budget / If a single fetch uses more than 1.5 seconds of CPU, the provider is suspended.
ProcessGuard / Diffs the process table before and after a fetch; a forbidden process appearing fails the fetch.
Stale-while-revalidate / On failure, keeps the last good data and shows the fetch time.
UsageSnapshot
The only thing the UI renders
An immutable snapshot bundling daily token totals, quotas, the session list, and self-diagnostics. The popover only displays it and never triggers a fetch directly.
Six guards around every fetch
- Single-flight
- While a fetch for a provider is running, no new fetch starts; waiters share the in-flight result.
- Hard timeout
- Slow fetches are killed. Default 10 seconds.
- Circuit breaker
- Three consecutive failures suspend the provider for 15 minutes.
- CPU budget
- If a single fetch uses more than 1.5 seconds of CPU, the provider is suspended.
- ProcessGuard
- Diffs the process table before and after a fetch; a forbidden process appearing fails the fetch.
- Stale-while-revalidate
- On failure, keeps the last good data and shows the fetch time.
ProcessGuard: proving no-spawn at runtime
ProcessGuard snapshots the process table before and after each fetch (sysctl(KERN_PROC_ALL), itself an in-process syscall), and if a forbidden process appears in the diff, the fetch fails as forbiddenProcess. A design promise becomes runtime self-defense. The blocklist:
nodepythonnpmnpxuvchromeclaudecodexqwenbashshzsh…NoProcessSpawnTests). If the usage-fetch code path tries to spawn a subprocess, the tests fail.The three panes of the Graph window
A separate window opened from the Active tab (GraphWindowView) shows the trace graph from three angles.
- Graph
- An indented tree of call relationships between agents. Chains like Claude calling codex exec and that Codex calling claude -p are reconstructed from logs. Nodes are Runs (units of execution), so --resume or a re-run does not break parent-child links.
- Analysis
- Per-provider tokens, estimated cost, cache hit rate, and Run counts, plus graph health (chain-depth warnings from max depth, orphan Runs) and bottlenecks (the longest Run).
- Rules
- Manages your own agent configuration files. Global standard locations (~/.codex/AGENTS.md, ~/.claude/CLAUDE.md, etc.) are listed whether or not the files exist, present in green and missing in gray, and selecting one opens it for editing. Projects are listed the same way, and the Compare toggle puts global and project files side by side so you can check duplicated lines. The mapping of which tool reads which file (RulesCatalog, 2026 edition) is kept behind the ? reference. It also points out inconsistencies such as an un-imported @AGENTS.md.
Call edges are inferred. EdgeDetector detects tool-call commands (codex exec / claude -p / qwen / gemini) and correlates them with new sessions by timestamp and working directory.
Module layout
AgentBarCore (ライブラリ)
├── Models / Support 型、UsageProvider プロトコル(fetch/sessions/conversation/runSignal)
├── Providers/
│ ├── ClaudeProvider JSONL + rate-limits.json(usage/sessions/conversation/正確な runSignal)
│ ├── CodexProvider 日付ディレクトリ JSONL(session_meta/event_msg/response_item)
│ ├── QwenProvider chats JSONL(usageMetadata)+ usage_record.jsonl
│ └── CursorProvider SQLite(state.vscdb)を sqlite3 C API で直接読取
├── Trace/
│ ├── TraceModels AgentRun / TraceEvent / TraceEdge / AgentTrace / TraceGraph + RunState
│ ├── RunStateClassifier RunSignal → 状態分類(純粋)
│ ├── RunSignalDerivation 会話ターンからの最善推定 RunSignal(既定経路)
│ ├── ActivityWatcher ファイルポーリング監視、変更を AsyncStream で配信(actor)
│ ├── EdgeDetector 他エージェント起動コマンド検出 + 時刻/cwd 相関 → 推定辺
│ ├── TraceBuilder sessions + signals + edges を TraceGraph へ(actor + 純粋 TraceAssembler)
│ └── TraceAnalysis プロバイダ集計・キャッシュヒット率・グラフ健全性(純粋)
├── Rules/
│ ├── RulesCatalog ファイル→対応ツールの単一テーブル(2026 年版)
│ ├── RulesScanner プロジェクト走査・glob マッチ・不整合指摘
│ ├── GlobalRulesCatalog ホーム直下の標準ロケーション+走査
│ └── RulesCompare グローバル/プロジェクトの対照・共有行(純粋関数)
├── ProviderCoordinator actor。単一飛行・サーキットブレーカー・ハードタイムアウト・
│ スタッガースケジュール・自己監視・ProcessGuard・履歴集約
├── ProcessGuard sysctl でプロセステーブルを差分監視(spawn 検出)
├── SelfMonitor getrusage / task_info による自己 CPU・RSS 計測
├── Cost CostCalculator(モデル単価テーブル、純粋関数)
├── Redaction 診断/ログ用のパス・秘密情報マスク
└── Updater/ ToolUpdateService(actor)+ ToolCatalog + SystemCommandRunner
AgentBar (実行ファイル)
└── SwiftUI MenuBarExtra + Window
├── メニューバー Active / Usage / History / Update / Diag の5タブ(幅320pt固定)
└── Graph ウィンドウ Graph / Analysis / Rules の3ペイン(トレースツリー+詳細)A section that organizes CodexBar's design problems from its public issue reports, plus a comparison with the agent-spawning approach (also based on public issue reports), is on the product page under .
04 · Privacy
Privacy
AgentBar is local by default. Conversation text is never sent anywhere; only an explicitly configured remote usage source talks to its endpoint.
What it does not do
- No telemetry, analytics, or crash reports are ever sent.
- Network traffic is zero by default. The only exception is a remote usage source you explicitly configure.
- No Keychain access, and no reading of credentials, API keys, or tokens.
- No browser windows or authentication dialogs opened in the background.
What it reads
Only the files the agents themselves write to disk.
~/.claude/projects/**/*.jsonl and ~/.claude/usage-watch/rate-limits.json~/.codex/sessions/YYYY/MM/DD/*.jsonl~/.qwen/projects/<project>/chats/*.jsonl and ~/.qwen/usage_record.jsonl~/Library/Application Support/Cursor/User/globalStorage/state.vscdb (read-only)
SQLITE_OPEN_READONLY. No writes happen. Conversation text is read locally for display only; it is neither stored nor sent.brew / npm and similar as subprocesses. Every command has a hard timeout (SIGTERM, a grace period, then SIGKILL), and nothing runs on a schedule. Periodic usage fetching never spawns a subprocess.~/Library/Preferences/com.tsuvic.agentbar.plist). It stores no logs and no copies of conversations.Data flow and retention details are in docs/PRIVACY.md in the repository. Report privacy concerns through GitHub Issues.
05 · FAQ
FAQ
Frequently asked questions. The design comparison also lives on the product page.
Only the files the agents themselves write to disk. Claude reads ~/.claude/projects/**/*.jsonl and ~/.claude/usage-watch/rate-limits.json; Codex reads ~/.codex/sessions/YYYY/MM/DD/*.jsonl; Qwen reads ~/.qwen/projects/<project>/chats/*.jsonl; Cursor reads the local state.vscdb (SQLite, read-only).
It never touches credentials, API keys, or the Keychain. See the data source table in Architecture and the Privacy section for details.
No, they are estimates. They are computed from public list prices per model family (USD per 1M tokens). Usage covered by a subscription plan may not be billed, in which case the estimate runs higher than reality.
And when a source only reports total tokens, everything is priced at the highest output rate, which also pushes the number up. Use it to see trends, not as a basis for billing.
It opens Cursor's local SQLite database (state.vscdb) read-only and shows composer sessions and messages. Cursor does not reliably record per-message tokens, so token counts show as “—”.
Cursor changes its schema between versions, so every read is defensive. A broken schema does not crash the app; that session is skipped.
Usage fetching is file reads only. ProcessGuard additionally diffs the process table before and after each fetch and fails the fetch if node / npm / chrome or similar appears. This guarantee is enforced by regression tests as well.
The only subprocesses that ever run are the ones you trigger by pressing Update in the updater.
Checks and updates only run when you trigger them; there is no periodic polling. Every command has a hard timeout (SIGTERM, a grace period, then SIGKILL).
The actual update work is done by proper package managers such as brew / npm. AgentBar only invokes them.
The last good data stays on screen, shown together with the fetch time (stale-while-revalidate). It never drops the cache and leaves you with missing data the way CodexBar does (behavior reported in public issue #2241).
A provider that fails three times in a row is suspended for 15 minutes by the circuit breaker, so there are no retry storms.
CodexBar's problems all derive from its core design: spawning a full-stack CLI just to read usage. This analysis is based on public issue reports (#1844 / #2052 / #2251 / #2241 / #1999 / #1998, among others), with excerpts collected under on the product page.
AgentBar is a rebuild around a never-spawn design. It gets the same data from file reads alone.
Yes. The distribution is a universal binary covering both Apple Silicon and Intel. The only requirement is macOS 14 (Sonoma) or later.
A separate window opened from the Active tab, showing call relationships between agents (Claude calling codex exec, and that Codex calling claude -p, etc.) as an indented tree. It has three panes, Graph / Analysis / Rules: Analysis covers cache hit rates and bottlenecks, and Rules lists your global and project agent config files by presence (green/gray), with editing and side-by-side comparison. See the Architecture section for details.