@sriinnu/runic 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +8 -1
  3. package/RuniciOS/Core/RunicTypographyiOS.swift +24 -0
  4. package/RuniciOS/Views/ProviderDetailView.swift +9 -9
  5. package/RuniciOS/Views/ProviderListView.swift +10 -10
  6. package/RuniciOS/Widgets/LargeWidget.swift +14 -14
  7. package/RuniciOS/Widgets/LiveActivity.swift +19 -19
  8. package/RuniciOS/Widgets/LockScreenWidget.swift +15 -15
  9. package/RuniciOS/Widgets/MediumWidget.swift +10 -10
  10. package/RuniciOS/Widgets/RunicWidget.swift +5 -5
  11. package/RuniciOS/Widgets/SmallWidget.swift +9 -9
  12. package/Sources/Runic/About.swift +3 -3
  13. package/Sources/Runic/AppNotifications.swift +5 -3
  14. package/Sources/Runic/Controllers/StatusItemController+Actions.swift +7 -3
  15. package/Sources/Runic/Controllers/StatusItemController+Animation.swift +5 -4
  16. package/Sources/Runic/Controllers/StatusItemController+ChartSubmenus.swift +30 -16
  17. package/Sources/Runic/Controllers/StatusItemController+CustomProviders.swift +6 -3
  18. package/Sources/Runic/Controllers/StatusItemController+Menu.swift +18 -13
  19. package/Sources/Runic/Controllers/StatusItemController+MenuCards.swift +6 -4
  20. package/Sources/Runic/Controllers/StatusItemController+MenuHelpers.swift +40 -12
  21. package/Sources/Runic/Controllers/StatusItemController.swift +43 -43
  22. package/Sources/Runic/Core/BudgetNotificationManager.swift +2 -1
  23. package/Sources/Runic/Core/Login/ClaudeLoginRunner.swift +2 -2
  24. package/Sources/Runic/Core/Login/CodexLoginRunner.swift +1 -1
  25. package/Sources/Runic/Core/Login/CursorLoginRunner.swift +4 -4
  26. package/Sources/Runic/Core/Login/GeminiLoginRunner.swift +1 -1
  27. package/Sources/Runic/Core/Rendering/IconRenderer.swift +91 -85
  28. package/Sources/Runic/Core/Rendering/IconView.swift +3 -1
  29. package/Sources/Runic/Core/RunicColors.swift +6 -6
  30. package/Sources/Runic/Core/RunicSpacing.swift +7 -7
  31. package/Sources/Runic/Core/RunicTypography.swift +206 -0
  32. package/Sources/Runic/Core/Stores/AuggieTokenStore.swift +1 -3
  33. package/Sources/Runic/Core/Stores/AzureOpenAITokenStore.swift +1 -3
  34. package/Sources/Runic/Core/Stores/CerebrasTokenStore.swift +1 -3
  35. package/Sources/Runic/Core/Stores/CohereTokenStore.swift +1 -3
  36. package/Sources/Runic/Core/Stores/CopilotTokenStore.swift +1 -3
  37. package/Sources/Runic/Core/Stores/CustomProviderStore.swift +10 -10
  38. package/Sources/Runic/Core/Stores/DeepSeekTokenStore.swift +1 -3
  39. package/Sources/Runic/Core/Stores/FireworksTokenStore.swift +1 -3
  40. package/Sources/Runic/Core/Stores/GroqTokenStore.swift +1 -3
  41. package/Sources/Runic/Core/Stores/KimiTokenStore.swift +1 -3
  42. package/Sources/Runic/Core/Stores/MiniMaxCookieHeaderStore.swift +1 -3
  43. package/Sources/Runic/Core/Stores/MiniMaxGroupIDStore.swift +1 -3
  44. package/Sources/Runic/Core/Stores/MiniMaxTokenStore.swift +1 -3
  45. package/Sources/Runic/Core/Stores/MistralTokenStore.swift +1 -3
  46. package/Sources/Runic/Core/Stores/OpenRouterTokenStore.swift +1 -3
  47. package/Sources/Runic/Core/Stores/PerplexityTokenStore.swift +1 -3
  48. package/Sources/Runic/Core/Stores/ProviderToggleStore.swift +1 -1
  49. package/Sources/Runic/Core/Stores/QwenTokenStore.swift +1 -3
  50. package/Sources/Runic/Core/Stores/SambaNovaTokenStore.swift +1 -3
  51. package/Sources/Runic/Core/Stores/SettingsStore.swift +89 -51
  52. package/Sources/Runic/Core/Stores/TogetherTokenStore.swift +1 -3
  53. package/Sources/Runic/Core/Stores/UsageStore+Accessors.swift +19 -6
  54. package/Sources/Runic/Core/Stores/UsageStore+TokenCost.swift +1 -1
  55. package/Sources/Runic/Core/Stores/UsageStore+WidgetSnapshot.swift +1 -1
  56. package/Sources/Runic/Core/Stores/UsageStore.swift +187 -161
  57. package/Sources/Runic/Core/Stores/XAITokenStore.swift +1 -3
  58. package/Sources/Runic/Core/Stores/ZaiTokenStore.swift +1 -2
  59. package/Sources/Runic/Core/UsageExporter.swift +8 -4
  60. package/Sources/Runic/ProviderRegistry.swift +1 -1
  61. package/Sources/Runic/Providers/Antigravity/AntigravityProviderImplementation.swift +1 -1
  62. package/Sources/Runic/Providers/Auggie/AuggieProviderImplementation.swift +1 -1
  63. package/Sources/Runic/Providers/Azure/AzureProviderImplementation.swift +1 -1
  64. package/Sources/Runic/Providers/Bedrock/BedrockProviderImplementation.swift +1 -1
  65. package/Sources/Runic/Providers/Cerebras/CerebrasProviderImplementation.swift +1 -1
  66. package/Sources/Runic/Providers/Codex/CodexProviderImplementation.swift +1 -1
  67. package/Sources/Runic/Providers/Cohere/CohereProviderImplementation.swift +1 -1
  68. package/Sources/Runic/Providers/Cursor/CursorProviderImplementation.swift +1 -1
  69. package/Sources/Runic/Providers/DeepSeek/DeepSeekProviderImplementation.swift +1 -1
  70. package/Sources/Runic/Providers/Factory/FactoryProviderImplementation.swift +1 -1
  71. package/Sources/Runic/Providers/Fireworks/FireworksProviderImplementation.swift +1 -1
  72. package/Sources/Runic/Providers/Gemini/GeminiProviderImplementation.swift +1 -1
  73. package/Sources/Runic/Providers/Groq/GroqProviderImplementation.swift +1 -1
  74. package/Sources/Runic/Providers/Kimi/KimiProviderImplementation.swift +1 -1
  75. package/Sources/Runic/Providers/MiniMax/MiniMaxProviderImplementation.swift +1 -1
  76. package/Sources/Runic/Providers/Mistral/MistralProviderImplementation.swift +1 -1
  77. package/Sources/Runic/Providers/OpenRouter/OpenRouterProviderImplementation.swift +1 -1
  78. package/Sources/Runic/Providers/Perplexity/PerplexityProviderImplementation.swift +1 -1
  79. package/Sources/Runic/Providers/SambaNova/SambaNovaProviderImplementation.swift +1 -1
  80. package/Sources/Runic/Providers/Shared/ProviderImplementation.swift +5 -2
  81. package/Sources/Runic/Providers/Shared/ProviderImplementationRegistry.swift +1 -1
  82. package/Sources/Runic/Providers/Shared/ProviderSettingsDescriptors.swift +1 -1
  83. package/Sources/Runic/Providers/Together/TogetherProviderImplementation.swift +1 -1
  84. package/Sources/Runic/Providers/XAI/XAIProviderImplementation.swift +1 -1
  85. package/Sources/Runic/Providers/Zai/ZaiProviderImplementation.swift +1 -1
  86. package/Sources/Runic/Resources/Fonts/Caveat-Bold.ttf +0 -0
  87. package/Sources/Runic/Resources/Fonts/Caveat-Regular.ttf +0 -0
  88. package/Sources/Runic/Resources/Fonts/FiraCode-Bold.ttf +0 -0
  89. package/Sources/Runic/Resources/Fonts/FiraCode-Light.ttf +0 -0
  90. package/Sources/Runic/Resources/Fonts/FiraCode-Medium.ttf +0 -0
  91. package/Sources/Runic/Resources/Fonts/FiraCode-Regular.ttf +0 -0
  92. package/Sources/Runic/Resources/Fonts/FiraCode-SemiBold.ttf +0 -0
  93. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Bold.ttf +0 -0
  94. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Medium.ttf +0 -0
  95. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Regular.ttf +0 -0
  96. package/Sources/Runic/Resources/Fonts/IBMPlexMono-SemiBold.ttf +0 -0
  97. package/Sources/Runic/Resources/Fonts/Inconsolata-Bold.ttf +0 -0
  98. package/Sources/Runic/Resources/Fonts/Inconsolata-Medium.ttf +0 -0
  99. package/Sources/Runic/Resources/Fonts/Inconsolata-Regular.ttf +0 -0
  100. package/Sources/Runic/Resources/Fonts/Inconsolata-SemiBold.ttf +0 -0
  101. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Bold.ttf +0 -0
  102. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Medium.ttf +0 -0
  103. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Regular.ttf +0 -0
  104. package/Sources/Runic/Resources/Fonts/JetBrainsMono-SemiBold.ttf +0 -0
  105. package/Sources/Runic/Resources/Fonts/SpaceMono-Bold.ttf +0 -0
  106. package/Sources/Runic/Resources/Fonts/SpaceMono-Regular.ttf +0 -0
  107. package/Sources/Runic/RunicApp.swift +46 -36
  108. package/Sources/Runic/SessionQuotaNotifications.swift +2 -2
  109. package/Sources/Runic/UsagePaceText.swift +1 -1
  110. package/Sources/Runic/UsageProgressBar.swift +13 -9
  111. package/Sources/Runic/Utilities/LoadingPattern.swift +4 -2
  112. package/Sources/Runic/Utilities/PerformanceConstants.swift +28 -28
  113. package/Sources/Runic/Views/Menu/AlertsMenuView.swift +19 -21
  114. package/Sources/Runic/Views/Menu/CostComparativeChartMenuView.swift +19 -19
  115. package/Sources/Runic/Views/Menu/CostHistoryChartMenuView.swift +7 -7
  116. package/Sources/Runic/Views/Menu/CreditsHistoryChartMenuView.swift +5 -5
  117. package/Sources/Runic/Views/Menu/EfficiencyMetricsMenuView.swift +29 -30
  118. package/Sources/Runic/Views/Menu/HeroStatCardsMenuView.swift +20 -17
  119. package/Sources/Runic/Views/Menu/HourlyActivityChartMenuView.swift +14 -14
  120. package/Sources/Runic/Views/Menu/InlineUsageChartView.swift +12 -10
  121. package/Sources/Runic/Views/Menu/MenuCardEntranceModifier.swift +3 -4
  122. package/Sources/Runic/Views/Menu/MenuCardSidebarView.swift +5 -25
  123. package/Sources/Runic/Views/Menu/MenuCardSkeletonView.swift +1 -1
  124. package/Sources/Runic/Views/Menu/MenuCardView.swift +120 -131
  125. package/Sources/Runic/Views/Menu/MenuContent.swift +11 -8
  126. package/Sources/Runic/Views/Menu/MenuDescriptor.swift +4 -2
  127. package/Sources/Runic/Views/Menu/MenuHighlightStyle.swift +1 -8
  128. package/Sources/Runic/Views/Menu/ModelBreakdownMenuView.swift +20 -14
  129. package/Sources/Runic/Views/Menu/OverviewMenuView.swift +18 -15
  130. package/Sources/Runic/Views/Menu/ProjectBreakdownMenuView.swift +16 -11
  131. package/Sources/Runic/Views/Menu/ProjectBudgetMenuView.swift +27 -27
  132. package/Sources/Runic/Views/Menu/ProviderTabBarView.swift +4 -6
  133. package/Sources/Runic/Views/Menu/SubscriptionUtilizationChartMenuView.swift +24 -11
  134. package/Sources/Runic/Views/Menu/UsageBreakdownChartMenuView.swift +5 -5
  135. package/Sources/Runic/Views/Menu/UsageHeatmapMenuView.swift +7 -8
  136. package/Sources/Runic/Views/Menu/UsageTimelineChartMenuView.swift +22 -17
  137. package/Sources/Runic/Views/Menu/UsageWindowComparisonChartMenuView.swift +8 -7
  138. package/Sources/Runic/Views/Menu/WeeklyActivityChartMenuView.swift +7 -7
  139. package/Sources/Runic/Views/Performance/PerformanceDashboardView.swift +50 -47
  140. package/Sources/Runic/Views/Preferences/LiquidComponents.swift +15 -14
  141. package/Sources/Runic/Views/Preferences/PreferencesAboutPane.swift +7 -7
  142. package/Sources/Runic/Views/Preferences/PreferencesAdvancedPane.swift +27 -27
  143. package/Sources/Runic/Views/Preferences/PreferencesAlertsPane.swift +38 -42
  144. package/Sources/Runic/Views/Preferences/PreferencesAnalyticsPane.swift +39 -43
  145. package/Sources/Runic/Views/Preferences/PreferencesBudgetsPane.swift +21 -21
  146. package/Sources/Runic/Views/Preferences/PreferencesComponents.swift +7 -7
  147. package/Sources/Runic/Views/Preferences/PreferencesCustomProvidersPane.swift +49 -50
  148. package/Sources/Runic/Views/Preferences/PreferencesDebugPane.swift +10 -10
  149. package/Sources/Runic/Views/Preferences/PreferencesGeneralPane.swift +40 -21
  150. package/Sources/Runic/Views/Preferences/PreferencesHelpPane.swift +7 -7
  151. package/Sources/Runic/Views/Preferences/PreferencesIntegrationsPane.swift +44 -39
  152. package/Sources/Runic/Views/Preferences/PreferencesPerformancePane.swift +26 -23
  153. package/Sources/Runic/Views/Preferences/PreferencesProvidersPane.swift +271 -226
  154. package/Sources/Runic/Views/Preferences/PreferencesSelection.swift +6 -2
  155. package/Sources/Runic/Views/Preferences/PreferencesSyncPane.swift +7 -5
  156. package/Sources/Runic/Views/Preferences/PreferencesView.swift +38 -31
  157. package/Sources/Runic/Views/Rating/QualityRatingView.swift +11 -11
  158. package/Sources/Runic/Views/Team/TeamDashboardView.swift +29 -24
  159. package/Sources/Runic/Views/Team/TeamInviteSheet.swift +16 -16
  160. package/Sources/Runic/Views/Team/TeamManagementView.swift +50 -49
  161. package/Sources/Runic/Views/Team/TeamMemberRow.swift +8 -8
  162. package/Sources/RunicCLI/CLIEntry.swift +83 -42
  163. package/Sources/RunicCLI/CLIRenderer.swift +1 -1
  164. package/Sources/RunicCLI/Commands/EnhancedUsageCommand.swift +60 -60
  165. package/Sources/RunicCLI/Commands/ModelsCommand.swift +45 -44
  166. package/Sources/RunicCLI/Commands/ProjectsCommand.swift +83 -69
  167. package/Sources/RunicCLI/Commands/ResetCommand.swift +50 -49
  168. package/Sources/RunicCLI/Commands/UsageLedgerSourceFactory.swift +31 -32
  169. package/Sources/RunicClaudeWebProbe/main.swift +1 -1
  170. package/Sources/RunicCore/AlertRuleStore.swift +20 -20
  171. package/Sources/RunicCore/BrowserCookieImportOrder.swift +3 -3
  172. package/Sources/RunicCore/CostUsageModels.swift +1 -1
  173. package/Sources/RunicCore/CustomProviders/CustomProviderModels.swift +29 -30
  174. package/Sources/RunicCore/CustomProviders/GenericProviderFetcher.swift +73 -75
  175. package/Sources/RunicCore/CustomProviders/ProviderTemplates.swift +53 -109
  176. package/Sources/RunicCore/Host/PTY/TTYCommandRunner.swift +3 -3
  177. package/Sources/RunicCore/Integrations/GitHubIntegration.swift +3 -3
  178. package/Sources/RunicCore/Models/EnhancedUsageModels.swift +47 -48
  179. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardBrowserCookieImporter.swift +1 -1
  180. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardFetcher.swift +1 -1
  181. package/Sources/RunicCore/Performance/PerformanceModels.swift +4 -4
  182. package/Sources/RunicCore/Performance/PerformanceStorageImpl.swift +81 -64
  183. package/Sources/RunicCore/Policy/UsagePolicyEngine.swift +2 -2
  184. package/Sources/RunicCore/ProjectBudgetStore.swift +15 -12
  185. package/Sources/RunicCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +4 -2
  186. package/Sources/RunicCore/Providers/Antigravity/AntigravityStatusProbe.swift +2 -2
  187. package/Sources/RunicCore/Providers/Auggie/AuggieProviderDescriptor.swift +2 -2
  188. package/Sources/RunicCore/Providers/Auggie/AuggieUsageFetcher.swift +3 -3
  189. package/Sources/RunicCore/Providers/Azure/AzureProviderDescriptor.swift +8 -8
  190. package/Sources/RunicCore/Providers/Azure/AzureUsageFetcher.swift +3 -3
  191. package/Sources/RunicCore/Providers/Bedrock/BedrockProviderDescriptor.swift +6 -6
  192. package/Sources/RunicCore/Providers/Bedrock/BedrockUsageFetcher.swift +3 -7
  193. package/Sources/RunicCore/Providers/Cerebras/CerebrasProviderDescriptor.swift +2 -2
  194. package/Sources/RunicCore/Providers/Cerebras/CerebrasUsageFetcher.swift +2 -2
  195. package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthUsageFetcher.swift +3 -3
  196. package/Sources/RunicCore/Providers/Claude/ClaudeProviderDescriptor.swift +4 -2
  197. package/Sources/RunicCore/Providers/Claude/ClaudeStatusProbe.swift +4 -4
  198. package/Sources/RunicCore/Providers/Claude/ClaudeUsageDataSource.swift +3 -1
  199. package/Sources/RunicCore/Providers/Claude/ClaudeWeb/ClaudeWebAPIFetcher.swift +1 -1
  200. package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift +1 -1
  201. package/Sources/RunicCore/Providers/Codex/CodexProviderDescriptor.swift +4 -2
  202. package/Sources/RunicCore/Providers/Codex/CodexUsageDataSource.swift +3 -1
  203. package/Sources/RunicCore/Providers/Codex/CodexWebDashboardStrategy.swift +5 -3
  204. package/Sources/RunicCore/Providers/Cohere/CohereProviderDescriptor.swift +2 -2
  205. package/Sources/RunicCore/Providers/Cohere/CohereUsageFetcher.swift +3 -3
  206. package/Sources/RunicCore/Providers/Copilot/CopilotGitHubCLITokenReader.swift +7 -4
  207. package/Sources/RunicCore/Providers/Copilot/CopilotProviderDescriptor.swift +4 -4
  208. package/Sources/RunicCore/Providers/Copilot/CopilotUsageFetcher.swift +5 -3
  209. package/Sources/RunicCore/Providers/Copilot/CopilotVSCodeTokenReader.swift +9 -10
  210. package/Sources/RunicCore/Providers/Cursor/CursorProviderDescriptor.swift +4 -2
  211. package/Sources/RunicCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift +2 -2
  212. package/Sources/RunicCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift +2 -2
  213. package/Sources/RunicCore/Providers/Factory/FactoryLocalStorageImporter.swift +4 -4
  214. package/Sources/RunicCore/Providers/Factory/FactoryProviderDescriptor.swift +4 -2
  215. package/Sources/RunicCore/Providers/Factory/FactoryStatusProbe.swift +2 -2
  216. package/Sources/RunicCore/Providers/Fireworks/FireworksProviderDescriptor.swift +2 -2
  217. package/Sources/RunicCore/Providers/Fireworks/FireworksUsageFetcher.swift +2 -2
  218. package/Sources/RunicCore/Providers/Gemini/GeminiProviderDescriptor.swift +4 -2
  219. package/Sources/RunicCore/Providers/Gemini/GeminiStatusProbe.swift +5 -2
  220. package/Sources/RunicCore/Providers/Groq/GroqProviderDescriptor.swift +2 -2
  221. package/Sources/RunicCore/Providers/Groq/GroqUsageFetcher.swift +2 -2
  222. package/Sources/RunicCore/Providers/Kimi/KimiProviderDescriptor.swift +2 -2
  223. package/Sources/RunicCore/Providers/Kimi/KimiUsageFetcher.swift +2 -2
  224. package/Sources/RunicCore/Providers/MiniMax/MiniMaxProviderDescriptor.swift +10 -5
  225. package/Sources/RunicCore/Providers/MiniMax/MiniMaxUsageFetcher.swift +7 -7
  226. package/Sources/RunicCore/Providers/MiniMax/MiniMaxWebUsageFetcher.swift +10 -10
  227. package/Sources/RunicCore/Providers/Mistral/MistralProviderDescriptor.swift +2 -2
  228. package/Sources/RunicCore/Providers/Mistral/MistralUsageFetcher.swift +2 -2
  229. package/Sources/RunicCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift +2 -2
  230. package/Sources/RunicCore/Providers/OpenRouter/OpenRouterUsageFetcher.swift +23 -10
  231. package/Sources/RunicCore/Providers/Perplexity/PerplexityProviderDescriptor.swift +2 -2
  232. package/Sources/RunicCore/Providers/Perplexity/PerplexityUsageFetcher.swift +2 -2
  233. package/Sources/RunicCore/Providers/ProviderFetchPlan.swift +2 -2
  234. package/Sources/RunicCore/Providers/ProviderTokenResolver.swift +2 -2
  235. package/Sources/RunicCore/Providers/Qwen/QwenProviderDescriptor.swift +5 -3
  236. package/Sources/RunicCore/Providers/Qwen/QwenUsageStats.swift +26 -13
  237. package/Sources/RunicCore/Providers/SambaNova/SambaNovaProviderDescriptor.swift +2 -2
  238. package/Sources/RunicCore/Providers/SambaNova/SambaNovaUsageFetcher.swift +2 -2
  239. package/Sources/RunicCore/Providers/Together/TogetherProviderDescriptor.swift +2 -2
  240. package/Sources/RunicCore/Providers/Together/TogetherUsageFetcher.swift +2 -2
  241. package/Sources/RunicCore/Providers/VertexAI/VertexAIProviderDescriptor.swift +5 -5
  242. package/Sources/RunicCore/Providers/VertexAI/VertexAISettingsReader.swift +1 -1
  243. package/Sources/RunicCore/Providers/VertexAI/VertexAIUsageFetcher.swift +3 -3
  244. package/Sources/RunicCore/Providers/XAI/XAIProviderDescriptor.swift +2 -2
  245. package/Sources/RunicCore/Providers/XAI/XAIUsageFetcher.swift +2 -2
  246. package/Sources/RunicCore/Providers/Zai/ZaiProviderDescriptor.swift +4 -2
  247. package/Sources/RunicCore/Providers/Zai/ZaiUsageStats.swift +48 -21
  248. package/Sources/RunicCore/Sync/BackgroundSyncManager.swift +76 -77
  249. package/Sources/RunicCore/Sync/SyncConflictResolver.swift +55 -58
  250. package/Sources/RunicCore/Sync/SyncProtocol.swift +21 -22
  251. package/Sources/RunicCore/Sync/SyncRecord.swift +46 -49
  252. package/Sources/RunicCore/Sync/SyncUsageExample.swift +44 -50
  253. package/Sources/RunicCore/Sync/TeamSyncRecords.swift +94 -101
  254. package/Sources/RunicCore/Sync/iCloudSyncEngine.swift +51 -46
  255. package/Sources/RunicCore/Team/TeamModels.swift +111 -110
  256. package/Sources/RunicCore/Team/TeamStore.swift +126 -109
  257. package/Sources/RunicCore/UsageFetcher.swift +2 -2
  258. package/Sources/RunicCore/UsageFormatter.swift +25 -25
  259. package/Sources/RunicCore/UsageLedger/ClaudeUsageLogSource.swift +27 -13
  260. package/Sources/RunicCore/UsageLedger/CodexUsageLogSource.swift +11 -3
  261. package/Sources/RunicCore/UsageLedger/LedgerCache.swift +5 -2
  262. package/Sources/RunicCore/UsageLedger/OTelGenAILedgerAdapter.swift +1 -1
  263. package/Sources/RunicCore/UsageLedger/UsageLedgerAggregator.swift +40 -25
  264. package/Sources/RunicCore/UsageLedger/UsageLedgerInsightsAdvisor.swift +1 -1
  265. package/Sources/RunicCore/UsageLedger/UsageLedgerProjectIdentity.swift +55 -16
  266. package/Sources/RunicCore/Vendored/CostUsage/CostUsageCache.swift +6 -6
  267. package/Sources/RunicCore/Vendored/CostUsage/CostUsageJsonl.swift +1 -1
  268. package/Sources/RunicCore/Vendored/CostUsage/CostUsagePricing.swift +2 -2
  269. package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner.swift +5 -5
  270. package/Tests/RunicTests/AppDelegateTests.swift +8 -3
  271. package/Tests/RunicTests/BrowserCookieOrderLabelTests.swift +2 -3
  272. package/Tests/RunicTests/CLIArgumentParsingTests.swift +3 -4
  273. package/Tests/RunicTests/CLICostTests.swift +6 -7
  274. package/Tests/RunicTests/CLIProviderSelectionTests.swift +2 -3
  275. package/Tests/RunicTests/CLISnapshotTests.swift +3 -4
  276. package/Tests/RunicTests/CLIWebFallbackTests.swift +3 -4
  277. package/Tests/RunicTests/ClaudeOAuthTests.swift +11 -12
  278. package/Tests/RunicTests/ClaudeResilienceTests.swift +3 -4
  279. package/Tests/RunicTests/ClaudeUsageTests.swift +20 -21
  280. package/Tests/RunicTests/CodexOAuthTests.swift +7 -8
  281. package/Tests/RunicTests/CodexUsageLogSourceTests.swift +1 -3
  282. package/Tests/RunicTests/CopilotTokenResolverTests.swift +5 -6
  283. package/Tests/RunicTests/CopilotVSCodeTokenReaderTests.swift +4 -5
  284. package/Tests/RunicTests/CostUsageDecodingTests.swift +15 -17
  285. package/Tests/RunicTests/CostUsagePricingTests.swift +5 -7
  286. package/Tests/RunicTests/CostUsageScannerTests.swift +10 -12
  287. package/Tests/RunicTests/CursorStatusProbeTests.swift +15 -16
  288. package/Tests/RunicTests/FactoryStatusProbeTests.swift +3 -5
  289. package/Tests/RunicTests/GeminiLoginAlertTests.swift +3 -4
  290. package/Tests/RunicTests/GeminiStatusProbeAPITests.swift +11 -11
  291. package/Tests/RunicTests/GeminiStatusProbePlanTests.swift +8 -8
  292. package/Tests/RunicTests/GeminiStatusProbeTests.swift +20 -21
  293. package/Tests/RunicTests/GoogleWorkspaceStatusTests.swift +2 -3
  294. package/Tests/RunicTests/InstallOriginTests.swift +1 -2
  295. package/Tests/RunicTests/KeyboardShortcutsBundleTests.swift +2 -2
  296. package/Tests/RunicTests/LiveAccountTests.swift +3 -3
  297. package/Tests/RunicTests/LoadingPatternTests.swift +3 -4
  298. package/Tests/RunicTests/MenuCardModelTests.swift +33 -34
  299. package/Tests/RunicTests/MiniMaxCookieHeaderStoreTestSupport.swift +4 -1
  300. package/Tests/RunicTests/MiniMaxGroupIDStoreTestSupport.swift +4 -1
  301. package/Tests/RunicTests/MiniMaxParsingTests.swift +4 -5
  302. package/Tests/RunicTests/MiniMaxTokenStoreTestSupport.swift +4 -1
  303. package/Tests/RunicTests/OTelGenAILedgerAdapterTests.swift +4 -6
  304. package/Tests/RunicTests/OpenAIDashboardBrowserCookieImporterTests.swift +1 -2
  305. package/Tests/RunicTests/OpenAIDashboardFetcherCreditsWaitTests.swift +5 -6
  306. package/Tests/RunicTests/OpenAIDashboardOffscreenHostTests.swift +2 -3
  307. package/Tests/RunicTests/OpenAIDashboardParserTests.swift +12 -13
  308. package/Tests/RunicTests/OpenAIWebAccountSwitchTests.swift +17 -6
  309. package/Tests/RunicTests/OpenRouterTokenStoreTestSupport.swift +52 -13
  310. package/Tests/RunicTests/PathBuilderTests.swift +14 -15
  311. package/Tests/RunicTests/ProviderFetchPipelineTests.swift +3 -4
  312. package/Tests/RunicTests/ProviderIconResourcesTests.swift +1 -2
  313. package/Tests/RunicTests/ProviderMetadataStatusLinkTests.swift +1 -2
  314. package/Tests/RunicTests/ProviderSettingsDescriptorTests.swift +53 -19
  315. package/Tests/RunicTests/ProviderToggleStoreTests.swift +10 -11
  316. package/Tests/RunicTests/RunicTests.swift +6 -7
  317. package/Tests/RunicTests/SessionQuotaNotificationLogicTests.swift +5 -6
  318. package/Tests/RunicTests/SettingsStoreTests.swift +149 -45
  319. package/Tests/RunicTests/StatusItemAnimationTests.swift +8 -3
  320. package/Tests/RunicTests/StatusMenuTests.swift +63 -22
  321. package/Tests/RunicTests/StatusProbeTests.swift +28 -29
  322. package/Tests/RunicTests/SubprocessRunnerTests.swift +1 -3
  323. package/Tests/RunicTests/SubscriptionDetectionTests.swift +8 -9
  324. package/Tests/RunicTests/TTYCommandRunnerTests.swift +8 -9
  325. package/Tests/RunicTests/TeamShowbackExporterTests.swift +2 -4
  326. package/Tests/RunicTests/TextParsingTests.swift +1 -2
  327. package/Tests/RunicTests/UsageFormatterTests.swift +15 -16
  328. package/Tests/RunicTests/UsageLedgerAnomalyDetectionTests.swift +12 -14
  329. package/Tests/RunicTests/UsageLedgerForecastTests.swift +4 -6
  330. package/Tests/RunicTests/UsageLedgerInsightsAdvisorTests.swift +7 -9
  331. package/Tests/RunicTests/UsageLedgerProjectNameTests.swift +6 -8
  332. package/Tests/RunicTests/UsagePaceTests.swift +5 -6
  333. package/Tests/RunicTests/UsagePaceTextTests.swift +8 -9
  334. package/Tests/RunicTests/UsagePolicyEngineTests.swift +3 -5
  335. package/Tests/RunicTests/WidgetSnapshotTests.swift +1 -3
  336. package/Tests/RunicTests/ZaiProviderTests.swift +3 -5
  337. package/Tests/RunicTests/ZaiTokenStoreTestSupport.swift +4 -1
  338. package/appcast.xml +36 -76
  339. package/package.json +1 -1
  340. package/runic.png +0 -0
  341. package/runic.svg +15 -0
  342. package/version.env +2 -2
