@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
@@ -8,7 +8,7 @@ struct CerebrasModelsResponse: Decodable {
8
8
  }
9
9
  }
10
10
 
11
- struct CerebrasUsageFetcher {
11
+ enum CerebrasUsageFetcher {
12
12
  static let apiURL = URL(string: "https://api.cerebras.ai/v1/models")!
13
13
 
14
14
  static func fetchModels(apiKey: String) async throws -> CerebrasModelsResponse {
@@ -57,7 +57,7 @@ extension CerebrasModelsResponse {
57
57
  }
58
58
  }
59
59
 
60
- enum CerebrasAPIError: LocalizedError, Sendable {
60
+ enum CerebrasAPIError: LocalizedError {
61
61
  case invalidResponse
62
62
  case httpError(statusCode: Int, body: String?)
63
63
 
@@ -82,7 +82,7 @@ enum ClaudeOAuthUsageFetcher {
82
82
  }
83
83
  }
84
84
 
85
- struct OAuthUsageResponse: Decodable, Sendable {
85
+ struct OAuthUsageResponse: Decodable {
86
86
  let fiveHour: OAuthUsageWindow?
87
87
  let sevenDay: OAuthUsageWindow?
88
88
  let sevenDayOAuthApps: OAuthUsageWindow?
@@ -102,7 +102,7 @@ struct OAuthUsageResponse: Decodable, Sendable {
102
102
  }
103
103
  }
104
104
 
105
- struct OAuthUsageWindow: Decodable, Sendable {
105
+ struct OAuthUsageWindow: Decodable {
106
106
  let utilization: Double?
107
107
  let resetsAt: String?
108
108
 
@@ -112,7 +112,7 @@ struct OAuthUsageWindow: Decodable, Sendable {
112
112
  }
113
113
  }
114
114
 
115
- struct OAuthExtraUsage: Decodable, Sendable {
115
+ struct OAuthExtraUsage: Decodable {
116
116
  let isEnabled: Bool?
117
117
  let monthlyLimit: Double?
118
118
  let usedCredits: Double?
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -191,7 +191,9 @@ struct ClaudeCLIFetchStrategy: ProviderFetchStrategy {
191
191
  let kind: ProviderFetchKind = .cli
192
192
  let useWebExtras: Bool
193
193
 
194
- func isAvailable(_: ProviderFetchContext) async -> Bool { true }
194
+ func isAvailable(_: ProviderFetchContext) async -> Bool {
195
+ true
196
+ }
195
197
 
196
198
  func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
197
199
  let fetcher = ClaudeUsageFetcher(dataSource: .cli, useWebExtras: self.useWebExtras)
@@ -326,7 +326,7 @@ public struct ClaudeStatusProbe: Sendable {
326
326
  return nil
327
327
  }
328
328
 
329
- // Collect remaining percentages in the order they appear; used as a backup when labels move/rename.
329
+ /// Collect remaining percentages in the order they appear; used as a backup when labels move/rename.
330
330
  private static func allPercents(_ text: String) -> [Int] {
331
331
  let pat = #"([0-9]{1,3})\p{Zs}*%\s*(left|used)"#
332
332
  guard let regex = try? NSRegularExpression(pattern: pat, options: [.caseInsensitive]) else { return [] }
@@ -379,7 +379,7 @@ public struct ClaudeStatusProbe: Sendable {
379
379
  .joined(separator: " ")
380
380
  }
381
381
 
382
- // Capture all "Resets ..." strings to surface in the menu.
382
+ /// Capture all "Resets ..." strings to surface in the menu.
383
383
  private static func allResets(_ text: String) -> [String] {
384
384
  let pat = #"Resets[^\r\n]*"#
385
385
  guard let regex = try? NSRegularExpression(pattern: pat, options: [.caseInsensitive]) else { return [] }
@@ -500,7 +500,7 @@ public struct ClaudeStatusProbe: Sendable {
500
500
  return nil
501
501
  }
502
502
 
503
- // Extract login/plan string from CLI output.
503
+ /// Extract login/plan string from CLI output.
504
504
  private static func extractLoginMethod(text: String) -> String? {
505
505
  guard !text.isEmpty else { return nil }
506
506
  if let explicit = self.extractFirst(pattern: #"(?i)login\s+method:\s*(.+)"#, text: text) {
@@ -627,7 +627,7 @@ public struct ClaudeStatusProbe: Sendable {
627
627
  }
628
628
  }
629
629
 
630
- // Run claude CLI inside a PTY so we can respond to interactive permission prompts.
630
+ /// Run claude CLI inside a PTY so we can respond to interactive permission prompts.
631
631
  private static func capture(subcommand: String, binary: String, timeout: TimeInterval) async throws -> String {
632
632
  let stopOnSubstrings = subcommand == "/usage" ? ["Current session"] : []
633
633
  do {
@@ -5,7 +5,9 @@ public enum ClaudeUsageDataSource: String, CaseIterable, Identifiable, Sendable
5
5
  case web
6
6
  case cli
7
7
 
8
- public var id: String { self.rawValue }
8
+ public var id: String {
9
+ self.rawValue
10
+ }
9
11
 
10
12
  public var displayName: String {
11
13
  switch self {
@@ -633,7 +633,7 @@ public enum ClaudeWebAPIFetcher {
633
633
  return nil
634
634
  }
635
635
 
636
- private struct ProbeParseResult: Sendable {
636
+ private struct ProbeParseResult {
637
637
  let keys: [String]
638
638
  let emails: [String]
639
639
  let planHints: [String]
@@ -208,7 +208,7 @@ public enum CodexOAuthUsageFetcher {
208
208
  private static func isAllowedHost(_ url: URL) -> Bool {
209
209
  guard url.scheme?.lowercased() == "https" else { return false }
210
210
  guard let host = url.host?.lowercased() else { return false }
211
- return allowedHostSuffixes.contains { host == $0 || host.hasSuffix("." + $0) }
211
+ return self.allowedHostSuffixes.contains { host == $0 || host.hasSuffix("." + $0) }
212
212
  }
213
213
 
214
214
  private static func resolveChatGPTBaseURL(env: [String: String], configContents: String?) -> String {
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -119,7 +119,9 @@ struct CodexCLIUsageStrategy: ProviderFetchStrategy {
119
119
  let id: String = "codex.cli"
120
120
  let kind: ProviderFetchKind = .cli
121
121
 
122
- func isAvailable(_: ProviderFetchContext) async -> Bool { true }
122
+ func isAvailable(_: ProviderFetchContext) async -> Bool {
123
+ true
124
+ }
123
125
 
124
126
  func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
125
127
  let usage = try await context.fetcher.loadLatestUsage()
@@ -4,7 +4,9 @@ public enum CodexUsageDataSource: String, CaseIterable, Identifiable, Sendable {
4
4
  case oauth
5
5
  case cli
6
6
 
7
- public var id: String { self.rawValue }
7
+ public var id: String {
8
+ self.rawValue
9
+ }
8
10
 
9
11
  public var displayName: String {
10
12
  switch self {
@@ -39,7 +39,7 @@ public struct CodexWebDashboardStrategy: ProviderFetchStrategy {
39
39
  }
40
40
  }
41
41
 
42
- private struct OpenAIWebCodexResult: Sendable {
42
+ private struct OpenAIWebCodexResult {
43
43
  let usage: UsageSnapshot
44
44
  let credits: CreditsSnapshot?
45
45
  let dashboard: OpenAIDashboardSnapshot
@@ -56,7 +56,7 @@ private enum OpenAIWebCodexError: LocalizedError {
56
56
  }
57
57
  }
58
58
 
59
- private struct OpenAIWebOptions: Sendable {
59
+ private struct OpenAIWebOptions {
60
60
  let timeout: TimeInterval
61
61
  let debugDumpHTML: Bool
62
62
  let verbose: Bool
@@ -168,7 +168,9 @@ public struct CodexWebDashboardStrategy: ProviderFetchStrategy {
168
168
 
169
169
  public init() {}
170
170
 
171
- public func isAvailable(_: ProviderFetchContext) async -> Bool { false }
171
+ public func isAvailable(_: ProviderFetchContext) async -> Bool {
172
+ false
173
+ }
172
174
 
173
175
  public func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
174
176
  throw ProviderFetchError.noAvailableStrategy(.codex)
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -71,7 +71,7 @@ struct CohereAPIFetchStrategy: ProviderFetchStrategy {
71
71
  }
72
72
  }
73
73
 
74
- enum CohereSettingsError: LocalizedError, Sendable {
74
+ enum CohereSettingsError: LocalizedError {
75
75
  case missingToken
76
76
 
77
77
  var errorDescription: String? {
@@ -9,7 +9,7 @@ struct CohereModelsResponse: Decodable {
9
9
  let name: String?
10
10
 
11
11
  var modelID: String? {
12
- let candidate = id ?? name
12
+ let candidate = self.id ?? self.name
13
13
  guard let candidate else { return nil }
14
14
  let trimmed = candidate.trimmingCharacters(in: .whitespacesAndNewlines)
15
15
  return trimmed.isEmpty ? nil : trimmed
@@ -17,7 +17,7 @@ struct CohereModelsResponse: Decodable {
17
17
  }
18
18
  }
19
19
 
20
- struct CohereUsageFetcher {
20
+ enum CohereUsageFetcher {
21
21
  static let apiURL = URL(string: "https://api.cohere.ai/v1/models")!
22
22
 
23
23
  static func fetchModels(apiKey: String) async throws -> CohereModelsResponse {
@@ -67,7 +67,7 @@ extension CohereModelsResponse {
67
67
  }
68
68
  }
69
69
 
70
- enum CohereAPIError: LocalizedError, Sendable {
70
+ enum CohereAPIError: LocalizedError {
71
71
  case invalidResponse
72
72
  case httpError(statusCode: Int, body: String?)
73
73
 
@@ -67,7 +67,7 @@ public enum CopilotGitHubCLITokenReader {
67
67
 
68
68
  private static func isLikelyGitHubToken(_ token: String) -> Bool {
69
69
  guard !token.isEmpty else { return false }
70
- return tokenPrefixes.contains { token.hasPrefix($0) }
70
+ return self.tokenPrefixes.contains { token.hasPrefix($0) }
71
71
  }
72
72
 
73
73
  private static func candidateHostConfigPaths(environment: [String: String]) -> [URL] {
@@ -97,9 +97,12 @@ public enum CopilotGitHubCLITokenReader {
97
97
 
98
98
  for home in homes {
99
99
  let homeURL = URL(fileURLWithPath: home)
100
- addCandidate(homeURL.appendingPathComponent(".config").appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
101
- addCandidate(homeURL.appendingPathComponent("Library").appendingPathComponent("Application Support").appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
102
- addCandidate(homeURL.appendingPathComponent(".local").appendingPathComponent("share").appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
100
+ addCandidate(homeURL.appendingPathComponent(".config").appendingPathComponent("gh")
101
+ .appendingPathComponent("hosts.yml"))
102
+ addCandidate(homeURL.appendingPathComponent("Library").appendingPathComponent("Application Support")
103
+ .appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
104
+ addCandidate(homeURL.appendingPathComponent(".local").appendingPathComponent("share")
105
+ .appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
103
106
  }
104
107
 
105
108
  return candidates
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -85,11 +85,11 @@ struct CopilotAPIFetchStrategy: ProviderFetchStrategy {
85
85
  private static func sourceLabel(from source: ProviderTokenSource, sourceKey: String?) -> String {
86
86
  switch source {
87
87
  case .keychain:
88
- return sourceKey ?? "keychain"
88
+ sourceKey ?? "keychain"
89
89
  case .environment:
90
- return sourceKey ?? "env"
90
+ sourceKey ?? "env"
91
91
  case .vscode:
92
- return sourceKey ?? "vscode"
92
+ sourceKey ?? "vscode"
93
93
  }
94
94
  }
95
95
 
@@ -158,7 +158,8 @@ public struct CopilotUsageFetcher: Sendable {
158
158
  guard httpResponse.statusCode == 200 else {
159
159
  let body = self.errorSnippet(from: data)
160
160
  if httpResponse.statusCode == 401 || httpResponse.statusCode == 403 {
161
- throw CopilotUsageFetchError.unauthorized(details: "token exchange HTTP \(httpResponse.statusCode). \(body)")
161
+ throw CopilotUsageFetchError
162
+ .unauthorized(details: "token exchange HTTP \(httpResponse.statusCode). \(body)")
162
163
  }
163
164
  throw CopilotUsageFetchError.invalidResponse(
164
165
  details: "token exchange HTTP \(httpResponse.statusCode). \(body)")
@@ -253,7 +254,9 @@ public struct CopilotUsageFetcher: Sendable {
253
254
  .replacingOccurrences(of: "-", with: " ")
254
255
  }
255
256
 
256
- private func orderedQuotaSnapshots(_ snapshots: CopilotUsageResponse.QuotaSnapshots?) -> [CopilotUsageResponse.QuotaSnapshot] {
257
+ private func orderedQuotaSnapshots(_ snapshots: CopilotUsageResponse
258
+ .QuotaSnapshots?) -> [CopilotUsageResponse.QuotaSnapshot]
259
+ {
257
260
  guard let snapshots else { return [] }
258
261
  let candidates = [snapshots.premiumInteractions, snapshots.completions, snapshots.chat]
259
262
  var ordered: [CopilotUsageResponse.QuotaSnapshot] = []
@@ -287,5 +290,4 @@ public struct CopilotUsageFetcher: Sendable {
287
290
  let end = text.index(text.startIndex, offsetBy: 220)
288
291
  return "\(text[..<end])…"
289
292
  }
290
-
291
293
  }
@@ -10,7 +10,7 @@ import CryptoKit
10
10
  #endif
11
11
 
12
12
  public enum CopilotVSCodeTokenReader {
13
- private struct VSCodeStoreCandidate: Sendable {
13
+ private struct VSCodeStoreCandidate {
14
14
  let databaseURL: URL
15
15
  let safeStorageService: String
16
16
  }
@@ -36,9 +36,9 @@ public enum CopilotVSCodeTokenReader {
36
36
  guard let password = self.readSafeStoragePassword(
37
37
  service: candidate.safeStorageService,
38
38
  allowUserInteraction: allowUserInteraction),
39
- let legacyKey = self.deriveLegacyKey(from: password),
40
- let decryptedJSON = self.decryptSecretPayload(encryptedPayload, legacyKey: legacyKey),
41
- let token = self.extractToken(fromDecryptedJSON: decryptedJSON)
39
+ let legacyKey = self.deriveLegacyKey(from: password),
40
+ let decryptedJSON = self.decryptSecretPayload(encryptedPayload, legacyKey: legacyKey),
41
+ let token = self.extractToken(fromDecryptedJSON: decryptedJSON)
42
42
  else {
43
43
  continue
44
44
  }
@@ -217,14 +217,13 @@ public enum CopilotVSCodeTokenReader {
217
217
  }
218
218
 
219
219
  private static func decryptSecretPayload(_ payload: Data, legacyKey: Data) -> String? {
220
- let encryptedPayload: Data
221
- if payload.count >= 3,
222
- let prefix = String(data: payload.prefix(3), encoding: .utf8),
223
- prefix == "v10" || prefix == "v11"
220
+ let encryptedPayload: Data = if payload.count >= 3,
221
+ let prefix = String(data: payload.prefix(3), encoding: .utf8),
222
+ prefix == "v10" || prefix == "v11"
224
223
  {
225
- encryptedPayload = Data(payload.dropFirst(3))
224
+ Data(payload.dropFirst(3))
226
225
  } else {
227
- encryptedPayload = payload
226
+ payload
228
227
  }
229
228
 
230
229
  let iv = Data(repeating: 0x20, count: kCCBlockSizeAES128)
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -49,7 +49,9 @@ struct CursorStatusFetchStrategy: ProviderFetchStrategy {
49
49
  let id: String = "cursor.web"
50
50
  let kind: ProviderFetchKind = .web
51
51
 
52
- func isAvailable(_: ProviderFetchContext) async -> Bool { true }
52
+ func isAvailable(_: ProviderFetchContext) async -> Bool {
53
+ true
54
+ }
53
55
 
54
56
  func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
55
57
  let probe = CursorStatusProbe()
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -72,7 +72,7 @@ struct DeepSeekAPIFetchStrategy: ProviderFetchStrategy {
72
72
  }
73
73
  }
74
74
 
75
- enum DeepSeekSettingsError: LocalizedError, Sendable {
75
+ enum DeepSeekSettingsError: LocalizedError {
76
76
  case missingToken
77
77
 
78
78
  var errorDescription: String? {
@@ -25,7 +25,7 @@ struct DeepSeekBalanceResponse: Decodable {
25
25
  }
26
26
  }
27
27
 
28
- struct DeepSeekUsageFetcher {
28
+ enum DeepSeekUsageFetcher {
29
29
  static let apiURL = URL(string: "https://api.deepseek.com/user/balance")!
30
30
 
31
31
  static func fetchBalance(apiKey: String) async throws -> DeepSeekBalanceResponse {
@@ -90,7 +90,7 @@ extension DeepSeekBalanceResponse {
90
90
  }
91
91
  }
92
92
 
93
- enum DeepSeekAPIError: LocalizedError, Sendable {
93
+ enum DeepSeekAPIError: LocalizedError {
94
94
  case invalidResponse
95
95
  case httpError(statusCode: Int, body: String?)
96
96
 
@@ -5,7 +5,7 @@ import SQLite3
5
5
 
6
6
  #if os(macOS)
7
7
  enum FactoryLocalStorageImporter {
8
- struct TokenInfo: Sendable {
8
+ struct TokenInfo {
9
9
  let refreshToken: String
10
10
  let accessToken: String?
11
11
  let organizationID: String?
@@ -61,12 +61,12 @@ enum FactoryLocalStorageImporter {
61
61
 
62
62
  // MARK: - Chrome local storage discovery
63
63
 
64
- private enum LocalStorageSourceKind: Sendable {
64
+ private enum LocalStorageSourceKind {
65
65
  case chromeLevelDB(URL)
66
66
  case safariSQLite(URL)
67
67
  }
68
68
 
69
- private struct LocalStorageCandidate: Sendable {
69
+ private struct LocalStorageCandidate {
70
70
  let label: String
71
71
  let kind: LocalStorageSourceKind
72
72
  }
@@ -207,7 +207,7 @@ enum FactoryLocalStorageImporter {
207
207
 
208
208
  // MARK: - Token extraction
209
209
 
210
- private struct WorkOSTokenMatch: Sendable {
210
+ private struct WorkOSTokenMatch {
211
211
  let refreshToken: String
212
212
  let accessToken: String?
213
213
  let organizationID: String?
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -49,7 +49,9 @@ struct FactoryStatusFetchStrategy: ProviderFetchStrategy {
49
49
  let id: String = "factory.web"
50
50
  let kind: ProviderFetchKind = .web
51
51
 
52
- func isAvailable(_: ProviderFetchContext) async -> Bool { true }
52
+ func isAvailable(_: ProviderFetchContext) async -> Bool {
53
+ true
54
+ }
53
55
 
54
56
  func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
55
57
  let probe = FactoryStatusProbe()
@@ -536,7 +536,7 @@ public struct FactoryStatusProbe: Sendable {
536
536
  "client_01HNM792M5G5G1A2THWPXKFMXB",
537
537
  ]
538
538
 
539
- private struct WorkOSAuthResponse: Decodable, Sendable {
539
+ private struct WorkOSAuthResponse: Decodable {
540
540
  let access_token: String
541
541
  let refresh_token: String?
542
542
  let organization_id: String?
@@ -578,7 +578,7 @@ public struct FactoryStatusProbe: Sendable {
578
578
  throw FactoryStatusProbeError.noSessionCookie
579
579
  }
580
580
 
581
- private enum FetchAttemptResult: Sendable {
581
+ private enum FetchAttemptResult {
582
582
  case success(FactoryStatusSnapshot)
583
583
  case failure(Error)
584
584
  case skipped
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -71,7 +71,7 @@ struct FireworksAPIFetchStrategy: ProviderFetchStrategy {
71
71
  }
72
72
  }
73
73
 
74
- enum FireworksSettingsError: LocalizedError, Sendable {
74
+ enum FireworksSettingsError: LocalizedError {
75
75
  case missingToken
76
76
 
77
77
  var errorDescription: String? {
@@ -8,7 +8,7 @@ struct FireworksModelsResponse: Decodable {
8
8
  }
9
9
  }
10
10
 
11
- struct FireworksUsageFetcher {
11
+ enum FireworksUsageFetcher {
12
12
  static let apiURL = URL(string: "https://api.fireworks.ai/inference/v1/models")!
13
13
 
14
14
  static func fetchModels(apiKey: String) async throws -> FireworksModelsResponse {
@@ -57,7 +57,7 @@ extension FireworksModelsResponse {
57
57
  }
58
58
  }
59
59
 
60
- enum FireworksAPIError: LocalizedError, Sendable {
60
+ enum FireworksAPIError: LocalizedError {
61
61
  case invalidResponse
62
62
  case httpError(statusCode: Int, body: String?)
63
63
 
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -49,7 +49,9 @@ struct GeminiStatusFetchStrategy: ProviderFetchStrategy {
49
49
  let id: String = "gemini.api"
50
50
  let kind: ProviderFetchKind = .apiToken
51
51
 
52
- func isAvailable(_: ProviderFetchContext) async -> Bool { true }
52
+ func isAvailable(_: ProviderFetchContext) async -> Bool {
53
+ true
54
+ }
53
55
 
54
56
  func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
55
57
  let probe = GeminiStatusProbe()
@@ -21,8 +21,11 @@ public struct GeminiStatusSnapshot: Sendable {
21
21
  self.modelQuotas.min(by: { $0.percentLeft < $1.percentLeft })?.percentLeft
22
22
  }
23
23
 
24
- // Legacy compatibility
25
- public var dailyPercentLeft: Double? { self.lowestPercentLeft }
24
+ /// Legacy compatibility
25
+ public var dailyPercentLeft: Double? {
26
+ self.lowestPercentLeft
27
+ }
28
+
26
29
  public var resetDescription: String? {
27
30
  self.modelQuotas.min(by: { $0.percentLeft < $1.percentLeft })?.resetDescription
28
31
  }
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -71,7 +71,7 @@ struct GroqAPIFetchStrategy: ProviderFetchStrategy {
71
71
  }
72
72
  }
73
73
 
74
- enum GroqSettingsError: LocalizedError, Sendable {
74
+ enum GroqSettingsError: LocalizedError {
75
75
  case missingToken
76
76
 
77
77
  var errorDescription: String? {
@@ -8,7 +8,7 @@ struct GroqModelsResponse: Decodable {
8
8
  }
9
9
  }
10
10
 
11
- struct GroqUsageFetcher {
11
+ enum GroqUsageFetcher {
12
12
  static let apiURL = URL(string: "https://api.groq.com/openai/v1/models")!
13
13
 
14
14
  static func fetchModels(apiKey: String) async throws -> GroqModelsResponse {
@@ -53,7 +53,7 @@ extension GroqModelsResponse {
53
53
  }
54
54
  }
55
55
 
56
- enum GroqAPIError: LocalizedError, Sendable {
56
+ enum GroqAPIError: LocalizedError {
57
57
  case invalidResponse
58
58
  case httpError(statusCode: Int)
59
59
  case decodingError
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -71,7 +71,7 @@ struct KimiAPIFetchStrategy: ProviderFetchStrategy {
71
71
  }
72
72
  }
73
73
 
74
- enum KimiSettingsError: LocalizedError, Sendable {
74
+ enum KimiSettingsError: LocalizedError {
75
75
  case missingToken
76
76
 
77
77
  var errorDescription: String? {
@@ -8,7 +8,7 @@ struct KimiModelsResponse: Decodable {
8
8
  }
9
9
  }
10
10
 
11
- struct KimiUsageFetcher {
11
+ enum KimiUsageFetcher {
12
12
  static let apiURL = URL(string: "https://api.moonshot.ai/v1/models")!
13
13
  private static let requestTimeout: TimeInterval = 20
14
14
 
@@ -59,7 +59,7 @@ extension KimiModelsResponse {
59
59
  }
60
60
  }
61
61
 
62
- enum KimiAPIError: LocalizedError, Sendable {
62
+ enum KimiAPIError: LocalizedError {
63
63
  case invalidResponse
64
64
  case httpError(statusCode: Int, body: String?)
65
65
 
@@ -1,5 +1,5 @@
1
- import RunicMacroSupport
2
1
  import Foundation
2
+ import RunicMacroSupport
3
3
 
4
4
  @ProviderDescriptorRegistration
5
5
  @ProviderDescriptorDefinition
@@ -37,7 +37,10 @@ public enum MiniMaxProviderDescriptor {
37
37
  noDataMessage: { "MiniMax cost summary is not supported." }),
38
38
  fetchPlan: ProviderFetchPlan(
39
39
  sourceModes: [.auto, .api, .web],
40
- pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [MiniMaxAPIFetchStrategy(), MiniMaxWebFetchStrategy()] })),
40
+ pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [
41
+ MiniMaxAPIFetchStrategy(),
42
+ MiniMaxWebFetchStrategy(),
43
+ ] })),
41
44
  cli: ProviderCLIConfig(
42
45
  name: "minimax",
43
46
  aliases: ["minimax-api"],
@@ -49,7 +52,9 @@ struct MiniMaxWebFetchStrategy: ProviderFetchStrategy {
49
52
  let id: String = "minimax.web"
50
53
  let kind: ProviderFetchKind = .web
51
54
 
52
- func isAvailable(_: ProviderFetchContext) async -> Bool { true }
55
+ func isAvailable(_: ProviderFetchContext) async -> Bool {
56
+ true
57
+ }
53
58
 
54
59
  func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
55
60
  let fetcher = MiniMaxWebUsageFetcher()
@@ -78,9 +83,9 @@ struct MiniMaxAPIFetchStrategy: ProviderFetchStrategy {
78
83
  guard let tokenRes = ProviderTokenResolver.minimaxApiKeyResolution(environment: context.env) else {
79
84
  throw ProviderFetchError.missingCredentials
80
85
  }
81
-
86
+
82
87
  let snapshot = try await MiniMaxUsageFetcher.fetchUsage(apiKey: tokenRes.token)
83
-
88
+
84
89
  return self.makeResult(
85
90
  usage: snapshot.toUsageSnapshot(),
86
91
  sourceLabel: "API")