@sriinnu/runic 1.0.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 (348) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +1 -1
  3. package/README.md +47 -29
  4. package/RuniciOS/Core/RunicTypographyiOS.swift +24 -0
  5. package/RuniciOS/Views/ProviderDetailView.swift +9 -9
  6. package/RuniciOS/Views/ProviderListView.swift +10 -10
  7. package/RuniciOS/Widgets/LargeWidget.swift +14 -14
  8. package/RuniciOS/Widgets/LiveActivity.swift +19 -19
  9. package/RuniciOS/Widgets/LockScreenWidget.swift +15 -15
  10. package/RuniciOS/Widgets/MediumWidget.swift +10 -10
  11. package/RuniciOS/Widgets/RunicWidget.swift +5 -5
  12. package/RuniciOS/Widgets/SmallWidget.swift +9 -9
  13. package/Scripts/package_app.sh +2 -2
  14. package/Sources/Runic/About.swift +3 -3
  15. package/Sources/Runic/AppNotifications.swift +5 -3
  16. package/Sources/Runic/Controllers/StatusItemController+Actions.swift +17 -4
  17. package/Sources/Runic/Controllers/StatusItemController+Animation.swift +5 -4
  18. package/Sources/Runic/Controllers/StatusItemController+ChartSubmenus.swift +30 -16
  19. package/Sources/Runic/Controllers/StatusItemController+CustomProviders.swift +6 -3
  20. package/Sources/Runic/Controllers/StatusItemController+Menu.swift +47 -14
  21. package/Sources/Runic/Controllers/StatusItemController+MenuCards.swift +6 -4
  22. package/Sources/Runic/Controllers/StatusItemController+MenuHelpers.swift +40 -12
  23. package/Sources/Runic/Controllers/StatusItemController.swift +43 -43
  24. package/Sources/Runic/Core/BudgetNotificationManager.swift +2 -1
  25. package/Sources/Runic/Core/Login/ClaudeLoginRunner.swift +2 -2
  26. package/Sources/Runic/Core/Login/CodexLoginRunner.swift +1 -1
  27. package/Sources/Runic/Core/Login/CursorLoginRunner.swift +4 -4
  28. package/Sources/Runic/Core/Login/GeminiLoginRunner.swift +3 -6
  29. package/Sources/Runic/Core/Rendering/IconRenderer.swift +91 -85
  30. package/Sources/Runic/Core/Rendering/IconView.swift +3 -1
  31. package/Sources/Runic/Core/RunicColors.swift +6 -6
  32. package/Sources/Runic/Core/RunicSpacing.swift +7 -7
  33. package/Sources/Runic/Core/RunicTypography.swift +206 -0
  34. package/Sources/Runic/Core/Stores/AuggieTokenStore.swift +10 -36
  35. package/Sources/Runic/Core/Stores/AzureOpenAITokenStore.swift +10 -36
  36. package/Sources/Runic/Core/Stores/CerebrasTokenStore.swift +10 -36
  37. package/Sources/Runic/Core/Stores/CohereTokenStore.swift +10 -36
  38. package/Sources/Runic/Core/Stores/CopilotTokenStore.swift +10 -36
  39. package/Sources/Runic/Core/Stores/CustomProviderStore.swift +10 -10
  40. package/Sources/Runic/Core/Stores/DeepSeekTokenStore.swift +10 -36
  41. package/Sources/Runic/Core/Stores/FireworksTokenStore.swift +10 -36
  42. package/Sources/Runic/Core/Stores/GroqTokenStore.swift +10 -36
  43. package/Sources/Runic/Core/Stores/KimiTokenStore.swift +10 -36
  44. package/Sources/Runic/Core/Stores/MiniMaxCookieHeaderStore.swift +10 -36
  45. package/Sources/Runic/Core/Stores/MiniMaxGroupIDStore.swift +10 -36
  46. package/Sources/Runic/Core/Stores/MiniMaxTokenStore.swift +10 -36
  47. package/Sources/Runic/Core/Stores/MistralTokenStore.swift +10 -36
  48. package/Sources/Runic/Core/Stores/OpenRouterTokenStore.swift +10 -36
  49. package/Sources/Runic/Core/Stores/PerplexityTokenStore.swift +10 -36
  50. package/Sources/Runic/Core/Stores/ProviderToggleStore.swift +1 -1
  51. package/Sources/Runic/Core/Stores/QwenTokenStore.swift +10 -36
  52. package/Sources/Runic/Core/Stores/SambaNovaTokenStore.swift +10 -36
  53. package/Sources/Runic/Core/Stores/SettingsStore.swift +99 -52
  54. package/Sources/Runic/Core/Stores/TogetherTokenStore.swift +10 -36
  55. package/Sources/Runic/Core/Stores/UsageStore+Accessors.swift +19 -6
  56. package/Sources/Runic/Core/Stores/UsageStore+TokenCost.swift +1 -1
  57. package/Sources/Runic/Core/Stores/UsageStore+WidgetSnapshot.swift +1 -1
  58. package/Sources/Runic/Core/Stores/UsageStore.swift +234 -167
  59. package/Sources/Runic/Core/Stores/XAITokenStore.swift +10 -36
  60. package/Sources/Runic/Core/Stores/ZaiTokenStore.swift +10 -36
  61. package/Sources/Runic/Core/UsageExporter.swift +8 -4
  62. package/Sources/Runic/ProviderRegistry.swift +1 -1
  63. package/Sources/Runic/Providers/Antigravity/AntigravityProviderImplementation.swift +1 -1
  64. package/Sources/Runic/Providers/Auggie/AuggieProviderImplementation.swift +1 -1
  65. package/Sources/Runic/Providers/Azure/AzureProviderImplementation.swift +1 -1
  66. package/Sources/Runic/Providers/Bedrock/BedrockProviderImplementation.swift +1 -1
  67. package/Sources/Runic/Providers/Cerebras/CerebrasProviderImplementation.swift +1 -1
  68. package/Sources/Runic/Providers/Codex/CodexProviderImplementation.swift +1 -1
  69. package/Sources/Runic/Providers/Cohere/CohereProviderImplementation.swift +1 -1
  70. package/Sources/Runic/Providers/Cursor/CursorProviderImplementation.swift +1 -1
  71. package/Sources/Runic/Providers/DeepSeek/DeepSeekProviderImplementation.swift +1 -1
  72. package/Sources/Runic/Providers/Factory/FactoryProviderImplementation.swift +1 -1
  73. package/Sources/Runic/Providers/Fireworks/FireworksProviderImplementation.swift +1 -1
  74. package/Sources/Runic/Providers/Gemini/GeminiProviderImplementation.swift +1 -1
  75. package/Sources/Runic/Providers/Groq/GroqProviderImplementation.swift +1 -1
  76. package/Sources/Runic/Providers/Kimi/KimiProviderImplementation.swift +1 -1
  77. package/Sources/Runic/Providers/MiniMax/MiniMaxProviderImplementation.swift +1 -1
  78. package/Sources/Runic/Providers/Mistral/MistralProviderImplementation.swift +1 -1
  79. package/Sources/Runic/Providers/OpenRouter/OpenRouterProviderImplementation.swift +1 -1
  80. package/Sources/Runic/Providers/Perplexity/PerplexityProviderImplementation.swift +1 -1
  81. package/Sources/Runic/Providers/SambaNova/SambaNovaProviderImplementation.swift +1 -1
  82. package/Sources/Runic/Providers/Shared/ProviderImplementation.swift +5 -2
  83. package/Sources/Runic/Providers/Shared/ProviderImplementationRegistry.swift +1 -1
  84. package/Sources/Runic/Providers/Shared/ProviderSettingsDescriptors.swift +1 -1
  85. package/Sources/Runic/Providers/Together/TogetherProviderImplementation.swift +1 -1
  86. package/Sources/Runic/Providers/XAI/XAIProviderImplementation.swift +1 -1
  87. package/Sources/Runic/Providers/Zai/ZaiProviderImplementation.swift +1 -1
  88. package/Sources/Runic/Resources/Fonts/Caveat-Bold.ttf +0 -0
  89. package/Sources/Runic/Resources/Fonts/Caveat-Regular.ttf +0 -0
  90. package/Sources/Runic/Resources/Fonts/FiraCode-Bold.ttf +0 -0
  91. package/Sources/Runic/Resources/Fonts/FiraCode-Light.ttf +0 -0
  92. package/Sources/Runic/Resources/Fonts/FiraCode-Medium.ttf +0 -0
  93. package/Sources/Runic/Resources/Fonts/FiraCode-Regular.ttf +0 -0
  94. package/Sources/Runic/Resources/Fonts/FiraCode-SemiBold.ttf +0 -0
  95. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Bold.ttf +0 -0
  96. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Medium.ttf +0 -0
  97. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Regular.ttf +0 -0
  98. package/Sources/Runic/Resources/Fonts/IBMPlexMono-SemiBold.ttf +0 -0
  99. package/Sources/Runic/Resources/Fonts/Inconsolata-Bold.ttf +0 -0
  100. package/Sources/Runic/Resources/Fonts/Inconsolata-Medium.ttf +0 -0
  101. package/Sources/Runic/Resources/Fonts/Inconsolata-Regular.ttf +0 -0
  102. package/Sources/Runic/Resources/Fonts/Inconsolata-SemiBold.ttf +0 -0
  103. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Bold.ttf +0 -0
  104. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Medium.ttf +0 -0
  105. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Regular.ttf +0 -0
  106. package/Sources/Runic/Resources/Fonts/JetBrainsMono-SemiBold.ttf +0 -0
  107. package/Sources/Runic/Resources/Fonts/SpaceMono-Bold.ttf +0 -0
  108. package/Sources/Runic/Resources/Fonts/SpaceMono-Regular.ttf +0 -0
  109. package/Sources/Runic/Resources/provider-context-windows.json +20 -0
  110. package/Sources/Runic/RunicApp.swift +46 -36
  111. package/Sources/Runic/SessionQuotaNotifications.swift +2 -2
  112. package/Sources/Runic/UsagePaceText.swift +1 -1
  113. package/Sources/Runic/UsageProgressBar.swift +13 -9
  114. package/Sources/Runic/Utilities/LoadingPattern.swift +4 -2
  115. package/Sources/Runic/Utilities/PerformanceConstants.swift +28 -28
  116. package/Sources/Runic/Views/Menu/AlertsMenuView.swift +19 -21
  117. package/Sources/Runic/Views/Menu/CostComparativeChartMenuView.swift +19 -19
  118. package/Sources/Runic/Views/Menu/CostHistoryChartMenuView.swift +7 -7
  119. package/Sources/Runic/Views/Menu/CreditsHistoryChartMenuView.swift +5 -5
  120. package/Sources/Runic/Views/Menu/EfficiencyMetricsMenuView.swift +29 -30
  121. package/Sources/Runic/Views/Menu/HeroStatCardsMenuView.swift +20 -17
  122. package/Sources/Runic/Views/Menu/HourlyActivityChartMenuView.swift +14 -14
  123. package/Sources/Runic/Views/Menu/InlineUsageChartView.swift +15 -20
  124. package/Sources/Runic/Views/Menu/MenuCardEntranceModifier.swift +3 -4
  125. package/Sources/Runic/Views/Menu/MenuCardSidebarView.swift +5 -25
  126. package/Sources/Runic/Views/Menu/MenuCardSkeletonView.swift +1 -1
  127. package/Sources/Runic/Views/Menu/MenuCardView.swift +120 -131
  128. package/Sources/Runic/Views/Menu/MenuContent.swift +11 -8
  129. package/Sources/Runic/Views/Menu/MenuDescriptor.swift +4 -2
  130. package/Sources/Runic/Views/Menu/MenuHighlightStyle.swift +1 -8
  131. package/Sources/Runic/Views/Menu/ModelBreakdownMenuView.swift +20 -14
  132. package/Sources/Runic/Views/Menu/OverviewMenuView.swift +198 -58
  133. package/Sources/Runic/Views/Menu/ProjectBreakdownMenuView.swift +16 -11
  134. package/Sources/Runic/Views/Menu/ProjectBudgetMenuView.swift +27 -27
  135. package/Sources/Runic/Views/Menu/ProviderTabBarView.swift +4 -6
  136. package/Sources/Runic/Views/Menu/SubscriptionUtilizationChartMenuView.swift +24 -11
  137. package/Sources/Runic/Views/Menu/UsageBreakdownChartMenuView.swift +5 -5
  138. package/Sources/Runic/Views/Menu/UsageHeatmapMenuView.swift +7 -8
  139. package/Sources/Runic/Views/Menu/UsageTimelineChartMenuView.swift +28 -76
  140. package/Sources/Runic/Views/Menu/UsageWindowComparisonChartMenuView.swift +8 -7
  141. package/Sources/Runic/Views/Menu/WeeklyActivityChartMenuView.swift +7 -7
  142. package/Sources/Runic/Views/Performance/PerformanceDashboardView.swift +50 -47
  143. package/Sources/Runic/Views/Preferences/LiquidComponents.swift +15 -14
  144. package/Sources/Runic/Views/Preferences/PreferencesAboutPane.swift +7 -7
  145. package/Sources/Runic/Views/Preferences/PreferencesAdvancedPane.swift +27 -27
  146. package/Sources/Runic/Views/Preferences/PreferencesAlertsPane.swift +38 -42
  147. package/Sources/Runic/Views/Preferences/PreferencesAnalyticsPane.swift +39 -43
  148. package/Sources/Runic/Views/Preferences/PreferencesBudgetsPane.swift +21 -21
  149. package/Sources/Runic/Views/Preferences/PreferencesComponents.swift +7 -7
  150. package/Sources/Runic/Views/Preferences/PreferencesCustomProvidersPane.swift +49 -50
  151. package/Sources/Runic/Views/Preferences/PreferencesDebugPane.swift +10 -10
  152. package/Sources/Runic/Views/Preferences/PreferencesGeneralPane.swift +40 -21
  153. package/Sources/Runic/Views/Preferences/PreferencesHelpPane.swift +7 -7
  154. package/Sources/Runic/Views/Preferences/PreferencesIntegrationsPane.swift +108 -33
  155. package/Sources/Runic/Views/Preferences/PreferencesPerformancePane.swift +26 -23
  156. package/Sources/Runic/Views/Preferences/PreferencesProvidersPane.swift +271 -226
  157. package/Sources/Runic/Views/Preferences/PreferencesSelection.swift +6 -2
  158. package/Sources/Runic/Views/Preferences/PreferencesSyncPane.swift +7 -5
  159. package/Sources/Runic/Views/Preferences/PreferencesView.swift +38 -31
  160. package/Sources/Runic/Views/Rating/QualityRatingView.swift +11 -11
  161. package/Sources/Runic/Views/Team/TeamDashboardView.swift +29 -24
  162. package/Sources/Runic/Views/Team/TeamInviteSheet.swift +16 -16
  163. package/Sources/Runic/Views/Team/TeamManagementView.swift +50 -49
  164. package/Sources/Runic/Views/Team/TeamMemberRow.swift +8 -8
  165. package/Sources/RunicCLI/CLIEntry.swift +83 -42
  166. package/Sources/RunicCLI/CLIRenderer.swift +1 -1
  167. package/Sources/RunicCLI/Commands/EnhancedUsageCommand.swift +60 -60
  168. package/Sources/RunicCLI/Commands/ModelsCommand.swift +45 -44
  169. package/Sources/RunicCLI/Commands/ProjectsCommand.swift +83 -69
  170. package/Sources/RunicCLI/Commands/ResetCommand.swift +50 -49
  171. package/Sources/RunicCLI/Commands/UsageLedgerSourceFactory.swift +31 -32
  172. package/Sources/RunicClaudeWebProbe/main.swift +1 -1
  173. package/Sources/RunicCore/AlertRuleStore.swift +20 -20
  174. package/Sources/RunicCore/BrowserCookieImportOrder.swift +3 -3
  175. package/Sources/RunicCore/CostUsageModels.swift +1 -1
  176. package/Sources/RunicCore/CustomProviders/CustomProviderModels.swift +29 -30
  177. package/Sources/RunicCore/CustomProviders/GenericProviderFetcher.swift +80 -71
  178. package/Sources/RunicCore/CustomProviders/ProviderTemplates.swift +53 -109
  179. package/Sources/RunicCore/Host/PTY/TTYCommandRunner.swift +3 -3
  180. package/Sources/RunicCore/Integrations/GitHubIntegration.swift +3 -3
  181. package/Sources/RunicCore/Logging/OSLogLogHandler.swift +6 -6
  182. package/Sources/RunicCore/Models/EnhancedUsageModels.swift +47 -48
  183. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardBrowserCookieImporter.swift +1 -1
  184. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardFetcher.swift +1 -1
  185. package/Sources/RunicCore/Performance/PerformanceModels.swift +4 -4
  186. package/Sources/RunicCore/Performance/PerformanceStorageImpl.swift +81 -64
  187. package/Sources/RunicCore/Policy/UsagePolicyEngine.swift +2 -2
  188. package/Sources/RunicCore/ProjectBudgetStore.swift +15 -12
  189. package/Sources/RunicCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +4 -2
  190. package/Sources/RunicCore/Providers/Antigravity/AntigravityStatusProbe.swift +2 -2
  191. package/Sources/RunicCore/Providers/Auggie/AuggieProviderDescriptor.swift +2 -2
  192. package/Sources/RunicCore/Providers/Auggie/AuggieUsageFetcher.swift +3 -3
  193. package/Sources/RunicCore/Providers/Azure/AzureProviderDescriptor.swift +8 -8
  194. package/Sources/RunicCore/Providers/Azure/AzureUsageFetcher.swift +5 -3
  195. package/Sources/RunicCore/Providers/Bedrock/BedrockProviderDescriptor.swift +6 -6
  196. package/Sources/RunicCore/Providers/Bedrock/BedrockUsageFetcher.swift +3 -7
  197. package/Sources/RunicCore/Providers/Cerebras/CerebrasProviderDescriptor.swift +2 -2
  198. package/Sources/RunicCore/Providers/Cerebras/CerebrasUsageFetcher.swift +2 -2
  199. package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthUsageFetcher.swift +3 -3
  200. package/Sources/RunicCore/Providers/Claude/ClaudeProviderDescriptor.swift +4 -2
  201. package/Sources/RunicCore/Providers/Claude/ClaudeStatusProbe.swift +4 -4
  202. package/Sources/RunicCore/Providers/Claude/ClaudeUsageDataSource.swift +3 -1
  203. package/Sources/RunicCore/Providers/Claude/ClaudeWeb/ClaudeWebAPIFetcher.swift +1 -1
  204. package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthCredentials.swift +1 -0
  205. package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift +12 -1
  206. package/Sources/RunicCore/Providers/Codex/CodexProviderDescriptor.swift +4 -2
  207. package/Sources/RunicCore/Providers/Codex/CodexUsageDataSource.swift +3 -1
  208. package/Sources/RunicCore/Providers/Codex/CodexWebDashboardStrategy.swift +5 -3
  209. package/Sources/RunicCore/Providers/Cohere/CohereProviderDescriptor.swift +2 -2
  210. package/Sources/RunicCore/Providers/Cohere/CohereUsageFetcher.swift +3 -3
  211. package/Sources/RunicCore/Providers/Copilot/CopilotGitHubCLITokenReader.swift +7 -4
  212. package/Sources/RunicCore/Providers/Copilot/CopilotProviderDescriptor.swift +4 -4
  213. package/Sources/RunicCore/Providers/Copilot/CopilotUsageFetcher.swift +5 -3
  214. package/Sources/RunicCore/Providers/Copilot/CopilotVSCodeTokenReader.swift +9 -10
  215. package/Sources/RunicCore/Providers/Cursor/CursorProviderDescriptor.swift +4 -2
  216. package/Sources/RunicCore/Providers/Cursor/CursorStatusProbe.swift +1 -0
  217. package/Sources/RunicCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift +2 -2
  218. package/Sources/RunicCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift +2 -2
  219. package/Sources/RunicCore/Providers/Factory/FactoryLocalStorageImporter.swift +4 -4
  220. package/Sources/RunicCore/Providers/Factory/FactoryProviderDescriptor.swift +4 -2
  221. package/Sources/RunicCore/Providers/Factory/FactoryStatusProbe.swift +3 -2
  222. package/Sources/RunicCore/Providers/Fireworks/FireworksProviderDescriptor.swift +2 -2
  223. package/Sources/RunicCore/Providers/Fireworks/FireworksUsageFetcher.swift +2 -2
  224. package/Sources/RunicCore/Providers/Gemini/GeminiProviderDescriptor.swift +4 -2
  225. package/Sources/RunicCore/Providers/Gemini/GeminiStatusProbe.swift +6 -2
  226. package/Sources/RunicCore/Providers/Groq/GroqProviderDescriptor.swift +2 -2
  227. package/Sources/RunicCore/Providers/Groq/GroqUsageFetcher.swift +2 -2
  228. package/Sources/RunicCore/Providers/Kimi/KimiProviderDescriptor.swift +2 -2
  229. package/Sources/RunicCore/Providers/Kimi/KimiUsageFetcher.swift +2 -2
  230. package/Sources/RunicCore/Providers/MiniMax/MiniMaxProviderDescriptor.swift +10 -5
  231. package/Sources/RunicCore/Providers/MiniMax/MiniMaxUsageFetcher.swift +8 -11
  232. package/Sources/RunicCore/Providers/MiniMax/MiniMaxWebUsageFetcher.swift +10 -10
  233. package/Sources/RunicCore/Providers/Mistral/MistralProviderDescriptor.swift +2 -2
  234. package/Sources/RunicCore/Providers/Mistral/MistralUsageFetcher.swift +2 -2
  235. package/Sources/RunicCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift +2 -2
  236. package/Sources/RunicCore/Providers/OpenRouter/OpenRouterUsageFetcher.swift +25 -16
  237. package/Sources/RunicCore/Providers/Perplexity/PerplexityProviderDescriptor.swift +2 -2
  238. package/Sources/RunicCore/Providers/Perplexity/PerplexityUsageFetcher.swift +2 -2
  239. package/Sources/RunicCore/Providers/ProviderFetchPlan.swift +2 -2
  240. package/Sources/RunicCore/Providers/ProviderTokenResolver.swift +2 -2
  241. package/Sources/RunicCore/Providers/Qwen/QwenProviderDescriptor.swift +5 -3
  242. package/Sources/RunicCore/Providers/Qwen/QwenUsageStats.swift +27 -16
  243. package/Sources/RunicCore/Providers/SambaNova/SambaNovaProviderDescriptor.swift +2 -2
  244. package/Sources/RunicCore/Providers/SambaNova/SambaNovaUsageFetcher.swift +2 -2
  245. package/Sources/RunicCore/Providers/Together/TogetherProviderDescriptor.swift +2 -2
  246. package/Sources/RunicCore/Providers/Together/TogetherUsageFetcher.swift +2 -2
  247. package/Sources/RunicCore/Providers/VertexAI/VertexAIProviderDescriptor.swift +5 -5
  248. package/Sources/RunicCore/Providers/VertexAI/VertexAISettingsReader.swift +1 -1
  249. package/Sources/RunicCore/Providers/VertexAI/VertexAIUsageFetcher.swift +3 -3
  250. package/Sources/RunicCore/Providers/XAI/XAIProviderDescriptor.swift +2 -2
  251. package/Sources/RunicCore/Providers/XAI/XAIUsageFetcher.swift +2 -2
  252. package/Sources/RunicCore/Providers/Zai/ZaiProviderDescriptor.swift +4 -2
  253. package/Sources/RunicCore/Providers/Zai/ZaiUsageStats.swift +51 -30
  254. package/Sources/RunicCore/Sync/BackgroundSyncManager.swift +76 -77
  255. package/Sources/RunicCore/Sync/SyncConflictResolver.swift +55 -58
  256. package/Sources/RunicCore/Sync/SyncProtocol.swift +21 -22
  257. package/Sources/RunicCore/Sync/SyncRecord.swift +46 -49
  258. package/Sources/RunicCore/Sync/SyncUsageExample.swift +44 -50
  259. package/Sources/RunicCore/Sync/TeamSyncRecords.swift +94 -101
  260. package/Sources/RunicCore/Sync/iCloudSyncEngine.swift +51 -46
  261. package/Sources/RunicCore/Team/TeamModels.swift +111 -110
  262. package/Sources/RunicCore/Team/TeamStore.swift +126 -109
  263. package/Sources/RunicCore/UsageFetcher.swift +2 -2
  264. package/Sources/RunicCore/UsageFormatter.swift +25 -25
  265. package/Sources/RunicCore/UsageLedger/ClaudeUsageLogSource.swift +141 -29
  266. package/Sources/RunicCore/UsageLedger/CodexUsageLogSource.swift +59 -5
  267. package/Sources/RunicCore/UsageLedger/LedgerCache.swift +161 -0
  268. package/Sources/RunicCore/UsageLedger/OTelGenAILedgerAdapter.swift +1 -1
  269. package/Sources/RunicCore/UsageLedger/UsageLedgerAggregator.swift +40 -25
  270. package/Sources/RunicCore/UsageLedger/UsageLedgerInsightsAdvisor.swift +1 -1
  271. package/Sources/RunicCore/UsageLedger/UsageLedgerProjectIdentity.swift +55 -16
  272. package/Sources/RunicCore/Vendored/CostUsage/CostUsageCache.swift +6 -6
  273. package/Sources/RunicCore/Vendored/CostUsage/CostUsageJsonl.swift +1 -1
  274. package/Sources/RunicCore/Vendored/CostUsage/CostUsagePricing.swift +2 -2
  275. package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner.swift +5 -5
  276. package/Tests/RunicTests/AppDelegateTests.swift +8 -3
  277. package/Tests/RunicTests/BrowserCookieOrderLabelTests.swift +2 -3
  278. package/Tests/RunicTests/CLIArgumentParsingTests.swift +3 -4
  279. package/Tests/RunicTests/CLICostTests.swift +6 -7
  280. package/Tests/RunicTests/CLIProviderSelectionTests.swift +2 -3
  281. package/Tests/RunicTests/CLISnapshotTests.swift +3 -4
  282. package/Tests/RunicTests/CLIWebFallbackTests.swift +3 -4
  283. package/Tests/RunicTests/ClaudeOAuthTests.swift +11 -12
  284. package/Tests/RunicTests/ClaudeResilienceTests.swift +3 -4
  285. package/Tests/RunicTests/ClaudeUsageTests.swift +20 -21
  286. package/Tests/RunicTests/CodexOAuthTests.swift +7 -8
  287. package/Tests/RunicTests/CodexUsageLogSourceTests.swift +1 -3
  288. package/Tests/RunicTests/CopilotTokenResolverTests.swift +5 -6
  289. package/Tests/RunicTests/CopilotVSCodeTokenReaderTests.swift +4 -5
  290. package/Tests/RunicTests/CostUsageDecodingTests.swift +15 -17
  291. package/Tests/RunicTests/CostUsagePricingTests.swift +5 -7
  292. package/Tests/RunicTests/CostUsageScannerTests.swift +10 -12
  293. package/Tests/RunicTests/CursorStatusProbeTests.swift +15 -16
  294. package/Tests/RunicTests/FactoryStatusProbeTests.swift +3 -5
  295. package/Tests/RunicTests/GeminiLoginAlertTests.swift +3 -4
  296. package/Tests/RunicTests/GeminiStatusProbeAPITests.swift +11 -11
  297. package/Tests/RunicTests/GeminiStatusProbePlanTests.swift +8 -8
  298. package/Tests/RunicTests/GeminiStatusProbeTests.swift +20 -21
  299. package/Tests/RunicTests/GoogleWorkspaceStatusTests.swift +2 -3
  300. package/Tests/RunicTests/InstallOriginTests.swift +1 -2
  301. package/Tests/RunicTests/KeyboardShortcutsBundleTests.swift +2 -2
  302. package/Tests/RunicTests/LiveAccountTests.swift +3 -3
  303. package/Tests/RunicTests/LoadingPatternTests.swift +3 -4
  304. package/Tests/RunicTests/MenuCardModelTests.swift +33 -34
  305. package/Tests/RunicTests/MiniMaxCookieHeaderStoreTestSupport.swift +4 -1
  306. package/Tests/RunicTests/MiniMaxGroupIDStoreTestSupport.swift +4 -1
  307. package/Tests/RunicTests/MiniMaxParsingTests.swift +4 -5
  308. package/Tests/RunicTests/MiniMaxTokenStoreTestSupport.swift +4 -1
  309. package/Tests/RunicTests/OTelGenAILedgerAdapterTests.swift +4 -6
  310. package/Tests/RunicTests/OpenAIDashboardBrowserCookieImporterTests.swift +1 -2
  311. package/Tests/RunicTests/OpenAIDashboardFetcherCreditsWaitTests.swift +5 -6
  312. package/Tests/RunicTests/OpenAIDashboardOffscreenHostTests.swift +2 -3
  313. package/Tests/RunicTests/OpenAIDashboardParserTests.swift +12 -13
  314. package/Tests/RunicTests/OpenAIWebAccountSwitchTests.swift +17 -6
  315. package/Tests/RunicTests/OpenRouterTokenStoreTestSupport.swift +52 -13
  316. package/Tests/RunicTests/PathBuilderTests.swift +14 -15
  317. package/Tests/RunicTests/ProviderFetchPipelineTests.swift +3 -4
  318. package/Tests/RunicTests/ProviderIconResourcesTests.swift +1 -2
  319. package/Tests/RunicTests/ProviderMetadataStatusLinkTests.swift +1 -2
  320. package/Tests/RunicTests/ProviderSettingsDescriptorTests.swift +53 -19
  321. package/Tests/RunicTests/ProviderToggleStoreTests.swift +10 -11
  322. package/Tests/RunicTests/RunicTests.swift +6 -7
  323. package/Tests/RunicTests/SessionQuotaNotificationLogicTests.swift +5 -6
  324. package/Tests/RunicTests/SettingsStoreTests.swift +149 -45
  325. package/Tests/RunicTests/StatusItemAnimationTests.swift +8 -3
  326. package/Tests/RunicTests/StatusMenuTests.swift +63 -22
  327. package/Tests/RunicTests/StatusProbeTests.swift +28 -29
  328. package/Tests/RunicTests/SubprocessRunnerTests.swift +1 -3
  329. package/Tests/RunicTests/SubscriptionDetectionTests.swift +8 -9
  330. package/Tests/RunicTests/TTYCommandRunnerTests.swift +8 -9
  331. package/Tests/RunicTests/TeamShowbackExporterTests.swift +2 -4
  332. package/Tests/RunicTests/TextParsingTests.swift +1 -2
  333. package/Tests/RunicTests/UsageFormatterTests.swift +15 -16
  334. package/Tests/RunicTests/UsageLedgerAnomalyDetectionTests.swift +12 -14
  335. package/Tests/RunicTests/UsageLedgerForecastTests.swift +4 -6
  336. package/Tests/RunicTests/UsageLedgerInsightsAdvisorTests.swift +7 -9
  337. package/Tests/RunicTests/UsageLedgerProjectNameTests.swift +6 -8
  338. package/Tests/RunicTests/UsagePaceTests.swift +5 -6
  339. package/Tests/RunicTests/UsagePaceTextTests.swift +8 -9
  340. package/Tests/RunicTests/UsagePolicyEngineTests.swift +3 -5
  341. package/Tests/RunicTests/WidgetSnapshotTests.swift +1 -3
  342. package/Tests/RunicTests/ZaiProviderTests.swift +3 -5
  343. package/Tests/RunicTests/ZaiTokenStoreTestSupport.swift +4 -1
  344. package/appcast.xml +36 -37
  345. package/package.json +1 -1
  346. package/runic.png +0 -0
  347. package/runic.svg +15 -0
  348. package/version.env +2 -2