@@ -38,7 +38,7 @@ struct SubscriptionUtilizationChartMenuView: View {
38
38
  self.width = width
39
39
  }
40
40
 
41
- private static let barColor = RunicColors.chartColor(at: 4) // teal
41
+ private static let barColor = RunicColors.chartColor(at: 4) // teal
42
42
  private static let wastedColor = Color(nsColor: .systemGray).opacity(0.2)
43
43
 
44
44
  var body: some View {
@@ -50,7 +50,7 @@ struct SubscriptionUtilizationChartMenuView: View {
50
50
 
51
51
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
52
52
  Text("Utilization")
53
- .font(.system(.subheadline, design: .rounded))
53
+ .font(RunicFont.subheadline)
54
54
  .fontWeight(.semibold)
55
55
 
56
56
  Picker("", selection: self.$selectedPeriod) {
@@ -62,7 +62,7 @@ struct SubscriptionUtilizationChartMenuView: View {
62
62
 
63
63
  if model.bars.isEmpty {
64
64
  Text("No utilization data available.")
65
- .font(.system(.footnote, design: .rounded))
65
+ .font(RunicFont.footnote)
66
66
  .foregroundStyle(.secondary)
67
67
  .frame(height: 80)
68
68
  } else {
@@ -83,7 +83,7 @@ struct SubscriptionUtilizationChartMenuView: View {
83
83
  AxisValueLabel {
84
84
  if let pct = value.as(Int.self) {
85
85
  Text("\(pct)%")
86
- .font(.system(.caption2, design: .rounded))
86
+ .font(RunicFont.caption2)
87
87
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
88
88
  }
89
89
  }
@@ -92,7 +92,7 @@ struct SubscriptionUtilizationChartMenuView: View {
92
92
  .chartXAxis {
93
93
  AxisMarks(values: .automatic(desiredCount: 5)) { _ in
94
94
  AxisValueLabel()
95
- .font(.system(.caption2, design: .rounded))
95
+ .font(RunicFont.caption2)
96
96
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
97
97
  }
98
98
  }
@@ -104,7 +104,7 @@ struct SubscriptionUtilizationChartMenuView: View {
104
104
  let used = Int(latest.usedPercent.rounded())
105
105
  let unused = max(0, 100 - used)
106
106
  Text("\(latest.label): \(used)% used, \(unused)% unused")
107
- .font(.system(.caption, design: .rounded))
107
+ .font(RunicFont.caption)
108
108
  .foregroundStyle(.secondary)
109
109
  }
110
110
  }
@@ -159,7 +159,8 @@ struct SubscriptionUtilizationChartMenuView: View {
159
159
  // Aggregate by ISO week
160
160
  var weekBuckets: [(label: String, tokens: Int, date: Date, isThisWeek: Bool)] = []
161
161
  for weekOffset in stride(from: -3, through: 0, by: 1) {
162
- guard let weekStart = calendar.date(byAdding: .weekOfYear, value: weekOffset, to: todayStart) else { continue }
162
+ guard let weekStart = calendar.date(byAdding: .weekOfYear, value: weekOffset, to: todayStart)
163
+ else { continue }
163
164
  var total = 0
164
165
  for dayOffset in 0..<7 {
165
166
  guard let date = calendar.date(byAdding: .day, value: dayOffset, to: weekStart) else { continue }
@@ -171,20 +172,27 @@ struct SubscriptionUtilizationChartMenuView: View {
171
172
  let maxWeekTokens = weekBuckets.map(\.tokens).max() ?? 1
172
173
  let bars = weekBuckets.map { bucket in
173
174
  let pct = maxWeekTokens > 0 ? Double(bucket.tokens) / Double(maxWeekTokens) * 100 : 0
174
- return UtilizationBar(id: bucket.label, label: bucket.label, date: bucket.date, usedPercent: pct, isToday: bucket.isThisWeek)
175
+ return UtilizationBar(
176
+ id: bucket.label,
177
+ label: bucket.label,
178
+ date: bucket.date,
179
+ usedPercent: pct,
180
+ isToday: bucket.isThisWeek)
175
181
  }
176
182
  return UtilizationModel(bars: bars)
177
183
 
178
184
  case .monthly:
179
185
  var monthBuckets: [(label: String, tokens: Int, date: Date, isThisMonth: Bool)] = []
180
186
  for monthOffset in stride(from: -2, through: 0, by: 1) {
181
- guard let monthStart = calendar.date(byAdding: .month, value: monthOffset, to: todayStart) else { continue }
187
+ guard let monthStart = calendar.date(byAdding: .month, value: monthOffset, to: todayStart)
188
+ else { continue }
182
189
  let monthComponents = calendar.dateComponents([.year, .month], from: monthStart)
183
190
  guard let actualMonthStart = calendar.date(from: monthComponents),
184
191
  let range = calendar.range(of: .day, in: .month, for: actualMonthStart) else { continue }
185
192
  var total = 0
186
193
  for dayOffset in 0..<range.count {
187
- guard let date = calendar.date(byAdding: .day, value: dayOffset, to: actualMonthStart) else { continue }
194
+ guard let date = calendar.date(byAdding: .day, value: dayOffset, to: actualMonthStart)
195
+ else { continue }
188
196
  total += tokensByDay[formatter.string(from: date)] ?? 0
189
197
  }
190
198
  let label = monthStart.formatted(.dateTime.month(.abbreviated))
@@ -193,7 +201,12 @@ struct SubscriptionUtilizationChartMenuView: View {
193
201
  let maxMonthTokens = monthBuckets.map(\.tokens).max() ?? 1
194
202
  let bars = monthBuckets.map { bucket in
195
203
  let pct = maxMonthTokens > 0 ? Double(bucket.tokens) / Double(maxMonthTokens) * 100 : 0
196
- return UtilizationBar(id: bucket.label, label: bucket.label, date: bucket.date, usedPercent: pct, isToday: bucket.isThisMonth)
204
+ return UtilizationBar(
205
+ id: bucket.label,
206
+ label: bucket.label,
207
+ date: bucket.date,
208
+ usedPercent: pct,
209
+ isToday: bucket.isThisMonth)
197
210
  }
198
211
  return UtilizationModel(bars: bars)
199
212
  }
@@ -32,7 +32,7 @@ struct UsageBreakdownChartMenuView: View {
32
32
  VStack(alignment: .leading, spacing: RunicSpacing.sm) {
33
33
  if model.points.isEmpty {
34
34
  Text("No usage breakdown data.")
35
- .font(.footnote)
35
+ .font(RunicFont.footnote)
36
36
  .foregroundStyle(.secondary)
37
37
  } else {
38
38
  Chart {
@@ -58,7 +58,7 @@ struct UsageBreakdownChartMenuView: View {
58
58
  AxisGridLine().foregroundStyle(Color.clear)
59
59
  AxisTick().foregroundStyle(Color.clear)
60
60
  AxisValueLabel(format: .dateTime.month(.abbreviated).day())
61
- .font(.caption2)
61
+ .font(RunicFont.caption2)
62
62
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
63
63
  }
64
64
  }
@@ -88,13 +88,13 @@ struct UsageBreakdownChartMenuView: View {
88
88
  let detail = self.detailLines(model: model)
89
89
  VStack(alignment: .leading, spacing: 0) {
90
90
  Text(detail.primary)
91
- .font(.system(.caption, design: .rounded))
91
+ .font(RunicFont.caption)
92
92
  .foregroundStyle(.secondary)
93
93
  .lineLimit(1)
94
94
  .truncationMode(.tail)
95
95
  .frame(height: 16, alignment: .leading)
96
96
  Text(detail.secondary ?? " ")
97
- .font(.system(.caption, design: .rounded))
97
+ .font(RunicFont.caption)
98
98
  .foregroundStyle(.secondary)
99
99
  .lineLimit(1)
100
100
  .truncationMode(.tail)
@@ -113,7 +113,7 @@ struct UsageBreakdownChartMenuView: View {
113
113
  .fill(model.color(for: service))
114
114
  .frame(width: RunicSpacing.chartLegendDot, height: RunicSpacing.chartLegendDot)
115
115
  Text(service)
116
- .font(.caption2)
116
+ .font(RunicFont.caption2)
117
117
  .foregroundStyle(.secondary)
118
118
  .lineLimit(1)
119
119
  }
@@ -46,12 +46,12 @@ struct UsageHeatmapMenuView: View {
46
46
  let model = Self.makeModel(from: self.hourlySummaries)
47
47
  VStack(alignment: .leading, spacing: RunicSpacing.sm) {
48
48
  Text("Usage Heatmap (24×7)")
49
- .font(.headline)
49
+ .font(RunicFont.headline)
50
50
  .fontWeight(.semibold)
51
51
 
52
52
  if model.isEmpty {
53
53
  Text("No heatmap data.")
54
- .font(.footnote)
54
+ .font(RunicFont.footnote)
55
55
  .foregroundStyle(.secondary)
56
56
  } else {
57
57
  ScrollView(.horizontal, showsIndicators: true) {
@@ -62,7 +62,7 @@ struct UsageHeatmapMenuView: View {
62
62
  .frame(width: 40, alignment: .leading)
63
63
  ForEach(0..<24, id: \.self) { hour in
64
64
  Text(self.hourLabel(hour))
65
- .font(.caption2)
65
+ .font(RunicFont.caption2)
66
66
  .foregroundStyle(.secondary)
67
67
  .frame(width: 40, alignment: .center)
68
68
  .lineLimit(1)
@@ -73,7 +73,7 @@ struct UsageHeatmapMenuView: View {
73
73
  ForEach(0..<7, id: \.self) { weekday in
74
74
  HStack(spacing: 2) {
75
75
  Text(self.weekdayLabel(weekday))
76
- .font(.caption)
76
+ .font(RunicFont.caption)
77
77
  .foregroundStyle(.secondary)
78
78
  .frame(width: 38, alignment: .leading)
79
79
 
@@ -99,7 +99,7 @@ struct UsageHeatmapMenuView: View {
99
99
  // Legend
100
100
  HStack(spacing: RunicSpacing.xs) {
101
101
  Text("Low")
102
- .font(.caption2)
102
+ .font(RunicFont.caption2)
103
103
  .foregroundStyle(.secondary)
104
104
  HStack(spacing: 2) {
105
105
  ForEach(0..<5, id: \.self) { level in
@@ -110,7 +110,7 @@ struct UsageHeatmapMenuView: View {
110
110
  }
111
111
  }
112
112
  Text("High")
113
- .font(.caption2)
113
+ .font(RunicFont.caption2)
114
114
  .foregroundStyle(.secondary)
115
115
  }
116
116
  .padding(.top, RunicSpacing.xs)
@@ -121,7 +121,7 @@ struct UsageHeatmapMenuView: View {
121
121
 
122
122
  let detail = self.detailText(model: model)
123
123
  Text(detail)
124
- .font(.caption)
124
+ .font(RunicFont.caption)
125
125
  .foregroundStyle(.secondary)
126
126
  .lineLimit(2)
127
127
  .frame(height: 32, alignment: .leading)
@@ -229,4 +229,3 @@ private struct HeatmapCellView: View {
229
229
  .cornerRadius(RunicCornerRadius.xs)
230
230
  }
231
231
  }
232
-
@@ -13,17 +13,21 @@ struct UsageTimelineChartMenuView: View {
13
13
 
14
14
  var cutoffInterval: TimeInterval {
15
15
  switch self {
16
- case .threeDays: return -259200
17
- case .sevenDays: return -604800
18
- case .thirtyDays: return -2592000
19
- case .quarter: return -7776000
20
- case .year: return -31536000
16
+ case .threeDays: -259_200
17
+ case .sevenDays: -604_800
18
+ case .thirtyDays: -2_592_000
19
+ case .quarter: -7_776_000
20
+ case .year: -31_536_000
21
21
  }
22
22
  }
23
23
 
24
- var usesHourlyData: Bool { false }
24
+ var usesHourlyData: Bool {
25
+ false
26
+ }
25
27
 
26
- var label: String { self.rawValue }
28
+ var label: String {
29
+ self.rawValue
30
+ }
27
31
  }
28
32
 
29
33
  private struct Point: Identifiable {
@@ -65,7 +69,7 @@ struct UsageTimelineChartMenuView: View {
65
69
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
66
70
  // Header on its own line
67
71
  Text("Timeline")
68
- .font(.system(.subheadline, design: .rounded))
72
+ .font(RunicFont.subheadline)
69
73
  .fontWeight(.semibold)
70
74
 
71
75
  // Range picker on its own line
@@ -78,7 +82,7 @@ struct UsageTimelineChartMenuView: View {
78
82
 
79
83
  if model.points.isEmpty {
80
84
  Text("No data for selected range.")
81
- .font(.system(.footnote, design: .rounded))
85
+ .font(RunicFont.footnote)
82
86
  .foregroundStyle(.secondary)
83
87
  .frame(height: 100)
84
88
  } else {
@@ -112,7 +116,7 @@ struct UsageTimelineChartMenuView: View {
112
116
  .symbolSize(60)
113
117
  .annotation(position: .top, spacing: 4) {
114
118
  Text("Peak")
115
- .font(.system(.caption2, design: .rounded))
119
+ .font(RunicFont.caption2)
116
120
  .foregroundStyle(Color(nsColor: .systemYellow))
117
121
  }
118
122
  }
@@ -124,7 +128,7 @@ struct UsageTimelineChartMenuView: View {
124
128
  AxisValueLabel {
125
129
  if let tokens = value.as(Int.self) {
126
130
  Text(UsageFormatter.tokenCountString(tokens))
127
- .font(.system(.caption2, design: .rounded))
131
+ .font(RunicFont.caption2)
128
132
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
129
133
  }
130
134
  }
@@ -135,7 +139,7 @@ struct UsageTimelineChartMenuView: View {
135
139
  AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5, dash: [4, 3]))
136
140
  .foregroundStyle(Color(nsColor: .separatorColor).opacity(0.3))
137
141
  AxisValueLabel(format: model.xAxisFormat)
138
- .font(.system(.caption2, design: .rounded))
142
+ .font(RunicFont.caption2)
139
143
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
140
144
  }
141
145
  }
@@ -163,7 +167,7 @@ struct UsageTimelineChartMenuView: View {
163
167
  // Detail line
164
168
  let detail = self.detailText(model: model)
165
169
  Text(detail)
166
- .font(.system(.caption, design: .rounded))
170
+ .font(RunicFont.caption)
167
171
  .foregroundStyle(.secondary)
168
172
  .lineLimit(1)
169
173
  .truncationMode(.tail)
@@ -184,7 +188,8 @@ struct UsageTimelineChartMenuView: View {
184
188
  }
185
189
  .chartPanelStyle(width: self.width)
186
190
  .accessibilityElement(children: .ignore)
187
- .accessibilityLabel("Usage timeline chart showing \(model.points.count) data points over \(self.selectedTimeRange.label)")
191
+ .accessibilityLabel(
192
+ "Usage timeline chart showing \(model.points.count) data points over \(self.selectedTimeRange.label)")
188
193
  }
189
194
 
190
195
  // MARK: - Stat cell
@@ -196,10 +201,10 @@ struct UsageTimelineChartMenuView: View {
196
201
  var body: some View {
197
202
  VStack(alignment: .leading, spacing: RunicSpacing.xxxs) {
198
203
  Text(self.label)
199
- .font(.system(.caption2, design: .rounded))
204
+ .font(RunicFont.caption2)
200
205
  .foregroundStyle(.tertiary)
201
206
  Text(self.value)
202
- .font(.system(.caption, design: .rounded))
207
+ .font(RunicFont.caption)
203
208
  .fontWeight(.medium)
204
209
  }
205
210
  }
@@ -254,7 +259,7 @@ struct UsageTimelineChartMenuView: View {
254
259
  }
255
260
  }
256
261
 
257
- let desiredAxisCount: Int = switch timeRange {
262
+ let desiredAxisCount = switch timeRange {
258
263
  case .threeDays: 3
259
264
  case .sevenDays: 5
260
265
  case .thirtyDays: 6
@@ -49,12 +49,12 @@ struct UsageWindowComparisonChartMenuView: View {
49
49
 
50
50
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
51
51
  Text("Windows")
52
- .font(.system(.subheadline, design: .rounded))
52
+ .font(RunicFont.subheadline)
53
53
  .fontWeight(.semibold)
54
54
 
55
55
  if model.points.isEmpty {
56
56
  Text("No usage window data available.")
57
- .font(.system(.footnote, design: .rounded))
57
+ .font(RunicFont.footnote)
58
58
  .foregroundStyle(.secondary)
59
59
  .frame(height: 80)
60
60
  } else {
@@ -64,7 +64,8 @@ struct UsageWindowComparisonChartMenuView: View {
64
64
  x: .value("Date", point.date),
65
65
  y: .value("%", point.percent),
66
66
  series: .value("Window", point.series))
67
- .foregroundStyle(point.series == self.primaryLabel ? Self.primaryColor : Self.secondaryColor)
67
+ .foregroundStyle(point.series == self.primaryLabel ? Self.primaryColor : Self
68
+ .secondaryColor)
68
69
  .lineStyle(StrokeStyle(lineWidth: 2))
69
70
  .interpolationMethod(.catmullRom)
70
71
  }
@@ -77,7 +78,7 @@ struct UsageWindowComparisonChartMenuView: View {
77
78
  AxisValueLabel {
78
79
  if let pct = value.as(Int.self) {
79
80
  Text("\(pct)%")
80
- .font(.system(.caption2, design: .rounded))
81
+ .font(RunicFont.caption2)
81
82
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
82
83
  }
83
84
  }
@@ -88,7 +89,7 @@ struct UsageWindowComparisonChartMenuView: View {
88
89
  AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5, dash: [4, 3]))
89
90
  .foregroundStyle(Color(nsColor: .separatorColor).opacity(0.3))
90
91
  AxisValueLabel(format: .dateTime.month(.abbreviated).day())
91
- .font(.system(.caption2, design: .rounded))
92
+ .font(RunicFont.caption2)
92
93
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
93
94
  }
94
95
  }
@@ -102,7 +103,7 @@ struct UsageWindowComparisonChartMenuView: View {
102
103
  .fill(Self.primaryColor)
103
104
  .frame(width: RunicSpacing.chartLegendDot, height: RunicSpacing.chartLegendDot)
104
105
  Text(self.primaryLabel)
105
- .font(.system(.caption2, design: .rounded))
106
+ .font(RunicFont.caption2)
106
107
  .foregroundStyle(.secondary)
107
108
  }
108
109
  if let secondaryLabel = self.secondaryLabel {
@@ -111,7 +112,7 @@ struct UsageWindowComparisonChartMenuView: View {
111
112
  .fill(Self.secondaryColor)
112
113
  .frame(width: RunicSpacing.chartLegendDot, height: RunicSpacing.chartLegendDot)
113
114
  Text(secondaryLabel)
114
- .font(.system(.caption2, design: .rounded))
115
+ .font(RunicFont.caption2)
115
116
  .foregroundStyle(.secondary)
116
117
  }
117
118
  }
@@ -33,20 +33,20 @@ struct WeeklyActivityChartMenuView: View {
33
33
  VStack(alignment: .leading, spacing: RunicSpacing.sm) {
34
34
  HStack(alignment: .firstTextBaseline) {
35
35
  Text("Last 7 Days")
36
- .font(.system(.subheadline, design: .rounded))
36
+ .font(RunicFont.subheadline)
37
37
  .fontWeight(.semibold)
38
38
  Spacer()
39
39
  if model.bars.count > 1 {
40
- let avg = model.totalTokens / max(1, model.bars.filter { $0.totalTokens > 0 }.count)
40
+ let avg = model.totalTokens / max(1, model.bars.count(where: { $0.totalTokens > 0 }))
41
41
  Text("\(UsageFormatter.tokenCountString(avg)) avg")
42
- .font(.system(.caption, design: .rounded))
42
+ .font(RunicFont.caption)
43
43
  .foregroundStyle(.secondary)
44
44
  }
45
45
  }
46
46
 
47
47
  if model.bars.allSatisfy({ $0.totalTokens == 0 }) {
48
48
  Text("No usage in the last 7 days.")
49
- .font(.system(.footnote, design: .rounded))
49
+ .font(RunicFont.footnote)
50
50
  .foregroundStyle(.secondary)
51
51
  .frame(height: 80)
52
52
  } else {
@@ -60,9 +60,9 @@ struct WeeklyActivityChartMenuView: View {
60
60
  }
61
61
  }
62
62
  .chartXAxis {
63
- AxisMarks { value in
63
+ AxisMarks { _ in
64
64
  AxisValueLabel()
65
- .font(.system(.caption2, design: .rounded))
65
+ .font(RunicFont.caption2)
66
66
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
67
67
  }
68
68
  }
@@ -73,7 +73,7 @@ struct WeeklyActivityChartMenuView: View {
73
73
  AxisValueLabel {
74
74
  if let tokens = value.as(Int.self) {
75
75
  Text(UsageFormatter.tokenCountString(tokens))
76
- .font(.system(.caption2, design: .rounded))
76
+ .font(RunicFont.caption2)
77
77
  .foregroundStyle(Color(nsColor: .tertiaryLabelColor))
78
78
  }
79
79
  }