codeburn/mac/Tests/CodeBurnMenubarTests
ozymandiashh 1959550218 feat(menubar): add preferred terminal setting with Terminal.app fallback
Full Report and Optimize always opened Terminal.app. Add a closed
PreferredTerminal enum (Terminal.app, iTerm2), a General settings picker,
and graceful fallback: chosen terminal -> Terminal.app -> headless spawn.

Defaults to Terminal.app so existing users see no change.

The terminal is selected from a closed enum, never a user string, so the
`tell application "..."` target stays a compile-time literal. Commands are
still whitespace-joined argv validated token-by-token by CodeburnCLI.isSafe
before any interpolation, preserving the shell-injection invariant.

Only terminals with a real "run in a live window" scripting verb are listed:
Terminal.app has `do script`, iTerm2 has `write text` on a session. Ghostty,
WezTerm, Warp, Alacritty and kitty expose no equivalent, so they keep the
existing headless fallback rather than shipping a window that closes on exit.

The iTerm2 script targets `application "iTerm"`, not `"iTerm2"`. AppleScript
resolves the name of a not-yet-running app through LaunchServices by bundle
file name, and the bundle is iTerm.app. Measured on iTerm2 3.6.11: with the
app quit, `tell application "iTerm2"` fails to compile (-2741) while
`tell application "iTerm"` compiles, cold-launches iTerm2 and runs the
command. The `"iTerm2"` spelling only works while the app already happens to
be running.

Fallback is a chain that checks results rather than a single fire-and-forget
pick, because "installed" does not imply "scriptable": osascript can still
fail on a missing Automation approval or a broken bundle. Each candidate is
run, waited on and its exit status checked, off the main thread so the
popover stays responsive; only once every candidate has failed do we spawn
headless. Every step logs via NSLog, so a user who sees no window has a trail
in Console.app instead of an app that looks dead. The decision logic is
extracted into terminalChain/runFirstWorking so tests exercise
"primary failed -> fell back" without launching anything.

Document the setting in the README next to the other menubar defaults keys.

Closes #877
2026-08-04 00:19:00 +03:00
..
AppStoreRefreshRecoveryTests.swift feat(menubar): mark badge when a paired device is unreachable in combined scope 2026-07-31 15:13:38 -06:00
AppVersionTests.swift Normalize menubar version display 2026-05-11 11:21:39 -07:00
CapacityEstimatorTests.swift feat(mac): native Swift menubar app + one-command install 2026-04-17 16:55:56 -07:00
ClaudeRateLimitTests.swift menubar: honor Retry-After on Claude quota 429s, back off failed refreshes (#702) 2026-07-16 14:52:47 -07:00
ClaudeSubscriptionParsingTests.swift fix(menubar): provider-correct plan tab copy; surface model-scoped weekly limits 2026-07-02 19:37:51 +02:00
CLIDevinConfigTests.swift feat: add devin provider (#444) 2026-06-09 21:58:31 +02:00
CodexPlanParsingTests.swift feat(codex): show the credit limit on credit-metered ChatGPT workspaces 2026-07-27 08:19:59 -04:00
CodexQuotaSummaryTests.swift fix(codex): align credit/dollar footer formatting across desktop and menubar 2026-08-01 22:32:53 +02:00
CodexResetCreditsTests.swift menubar: surface Codex limit-reset credits (count and next expiry) in the Plan tab (#723) (#724) 2026-07-17 05:58:21 -07:00
CodexTerminalFailureTests.swift test(menubar): lock in Codex terminal-failure classification 2026-05-30 12:32:19 -07:00
ContributionHeatmapTests.swift fix(menubar-tests): add missing localModelSavings/savingsUSD args so swift tests compile (#465) 2026-06-09 21:56:13 +02:00
DataClientProcessTests.swift feat(menubar): Claude config selector, hardened (supersedes #635) 2026-07-10 01:44:51 +02:00
KimiQuotaPresentationTests.swift fix(menubar): keep showing Kimi quota when the login is idle, stamp stale data 2026-07-26 06:35:13 -07:00
KimiUsageParsingTests.swift menubar: add Kimi Code subscription quota tracking 2026-07-23 21:31:55 +02:00
MenubarPayloadCombinedTests.swift feat(menubar): add Local/Combined usage toggle (#566) (#568) 2026-06-28 22:01:01 +02:00
MenubarPeriodSettingsTests.swift fix(clients): display CLI-computed values verbatim, align period windows across app/dash/menubar 2026-07-20 06:26:15 -07:00
MenubarStatusCacheTests.swift feat(menubar): add Local/Combined usage toggle (#566) (#568) 2026-06-28 22:01:01 +02:00
QuotaPaceTests.swift menubar: linear pace on Codex quota windows — deficit/reserve, projection, run-out ETA (#726) (#728) 2026-07-20 05:21:43 -07:00
RefreshCadenceTests.swift menubar: skip unchanged background refreshes, 120s AC idle cadence, utility QoS for tick spawns (#703) (#704) 2026-07-16 15:11:25 -07:00
StatusItemContextMenuPolicyTests.swift test(mac): lock status-item context menu policy (#802) 2026-07-24 19:27:25 +07:00
TerminalLauncherTests.swift feat(menubar): add preferred terminal setting with Terminal.app fallback 2026-08-04 00:19:00 +03:00
UpdateCheckerTests.swift fix(menubar): clarify update failure status 2026-07-26 15:20:13 +08:00
UsageDataChangeGuardTests.swift menubar: skip unchanged background refreshes, 120s AC idle cadence, utility QoS for tick spawns (#703) (#704) 2026-07-16 15:11:25 -07:00
WorkflowStripTests.swift menubar: add Workflow strip after the Models section (#785) 2026-07-20 13:55:55 -07:00