this repo has no description
at main 53 lines 3.5 kB view raw view rendered
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.