feat(mac): hide agent tabs when fewer than two providers have spend

The tab strip was visible for everyone regardless of which tools they
actually run, which produced a row of All + one provider for Claude-only
users and a row of All + zeros for users on exotic stacks. Hide the
whole row until a second provider has real spend, matching the behavior
the GNOME extension ships with.

Also expand ProviderFilter to include every provider the CLI supports
(OpenCode and Pi were missing) so their tabs appear when those tools
produce sessions. The CLI already emits pi and opencode in the payload's
providers map; the Mac app just wasn't offering a tab for them.

visibleFilters now filters on value > 0 instead of key presence, because
the CLI includes zero-cost entries for discovered-but-unused providers
and we don't want those rendering as blank tabs.
This commit is contained in:
AgentSeal 2026-04-18 05:07:36 -07:00
parent b232b3cfbe
commit 85d7bea7ea
3 changed files with 29 additions and 4 deletions

View file

@ -33,7 +33,16 @@ struct AgentTabStrip: View {
}
private var visibleFilters: [ProviderFilter] {
let activeKeys = Set(allProvidersToday.current.providers.keys.map { $0.lowercased() })
// Only surface providers that actually spent money in the all-provider view.
// The CLI includes zero-cost providers in the payload for completeness, so
// filtering on value > 0 keeps the tab row honest and avoids showing tabs
// for tools the user hasn't run yet.
let activeKeys = Set(
allProvidersToday.current.providers
.filter { $0.value > 0 }
.keys
.map { $0.lowercased() }
)
return ProviderFilter.allCases.filter { filter in
if filter == .all { return true }
return activeKeys.contains(filter.rawValue.lowercased())
@ -87,6 +96,8 @@ extension ProviderFilter {
case .codex: return Theme.categoricalCodex
case .cursor: return Theme.categoricalCursor
case .copilot: return Color(red: 0x6D/255.0, green: 0x8F/255.0, blue: 0xA6/255.0)
case .opencode: return Color(red: 0x5B/255.0, green: 0x83/255.0, blue: 0x5B/255.0)
case .pi: return Color(red: 0xB2/255.0, green: 0x6B/255.0, blue: 0x3D/255.0)
}
}
}