@@ -16,10 +16,14 @@ enum PreferencesTab: String, Hashable, CaseIterable, Identifiable {
16
16
  case about
17
17
  case debug
18
18
 
19
- var id: String { self.rawValue }
19
+ var id: String {
20
+ self.rawValue
21
+ }
20
22
 
21
23
  static let windowWidth: CGFloat = 560
22
24
  static let windowHeight: CGFloat = 726
23
25
 
24
- var preferredHeight: CGFloat { PreferencesTab.windowHeight }
26
+ var preferredHeight: CGFloat {
27
+ PreferencesTab.windowHeight
28
+ }
25
29
  }
@@ -13,19 +13,21 @@ struct SyncPane: View {
13
13
  case integrations
14
14
  case teams
15
15
 
16
- var id: String { self.rawValue }
16
+ var id: String {
17
+ self.rawValue
18
+ }
17
19
 
18
20
  var label: String {
19
21
  switch self {
20
- case .integrations: return "Integrations"
21
- case .teams: return "Teams"
22
+ case .integrations: "Integrations"
23
+ case .teams: "Teams"
22
24
  }
23
25
  }
24
26
 
25
27
  var icon: String {
26
28
  switch self {
27
- case .integrations: return "link"
28
- case .teams: return "person.3"
29
+ case .integrations: "link"
30
+ case .teams: "person.3"
29
31
  }
30
32
  }
31
33
  }
