@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
@@ -1,51 +1,51 @@
1
1
  import AppKit
2
- import RunicCore
3
2
  import Observation
4
3
  import QuartzCore
4
+ import RunicCore
5
5
  import SwiftUI
6
6
 
7
- /// **StatusItemController** - Manages macOS menubar status item and dropdown menu
8
- ///
9
- /// **Purpose:**
10
- /// Coordinates the menubar icon, animations, menu construction, and user interactions.
11
- /// Acts as the bridge between AppKit (NSStatusItem) and SwiftUI (menu cards).
12
- ///
13
- /// **Responsibilities:**
14
- /// - Create and manage NSStatusItem in menubar
15
- /// - Coordinate icon rendering via IconRenderer
16
- /// - Build rich NSMenu with embedded SwiftUI views
17
- /// - Handle animation lifecycle (60 FPS during pings)
18
- /// - Schedule background "ping" operations when menu opens
19
- /// - Manage keyboard shortcuts and user actions
20
- ///
21
- /// **Architecture Pattern:**
22
- /// This file is split across 4 files via extensions:
23
- /// - `StatusItemController.swift` - Core setup (318 lines)
24
- /// - `StatusItemController+Menu.swift` - Menu construction (1878 lines)
25
- /// - `StatusItemController+Actions.swift` - User actions (200 lines)
26
- /// - `StatusItemController+Animation.swift` - Animation system (469 lines)
27
- ///
28
- /// **Performance:**
29
- /// - **60 FPS cap** during active pings (PerformanceConstants.menubarFPS)
30
- /// - **Auto-stop animations** when data loaded or error encountered
31
- /// - **1.2s delay** before background ping when menu opens (reduce perceived lag)
32
- ///
33
- /// **Dependencies:**
34
- /// - `UsageStore` - Data source
35
- /// - `SettingsStore` - User preferences
36
- /// - `IconRenderer` - Icon generation
37
- /// - `MenuCardView` - SwiftUI menu content
38
- ///
39
- /// **Usage:**
40
- /// ```swift
41
- /// let controller = StatusItemController(
42
- /// store: usageStore,
43
- /// settings: settingsStore,
44
- /// account: accountInfo,
45
- /// updater: updater,
46
- /// preferencesSelection: selection
47
- /// )
48
- /// ```
7
+ // **StatusItemController** - Manages macOS menubar status item and dropdown menu
8
+ //
9
+ // **Purpose:**
10
+ // Coordinates the menubar icon, animations, menu construction, and user interactions.
11
+ // Acts as the bridge between AppKit (NSStatusItem) and SwiftUI (menu cards).
12
+ //
13
+ // **Responsibilities:**
14
+ // - Create and manage NSStatusItem in menubar
15
+ // - Coordinate icon rendering via IconRenderer
16
+ // - Build rich NSMenu with embedded SwiftUI views
17
+ // - Handle animation lifecycle (60 FPS during pings)
18
+ // - Schedule background "ping" operations when menu opens
19
+ // - Manage keyboard shortcuts and user actions
20
+ //
21
+ // **Architecture Pattern:**
22
+ // This file is split across 4 files via extensions:
23
+ // - `StatusItemController.swift` - Core setup (318 lines)
24
+ // - `StatusItemController+Menu.swift` - Menu construction (1878 lines)
25
+ // - `StatusItemController+Actions.swift` - User actions (200 lines)
26
+ // - `StatusItemController+Animation.swift` - Animation system (469 lines)
27
+ //
28
+ // **Performance:**
29
+ // - **60 FPS cap** during active pings (PerformanceConstants.menubarFPS)
30
+ // - **Auto-stop animations** when data loaded or error encountered
31
+ // - **1.2s delay** before background ping when menu opens (reduce perceived lag)
32
+ //
33
+ // **Dependencies:**
34
+ // - `UsageStore` - Data source
35
+ // - `SettingsStore` - User preferences
36
+ // - `IconRenderer` - Icon generation
37
+ // - `MenuCardView` - SwiftUI menu content
38
+ //
39
+ // **Usage:**
40
+ // ```swift
41
+ // let controller = StatusItemController(
42
+ // store: usageStore,
43
+ // settings: settingsStore,
44
+ // account: accountInfo,
45
+ // updater: updater,
46
+ // preferencesSelection: selection
47
+ // )
48
+ // ```
49
49
 
