@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
@@ -29,15 +29,20 @@ struct IntegrationsPane: View {
29
29
  var isRunning: Bool
30
30
  var port: Int
31
31
 
32
- var statusIndicator: String { "●" }
33
- var statusColor: Color { self.isRunning ? .green : .red }
32
+ var statusIndicator: String {
33
+ "●"
34
+ }
35
+
36
+ var statusColor: Color {
37
+ self.isRunning ? .green : .red
38
+ }
34
39
  }
35
40
 
36
41
  var body: some View {
37
42
  PreferencesPane {
38
43
  SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
39
44
  Text("vaayu Integration")
40
- .font(.caption)
45
+ .font(RunicFont.caption)
41
46
  .foregroundStyle(.secondary)
42
47
  .textCase(.uppercase)
43
48
 
@@ -50,11 +55,11 @@ struct IntegrationsPane: View {
50
55
 
51
56
  if self.vaayuAPIServerEnabled {
52
57
  Text("Running on port \(self.vaayuAPIServerPort)")
53
- .font(.footnote)
58
+ .font(RunicFont.footnote)
54
59
  .foregroundStyle(.green)
55
60
  } else {
56
61
  Text("Stopped")
57
- .font(.footnote)
62
+ .font(RunicFont.footnote)
58
63
  .foregroundStyle(.secondary)
59
64
  }
60
65
  }
@@ -62,21 +67,21 @@ struct IntegrationsPane: View {
62
67
  if self.vaayuAPIServerEnabled {
63
68
  VStack(alignment: .leading, spacing: 4) {
64
69
  Text("Port number")
65
- .font(.body)
70
+ .font(RunicFont.body)
66
71
 
67
72
  TextField("Port", value: self.$vaayuAPIServerPort, format: .number)
68
73
  .textFieldStyle(.roundedBorder)
69
74
  .frame(maxWidth: 150)
70
75
 
71
76
  Text("Default: 3000. Restart required after changing port.")
72
- .font(.footnote)
77
+ .font(RunicFont.footnote)
73
78
  .foregroundStyle(.tertiary)
74
79
  }
75
80
 
76
81
  VStack(alignment: .leading, spacing: 4) {
77
82
  HStack {
78
83
  Text("API Key")
79
- .font(.body)
84
+ .font(RunicFont.body)
80
85
 
81
86
  Spacer()
82
87
 
@@ -99,7 +104,7 @@ struct IntegrationsPane: View {
99
104
 
100
105
  if !self.vaayuAPIKey.isEmpty {
101
106
  Text(self.maskedAPIKey)
102
- .font(.footnote.monospaced())
107
+ .font(RunicFont.footnote.monospaced())
103
108
  .foregroundStyle(.secondary)
104
109
  .padding(RunicSpacing.xs)
105
110
  .background(Color(nsColor: .controlBackgroundColor))
@@ -108,14 +113,14 @@ struct IntegrationsPane: View {
108
113
 
109
114
  if let generatedKey = self.generatedAPIKey {
110
115
  Text("New key generated: \(generatedKey)")
111
- .font(.footnote)
116
+ .font(RunicFont.footnote)
112
117
  .foregroundStyle(.green)
113
118
  }
114
119
  }
115
120
  }
116
121
 
117
122
  Text("Exposes Runic usage data via REST API for external integrations.")
118
- .font(.footnote)
123
+ .font(RunicFont.footnote)
119
124
  .foregroundStyle(.tertiary)
120
125
  }
121
126
  }
@@ -124,14 +129,14 @@ struct IntegrationsPane: View {
124
129
 
125
130
  SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
126
131
  Text("MCP Servers")
127
- .font(.caption)
132
+ .font(RunicFont.caption)
128
133
  .foregroundStyle(.secondary)
129
134
  .textCase(.uppercase)
130
135
 
131
136
  VStack(spacing: RunicSpacing.xs) {
132
137
  HStack {
133
138
  Text("Configured servers")
134
- .font(.body)
139
+ .font(RunicFont.body)
135
140
  Spacer()
136
141
  Button {
137
142
  self.showingAddServerSheet = true
@@ -148,10 +153,10 @@ struct IntegrationsPane: View {
148
153
  .font(.system(size: 32))
149
154
  .foregroundStyle(.tertiary)
150
155
  Text("No MCP servers yet")
151
- .font(.body.weight(.semibold))
156
+ .font(RunicFont.body.weight(.semibold))
152
157
  .foregroundStyle(.secondary)
153
158
  Text("Add a server to manage connection details")
154
- .font(.footnote)
159
+ .font(RunicFont.footnote)
155
160
  .foregroundStyle(.tertiary)
156
161
  }
157
162
  .frame(maxWidth: .infinity)
@@ -161,13 +166,13 @@ struct IntegrationsPane: View {
161
166
  HStack(spacing: RunicSpacing.sm) {
162
167
  Text(server.statusIndicator)
163
168
  .foregroundStyle(server.statusColor)
164
- .font(.title3)
169
+ .font(RunicFont.title3)
165
170
 
166
171
  VStack(alignment: .leading, spacing: RunicSpacing.xxs) {
167
172
  Text(server.name)
168
- .font(.body)
173
+ .font(RunicFont.body)
169
174
  Text("Port \(server.port)")
170
- .font(.footnote)
175
+ .font(RunicFont.footnote)
171
176
  .foregroundStyle(.secondary)
172
177
  }
173
178
 
@@ -206,7 +211,7 @@ struct IntegrationsPane: View {
206
211
  }
207
212
 
208
213
  Text("MCP servers enable Claude Desktop and other tools to access Runic data.")
209
- .font(.footnote)
214
+ .font(RunicFont.footnote)
210
215
  .foregroundStyle(.tertiary)
211
216
  }
212
217
 
@@ -214,26 +219,26 @@ struct IntegrationsPane: View {
214
219
 
215
220
  SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
216
221
  Text("Webhooks")
217
- .font(.caption)
222
+ .font(RunicFont.caption)
218
223
  .foregroundStyle(.secondary)
219
224
  .textCase(.uppercase)
220
225
 
221
226
  VStack(alignment: .leading, spacing: RunicSpacing.sm) {
222
227
  VStack(alignment: .leading, spacing: 4) {
223
228
  Text("Default webhook URL")
224
- .font(.body)
229
+ .font(RunicFont.body)
225
230
 
226
231
  TextField("https://hooks.slack.com/services/...", text: self.$defaultWebhookURL)
227
232
  .textFieldStyle(.roundedBorder)
228
233
 
229
234
  Text("Used for all alerts unless overridden in alert rule settings.")
230
- .font(.footnote)
235
+ .font(RunicFont.footnote)
231
236
  .foregroundStyle(.tertiary)
232
237
  }
233
238
 
234
239
  VStack(alignment: .leading, spacing: 4) {
235
240
  Text("Webhook format")
236
- .font(.body)
241
+ .font(RunicFont.body)
237
242
 
238
243
  Picker("", selection: self.$webhookFormat) {
239
244
  Text("Slack").tag("slack")
@@ -244,7 +249,7 @@ struct IntegrationsPane: View {
244
249
  .frame(maxWidth: 300)
245
250
 
246
251
  Text("Formats webhook payloads for different platforms.")
247
- .font(.footnote)
252
+ .font(RunicFont.footnote)
248
253
  .foregroundStyle(.tertiary)
249
254
  }
250
255
 
@@ -257,7 +262,7 @@ struct IntegrationsPane: View {
257
262
 
258
263
  if let result = self.testWebhookResult {
259
264
  Text(result)
260
- .font(.footnote)
265
+ .font(RunicFont.footnote)
261
266
  .foregroundStyle(result.contains("Success") ? .green : .red)
262
267
  }
263
268
  }
@@ -268,7 +273,7 @@ struct IntegrationsPane: View {
268
273
 
269
274
  SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
270
275
  Text("GitHub Integration")
271
- .font(.caption)
276
+ .font(RunicFont.caption)
272
277
  .foregroundStyle(.secondary)
273
278
  .textCase(.uppercase)
274
279
 
@@ -281,7 +286,7 @@ struct IntegrationsPane: View {
281
286
  if self.githubIntegrationEnabled {
282
287
  VStack(alignment: .leading, spacing: 4) {
283
288
  Text("Repository path")
284
- .font(.body)
289
+ .font(RunicFont.body)
285
290
 
286
291
  HStack {
287
292
  TextField("/path/to/repo", text: self.$githubRepositoryPath)
@@ -300,7 +305,7 @@ struct IntegrationsPane: View {
300
305
  Image(systemName: "checkmark.circle.fill")
301
306
  .foregroundStyle(.green)
302
307
  Text("Valid Git repository")
303
- .font(.footnote)
308
+ .font(RunicFont.footnote)
304
309
  .foregroundStyle(.green)
305
310
  }
306
311
  } else {
@@ -308,7 +313,7 @@ struct IntegrationsPane: View {
308
313
  Image(systemName: "xmark.circle.fill")
309
314
  .foregroundStyle(.red)
310
315
  Text("Not a valid Git repository")
311
- .font(.footnote)
316
+ .font(RunicFont.footnote)
312
317
  .foregroundStyle(.red)
313
318
  }
314
319
  }
@@ -479,11 +484,11 @@ private struct AddMCPServerSheet: View {
479
484
  var body: some View {
480
485
  VStack(alignment: .leading, spacing: RunicSpacing.lg) {
481
486
  Text("Add MCP Server")
482
- .font(.title2.weight(.semibold))
487
+ .font(RunicFont.title2.weight(.semibold))
483
488
 
484
489
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
485
490
  Text("Name")
486
- .font(.subheadline.weight(.medium))
491
+ .font(RunicFont.subheadline.weight(.medium))
487
492
  TextField("Local MCP Server", text: self.$name)
488
493
  .textFieldStyle(.roundedBorder)
489
494
  .focused(self.$isNameFocused)
@@ -491,7 +496,7 @@ private struct AddMCPServerSheet: View {
491
496
 
492
497
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
493
498
  Text("Port")
494
- .font(.subheadline.weight(.medium))
499
+ .font(RunicFont.subheadline.weight(.medium))
495
500
  TextField("", value: self.$port, format: .number)
496
501
  .textFieldStyle(.roundedBorder)
497
502
  .frame(width: 140)
@@ -523,8 +528,8 @@ private enum VaayuKeychainHelper {
523
528
  var result: CFTypeRef?
524
529
  let query: [String: Any] = [
525
530
  kSecClass as String: kSecClassGenericPassword,
526
- kSecAttrService as String: service,
527
- kSecAttrAccount as String: account,
531
+ kSecAttrService as String: self.service,
532
+ kSecAttrAccount as String: self.account,
528
533
  kSecMatchLimit as String: kSecMatchLimitOne,
529
534
  kSecReturnData as String: true,
530
535
  kSecUseAuthenticationUI as String: kSecUseAuthenticationUIFail,
@@ -542,12 +547,12 @@ private enum VaayuKeychainHelper {
542
547
 
543
548
  @discardableResult
544
549
  static func save(_ value: String) -> Bool {
545
- delete()
550
+ self.delete()
546
551
  let data = Data(value.utf8)
547
552
  let query: [String: Any] = [
548
553
  kSecClass as String: kSecClassGenericPassword,
549
- kSecAttrService as String: service,
550
- kSecAttrAccount as String: account,
554
+ kSecAttrService as String: self.service,
555
+ kSecAttrAccount as String: self.account,
551
556
  kSecValueData as String: data,
552
557
  kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock,
553
558
  ]
@@ -558,8 +563,8 @@ private enum VaayuKeychainHelper {
558
563
  static func delete() -> Bool {
559
564
  let query: [String: Any] = [
560
565
  kSecClass as String: kSecClassGenericPassword,
561
- kSecAttrService as String: service,
562
- kSecAttrAccount as String: account,
566
+ kSecAttrService as String: self.service,
567
+ kSecAttrAccount as String: self.account,
563
568
  ]
564
569
  let status = SecItemDelete(query as CFDictionary)
565
570
  return status == errSecSuccess || status == errSecItemNotFound
@@ -23,17 +23,19 @@ struct PerformancePane: View {
23
23
  @State private var appeared = false
24
24
 
25
25
  enum QualityRatingFrequency: String, CaseIterable, Identifiable {
26
- case every = "every"
26
+ case every
27
27
  case over1000 = "over_1000"
28
28
  case over5000 = "over_5000"
29
29
 
30
- var id: String { self.rawValue }
30
+ var id: String {
31
+ self.rawValue
32
+ }
31
33
 
32
34
  var label: String {
33
35
  switch self {
34
- case .every: return "After every response"
35
- case .over1000: return "Only >1000 tokens"
36
- case .over5000: return "Only >5000 tokens"
36
+ case .every: "After every response"
37
+ case .over1000: "Only >1000 tokens"
38
+ case .over5000: "Only >5000 tokens"
37
39
  }
38
40
  }
39
41
  }
@@ -47,8 +49,9 @@ struct PerformancePane: View {
47
49
  binding: self.$performanceTrackingEnabled)
48
50
 
49
51
  if !self.performanceTrackingEnabled {
50
- Text("Performance tracking is disabled. Historical data is preserved but new metrics won't be collected.")
51
- .font(.footnote)
52
+ Text(
53
+ "Performance tracking is disabled. Historical data is preserved but new metrics won't be collected.")
54
+ .font(RunicFont.footnote)
52
55
  .foregroundStyle(.orange)
53
56
  .padding(.vertical, RunicSpacing.xs)
54
57
  }
@@ -59,7 +62,7 @@ struct PerformancePane: View {
59
62
  VStack(alignment: .leading, spacing: RunicSpacing.sm) {
60
63
  VStack(alignment: .leading, spacing: 4) {
61
64
  Text("Raw metrics retention")
62
- .font(.body)
65
+ .font(RunicFont.body)
63
66
 
64
67
  Picker("", selection: self.$rawMetricsRetentionDays) {
65
68
  Text("30 days").tag(30)
@@ -70,13 +73,13 @@ struct PerformancePane: View {
70
73
  .frame(maxWidth: 300)
71
74
 
72
75
  Text("How long to keep detailed latency and error records.")
73
- .font(.footnote)
76
+ .font(RunicFont.footnote)
74
77
  .foregroundStyle(.tertiary)
75
78
  }
76
79
 
77
80
  VStack(alignment: .leading, spacing: 4) {
78
81
  Text("Aggregated stats retention")
79
- .font(.body)
82
+ .font(RunicFont.body)
80
83
 
81
84
  Picker("", selection: self.$aggregatedStatsRetentionYears) {
82
85
  Text("1 year").tag(1)
@@ -87,7 +90,7 @@ struct PerformancePane: View {
87
90
  .frame(maxWidth: 300)
88
91
 
89
92
  Text("How long to keep daily performance summaries.")
90
- .font(.footnote)
93
+ .font(RunicFont.footnote)
91
94
  .foregroundStyle(.tertiary)
92
95
  }
93
96
  }
@@ -104,7 +107,7 @@ struct PerformancePane: View {
104
107
  if self.qualityRatingPromptsEnabled {
105
108
  VStack(alignment: .leading, spacing: 4) {
106
109
  Text("Prompt frequency")
107
- .font(.body)
110
+ .font(RunicFont.body)
108
111
 
109
112
  Picker("", selection: self.$qualityRatingFrequency) {
110
113
  ForEach(QualityRatingFrequency.allCases) { freq in
@@ -115,7 +118,7 @@ struct PerformancePane: View {
115
118
  .frame(maxWidth: 400)
116
119
 
117
120
  Text("When to show rating prompts based on response size.")
118
- .font(.footnote)
121
+ .font(RunicFont.footnote)
119
122
  .foregroundStyle(.tertiary)
120
123
  }
121
124
 
@@ -135,9 +138,9 @@ struct PerformancePane: View {
135
138
  VStack(alignment: .leading, spacing: RunicSpacing.sm) {
136
139
  HStack {
137
140
  Text("Current database size:")
138
- .font(.body)
141
+ .font(RunicFont.body)
139
142
  Text(self.databaseSize)
140
- .font(.body.weight(.semibold))
143
+ .font(RunicFont.body.weight(.semibold))
141
144
  .foregroundStyle(.secondary)
142
145
  }
143
146
 
@@ -157,13 +160,13 @@ struct PerformancePane: View {
157
160
 
158
161
  if let status = self.vacuumStatus {
159
162
  Text(status)
160
- .font(.footnote)
163
+ .font(RunicFont.footnote)
161
164
  .foregroundStyle(status.contains("Success") ? .green : .red)
162
165
  }
163
166
  }
164
167
 
165
168
  Text("Optimizes database file by reclaiming unused space.")
166
- .font(.footnote)
169
+ .font(RunicFont.footnote)
167
170
  .foregroundStyle(.tertiary)
168
171
 
169
172
  Divider()
@@ -185,13 +188,13 @@ struct PerformancePane: View {
185
188
 
186
189
  if let status = self.clearDataStatus {
187
190
  Text(status)
188
- .font(.footnote)
191
+ .font(RunicFont.footnote)
189
192
  .foregroundStyle(status.contains("Success") ? .green : .red)
190
193
  }
191
194
  }
192
195
 
193
196
  Text("Removes metrics older than configured retention periods.")
194
- .font(.footnote)
197
+ .font(RunicFont.footnote)
195
198
  .foregroundStyle(.tertiary)
196
199
  }
197
200
  }
@@ -204,8 +207,9 @@ struct PerformancePane: View {
204
207
  binding: self.$anonymousUsageStatsEnabled)
205
208
 
206
209
  if self.anonymousUsageStatsEnabled {
207
- Text("Only aggregate statistics are shared. Request IDs, prompts, and responses are never included.")
208
- .font(.footnote)
210
+ Text(
211
+ "Only aggregate statistics are shared. Request IDs, prompts, and responses are never included.")
212
+ .font(RunicFont.footnote)
209
213
  .foregroundStyle(.tertiary)
210
214
  .padding(.vertical, RunicSpacing.xs)
211
215
  }
@@ -223,8 +227,7 @@ struct PerformancePane: View {
223
227
  Task {
224
228
  let appSupport = FileManager.default.urls(
225
229
  for: .applicationSupportDirectory,
226
- in: .userDomainMask
227
- ).first!
230
+ in: .userDomainMask).first!
228
231
  let dbPath = appSupport.appendingPathComponent("Runic/performance.db")
229
232
 
230
233
  if let attributes = try? FileManager.default.attributesOfItem(atPath: dbPath.path),