Sources/CodexBar: Swift 6 menu bar app (usage/credits probes, icon renderer, settings). Keep changes small and reuse existing helpers.Tests/CodexBarTests: XCTest coverage for usage parsing, status probes, icon patterns; mirror new logic with focused tests.Scripts: build/package helpers (package_app.sh,sign-and-notarize.sh,make_appcast.sh,build_icon.sh,compile_and_run.sh). Release wrappers callScripts/mac-release, which resolvesMAC_RELEASE_TOOLor the sharedagent-scriptscheckout.docs: release notes and process (docs/RELEASING.md, screenshots). Root-level zips/appcast are generated artifacts—avoid editing except during releases.
- Dev loop:
./Scripts/compile_and_run.shkills old instances, builds, packages, relaunchesCodexBar.app, and confirms it stays running; add--testfor the sharded full suite. - Quick build/test:
swift build(debug) orswift build -c release;make testfor the sharded full suite. - Package locally:
./Scripts/package_app.shto refreshCodexBar.app, then restart withpkill -x CodexBar || pkill -f CodexBar.app || true; cd /Users/steipete/Projects/codexbar && open -n /Users/steipete/Projects/codexbar/CodexBar.app. - Release flow:
./Scripts/release.sh; app metadata lives in.mac-release.env, repo build/signing stays inScripts/sign-and-notarize.sh, and validation steps live indocs/RELEASING.md.
- Enforce SwiftFormat/SwiftLint: run
swiftformat Sources Testsandswiftlint --strict. 4-space indent, 120-char lines, explicitselfis intentional—do not remove. - Favor small, typed structs/enums; maintain existing
MARKorganization. Use descriptive symbols; match current commit tone.
- Add/extend XCTest cases under
Tests/CodexBarTests/*Tests.swift(FeatureNameTestswithtest_caseDescriptionmethods). - Model names in tests/code: released models or clearly fictitious names only; never expose unreleased names.
- Always run
make testbefore handoff; add focusedswift test --filter ...runs for parser/provider fixes when possible. - After any code change, run
make checkand fix all reported format/lint issues before handoff. - Prefer CLI/focused tests over app-bundle live tests when behavior can be verified without relaunching CodexBar.
- Never run tests/checks or ad-hoc validation that can display macOS Keychain prompts. Live provider probes, browser-cookie imports,
codexbar usageagainst real accounts, and real SecItem reads must be explicitly requested; otherwise use parser tests, stubs, test stores, orKeychainNoUIQuery. - macOS CI is brittle around headless AppKit status/menu tests. Prefer covering menu behavior through stable state/model seams (
MenuDescriptor,ProvidersPane,CodexAccountsSectionState, etc.) instead of constructing liveNSStatusBar/NSMenuflows unless the AppKit wiring itself is the thing under test.
- Commit messages: short imperative clauses (e.g., “Improve usage probe”, “Fix icon dimming”); keep commits scoped.
- PRs/patches should list summary, commands run, screenshots/GIFs for UI changes, and linked issue/reference when relevant.
- Use the provided scripts and package manager (SwiftPM); avoid adding dependencies or tooling without confirmation.
- Menu bar automation: capture the target screen first and verify the CodexBar icon is visibly onscreen. Reject
click-extrasuccess when coordinates fall outside display bounds; hidden menu extras are not click proof. - Validate UI/runtime behavior against the freshly built bundle; restart via the pkill+open command above to avoid running stale binaries.
- To guarantee the right bundle is running after a rebuild, use:
pkill -x CodexBar || pkill -f CodexBar.app || true; cd /Users/steipete/Projects/codexbar && open -n /Users/steipete/Projects/codexbar/CodexBar.app. - For CLI-testable provider/parser/settings behavior, use CLI/focused tests instead of
Scripts/package_app.shor./Scripts/compile_and_run.sh. - Run
./Scripts/compile_and_run.shonly when UI/runtime behavior needs bundle-level validation; it builds, tests, packages, relaunches, and verifies the app stays running. - Widget/Tahoe UI issues: use Parallels macOS VM plus screenshots/clicks for autonomous verification.
- Release script: keep it in the foreground; do not background it—wait until it finishes.
- Sparkle release key: use
.mac-release.envMAC_RELEASE_SIGNING_KEY_FILE, the legacyAGCY8w5vHirVfGGDGc8Szc5iuOqupZSh9pMj/Qs67XI=key. Do not usesparkle-private-key-KEEP-SECURE.txt; that is VibeTunnel's mismatched key. - Swift concurrency: treat sibling
async lettasks as a review red flag when one child is required and another is optional/best-effort. Prefer sequential awaits or a drainedwithThrowingTaskGroupthat surfaces required failures and explicitly contains optional failures; crash stacks mentioningswift_task_deallocorasyncLet_finish_after_task_completionshould trigger an audit of nearbyasync letusage. - Prefer modern SwiftUI/Observation macros: use
@Observablemodels with@Stateownership and@Bindablein views; avoidObservableObject,@ObservedObject, and@StateObject. - Favor modern macOS 15+ APIs over legacy/deprecated counterparts when refactoring (Observation, new display link APIs, updated menu item styling, etc.).
- Keep provider data siloed: when rendering usage or account info for a provider (Claude vs Codex), never display identity/plan fields sourced from a different provider.***
- Claude CLI status line is custom + user-configurable; never rely on it for usage parsing.
- Cookie imports: default Chrome-only when possible to avoid other browser prompts; override via browser list when needed.