@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.
- package/CHANGELOG.md +11 -0
- package/README.md +8 -1
- package/RuniciOS/Core/RunicTypographyiOS.swift +24 -0
- package/RuniciOS/Views/ProviderDetailView.swift +9 -9
- package/RuniciOS/Views/ProviderListView.swift +10 -10
- package/RuniciOS/Widgets/LargeWidget.swift +14 -14
- package/RuniciOS/Widgets/LiveActivity.swift +19 -19
- package/RuniciOS/Widgets/LockScreenWidget.swift +15 -15
- package/RuniciOS/Widgets/MediumWidget.swift +10 -10
- package/RuniciOS/Widgets/RunicWidget.swift +5 -5
- package/RuniciOS/Widgets/SmallWidget.swift +9 -9
- package/Sources/Runic/About.swift +3 -3
- package/Sources/Runic/AppNotifications.swift +5 -3
- package/Sources/Runic/Controllers/StatusItemController+Actions.swift +7 -3
- package/Sources/Runic/Controllers/StatusItemController+Animation.swift +5 -4
- package/Sources/Runic/Controllers/StatusItemController+ChartSubmenus.swift +30 -16
- package/Sources/Runic/Controllers/StatusItemController+CustomProviders.swift +6 -3
- package/Sources/Runic/Controllers/StatusItemController+Menu.swift +18 -13
- package/Sources/Runic/Controllers/StatusItemController+MenuCards.swift +6 -4
- package/Sources/Runic/Controllers/StatusItemController+MenuHelpers.swift +40 -12
- package/Sources/Runic/Controllers/StatusItemController.swift +43 -43
- package/Sources/Runic/Core/BudgetNotificationManager.swift +2 -1
- package/Sources/Runic/Core/Login/ClaudeLoginRunner.swift +2 -2
- package/Sources/Runic/Core/Login/CodexLoginRunner.swift +1 -1
- package/Sources/Runic/Core/Login/CursorLoginRunner.swift +4 -4
- package/Sources/Runic/Core/Login/GeminiLoginRunner.swift +1 -1
- package/Sources/Runic/Core/Rendering/IconRenderer.swift +91 -85
- package/Sources/Runic/Core/Rendering/IconView.swift +3 -1
- package/Sources/Runic/Core/RunicColors.swift +6 -6
- package/Sources/Runic/Core/RunicSpacing.swift +7 -7
- package/Sources/Runic/Core/RunicTypography.swift +206 -0
- package/Sources/Runic/Core/Stores/AuggieTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/AzureOpenAITokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CerebrasTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CohereTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CopilotTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CustomProviderStore.swift +10 -10
- package/Sources/Runic/Core/Stores/DeepSeekTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/FireworksTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/GroqTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/KimiTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MiniMaxCookieHeaderStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MiniMaxGroupIDStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MiniMaxTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MistralTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/OpenRouterTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/PerplexityTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/ProviderToggleStore.swift +1 -1
- package/Sources/Runic/Core/Stores/QwenTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/SambaNovaTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/SettingsStore.swift +89 -51
- package/Sources/Runic/Core/Stores/TogetherTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/UsageStore+Accessors.swift +19 -6
- package/Sources/Runic/Core/Stores/UsageStore+TokenCost.swift +1 -1
- package/Sources/Runic/Core/Stores/UsageStore+WidgetSnapshot.swift +1 -1
- package/Sources/Runic/Core/Stores/UsageStore.swift +187 -161
- package/Sources/Runic/Core/Stores/XAITokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/ZaiTokenStore.swift +1 -2
- package/Sources/Runic/Core/UsageExporter.swift +8 -4
- package/Sources/Runic/ProviderRegistry.swift +1 -1
- package/Sources/Runic/Providers/Antigravity/AntigravityProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Auggie/AuggieProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Azure/AzureProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Bedrock/BedrockProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Cerebras/CerebrasProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Codex/CodexProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Cohere/CohereProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Cursor/CursorProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/DeepSeek/DeepSeekProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Factory/FactoryProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Fireworks/FireworksProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Gemini/GeminiProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Groq/GroqProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Kimi/KimiProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/MiniMax/MiniMaxProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Mistral/MistralProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/OpenRouter/OpenRouterProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Perplexity/PerplexityProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/SambaNova/SambaNovaProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Shared/ProviderImplementation.swift +5 -2
- package/Sources/Runic/Providers/Shared/ProviderImplementationRegistry.swift +1 -1
- package/Sources/Runic/Providers/Shared/ProviderSettingsDescriptors.swift +1 -1
- package/Sources/Runic/Providers/Together/TogetherProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/XAI/XAIProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Zai/ZaiProviderImplementation.swift +1 -1
- package/Sources/Runic/Resources/Fonts/Caveat-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Caveat-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Light.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/SpaceMono-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/SpaceMono-Regular.ttf +0 -0
- package/Sources/Runic/RunicApp.swift +46 -36
- package/Sources/Runic/SessionQuotaNotifications.swift +2 -2
- package/Sources/Runic/UsagePaceText.swift +1 -1
- package/Sources/Runic/UsageProgressBar.swift +13 -9
- package/Sources/Runic/Utilities/LoadingPattern.swift +4 -2
- package/Sources/Runic/Utilities/PerformanceConstants.swift +28 -28
- package/Sources/Runic/Views/Menu/AlertsMenuView.swift +19 -21
- package/Sources/Runic/Views/Menu/CostComparativeChartMenuView.swift +19 -19
- package/Sources/Runic/Views/Menu/CostHistoryChartMenuView.swift +7 -7
- package/Sources/Runic/Views/Menu/CreditsHistoryChartMenuView.swift +5 -5
- package/Sources/Runic/Views/Menu/EfficiencyMetricsMenuView.swift +29 -30
- package/Sources/Runic/Views/Menu/HeroStatCardsMenuView.swift +20 -17
- package/Sources/Runic/Views/Menu/HourlyActivityChartMenuView.swift +14 -14
- package/Sources/Runic/Views/Menu/InlineUsageChartView.swift +12 -10
- package/Sources/Runic/Views/Menu/MenuCardEntranceModifier.swift +3 -4
- package/Sources/Runic/Views/Menu/MenuCardSidebarView.swift +5 -25
- package/Sources/Runic/Views/Menu/MenuCardSkeletonView.swift +1 -1
- package/Sources/Runic/Views/Menu/MenuCardView.swift +120 -131
- package/Sources/Runic/Views/Menu/MenuContent.swift +11 -8
- package/Sources/Runic/Views/Menu/MenuDescriptor.swift +4 -2
- package/Sources/Runic/Views/Menu/MenuHighlightStyle.swift +1 -8
- package/Sources/Runic/Views/Menu/ModelBreakdownMenuView.swift +20 -14
- package/Sources/Runic/Views/Menu/OverviewMenuView.swift +18 -15
- package/Sources/Runic/Views/Menu/ProjectBreakdownMenuView.swift +16 -11
- package/Sources/Runic/Views/Menu/ProjectBudgetMenuView.swift +27 -27
- package/Sources/Runic/Views/Menu/ProviderTabBarView.swift +4 -6
- package/Sources/Runic/Views/Menu/SubscriptionUtilizationChartMenuView.swift +24 -11
- package/Sources/Runic/Views/Menu/UsageBreakdownChartMenuView.swift +5 -5
- package/Sources/Runic/Views/Menu/UsageHeatmapMenuView.swift +7 -8
- package/Sources/Runic/Views/Menu/UsageTimelineChartMenuView.swift +22 -17
- package/Sources/Runic/Views/Menu/UsageWindowComparisonChartMenuView.swift +8 -7
- package/Sources/Runic/Views/Menu/WeeklyActivityChartMenuView.swift +7 -7
- package/Sources/Runic/Views/Performance/PerformanceDashboardView.swift +50 -47
- package/Sources/Runic/Views/Preferences/LiquidComponents.swift +15 -14
- package/Sources/Runic/Views/Preferences/PreferencesAboutPane.swift +7 -7
- package/Sources/Runic/Views/Preferences/PreferencesAdvancedPane.swift +27 -27
- package/Sources/Runic/Views/Preferences/PreferencesAlertsPane.swift +38 -42
- package/Sources/Runic/Views/Preferences/PreferencesAnalyticsPane.swift +39 -43
- package/Sources/Runic/Views/Preferences/PreferencesBudgetsPane.swift +21 -21
- package/Sources/Runic/Views/Preferences/PreferencesComponents.swift +7 -7
- package/Sources/Runic/Views/Preferences/PreferencesCustomProvidersPane.swift +49 -50
- package/Sources/Runic/Views/Preferences/PreferencesDebugPane.swift +10 -10
- package/Sources/Runic/Views/Preferences/PreferencesGeneralPane.swift +40 -21
- package/Sources/Runic/Views/Preferences/PreferencesHelpPane.swift +7 -7
- package/Sources/Runic/Views/Preferences/PreferencesIntegrationsPane.swift +44 -39
- package/Sources/Runic/Views/Preferences/PreferencesPerformancePane.swift +26 -23
- package/Sources/Runic/Views/Preferences/PreferencesProvidersPane.swift +271 -226
- package/Sources/Runic/Views/Preferences/PreferencesSelection.swift +6 -2
- package/Sources/Runic/Views/Preferences/PreferencesSyncPane.swift +7 -5
- package/Sources/Runic/Views/Preferences/PreferencesView.swift +38 -31
- package/Sources/Runic/Views/Rating/QualityRatingView.swift +11 -11
- package/Sources/Runic/Views/Team/TeamDashboardView.swift +29 -24
- package/Sources/Runic/Views/Team/TeamInviteSheet.swift +16 -16
- package/Sources/Runic/Views/Team/TeamManagementView.swift +50 -49
- package/Sources/Runic/Views/Team/TeamMemberRow.swift +8 -8
- package/Sources/RunicCLI/CLIEntry.swift +83 -42
- package/Sources/RunicCLI/CLIRenderer.swift +1 -1
- package/Sources/RunicCLI/Commands/EnhancedUsageCommand.swift +60 -60
- package/Sources/RunicCLI/Commands/ModelsCommand.swift +45 -44
- package/Sources/RunicCLI/Commands/ProjectsCommand.swift +83 -69
- package/Sources/RunicCLI/Commands/ResetCommand.swift +50 -49
- package/Sources/RunicCLI/Commands/UsageLedgerSourceFactory.swift +31 -32
- package/Sources/RunicClaudeWebProbe/main.swift +1 -1
- package/Sources/RunicCore/AlertRuleStore.swift +20 -20
- package/Sources/RunicCore/BrowserCookieImportOrder.swift +3 -3
- package/Sources/RunicCore/CostUsageModels.swift +1 -1
- package/Sources/RunicCore/CustomProviders/CustomProviderModels.swift +29 -30
- package/Sources/RunicCore/CustomProviders/GenericProviderFetcher.swift +73 -75
- package/Sources/RunicCore/CustomProviders/ProviderTemplates.swift +53 -109
- package/Sources/RunicCore/Host/PTY/TTYCommandRunner.swift +3 -3
- package/Sources/RunicCore/Integrations/GitHubIntegration.swift +3 -3
- package/Sources/RunicCore/Models/EnhancedUsageModels.swift +47 -48
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardBrowserCookieImporter.swift +1 -1
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardFetcher.swift +1 -1
- package/Sources/RunicCore/Performance/PerformanceModels.swift +4 -4
- package/Sources/RunicCore/Performance/PerformanceStorageImpl.swift +81 -64
- package/Sources/RunicCore/Policy/UsagePolicyEngine.swift +2 -2
- package/Sources/RunicCore/ProjectBudgetStore.swift +15 -12
- package/Sources/RunicCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Antigravity/AntigravityStatusProbe.swift +2 -2
- package/Sources/RunicCore/Providers/Auggie/AuggieProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Auggie/AuggieUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Azure/AzureProviderDescriptor.swift +8 -8
- package/Sources/RunicCore/Providers/Azure/AzureUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Bedrock/BedrockProviderDescriptor.swift +6 -6
- package/Sources/RunicCore/Providers/Bedrock/BedrockUsageFetcher.swift +3 -7
- package/Sources/RunicCore/Providers/Cerebras/CerebrasProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Cerebras/CerebrasUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Claude/ClaudeProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Claude/ClaudeStatusProbe.swift +4 -4
- package/Sources/RunicCore/Providers/Claude/ClaudeUsageDataSource.swift +3 -1
- package/Sources/RunicCore/Providers/Claude/ClaudeWeb/ClaudeWebAPIFetcher.swift +1 -1
- package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift +1 -1
- package/Sources/RunicCore/Providers/Codex/CodexProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Codex/CodexUsageDataSource.swift +3 -1
- package/Sources/RunicCore/Providers/Codex/CodexWebDashboardStrategy.swift +5 -3
- package/Sources/RunicCore/Providers/Cohere/CohereProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Cohere/CohereUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Copilot/CopilotGitHubCLITokenReader.swift +7 -4
- package/Sources/RunicCore/Providers/Copilot/CopilotProviderDescriptor.swift +4 -4
- package/Sources/RunicCore/Providers/Copilot/CopilotUsageFetcher.swift +5 -3
- package/Sources/RunicCore/Providers/Copilot/CopilotVSCodeTokenReader.swift +9 -10
- package/Sources/RunicCore/Providers/Cursor/CursorProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Factory/FactoryLocalStorageImporter.swift +4 -4
- package/Sources/RunicCore/Providers/Factory/FactoryProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Factory/FactoryStatusProbe.swift +2 -2
- package/Sources/RunicCore/Providers/Fireworks/FireworksProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Fireworks/FireworksUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Gemini/GeminiProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Gemini/GeminiStatusProbe.swift +5 -2
- package/Sources/RunicCore/Providers/Groq/GroqProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Groq/GroqUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Kimi/KimiProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Kimi/KimiUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxProviderDescriptor.swift +10 -5
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxUsageFetcher.swift +7 -7
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxWebUsageFetcher.swift +10 -10
- package/Sources/RunicCore/Providers/Mistral/MistralProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Mistral/MistralUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/OpenRouter/OpenRouterUsageFetcher.swift +23 -10
- package/Sources/RunicCore/Providers/Perplexity/PerplexityProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Perplexity/PerplexityUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/ProviderFetchPlan.swift +2 -2
- package/Sources/RunicCore/Providers/ProviderTokenResolver.swift +2 -2
- package/Sources/RunicCore/Providers/Qwen/QwenProviderDescriptor.swift +5 -3
- package/Sources/RunicCore/Providers/Qwen/QwenUsageStats.swift +26 -13
- package/Sources/RunicCore/Providers/SambaNova/SambaNovaProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/SambaNova/SambaNovaUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Together/TogetherProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Together/TogetherUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/VertexAI/VertexAIProviderDescriptor.swift +5 -5
- package/Sources/RunicCore/Providers/VertexAI/VertexAISettingsReader.swift +1 -1
- package/Sources/RunicCore/Providers/VertexAI/VertexAIUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/XAI/XAIProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/XAI/XAIUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Zai/ZaiProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Zai/ZaiUsageStats.swift +48 -21
- package/Sources/RunicCore/Sync/BackgroundSyncManager.swift +76 -77
- package/Sources/RunicCore/Sync/SyncConflictResolver.swift +55 -58
- package/Sources/RunicCore/Sync/SyncProtocol.swift +21 -22
- package/Sources/RunicCore/Sync/SyncRecord.swift +46 -49
- package/Sources/RunicCore/Sync/SyncUsageExample.swift +44 -50
- package/Sources/RunicCore/Sync/TeamSyncRecords.swift +94 -101
- package/Sources/RunicCore/Sync/iCloudSyncEngine.swift +51 -46
- package/Sources/RunicCore/Team/TeamModels.swift +111 -110
- package/Sources/RunicCore/Team/TeamStore.swift +126 -109
- package/Sources/RunicCore/UsageFetcher.swift +2 -2
- package/Sources/RunicCore/UsageFormatter.swift +25 -25
- package/Sources/RunicCore/UsageLedger/ClaudeUsageLogSource.swift +27 -13
- package/Sources/RunicCore/UsageLedger/CodexUsageLogSource.swift +11 -3
- package/Sources/RunicCore/UsageLedger/LedgerCache.swift +5 -2
- package/Sources/RunicCore/UsageLedger/OTelGenAILedgerAdapter.swift +1 -1
- package/Sources/RunicCore/UsageLedger/UsageLedgerAggregator.swift +40 -25
- package/Sources/RunicCore/UsageLedger/UsageLedgerInsightsAdvisor.swift +1 -1
- package/Sources/RunicCore/UsageLedger/UsageLedgerProjectIdentity.swift +55 -16
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageCache.swift +6 -6
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageJsonl.swift +1 -1
- package/Sources/RunicCore/Vendored/CostUsage/CostUsagePricing.swift +2 -2
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner.swift +5 -5
- package/Tests/RunicTests/AppDelegateTests.swift +8 -3
- package/Tests/RunicTests/BrowserCookieOrderLabelTests.swift +2 -3
- package/Tests/RunicTests/CLIArgumentParsingTests.swift +3 -4
- package/Tests/RunicTests/CLICostTests.swift +6 -7
- package/Tests/RunicTests/CLIProviderSelectionTests.swift +2 -3
- package/Tests/RunicTests/CLISnapshotTests.swift +3 -4
- package/Tests/RunicTests/CLIWebFallbackTests.swift +3 -4
- package/Tests/RunicTests/ClaudeOAuthTests.swift +11 -12
- package/Tests/RunicTests/ClaudeResilienceTests.swift +3 -4
- package/Tests/RunicTests/ClaudeUsageTests.swift +20 -21
- package/Tests/RunicTests/CodexOAuthTests.swift +7 -8
- package/Tests/RunicTests/CodexUsageLogSourceTests.swift +1 -3
- package/Tests/RunicTests/CopilotTokenResolverTests.swift +5 -6
- package/Tests/RunicTests/CopilotVSCodeTokenReaderTests.swift +4 -5
- package/Tests/RunicTests/CostUsageDecodingTests.swift +15 -17
- package/Tests/RunicTests/CostUsagePricingTests.swift +5 -7
- package/Tests/RunicTests/CostUsageScannerTests.swift +10 -12
- package/Tests/RunicTests/CursorStatusProbeTests.swift +15 -16
- package/Tests/RunicTests/FactoryStatusProbeTests.swift +3 -5
- package/Tests/RunicTests/GeminiLoginAlertTests.swift +3 -4
- package/Tests/RunicTests/GeminiStatusProbeAPITests.swift +11 -11
- package/Tests/RunicTests/GeminiStatusProbePlanTests.swift +8 -8
- package/Tests/RunicTests/GeminiStatusProbeTests.swift +20 -21
- package/Tests/RunicTests/GoogleWorkspaceStatusTests.swift +2 -3
- package/Tests/RunicTests/InstallOriginTests.swift +1 -2
- package/Tests/RunicTests/KeyboardShortcutsBundleTests.swift +2 -2
- package/Tests/RunicTests/LiveAccountTests.swift +3 -3
- package/Tests/RunicTests/LoadingPatternTests.swift +3 -4
- package/Tests/RunicTests/MenuCardModelTests.swift +33 -34
- package/Tests/RunicTests/MiniMaxCookieHeaderStoreTestSupport.swift +4 -1
- package/Tests/RunicTests/MiniMaxGroupIDStoreTestSupport.swift +4 -1
- package/Tests/RunicTests/MiniMaxParsingTests.swift +4 -5
- package/Tests/RunicTests/MiniMaxTokenStoreTestSupport.swift +4 -1
- package/Tests/RunicTests/OTelGenAILedgerAdapterTests.swift +4 -6
- package/Tests/RunicTests/OpenAIDashboardBrowserCookieImporterTests.swift +1 -2
- package/Tests/RunicTests/OpenAIDashboardFetcherCreditsWaitTests.swift +5 -6
- package/Tests/RunicTests/OpenAIDashboardOffscreenHostTests.swift +2 -3
- package/Tests/RunicTests/OpenAIDashboardParserTests.swift +12 -13
- package/Tests/RunicTests/OpenAIWebAccountSwitchTests.swift +17 -6
- package/Tests/RunicTests/OpenRouterTokenStoreTestSupport.swift +52 -13
- package/Tests/RunicTests/PathBuilderTests.swift +14 -15
- package/Tests/RunicTests/ProviderFetchPipelineTests.swift +3 -4
- package/Tests/RunicTests/ProviderIconResourcesTests.swift +1 -2
- package/Tests/RunicTests/ProviderMetadataStatusLinkTests.swift +1 -2
- package/Tests/RunicTests/ProviderSettingsDescriptorTests.swift +53 -19
- package/Tests/RunicTests/ProviderToggleStoreTests.swift +10 -11
- package/Tests/RunicTests/RunicTests.swift +6 -7
- package/Tests/RunicTests/SessionQuotaNotificationLogicTests.swift +5 -6
- package/Tests/RunicTests/SettingsStoreTests.swift +149 -45
- package/Tests/RunicTests/StatusItemAnimationTests.swift +8 -3
- package/Tests/RunicTests/StatusMenuTests.swift +63 -22
- package/Tests/RunicTests/StatusProbeTests.swift +28 -29
- package/Tests/RunicTests/SubprocessRunnerTests.swift +1 -3
- package/Tests/RunicTests/SubscriptionDetectionTests.swift +8 -9
- package/Tests/RunicTests/TTYCommandRunnerTests.swift +8 -9
- package/Tests/RunicTests/TeamShowbackExporterTests.swift +2 -4
- package/Tests/RunicTests/TextParsingTests.swift +1 -2
- package/Tests/RunicTests/UsageFormatterTests.swift +15 -16
- package/Tests/RunicTests/UsageLedgerAnomalyDetectionTests.swift +12 -14
- package/Tests/RunicTests/UsageLedgerForecastTests.swift +4 -6
- package/Tests/RunicTests/UsageLedgerInsightsAdvisorTests.swift +7 -9
- package/Tests/RunicTests/UsageLedgerProjectNameTests.swift +6 -8
- package/Tests/RunicTests/UsagePaceTests.swift +5 -6
- package/Tests/RunicTests/UsagePaceTextTests.swift +8 -9
- package/Tests/RunicTests/UsagePolicyEngineTests.swift +3 -5
- package/Tests/RunicTests/WidgetSnapshotTests.swift +1 -3
- package/Tests/RunicTests/ZaiProviderTests.swift +3 -5
- package/Tests/RunicTests/ZaiTokenStoreTestSupport.swift +4 -1
- package/appcast.xml +36 -76
- package/package.json +1 -1
- package/runic.png +0 -0
- package/runic.svg +15 -0
- package/version.env +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AppKit
|
|
2
|
-
import RunicCore
|
|
3
2
|
import Observation
|
|
3
|
+
import RunicCore
|
|
4
4
|
import ServiceManagement
|
|
5
5
|
|
|
6
6
|
enum RefreshFrequency: String, CaseIterable, Identifiable {
|
|
@@ -10,7 +10,9 @@ enum RefreshFrequency: String, CaseIterable, Identifiable {
|
|
|
10
10
|
case fiveMinutes
|
|
11
11
|
case fifteenMinutes
|
|
12
12
|
|
|
13
|
-
var id: String {
|
|
13
|
+
var id: String {
|
|
14
|
+
self.rawValue
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
var seconds: TimeInterval? {
|
|
16
18
|
switch self {
|
|
@@ -38,7 +40,9 @@ enum UsageMetricDisplayMode: String, CaseIterable, Identifiable {
|
|
|
38
40
|
case barsOnly
|
|
39
41
|
case percentOnly
|
|
40
42
|
|
|
41
|
-
var id: String {
|
|
43
|
+
var id: String {
|
|
44
|
+
self.rawValue
|
|
45
|
+
}
|
|
42
46
|
|
|
43
47
|
var label: String {
|
|
44
48
|
switch self {
|
|
@@ -72,7 +76,9 @@ enum MenuMode: String, CaseIterable, Identifiable {
|
|
|
72
76
|
case analyst
|
|
73
77
|
case `operator`
|
|
74
78
|
|
|
75
|
-
var id: String {
|
|
79
|
+
var id: String {
|
|
80
|
+
self.rawValue
|
|
81
|
+
}
|
|
76
82
|
|
|
77
83
|
var label: String {
|
|
78
84
|
switch self {
|
|
@@ -80,7 +86,7 @@ enum MenuMode: String, CaseIterable, Identifiable {
|
|
|
80
86
|
"Glance"
|
|
81
87
|
case .analyst:
|
|
82
88
|
"Analyst"
|
|
83
|
-
case
|
|
89
|
+
case .operator:
|
|
84
90
|
"Operator"
|
|
85
91
|
}
|
|
86
92
|
}
|
|
@@ -91,13 +97,15 @@ enum ChartStyle: String, CaseIterable, Identifiable {
|
|
|
91
97
|
case area
|
|
92
98
|
case bar
|
|
93
99
|
|
|
94
|
-
var id: String {
|
|
100
|
+
var id: String {
|
|
101
|
+
self.rawValue
|
|
102
|
+
}
|
|
95
103
|
|
|
96
104
|
var label: String {
|
|
97
105
|
switch self {
|
|
98
|
-
case .line:
|
|
99
|
-
case .area:
|
|
100
|
-
case .bar:
|
|
106
|
+
case .line: "Line"
|
|
107
|
+
case .area: "Area"
|
|
108
|
+
case .bar: "Bar"
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
}
|
|
@@ -106,12 +114,14 @@ enum NumberFormat: String, CaseIterable, Identifiable {
|
|
|
106
114
|
case abbreviated
|
|
107
115
|
case full
|
|
108
116
|
|
|
109
|
-
var id: String {
|
|
117
|
+
var id: String {
|
|
118
|
+
self.rawValue
|
|
119
|
+
}
|
|
110
120
|
|
|
111
121
|
var label: String {
|
|
112
122
|
switch self {
|
|
113
|
-
case .abbreviated:
|
|
114
|
-
case .full:
|
|
123
|
+
case .abbreviated: "Abbreviated"
|
|
124
|
+
case .full: "Full"
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
127
|
}
|
|
@@ -120,12 +130,14 @@ enum DateFormat: String, CaseIterable, Identifiable {
|
|
|
120
130
|
case relative
|
|
121
131
|
case absolute
|
|
122
132
|
|
|
123
|
-
var id: String {
|
|
133
|
+
var id: String {
|
|
134
|
+
self.rawValue
|
|
135
|
+
}
|
|
124
136
|
|
|
125
137
|
var label: String {
|
|
126
138
|
switch self {
|
|
127
|
-
case .relative:
|
|
128
|
-
case .absolute:
|
|
139
|
+
case .relative: "Relative"
|
|
140
|
+
case .absolute: "Absolute"
|
|
129
141
|
}
|
|
130
142
|
}
|
|
131
143
|
}
|
|
@@ -135,13 +147,15 @@ enum Theme: String, CaseIterable, Identifiable {
|
|
|
135
147
|
case light
|
|
136
148
|
case dark
|
|
137
149
|
|
|
138
|
-
var id: String {
|
|
150
|
+
var id: String {
|
|
151
|
+
self.rawValue
|
|
152
|
+
}
|
|
139
153
|
|
|
140
154
|
var label: String {
|
|
141
155
|
switch self {
|
|
142
|
-
case .system:
|
|
143
|
-
case .light:
|
|
144
|
-
case .dark:
|
|
156
|
+
case .system: "System"
|
|
157
|
+
case .light: "Light"
|
|
158
|
+
case .dark: "Dark"
|
|
145
159
|
}
|
|
146
160
|
}
|
|
147
161
|
}
|
|
@@ -150,12 +164,14 @@ enum ProviderSwitcherLayout: String, CaseIterable, Identifiable {
|
|
|
150
164
|
case top
|
|
151
165
|
case sidebar
|
|
152
166
|
|
|
153
|
-
var id: String {
|
|
167
|
+
var id: String {
|
|
168
|
+
self.rawValue
|
|
169
|
+
}
|
|
154
170
|
|
|
155
171
|
var label: String {
|
|
156
172
|
switch self {
|
|
157
|
-
case .top:
|
|
158
|
-
case .sidebar:
|
|
173
|
+
case .top: "Top"
|
|
174
|
+
case .sidebar: "Sidebar"
|
|
159
175
|
}
|
|
160
176
|
}
|
|
161
177
|
}
|
|
@@ -164,12 +180,14 @@ enum ProviderSwitcherIconSize: String, CaseIterable, Identifiable {
|
|
|
164
180
|
case small
|
|
165
181
|
case medium
|
|
166
182
|
|
|
167
|
-
var id: String {
|
|
183
|
+
var id: String {
|
|
184
|
+
self.rawValue
|
|
185
|
+
}
|
|
168
186
|
|
|
169
187
|
var label: String {
|
|
170
188
|
switch self {
|
|
171
|
-
case .small:
|
|
172
|
-
case .medium:
|
|
189
|
+
case .small: "Small"
|
|
190
|
+
case .medium: "Medium"
|
|
173
191
|
}
|
|
174
192
|
}
|
|
175
193
|
}
|
|
@@ -189,15 +207,21 @@ final class SettingsStore {
|
|
|
189
207
|
}
|
|
190
208
|
|
|
191
209
|
var autoDisableRefreshWhenIdleEnabled: Bool {
|
|
192
|
-
didSet { self.userDefaults.set(
|
|
210
|
+
didSet { self.userDefaults.set(
|
|
211
|
+
self.autoDisableRefreshWhenIdleEnabled,
|
|
212
|
+
forKey: "autoDisableRefreshWhenIdleEnabled") }
|
|
193
213
|
}
|
|
194
214
|
|
|
195
215
|
var autoDisableRefreshWhenIdleMinutes: Int {
|
|
196
|
-
didSet { self.userDefaults.set(
|
|
216
|
+
didSet { self.userDefaults.set(
|
|
217
|
+
self.autoDisableRefreshWhenIdleMinutes,
|
|
218
|
+
forKey: "autoDisableRefreshWhenIdleMinutes") }
|
|
197
219
|
}
|
|
198
220
|
|
|
199
221
|
var autoDisableRefreshOnSleepEnabled: Bool {
|
|
200
|
-
didSet {
|
|
222
|
+
didSet {
|
|
223
|
+
self.userDefaults.set(self.autoDisableRefreshOnSleepEnabled, forKey: "autoDisableRefreshOnSleepEnabled")
|
|
224
|
+
}
|
|
201
225
|
}
|
|
202
226
|
|
|
203
227
|
var autoRefreshWarningEnabled: Bool {
|
|
@@ -210,13 +234,17 @@ final class SettingsStore {
|
|
|
210
234
|
|
|
211
235
|
var autoSuspendInactiveProvidersEnabled: Bool {
|
|
212
236
|
didSet {
|
|
213
|
-
self.userDefaults.set(
|
|
237
|
+
self.userDefaults.set(
|
|
238
|
+
self.autoSuspendInactiveProvidersEnabled,
|
|
239
|
+
forKey: "autoSuspendInactiveProvidersEnabled")
|
|
214
240
|
}
|
|
215
241
|
}
|
|
216
242
|
|
|
217
243
|
var autoSuspendInactiveProvidersMinutes: Int {
|
|
218
244
|
didSet {
|
|
219
|
-
self.userDefaults.set(
|
|
245
|
+
self.userDefaults.set(
|
|
246
|
+
self.autoSuspendInactiveProvidersMinutes,
|
|
247
|
+
forKey: "autoSuspendInactiveProvidersMinutes")
|
|
220
248
|
}
|
|
221
249
|
}
|
|
222
250
|
|
|
@@ -227,7 +255,8 @@ final class SettingsStore {
|
|
|
227
255
|
}
|
|
228
256
|
}
|
|
229
257
|
|
|
230
|
-
/// Hidden toggle to reveal debug-only menu items (enable via defaults write com.sriinnu.athena.Runic
|
|
258
|
+
/// Hidden toggle to reveal debug-only menu items (enable via defaults write com.sriinnu.athena.Runic
|
|
259
|
+
/// debugMenuEnabled
|
|
231
260
|
/// -bool YES).
|
|
232
261
|
var debugMenuEnabled: Bool {
|
|
233
262
|
didSet { self.userDefaults.set(self.debugMenuEnabled, forKey: "debugMenuEnabled") }
|
|
@@ -296,6 +325,13 @@ final class SettingsStore {
|
|
|
296
325
|
}
|
|
297
326
|
}
|
|
298
327
|
|
|
328
|
+
var selectedFontFamily: String {
|
|
329
|
+
didSet {
|
|
330
|
+
self.userDefaults.set(self.selectedFontFamily, forKey: "selectedFontFamily")
|
|
331
|
+
RunicFont.family = self.selectedFontFamily
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
299
335
|
/// Optional: use provider branding icons with a percentage in the menu bar.
|
|
300
336
|
var menuBarShowsBrandIconWithPercent: Bool {
|
|
301
337
|
didSet {
|
|
@@ -406,7 +442,7 @@ final class SettingsStore {
|
|
|
406
442
|
var zaiAPIToken: String {
|
|
407
443
|
didSet {
|
|
408
444
|
self.schedulePersistZaiAPIToken()
|
|
409
|
-
if !zaiAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
445
|
+
if !self.zaiAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
410
446
|
self.autoEnableProviderIfNeeded(cliName: "zai")
|
|
411
447
|
}
|
|
412
448
|
}
|
|
@@ -416,7 +452,7 @@ final class SettingsStore {
|
|
|
416
452
|
var minimaxAPIToken: String {
|
|
417
453
|
didSet {
|
|
418
454
|
self.schedulePersistMiniMaxAPIToken()
|
|
419
|
-
if !minimaxAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
455
|
+
if !self.minimaxAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
420
456
|
self.autoEnableProviderIfNeeded(cliName: "minimax")
|
|
421
457
|
}
|
|
422
458
|
}
|
|
@@ -426,7 +462,7 @@ final class SettingsStore {
|
|
|
426
462
|
var minimaxCookieHeader: String {
|
|
427
463
|
didSet {
|
|
428
464
|
self.schedulePersistMiniMaxCookieHeader()
|
|
429
|
-
if !minimaxCookieHeader.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
465
|
+
if !self.minimaxCookieHeader.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
430
466
|
self.autoEnableProviderIfNeeded(cliName: "minimax")
|
|
431
467
|
}
|
|
432
468
|
}
|
|
@@ -441,7 +477,7 @@ final class SettingsStore {
|
|
|
441
477
|
var copilotAPIToken: String {
|
|
442
478
|
didSet {
|
|
443
479
|
self.schedulePersistCopilotAPIToken()
|
|
444
|
-
if !copilotAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
480
|
+
if !self.copilotAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
445
481
|
self.autoEnableProviderIfNeeded(cliName: "copilot")
|
|
446
482
|
}
|
|
447
483
|
}
|
|
@@ -451,7 +487,7 @@ final class SettingsStore {
|
|
|
451
487
|
var openRouterAPIToken: String {
|
|
452
488
|
didSet {
|
|
453
489
|
self.schedulePersistOpenRouterAPIToken()
|
|
454
|
-
if !openRouterAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
490
|
+
if !self.openRouterAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
455
491
|
self.autoEnableProviderIfNeeded(cliName: "openrouter")
|
|
456
492
|
}
|
|
457
493
|
}
|
|
@@ -461,7 +497,7 @@ final class SettingsStore {
|
|
|
461
497
|
var groqAPIToken: String {
|
|
462
498
|
didSet {
|
|
463
499
|
self.schedulePersistGroqAPIToken()
|
|
464
|
-
if !groqAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
500
|
+
if !self.groqAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
465
501
|
self.autoEnableProviderIfNeeded(cliName: "groq")
|
|
466
502
|
}
|
|
467
503
|
}
|
|
@@ -471,7 +507,7 @@ final class SettingsStore {
|
|
|
471
507
|
var deepSeekAPIToken: String {
|
|
472
508
|
didSet {
|
|
473
509
|
self.schedulePersistDeepSeekAPIToken()
|
|
474
|
-
if !deepSeekAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
510
|
+
if !self.deepSeekAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
475
511
|
self.autoEnableProviderIfNeeded(cliName: "deepseek")
|
|
476
512
|
}
|
|
477
513
|
}
|
|
@@ -481,7 +517,7 @@ final class SettingsStore {
|
|
|
481
517
|
var fireworksAPIToken: String {
|
|
482
518
|
didSet {
|
|
483
519
|
self.schedulePersistFireworksAPIToken()
|
|
484
|
-
if !fireworksAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
520
|
+
if !self.fireworksAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
485
521
|
self.autoEnableProviderIfNeeded(cliName: "fireworks")
|
|
486
522
|
}
|
|
487
523
|
}
|
|
@@ -491,7 +527,7 @@ final class SettingsStore {
|
|
|
491
527
|
var mistralAPIToken: String {
|
|
492
528
|
didSet {
|
|
493
529
|
self.schedulePersistMistralAPIToken()
|
|
494
|
-
if !mistralAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
530
|
+
if !self.mistralAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
495
531
|
self.autoEnableProviderIfNeeded(cliName: "mistral")
|
|
496
532
|
}
|
|
497
533
|
}
|
|
@@ -501,7 +537,7 @@ final class SettingsStore {
|
|
|
501
537
|
var perplexityAPIToken: String {
|
|
502
538
|
didSet {
|
|
503
539
|
self.schedulePersistPerplexityAPIToken()
|
|
504
|
-
if !perplexityAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
540
|
+
if !self.perplexityAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
505
541
|
self.autoEnableProviderIfNeeded(cliName: "perplexity")
|
|
506
542
|
}
|
|
507
543
|
}
|
|
@@ -511,7 +547,7 @@ final class SettingsStore {
|
|
|
511
547
|
var kimiAPIToken: String {
|
|
512
548
|
didSet {
|
|
513
549
|
self.schedulePersistKimiAPIToken()
|
|
514
|
-
if !kimiAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
550
|
+
if !self.kimiAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
515
551
|
self.autoEnableProviderIfNeeded(cliName: "kimi")
|
|
516
552
|
}
|
|
517
553
|
}
|
|
@@ -521,7 +557,7 @@ final class SettingsStore {
|
|
|
521
557
|
var auggieAPIToken: String {
|
|
522
558
|
didSet {
|
|
523
559
|
self.schedulePersistAuggieAPIToken()
|
|
524
|
-
if !auggieAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
560
|
+
if !self.auggieAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
525
561
|
self.autoEnableProviderIfNeeded(cliName: "auggie")
|
|
526
562
|
}
|
|
527
563
|
}
|
|
@@ -531,7 +567,7 @@ final class SettingsStore {
|
|
|
531
567
|
var togetherAPIToken: String {
|
|
532
568
|
didSet {
|
|
533
569
|
self.schedulePersistTogetherAPIToken()
|
|
534
|
-
if !togetherAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
570
|
+
if !self.togetherAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
535
571
|
self.autoEnableProviderIfNeeded(cliName: "together")
|
|
536
572
|
}
|
|
537
573
|
}
|
|
@@ -541,7 +577,7 @@ final class SettingsStore {
|
|
|
541
577
|
var cohereAPIToken: String {
|
|
542
578
|
didSet {
|
|
543
579
|
self.schedulePersistCohereAPIToken()
|
|
544
|
-
if !cohereAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
580
|
+
if !self.cohereAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
545
581
|
self.autoEnableProviderIfNeeded(cliName: "cohere")
|
|
546
582
|
}
|
|
547
583
|
}
|
|
@@ -551,7 +587,7 @@ final class SettingsStore {
|
|
|
551
587
|
var xaiAPIToken: String {
|
|
552
588
|
didSet {
|
|
553
589
|
self.schedulePersistXAiAPIToken()
|
|
554
|
-
if !xaiAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
590
|
+
if !self.xaiAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
555
591
|
self.autoEnableProviderIfNeeded(cliName: "xai")
|
|
556
592
|
}
|
|
557
593
|
}
|
|
@@ -561,7 +597,7 @@ final class SettingsStore {
|
|
|
561
597
|
var cerebrasAPIToken: String {
|
|
562
598
|
didSet {
|
|
563
599
|
self.schedulePersistCerebrasAPIToken()
|
|
564
|
-
if !cerebrasAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
600
|
+
if !self.cerebrasAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
565
601
|
self.autoEnableProviderIfNeeded(cliName: "cerebras")
|
|
566
602
|
}
|
|
567
603
|
}
|
|
@@ -571,7 +607,7 @@ final class SettingsStore {
|
|
|
571
607
|
var qwenAPIToken: String {
|
|
572
608
|
didSet {
|
|
573
609
|
self.schedulePersistQwenAPIToken()
|
|
574
|
-
if !qwenAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
610
|
+
if !self.qwenAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
575
611
|
self.autoEnableProviderIfNeeded(cliName: "qwen")
|
|
576
612
|
}
|
|
577
613
|
}
|
|
@@ -581,7 +617,7 @@ final class SettingsStore {
|
|
|
581
617
|
var sambaNovaAPIToken: String {
|
|
582
618
|
didSet {
|
|
583
619
|
self.schedulePersistSambaNovaAPIToken()
|
|
584
|
-
if !sambaNovaAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
620
|
+
if !self.sambaNovaAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
585
621
|
self.autoEnableProviderIfNeeded(cliName: "sambanova")
|
|
586
622
|
}
|
|
587
623
|
}
|
|
@@ -606,7 +642,7 @@ final class SettingsStore {
|
|
|
606
642
|
var azureOpenAIAPIToken: String {
|
|
607
643
|
didSet {
|
|
608
644
|
self.schedulePersistAzureOpenAIAPIToken()
|
|
609
|
-
if !azureOpenAIAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
645
|
+
if !self.azureOpenAIAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
610
646
|
self.autoEnableProviderIfNeeded(cliName: "azure")
|
|
611
647
|
}
|
|
612
648
|
}
|
|
@@ -884,7 +920,7 @@ final class SettingsStore {
|
|
|
884
920
|
let metricDisplayRaw = userDefaults.string(forKey: "usageMetricDisplayMode")
|
|
885
921
|
self.usageMetricDisplayMode = UsageMetricDisplayMode(rawValue: metricDisplayRaw ?? "") ?? .barsAndPercent
|
|
886
922
|
let menuModeRaw = userDefaults.string(forKey: "menuMode")
|
|
887
|
-
self.menuMode = MenuMode(rawValue: menuModeRaw ?? "") ??
|
|
923
|
+
self.menuMode = MenuMode(rawValue: menuModeRaw ?? "") ?? .operator
|
|
888
924
|
let chartStyleRaw = userDefaults.string(forKey: "chartStyle")
|
|
889
925
|
self.chartStyle = ChartStyle(rawValue: chartStyleRaw ?? "") ?? .line
|
|
890
926
|
let numberFormatRaw = userDefaults.string(forKey: "numberFormat")
|
|
@@ -893,6 +929,7 @@ final class SettingsStore {
|
|
|
893
929
|
self.dateFormat = DateFormat(rawValue: dateFormatRaw ?? "") ?? .relative
|
|
894
930
|
let themeRaw = userDefaults.string(forKey: "theme")
|
|
895
931
|
self.theme = Theme(rawValue: themeRaw ?? "") ?? .system
|
|
932
|
+
self.selectedFontFamily = userDefaults.string(forKey: "selectedFontFamily") ?? "Fira Code"
|
|
896
933
|
self.menuBarShowsBrandIconWithPercent = userDefaults.object(
|
|
897
934
|
forKey: "menuBarShowsBrandIconWithPercent") as? Bool ?? false
|
|
898
935
|
self.menuBarVibrantIconEnabled = userDefaults.object(
|
|
@@ -965,6 +1002,7 @@ final class SettingsStore {
|
|
|
965
1002
|
if self.claudeUsageDataSource != .cli {
|
|
966
1003
|
self.claudeWebExtrasEnabled = false
|
|
967
1004
|
}
|
|
1005
|
+
RunicFont.family = self.selectedFontFamily
|
|
968
1006
|
}
|
|
969
1007
|
|
|
970
1008
|
func orderedProviders() -> [UsageProvider] {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicCore
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicCore
|
|
3
3
|
import Security
|
|
4
4
|
|
|
5
5
|
protocol TogetherTokenStoring: Sendable {
|
|
@@ -64,7 +64,6 @@ struct KeychainTogetherTokenStore: TogetherTokenStoring {
|
|
|
64
64
|
addQuery[kSecValueData as String] = data
|
|
65
65
|
addQuery[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
|
|
66
66
|
|
|
67
|
-
|
|
68
67
|
let addStatus = SecItemAdd(addQuery as CFDictionary, nil)
|
|
69
68
|
guard addStatus == errSecSuccess else {
|
|
70
69
|
Self.log.error("Keychain add failed: \(addStatus)")
|
|
@@ -115,5 +114,4 @@ struct KeychainTogetherTokenStore: TogetherTokenStoring {
|
|
|
115
114
|
}
|
|
116
115
|
return q
|
|
117
116
|
}
|
|
118
|
-
|
|
119
117
|
}
|
|
@@ -1,13 +1,26 @@
|
|
|
1
|
-
import RunicCore
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicCore
|
|
3
3
|
|
|
4
4
|
extension UsageStore {
|
|
5
|
-
var codexSnapshot: UsageSnapshot? {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
var codexSnapshot: UsageSnapshot? {
|
|
6
|
+
self.snapshots[.codex]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
var claudeSnapshot: UsageSnapshot? {
|
|
10
|
+
self.snapshots[.claude]
|
|
11
|
+
}
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
var lastCodexError: String? {
|
|
14
|
+
self.errors[.codex]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
var lastClaudeError: String? {
|
|
18
|
+
self.errors[.claude]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func error(for provider: UsageProvider) -> String? {
|
|
22
|
+
self.errors[provider]
|
|
23
|
+
}
|
|
11
24
|
|
|
12
25
|
func status(for provider: UsageProvider) -> ProviderStatus? {
|
|
13
26
|
guard self.statusChecksEnabled else { return nil }
|