@@ -18,12 +18,14 @@ struct PreferencesView: View {
18
18
  case builtIn
19
19
  case custom
20
20
 
21
- var id: String { self.rawValue }
21
+ var id: String {
22
+ self.rawValue
23
+ }
22
24
 
23
25
  var label: String {
24
26
  switch self {
25
- case .builtIn: return "Built-in"
26
- case .custom: return "Custom"
27
+ case .builtIn: "Built-in"
28
+ case .custom: "Custom"
27
29
  }
28
30
  }
29
31
  }
@@ -32,12 +34,14 @@ struct PreferencesView: View {
32
34
  case monitoring
33
35
  case refresh
34
36
 
35
- var id: String { self.rawValue }
37
+ var id: String {
38
+ self.rawValue
39
+ }
36
40
 
37
41
  var label: String {
38
42
  switch self {
39
- case .monitoring: return "Monitoring"
40
- case .refresh: return "Refresh & Safety"
43
+ case .monitoring: "Monitoring"
44
+ case .refresh: "Refresh & Safety"
41
45
  }
42
46
  }
43
47
  }
@@ -46,12 +50,14 @@ struct PreferencesView: View {
46
50
  case about
47
51
  case help
48
52
 
49
- var id: String { self.rawValue }
53
+ var id: String {
54
+ self.rawValue
55
+ }
50
56
 
51
57
  var label: String {
52
58
  switch self {
53
- case .about: return "About"
54
- case .help: return "Help"
59
+ case .about: "About"
60
+ case .help: "Help"
55
61
  }
56
62
  }
57
63
  }
