mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-04-28 06:59:37 +00:00
* Add Kiro provider and transparent auto-model naming - Add Kiro IDE provider: parses .chat JSON files, estimates tokens, normalizes dot-versioned model IDs for cost lookup - Show "Cursor (auto)", "Copilot (auto)", "Kiro (auto)" in CLI dashboard instead of pretending to know which model was used - Route auto model names through BUILTIN_ALIASES for cost estimation * Fix menubar tabs: add missing providers, show period-scoped costs - Add Kiro, OMP to ProviderFilter enum so installed providers appear as tabs - Merge Cursor + Cursor Agent into single Cursor tab - Tab costs now reflect the selected period (7d/30d/month/all) instead of always showing today - Tab visibility still uses today's provider list so tabs don't disappear when switching to periods with no data * Add accent color picker to menubar with Apple system presets - 9 presets using Apple's exact macOS dark-mode accent colors (Ember, Blue, Purple, Pink, Red, Orange, Yellow, Green, Graphite) - Color picker in header, persisted via UserDefaults - "Burn" text stays fixed ember regardless of accent - ThemeState is MainActor-isolated for thread safety - Picker state lifted to AppStore so it survives .id() tree rebuild - Accessibility labels on all color swatches - Renamed brandAccentDark/brandEmberDeep/brandEmberGlow to match their actual light/deep/glow semantics * Fix review findings: case-sensitive cost lookup, Kiro timestamp guard, cache versioning - Normalize provider dictionary keys to lowercase in tab cost lookup so "Cursor Agent" (title-case from CLI) matches providerKeys - Guard against missing/invalid/epoch startTime in Kiro parser to prevent RangeError crash or 1970-01-01 ghost entries - Bump DAILY_CACHE_VERSION to 4 so upgraded users get a clean recompute with the new auto-model naming (cursor-auto vs default) - Add version field to cursor-results.json cache to invalidate stale entries that still use the old 'default' model name
55 lines
1.9 KiB
Swift
55 lines
1.9 KiB
Swift
import SwiftUI
|
|
|
|
struct HeroSection: View {
|
|
@Environment(AppStore.self) private var store
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
SectionCaption(text: caption)
|
|
|
|
HStack(alignment: .firstTextBaseline) {
|
|
Text(store.payload.current.cost.asCurrency())
|
|
.font(.system(size: 32, weight: .semibold, design: .rounded))
|
|
.monospacedDigit()
|
|
.tracking(-1)
|
|
.foregroundStyle(
|
|
LinearGradient(
|
|
colors: [Theme.brandAccent, Theme.brandAccentDeep],
|
|
startPoint: .top,
|
|
endPoint: .bottom
|
|
)
|
|
)
|
|
|
|
Spacer()
|
|
|
|
VStack(alignment: .trailing, spacing: 2) {
|
|
Text("\(store.payload.current.calls.asThousandsSeparated()) calls")
|
|
.font(.system(size: 11))
|
|
.monospacedDigit()
|
|
.foregroundStyle(.secondary)
|
|
Text("\(store.payload.current.sessions) sessions")
|
|
.font(.system(size: 10.5))
|
|
.monospacedDigit()
|
|
.foregroundStyle(.tertiary)
|
|
}
|
|
}
|
|
}
|
|
.padding(.horizontal, 14)
|
|
.padding(.top, 10)
|
|
.padding(.bottom, 12)
|
|
}
|
|
|
|
private var caption: String {
|
|
let label = store.payload.current.label.isEmpty ? store.selectedPeriod.rawValue : store.payload.current.label
|
|
if store.selectedPeriod == .today {
|
|
return "\(label) · \(todayDate)"
|
|
}
|
|
return label
|
|
}
|
|
|
|
private var todayDate: String {
|
|
let formatter = DateFormatter()
|
|
formatter.dateFormat = "EEE MMM d"
|
|
return formatter.string(from: Date())
|
|
}
|
|
}
|