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

Recommended

Releases 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.

If Gatekeeper blocks the first launch, the DMG may be corrupted or tampered with. Official builds are signed and notarized, and normally open without any prompt. If you get blocked, download it again.

Build from source

Available

Clone 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).

terminal
git clone https://github.com/tsuvic/agentbar
cd agentbar

swift build

# 実行。ウィンドウは開きません。
# メニューバー(時計の左)にゲージアイコンが現れます。
swift run AgentBar

# テスト。プロセス非起動の回帰テストを含みます(172 テスト)。
swift test

Homebrew Cask

Planned

The cask definition lives in the repository at distribution/agentbar.rb, but no public tap exists yet. Use the DMG until then.

terminal
# 公開準備ができ次第アナウンスします。
brew install --cask agentbar
On launch, icons appear in both the menu bar and the Dock, and no window opens. The menu bar icon is a MenuBarExtra 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.

Active

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

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

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.

Update

Tool updater

Detects AI tools regardless of how they were installed.

MethodDetectionUpdate
npm globalpackage.json under npm root -gnpm install -g <pkg>@latest
Homebrew formulabrew list --versionsbrew upgrade <formula>
Homebrew caskbrew list --caskbrew upgrade --cask <cask>
App bundleInfo.plist in /Applications/*.apppackage manager only
Binarycheck ~/.local/bin and similar with --versionpackage 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).

Diag

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).

sessionsmost recent first
  • agentbarmain1.24Mtokens
    claude128 msgsclaude-sonnet2h ago
  • sitefeat/docs310.4ktokens
    codex42 msgsgpt-5-codex5h ago
  • pixeldexdevelop890.2ktokens
    qwen67 msgsqwen-maxyesterday
  • resume
    cursor23 msgscomposer3d ago
conversationagentbar @ main
user14:12

Triage 200 CodexBar issues and summarize the design-level causes.

assistant14:12claude-sonnet4,218 tokens

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…

Estimated cost for this session$1.87input $0.21 / output $1.42 / cache $0.24Estimate

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.

Neither Active nor History spawns extra processes. Claude, Codex, and Qwen re-parse JSONL files, and Cursor opens a local SQLite database read-only.

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

Hard timeout

Circuit breaker

CPU budget

ProcessGuard

Stale-while-revalidate

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
This guarantee is also enforced by tests (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

Sources/
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)
Cursor's database is opened with SQLITE_OPEN_READONLY. No writes happen. Conversation text is read locally for display only; it is neither stored nor sent.
The exception to the no-subprocess rule is the updater. Only when you press Update does it run 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.
The app persists exactly three settings, all refresh intervals (~/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.

Get AgentBar

See how lightly it runs on your own Mac.

AgentBar runs entirely on files your agents already write to disk. It spawns no CLI, MCP server, browser, or agent to get usage or history. The Diag tab reports AgentBar's own CPU, memory, and spawned process count — always 0. macOS 14+ · Swift 6 / SwiftUI · source on GitHub.

git clone https://github.com/tsuvic/agentbar