@@ -72,32 +78,32 @@ struct PreferencesView: View {
72
78
  LiquidMeshBackground().ignoresSafeArea().opacity(0.3)
73
79
  VStack(spacing: 0) {
74
80
  HStack(spacing: RunicSpacing.xs) {
75
- Picker("", selection: self.$providersSection) {
76
- ForEach(ProvidersSubSection.allCases) { section in
77
- Text(section.label).tag(section)
81
+ Picker("", selection: self.$providersSection) {
82
+ ForEach(ProvidersSubSection.allCases) { section in
83
+ Text(section.label).tag(section)
84
+ }
78
85
  }
79
- }
80
- .pickerStyle(.segmented)
86
+ .pickerStyle(.segmented)
81
87
 
82
- if self.providersSection == .builtIn {
83
- Picker("", selection: self.$settings.providersPaneSidebar) {
84
- Text("List").tag(false)
85
- Text("Sidebar").tag(true)
88
+ if self.providersSection == .builtIn {
89
+ Picker("", selection: self.$settings.providersPaneSidebar) {
90
+ Text("List").tag(false)
91
+ Text("Sidebar").tag(true)
92
+ }
93
+ .pickerStyle(.segmented)
94
+ .controlSize(.small)
86
95
  }
87
- .pickerStyle(.segmented)
88
- .controlSize(.small)
89
96
  }
90
- }
91
- .padding(.horizontal, PreferencesLayoutMetrics.paneHorizontal)
92
- .padding(.top, RunicSpacing.sm)
93
- .padding(.bottom, RunicSpacing.xs)
94
-
95
- switch self.providersSection {
96
- case .builtIn:
97
- ProvidersPane(settings: self.settings, store: self.store)
98
- case .custom:
99
- CustomProvidersPane(settings: self.settings, store: self.store)
100
- }
97
+ .padding(.horizontal, PreferencesLayoutMetrics.paneHorizontal)
98
+ .padding(.top, RunicSpacing.sm)
99
+ .padding(.bottom, RunicSpacing.xs)
100
+
101
+ switch self.providersSection {
102
+ case .builtIn:
103
+ ProvidersPane(settings: self.settings, store: self.store)
104
+ case .custom:
105
+ CustomProvidersPane(settings: self.settings, store: self.store)
106
+ }
101
107
  }
102
108
  }
103
109
  .tabItem {
@@ -181,6 +187,7 @@ struct PreferencesView: View {
181
187
  .tag(PreferencesTab.debug)
182
188
  }
183
189
  }
190
+ .runicTypography()
184
191
  .tabViewStyle(.automatic)
185
192
  .frame(
186
193
  minWidth: PreferencesTab.windowWidth,
@@ -3,7 +3,6 @@ import SwiftUI
3
3
 
4
4
  /// Inline quality rating UI for AI model interactions (1-5 stars)
5
5
  struct QualityRatingView: View {
6
-
7
6
  // MARK: - Types
8
7
 
9
8
  struct Model {
@@ -47,6 +46,7 @@ struct QualityRatingView: View {
47
46
  }
48
47
  }
49
48
  }
49
+ .runicTypography()
50
50
  .padding(RunicSpacing.sm)
51
51
  .background(Color(nsColor: .controlBackgroundColor))
52
52
  .clipShape(RoundedRectangle(cornerRadius: 8))
@@ -57,7 +57,7 @@ struct QualityRatingView: View {
57
57
  private var ratingSelector: some View {
58
58
  VStack(alignment: .leading, spacing: RunicSpacing.xxs) {
59
59
  Text("How would you rate this response?")
60
- .font(.subheadline)
60
+ .font(RunicFont.subheadline)
61
61
  .fontWeight(.medium)
62
62
 
63
63
  HStack(spacing: RunicSpacing.xs) {
@@ -66,7 +66,7 @@ struct QualityRatingView: View {
66
66
  self.selectRating(rating)
67
67
  } label: {
68
68
  Image(systemName: self.starIcon(for: rating))
69
- .font(.title2)
69
+ .font(RunicFont.title2)
70
70
  .foregroundStyle(self.starColor(for: rating))
71
71
  .contentShape(Rectangle())
72
72
  }
@@ -114,7 +114,7 @@ struct QualityRatingView: View {
114
114
  private var commentField: some View {
115
115
  VStack(alignment: .leading, spacing: RunicSpacing.xxs) {
116
116
  Text("Additional feedback (optional)")
117
- .font(.caption)
117
+ .font(RunicFont.caption)
118
118
  .foregroundStyle(.secondary)
119
119
 
120
120
  TextField("Share your thoughts...", text: self.$comment, axis: .vertical)
@@ -145,7 +145,7 @@ struct QualityRatingView: View {
145
145
  .frame(width: 12, height: 12)
146
146
  }
147
147
  Text(self.isSubmitting ? "Submitting..." : "Submit Rating")
148
- .font(.subheadline)
148
+ .font(RunicFont.subheadline)
149
149
  .fontWeight(.medium)
150
150
  }
151
151
  .padding(.horizontal, RunicSpacing.sm)
@@ -161,19 +161,19 @@ struct QualityRatingView: View {
161
161
  private var thankYouView: some View {
162
162
  HStack(spacing: RunicSpacing.xs) {
163
163
  Image(systemName: "checkmark.circle.fill")
164
- .font(.title3)
164
+ .font(RunicFont.title3)
165
165
  .foregroundStyle(.green)
166
166
 
167
167
  VStack(alignment: .leading, spacing: 2) {
168
168
  Text("Thank you for your feedback!")
169
- .font(.subheadline)
169
+ .font(RunicFont.subheadline)
170
170
  .fontWeight(.medium)
171
171
 
172
172
  if let rating = self.selectedRating {
173
173
  HStack(spacing: 4) {
174
174
  ForEach(1...5, id: \.self) { star in
175
175
  Image(systemName: star <= rating ? "star.fill" : "star")
176
- .font(.caption2)
176
+ .font(RunicFont.caption2)
177
177
  .foregroundStyle(star <= rating ? .yellow : Color(nsColor: .tertiaryLabelColor))
178
178
  }
179
179
  }
@@ -190,11 +190,11 @@ struct QualityRatingView: View {
190
190
  private func errorView(_ message: String) -> some View {
191
191
  HStack(spacing: RunicSpacing.xs) {
192
192
  Image(systemName: "exclamationmark.triangle.fill")
193
- .font(.caption)
193
+ .font(RunicFont.caption)
194
194
  .foregroundStyle(.red)
195
195
 
196
196
  Text(message)
197
- .font(.caption)
197
+ .font(RunicFont.caption)
198
198
  .foregroundStyle(.red)
199
199
  .lineLimit(2)
200
200
 
@@ -205,7 +205,7 @@ struct QualityRatingView: View {
205
205
  await self.submitRating()
206
206
  }
207
207
  }
208
- .font(.caption)
208
+ .font(RunicFont.caption)
209
209
  }
210
210
  .padding(RunicSpacing.xs)
211
211
  .background(Color.red.opacity(0.1))
@@ -26,6 +26,7 @@ struct TeamDashboardView: View {
26
26
  }
27
27
  .padding(RunicSpacing.lg)
28
28
  }
29
+ .runicTypography()
29
30
  .frame(width: 700, height: 600)
30
31
  }
31
32
 
@@ -34,9 +35,9 @@ struct TeamDashboardView: View {
34
35
  HStack {
35
36
  VStack(alignment: .leading, spacing: RunicSpacing.xxs) {
36
37
  Text(self.team.name)
37
- .font(.title.weight(.bold))
38
+ .font(RunicFont.title.weight(.bold))
38
39
  Text("\(self.team.members.count) member\(self.team.members.count == 1 ? "" : "s")")
39
- .font(.subheadline)
40
+ .font(RunicFont.subheadline)
40
41
  .foregroundStyle(.secondary)
41
42
  }
42
43
 
@@ -56,7 +57,7 @@ struct TeamDashboardView: View {
56
57
  private var usageOverviewSection: some View {
57
58
  VStack(alignment: .leading, spacing: RunicSpacing.md) {
58
59
  Text("Usage Overview")
59
- .font(.headline)
60
+ .font(RunicFont.headline)
60
61
 
61
62
  HStack(spacing: RunicSpacing.lg) {
62
63
  self.statCard(
@@ -99,13 +100,13 @@ struct TeamDashboardView: View {
99
100
  private var memberBreakdownSection: some View {
100
101
  VStack(alignment: .leading, spacing: RunicSpacing.md) {
101
102
  Text("Member Usage Breakdown")
102
- .font(.headline)
103
+ .font(RunicFont.headline)
103
104
 
104
105
  let data = self.memberUsageData
105
106
 
106
107
  if data.isEmpty {
107
108
  Text("No usage data available")
108
- .font(.footnote)
109
+ .font(RunicFont.footnote)
109
110
  .foregroundStyle(.tertiary)
110
111
  .frame(maxWidth: .infinity, alignment: .center)
111
112
  .padding(.vertical, RunicSpacing.xl)
@@ -121,7 +122,7 @@ struct TeamDashboardView: View {
121
122
  .annotation(position: .top) {
122
123
  if item.usage > 0 {
123
124
  Text("\(item.usage, specifier: "%d")")
124
- .font(.caption2)
125
+ .font(RunicFont.caption2)
125
126
  .foregroundStyle(.secondary)
126
127
  }
127
128
  }
@@ -131,7 +132,7 @@ struct TeamDashboardView: View {
131
132
  AxisValueLabel {
132
133
  if let name = value.as(String.self) {
133
134
  Text(name)
134
- .font(.caption)
135
+ .font(RunicFont.caption)
135
136
  .lineLimit(1)
136
137
  .truncationMode(.tail)
137
138
  }
@@ -144,7 +145,7 @@ struct TeamDashboardView: View {
144
145
  AxisValueLabel {
145
146
  if let intValue = value.as(Int.self) {
146
147
  Text("\(intValue / 1000)K")
147
- .font(.caption2)
148
+ .font(RunicFont.caption2)
148
149
  .foregroundStyle(.secondary)
149
150
  }
150
151
  }
@@ -173,14 +174,14 @@ struct TeamDashboardView: View {
173
174
  .fill(item.color)
174
175
  .frame(width: 8, height: 8)
175
176
  Text(item.memberName)
176
- .font(.caption)
177
+ .font(RunicFont.caption)
177
178
  .foregroundStyle(
178
179
  self.selectedMemberID == item.memberID
179
180
  ? .primary
180
181
  : .secondary)
181
182
  Spacer()
182
183
  Text("\(item.usage, specifier: "%d")")
183
- .font(.caption.monospacedDigit())
184
+ .font(RunicFont.caption.monospacedDigit())
184
185
  .foregroundStyle(.secondary)
185
186
  }
186
187
  .padding(.horizontal, RunicSpacing.xs)
@@ -208,21 +209,21 @@ struct TeamDashboardView: View {
208
209
  private var recentActivitySection: some View {
209
210
  VStack(alignment: .leading, spacing: RunicSpacing.md) {
210
211
  Text("Recent Activity")
211
- .font(.headline)
212
+ .font(RunicFont.headline)
212
213
 
213
214
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
214
215
  ForEach(self.recentActivities) { activity in
215
216
  HStack(spacing: RunicSpacing.sm) {
216
217
  Image(systemName: activity.icon)
217
- .font(.body)
218
+ .font(RunicFont.body)
218
219
  .foregroundStyle(activity.color)
219
220
  .frame(width: 24)
220
221
 
221
222
  VStack(alignment: .leading, spacing: RunicSpacing.xxxs) {
222
223
  Text(activity.title)
223
- .font(.footnote)
224
+ .font(RunicFont.footnote)
224
225
  Text(activity.timestamp)
225
- .font(.caption2)
226
+ .font(RunicFont.caption2)
226
227
  .foregroundStyle(.tertiary)
227
228
  }
228
229
 
@@ -248,21 +249,21 @@ struct TeamDashboardView: View {
248
249
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
249
250
  HStack {
250
251
  Image(systemName: icon)
251
- .font(.caption)
252
+ .font(RunicFont.caption)
252
253
  .foregroundStyle(color)
253
254
  Spacer()
254
255
  }
255
256
 
256
257
  Text(value)
257
- .font(.title2.weight(.bold))
258
+ .font(RunicFont.title2.weight(.bold))
258
259
  .foregroundStyle(color)
259
260
 
260
261
  Text(title)
261
- .font(.caption2.weight(.medium))
262
+ .font(RunicFont.caption2.weight(.medium))
262
263
  .foregroundStyle(.secondary)
263
264
 
264
265
  Text(subtitle)
265
- .font(.caption2)
266
+ .font(RunicFont.caption2)
266
267
  .foregroundStyle(.tertiary)
267
268
  }
268
269
  .frame(maxWidth: .infinity, alignment: .leading)
@@ -341,14 +342,16 @@ enum TimePeriod: String, CaseIterable, Identifiable {
341
342
  case month
342
343
  case year
343
344
 
344
- var id: String { self.rawValue }
345
+ var id: String {
346
+ self.rawValue
347
+ }
345
348
 
346
349
  var displayName: String {
347
350
  switch self {
348
- case .day: return "Today"
349
- case .week: return "Week"
350
- case .month: return "Month"
351
- case .year: return "Year"
351
+ case .day: "Today"
352
+ case .week: "Week"
353
+ case .month: "Month"
354
+ case .year: "Year"
352
355
  }
353
356
  }
354
357
  }
@@ -359,7 +362,9 @@ struct MemberUsageItem: Identifiable {
359
362
  let usage: Int
360
363
  let color: Color
361
364
 
362
- var id: String { self.memberID }
365
+ var id: String {
366
+ self.memberID
367
+ }
363
368
  }
364
369
 
365
370
  struct ActivityItem: Identifiable {
@@ -10,7 +10,7 @@ struct TeamInviteSheet: View {
10
10
  @State private var email = ""
11
11
  @State private var selectedRole: TeamRole = .member
12
12
  @State private var hasQuotaLimit = false
13
- @State private var quotaLimit = 10_000
13
+ @State private var quotaLimit = 10000
14
14
  @State private var emailError: String?
15
15
  @FocusState private var isEmailFieldFocused: Bool
16
16
 
@@ -18,9 +18,9 @@ struct TeamInviteSheet: View {
18
18
  VStack(alignment: .leading, spacing: RunicSpacing.lg) {
19
19
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
20
20
  Text("Invite to \(self.team.name)")
21
- .font(.title2.weight(.semibold))
21
+ .font(RunicFont.title2.weight(.semibold))
22
22
  Text("Send an invitation to join your team")
23
- .font(.footnote)
23
+ .font(RunicFont.footnote)
24
24
  .foregroundStyle(.tertiary)
25
25
  }
26
26
 
@@ -29,7 +29,7 @@ struct TeamInviteSheet: View {
29
29
  VStack(alignment: .leading, spacing: RunicSpacing.md) {
30
30
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
31
31
  Text("Email Address")
32
- .font(.subheadline.weight(.medium))
32
+ .font(RunicFont.subheadline.weight(.medium))
33
33
 
34
34
  TextField("colleague@example.com", text: self.$email)
35
35
  .textFieldStyle(.roundedBorder)
@@ -40,18 +40,18 @@ struct TeamInviteSheet: View {
40
40
 
41
41
  if let error = self.emailError {
42
42
  Text(error)
43
- .font(.caption)
43
+ .font(RunicFont.caption)
44
44
  .foregroundStyle(.red)
45
45
  } else {
46
46
  Text("They will receive an email invitation")
47
- .font(.caption)
47
+ .font(RunicFont.caption)
48
48
  .foregroundStyle(.tertiary)
49
49
  }
50
50
  }
51
51
 
52
52
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
53
53
  Text("Role")
54
- .font(.subheadline.weight(.medium))
54
+ .font(RunicFont.subheadline.weight(.medium))
55
55
 
56
56
  Picker("Role", selection: self.$selectedRole) {
57
57
  ForEach(TeamRole.allCases.filter { $0 != .owner }, id: \.self) { role in
@@ -69,18 +69,18 @@ struct TeamInviteSheet: View {
69
69
 
70
70
  VStack(alignment: .leading, spacing: RunicSpacing.xs) {
71
71
  Toggle("Set quota limit", isOn: self.$hasQuotaLimit)
72
- .font(.subheadline.weight(.medium))
72
+ .font(RunicFont.subheadline.weight(.medium))
73
73
 
74
74
  if self.hasQuotaLimit {
75
75
  HStack(spacing: RunicSpacing.sm) {
76
76
  Text("Credits")
77
- .font(.footnote)
77
+ .font(RunicFont.footnote)
78
78
  .foregroundStyle(.secondary)
79
79
 
80
80
  Stepper(
81
81
  value: self.$quotaLimit,
82
- in: 1_000...1_000_000,
83
- step: 1_000)
82
+ in: 1000...1_000_000,
83
+ step: 1000)
84
84
  {
85
85
  TextField(
86
86
  "",
@@ -92,11 +92,11 @@ struct TeamInviteSheet: View {
92
92
  }
93
93
 
94
94
  Text("Monthly credit allocation for this member")
95
- .font(.caption)
95
+ .font(RunicFont.caption)
96
96
  .foregroundStyle(.tertiary)
97
97
  } else {
98
98
  Text("No quota limit - uses shared team quota")
99
- .font(.caption)
99
+ .font(RunicFont.caption)
100
100
  .foregroundStyle(.tertiary)
101
101
  }
102
102
  }
@@ -140,15 +140,15 @@ struct TeamInviteSheet: View {
140
140
  Text("")
141
141
  }
142
142
  }
143
- .font(.caption)
143
+ .font(RunicFont.caption)
144
144
  .foregroundStyle(.tertiary)
145
145
  .fixedSize(horizontal: false, vertical: true)
146
146
  }
147
147
 
148
148
  private var isValid: Bool {
149
149
  !self.email.trimmingCharacters(in: .whitespaces).isEmpty &&
150
- self.email.contains("@") &&
151
- self.email.contains(".")
150
+ self.email.contains("@") &&
151
+ self.email.contains(".")
152
152
  }
153
153
 
154
154
  private func sendInvitation() {