this repo has no description
1---
2summary: "CodexBar implementation notes: data sources, refresh cadence, UI, and structure."
3read_when:
4 - Modifying usage fetching/parsing for Codex or Claude
5 - Changing refresh cadence, background tasks, or menu UI
6 - Reviewing architecture before feature work
7---
8
9# CodexBar – implementation notes
10
11## Data source
12- Codex: run `codex /status` inside a native PTY (no tmux, no web/cookie login). We parse the rendered rows for session/weekly limits and credits; when the CLI shows an update prompt we auto-press Down+Enter and retry.
13- Account info is decoded locally from `~/.codex/auth.json` (`id_token` JWT → `email`, `chatgpt_plan_type`); no browser scraping involved.
14- Claude: run `claude /usage` in a PTY and parse the text panel; retries enter and reports CLI errors verbosely.
15
16## Refresh model
17- `RefreshFrequency` presets: Manual, 1m, 2m (default), 5m; persisted in `UserDefaults`.
18- Background Task detaches on app start, wakes per cadence, calls `UsageFetcher.loadLatestUsage()`.
19- Manual “Refresh now” menu item always available; stale/errors are surfaced in-menu and dim the icon.
20- Optional future: auto‑seed a log if none exists via `codex exec --skip-git-repo-check --json "ping"`; currently not executed to avoid unsolicited usage.
21
22## UI / icon
23- `MenuBarExtra` only (LSUIElement=YES). No Dock icon. Label replaced with custom NSImage.
24- Icon: 20×18 template image; top bar = 5h window, bottom hairline = weekly window; fill represents “percent remaining.” Dimmed when last refresh failed.
25- Menu shows 5h + weekly rows (percent left, used, reset time), last-updated time, account email + plan, refresh cadence picker, Refresh now, Quit.
26
27## App structure (Swift 6, macOS 15+)
28- `UsageFetcher`: log discovery + parsing, JWT decode for account.
29- `UsageStore`: state, refresh loop, error handling.
30- `SettingsStore`: persisted cadence.
31- `IconRenderer`: template NSImage for bar.
32- Entry: `CodexBarApp`.
33
34## Packaging & signing
35- `Scripts/package_app.sh`: swift build (arm64), writes `CodexBar.app` + Info.plist, copies `Icon.icns` if present; seeds Sparkle keys/feed.
36- `Scripts/sign-and-notarize.sh`: uses APP_STORE_CONNECT_* creds and Developer ID identity (`Y5PE65HELJ`) to sign, notarize, staple, zip (`CodexBar-0.1.0.zip`). Adjust identity/versions as needed.
37- Sparkle: Info.plist contains `SUFeedURL` (GitHub Releases appcast) and `SUPublicEDKey` placeholder; updater is `SPUStandardUpdaterController`, menu has “Check for Updates…”.
38
39## Limits / edge cases
40- If no `token_count` yet in the latest session, menu shows “No usage yet.”
41- Schema changes to Codex events could break parsing; errors surface in the menu.
42- Only arm64 scripted; add x86_64/universal if desired.
43
44## Alternatives considered
45- Fake TTY + `/status`: unnecessary; structured `token_count` already present in logs after any prompt.
46- Browser scrape of `https://chatgpt.com/codex/settings/usage`: skipped (cookie handling & brittleness).
47
48## Learnings / decisions
49- About panel: `AboutPanelOptionKey.credits` needs `NSAttributedString`; we supply credits + icon safely.
50- Menu palette: keep primary by default, apply `.secondary` only to meta lines, and use `.buttonStyle(.plain)` to avoid tint overriding colors.
51- Usage fetch runs off-main via detached task to keep the menu responsive if logs grow.
52- Emoji branding lives only in README; app name stays `CodexBar`.
53- Swift 6 strict concurrency enabled via `StrictConcurrency` upcoming feature to catch data-race risks early.