50
50
  // MARK: - Status item controller (AppKit-hosted icons, SwiftUI popovers)
51
51
 
@@ -59,7 +59,8 @@ final class BudgetNotificationManager {
59
59
  let title = "Budget Alert: \(projectName)"
60
60
  let body = "Projected to exceed \(limitStr) limit by \(overshootStr) this month"
61
61
 
62
- self.logger.info("posting budget breach notification",
62
+ self.logger.info(
63
+ "posting budget breach notification",
63
64
  metadata: [
64
65
  "provider": provider.rawValue,
65
66
  "project": projectKey,
@@ -1,9 +1,9 @@
1
- import RunicCore
2
1
  import Darwin
3
2
  import Foundation
3
+ import RunicCore
4
4
 
5
5
  struct ClaudeLoginRunner {
6
- enum Phase: Sendable {
6
+ enum Phase {
7
7
  case requesting
8
8
  case waitingBrowser
9
9
  }
@@ -1,6 +1,6 @@
1
- import RunicCore
2
1
  import Darwin
3
2
  import Foundation
3
+ import RunicCore
4
4
 
5
5
  struct CodexLoginRunner {
6
6
  struct Result {
@@ -1,21 +1,21 @@
1
1
  import AppKit
2
- import RunicCore
3
2
  import Foundation
3
+ import RunicCore
4
4
  import WebKit
5
5
 
6
6
  /// Handles Cursor login flow using a WebKit-based browser window.
7
7
  /// Captures session cookies after successful authentication.
8
8
  @MainActor
9
9
  final class CursorLoginRunner: NSObject {
10
- enum Phase: Sendable {
10
+ enum Phase {
11
11
  case loading
12
12
  case waitingLogin
13
13
  case success
14
14
  case failed(String)
15
15
  }
16
16
 
17
- struct Result: Sendable {
18
- enum Outcome: Sendable {
17
+ struct Result {
18
+ enum Outcome {
19
19
  case success
20
20
  case cancelled
21
21
  case failed(String)
@@ -1,6 +1,6 @@
1
1
  import AppKit
2
- import RunicCore
3
2
  import Foundation
3
+ import RunicCore
4
4
 
5
5
  enum GeminiLoginRunner {
6
6
  private static let geminiConfigDir = FileManager.default.homeDirectoryForCurrentUser
@@ -1,49 +1,49 @@
1
1
  import AppKit
2
2
  import RunicCore
3
3
 
4
- /// **IconRenderer** - Generates menubar status item icons with usage visualization
5
- ///
6
- /// **Purpose:**
7
- /// Creates pixel-perfect 18×18pt (36×36px @2x) template images for the macOS menubar.
8
- /// Renders usage bars, stale indicators, and provider status into the icon.
9
- ///
10
- /// **Responsibilities:**
11
- /// - Generate icons showing session/weekly usage patterns
12
- /// - Apply stale data dimming when data is > 5 minutes old
13
- /// - Cache rendered icons for performance (64 icon cache, 512 morph cache)
14
- /// - Support template (adapts to menubar theme) and vibrant appearances
15
- /// - Render loading animations and error states
16
- ///
17
- /// **Performance:**
18
- /// - **O(1) icon cache lookup** via IconCacheKey hash
19
- /// - **O(1) morph cache** for animation frames
20
- /// - Cap cache sizes via `PerformanceConstants`
21
- /// - All rendering happens off main thread in `dispatchPrecondition(condition: .notOnQueue(.main))`
22
- ///
23
- /// **Dependencies:**
24
- /// - `PerformanceConstants` - Cache sizes and timing
25
- /// - `UsageProvider` - Provider-specific rendering
26
- /// - `AppKit/CoreGraphics` - Image generation
27
- ///
28
- /// **Usage:**
29
- /// ```swift
30
- /// let icon = IconRenderer.render(
31
- /// state: .usage(snap, status),
32
- /// indicator: .none,
33
- /// appearance: .template,
34
- /// dataMode: .remaining
35
- /// )
36
- /// statusItem.button?.image = icon
37
- /// ```
38
-
39
- enum IconAppearance: Sendable {
40
- case template // Adapts to menubar theme (light/dark mode)
41
- case vibrant // Full color rendering
4
+ // **IconRenderer** - Generates menubar status item icons with usage visualization
5
+ //
6
+ // **Purpose:**
7
+ // Creates pixel-perfect 18×18pt (36×36px @2x) template images for the macOS menubar.
8
+ // Renders usage bars, stale indicators, and provider status into the icon.
9
+ //
10
+ // **Responsibilities:**
11
+ // - Generate icons showing session/weekly usage patterns
12
+ // - Apply stale data dimming when data is > 5 minutes old
13
+ // - Cache rendered icons for performance (64 icon cache, 512 morph cache)
14
+ // - Support template (adapts to menubar theme) and vibrant appearances
15
+ // - Render loading animations and error states
16
+ //
17
+ // **Performance:**
18
+ // - **O(1) icon cache lookup** via IconCacheKey hash
19
+ // - **O(1) morph cache** for animation frames
20
+ // - Cap cache sizes via `PerformanceConstants`
21
+ // - All rendering happens off main thread in `dispatchPrecondition(condition: .notOnQueue(.main))`
22
+ //
23
+ // **Dependencies:**
24
+ // - `PerformanceConstants` - Cache sizes and timing
25
+ // - `UsageProvider` - Provider-specific rendering
26
+ // - `AppKit/CoreGraphics` - Image generation
27
+ //
28
+ // **Usage:**
29
+ // ```swift
30
+ // let icon = IconRenderer.render(
31
+ // state: .usage(snap, status),
32
+ // indicator: .none,
33
+ // appearance: .template,
34
+ // dataMode: .remaining
35
+ // )
36
+ // statusItem.button?.image = icon
37
+ // ```
38
+
39
+ enum IconAppearance {
40
+ case template // Adapts to menubar theme (light/dark mode)
41
+ case vibrant // Full color rendering
42
42
  }
43
43
 
44
- enum IconDataMode: Sendable {
45
- case remaining // Show remaining quota
46
- case used // Show used quota
44
+ enum IconDataMode {
45
+ case remaining // Show remaining quota
46
+ case used // Show used quota
47
47
  }
48
48
 
49
49
  enum IconRenderer {
@@ -53,17 +53,18 @@ enum IconRenderer {
53
53
  private static let outputSize = NSSize(width: 38, height: 22)
54
54
  private static let outputScale: CGFloat = 2
55
55
  private static let canvasPx = Int(outputSize.width * outputScale)
56
-
57
- // Infinity symbol base template - loaded lazily from Resources
56
+
57
+ /// Infinity symbol base template - loaded lazily from Resources
58
58
  private static let waveLogoTemplate: NSImage? = {
59
59
  guard let url = Bundle.main.url(forResource: "RunicMenubarIcon", withExtension: "svg"),
60
- let image = NSImage(contentsOf: url) else {
60
+ let image = NSImage(contentsOf: url)
61
+ else {
61
62
  return nil
62
63
  }
63
64
  return image
64
65
  }()
65
66
 
66
- private struct PixelGrid: Sendable {
67
+ private struct PixelGrid {
67
68
  let scale: CGFloat
68
69
 
69
70
  func pt(_ px: Int) -> CGFloat {
@@ -142,14 +143,19 @@ enum IconRenderer {
142
143
  }
143
144
  }
144
145
 
145
- private struct RectPx: Hashable, Sendable {
146
+ private struct RectPx: Hashable {
146
147
  let x: Int
147
148
  let y: Int
148
149
  let w: Int
149
150
  let h: Int
150
151
 
151
- var midXPx: Int { self.x + self.w / 2 }
152
- var midYPx: Int { self.y + self.h / 2 }
152
+ var midXPx: Int {
153
+ self.x + self.w / 2
154
+ }
155
+
156
+ var midYPx: Int {
157
+ self.y + self.h / 2
158
+ }
153
159
 
154
160
  func rect() -> CGRect {
155
161
  Self.grid.rect(x: self.x, y: self.y, w: self.w, h: self.h)
@@ -215,13 +221,13 @@ enum IconRenderer {
215
221
  dataMode: dataMode)
216
222
  let accentColor = Self.vibrantAccentColor(pressure: pressure, stale: stale)
217
223
  let baseColor = appearance == .template ? NSColor.labelColor : accentColor
218
-
224
+
219
225
  // Disable blink effect to prevent flicker
220
226
  let opacityMultiplier = 1.0
221
-
227
+
222
228
  let fillColor = baseColor.withAlphaComponent((stale ? 0.55 : 1.0) * opacityMultiplier)
223
229
  let baseAlpha: CGFloat = (stale ? 0.18 : (appearance == .template ? 0.28 : 0.38)) * opacityMultiplier
224
-
230
+
225
231
  let fillPercent = Self.iconFillPercent(
226
232
  primary: topValue,
227
233
  weekly: bottomValue,
@@ -265,33 +271,33 @@ enum IconRenderer {
265
271
 
266
272
  private static func sigilStyle(for style: IconStyle) -> SigilStyle {
267
273
  switch style {
268
- case .codex: return .codex
269
- case .claude: return .claude
270
- case .zai: return .zai
271
- case .gemini: return .gemini
272
- case .antigravity: return .antigravity
273
- case .cursor: return .cursor
274
- case .factory: return .factory
275
- case .copilot: return .copilot
276
- case .minimax: return .minimax
277
- case .openrouter: return .openrouter
278
- case .groq: return .groq
279
- case .deepseek: return .deepseek
280
- case .fireworks: return .fireworks
281
- case .mistral: return .mistral
282
- case .perplexity: return .perplexity
283
- case .kimi: return .kimi
284
- case .auggie: return .auggie
285
- case .together: return .together
286
- case .cohere: return .cohere
287
- case .xai: return .xai
288
- case .cerebras: return .cerebras
289
- case .sambanova: return .sambanova
290
- case .azure: return .azure
291
- case .bedrock: return .bedrock
292
- case .vertexai: return .vertexai
293
- case .qwen: return .qwen
294
- case .combined: return .combined
274
+ case .codex: .codex
275
+ case .claude: .claude
276
+ case .zai: .zai
277
+ case .gemini: .gemini
278
+ case .antigravity: .antigravity
279
+ case .cursor: .cursor
280
+ case .factory: .factory
281
+ case .copilot: .copilot
282
+ case .minimax: .minimax
283
+ case .openrouter: .openrouter
284
+ case .groq: .groq
285
+ case .deepseek: .deepseek
286
+ case .fireworks: .fireworks
287
+ case .mistral: .mistral
288
+ case .perplexity: .perplexity
289
+ case .kimi: .kimi
290
+ case .auggie: .auggie
291
+ case .together: .together
292
+ case .cohere: .cohere
293
+ case .xai: .xai
294
+ case .cerebras: .cerebras
295
+ case .sambanova: .sambanova
296
+ case .azure: .azure
297
+ case .bedrock: .bedrock
298
+ case .vertexai: .vertexai
299
+ case .qwen: .qwen
300
+ case .combined: .combined
295
301
  }
296
302
  }
297
303
 
@@ -515,7 +521,7 @@ enum IconRenderer {
515
521
  let barHeightPx = 6
516
522
  let totalWidth = barWidthPx * 3 + barGapPx * 2
517
523
  let startX = centerXPx - totalWidth / 2
518
- for idx in 0 ..< 3 {
524
+ for idx in 0..<3 {
519
525
  let x = startX + idx * (barWidthPx + barGapPx)
520
526
  let rect = Self.grid.rect(
521
527
  x: x,
@@ -835,7 +841,8 @@ enum IconRenderer {
835
841
  fillColor: NSColor)
836
842
  {
837
843
  guard let waveLogo = self.waveLogoTemplate,
838
- let ctx = NSGraphicsContext.current?.cgContext else {
844
+ let ctx = NSGraphicsContext.current?.cgContext
845
+ else {
839
846
  return
840
847
  }
841
848
 
@@ -867,7 +874,7 @@ enum IconRenderer {
867
874
  credits: Double?,
868
875
  dataMode: IconDataMode) -> Double
869
876
  {
870
- let values = [primary, weekly, credits].compactMap { $0 }
877
+ let values = [primary, weekly, credits].compactMap(\.self)
871
878
  guard !values.isEmpty else { return 0 }
872
879
  let normalized = values.map { max(0, min($0 / 100, 1)) }
873
880
  switch dataMode {
@@ -884,11 +891,10 @@ enum IconRenderer {
884
891
  let safe = NSColor(calibratedRed: 0.12, green: 0.86, blue: 0.78, alpha: 1)
885
892
  let warn = NSColor(calibratedRed: 1.00, green: 0.72, blue: 0.30, alpha: 1)
886
893
  let hot = NSColor(calibratedRed: 1.00, green: 0.31, blue: 0.44, alpha: 1)
887
- let color: NSColor
888
- if clamped <= 0.5 {
889
- color = self.mixColor(safe, warn, p: clamped / 0.5)
894
+ let color: NSColor = if clamped <= 0.5 {
895
+ self.mixColor(safe, warn, p: clamped / 0.5)
890
896
  } else {
891
- color = self.mixColor(warn, hot, p: (clamped - 0.5) / 0.5)
897
+ self.mixColor(warn, hot, p: (clamped - 0.5) / 0.5)
892
898
  }
893
899
  if stale {
894
900
  return color.withAlphaComponent(0.72)
@@ -19,7 +19,9 @@ struct IconView: View {
19
19
  private let cycleIntervalTicks = 20
20
20
  private let patterns = LoadingPattern.allCases
21
21
 
22
- private var isLoading: Bool { self.showLoadingAnimation && self.snapshot == nil }
22
+ private var isLoading: Bool {
23
+ self.showLoadingAnimation && self.snapshot == nil
24
+ }
23
25
 
24
26
  var body: some View {
25
27
  Group {
@@ -14,12 +14,12 @@ enum RunicColors {
14
14
  /// Ordered palette for chart series. Colors chosen for distinguishability in
15
15
  /// both light and dark mode and for common color-vision deficiencies.
16
16
  static let chartPalette: [Color] = [
17
- Color(red: 0.26, green: 0.55, blue: 0.96), // blue
18
- Color(red: 0.94, green: 0.53, blue: 0.18), // orange
19
- Color(red: 0.46, green: 0.75, blue: 0.36), // green
20
- Color(red: 0.80, green: 0.45, blue: 0.92), // purple
21
- Color(red: 0.26, green: 0.78, blue: 0.86), // teal
22
- Color(red: 0.94, green: 0.74, blue: 0.26), // yellow
17
+ Color(red: 0.26, green: 0.55, blue: 0.96), // blue
18
+ Color(red: 0.94, green: 0.53, blue: 0.18), // orange
19
+ Color(red: 0.46, green: 0.75, blue: 0.36), // green
20
+ Color(red: 0.80, green: 0.45, blue: 0.92), // purple
21
+ Color(red: 0.26, green: 0.78, blue: 0.86), // teal
22
+ Color(red: 0.94, green: 0.74, blue: 0.26), // yellow
23
23
  ]
24
24
 
25
25
  /// Returns a chart color for the given index, wrapping around if needed.
@@ -33,16 +33,16 @@ enum RunicSpacing {
33
33
  // MARK: - Semantic Spacing
34
34
 
35
35
  /// Horizontal padding for menu content
36
- static let menuHorizontalPadding: CGFloat = sm // 12pt
36
+ static let menuHorizontalPadding: CGFloat = sm // 12pt
37
37
 
38
38
  /// Vertical padding for menu content
39
- static let menuVerticalPadding: CGFloat = xs // 8pt
39
+ static let menuVerticalPadding: CGFloat = xs // 8pt
40
40
 
41
41
  /// Spacing between cards in menu
42
- static let cardSpacing: CGFloat = xs // 8pt
42
+ static let cardSpacing: CGFloat = xs // 8pt
43
43
 
44
44
  /// Spacing between major sections
45
- static let sectionSpacing: CGFloat = lg // 24pt
45
+ static let sectionSpacing: CGFloat = lg // 24pt
46
46
 
47
47
  // MARK: - Preferences Spacing
48
48
 
@@ -50,13 +50,13 @@ enum RunicSpacing {
50
50
  static let compact: CGFloat = 6
51
51
 
52
52
  /// Standardized spacing for toggle rows
53
- static let toggleRowSpacing: CGFloat = xs // 8pt
53
+ static let toggleRowSpacing: CGFloat = xs // 8pt
54
54
 
55
55
  /// Spacing after section headers
56
- static let sectionHeaderSpacing: CGFloat = md // 16pt
56
+ static let sectionHeaderSpacing: CGFloat = md // 16pt
57
57
 
58
58
  /// Spacing within stepper controls
59
- static let stepperControlSpacing: CGFloat = xs // 8pt
59
+ static let stepperControlSpacing: CGFloat = xs // 8pt
60
60
 
61
61
  // MARK: - Chart Metrics
62
62