@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
|
@@ -26,32 +26,32 @@ struct HeroTodayStatView: View {
|
|
|
26
26
|
VStack(alignment: .leading, spacing: 0) {
|
|
27
27
|
HStack(alignment: .firstTextBaseline, spacing: RunicSpacing.xxs) {
|
|
28
28
|
Text(UsageFormatter.tokenCountString(self.tokenCount))
|
|
29
|
-
.font(.system(size: 26, weight: .bold
|
|
29
|
+
.font(RunicFont.system(size: 26, weight: .bold))
|
|
30
30
|
.foregroundStyle(MenuHighlightStyle.primary(self.isHighlighted))
|
|
31
31
|
Text("today")
|
|
32
|
-
.font(.
|
|
32
|
+
.font(RunicFont.subheadline)
|
|
33
33
|
.foregroundStyle(MenuHighlightStyle.secondary(self.isHighlighted))
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
Spacer()
|
|
37
37
|
if let cost = self.costUSD, cost > 0 {
|
|
38
38
|
Text(UsageFormatter.usdString(cost))
|
|
39
|
-
.font(.
|
|
39
|
+
.font(RunicFont.subheadline)
|
|
40
40
|
.fontWeight(.medium)
|
|
41
41
|
.foregroundStyle(MenuHighlightStyle.secondary(self.isHighlighted))
|
|
42
42
|
.padding(.horizontal, RunicSpacing.xs)
|
|
43
43
|
.padding(.vertical, RunicSpacing.xxxs)
|
|
44
44
|
.background(
|
|
45
45
|
Capsule(style: .continuous)
|
|
46
|
-
.fill(Color(nsColor: .controlBackgroundColor).opacity(RunicColors.Opacity.light))
|
|
47
|
-
)
|
|
46
|
+
.fill(Color(nsColor: .controlBackgroundColor).opacity(RunicColors.Opacity.light)))
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
.padding(.horizontal, MenuCardMetrics.horizontalPadding)
|
|
51
50
|
.padding(.vertical, RunicSpacing.xxs)
|
|
52
51
|
.frame(minWidth: self.width, maxWidth: .infinity, alignment: .leading)
|
|
53
52
|
.accessibilityElement(children: .ignore)
|
|
54
|
-
.accessibilityLabel(
|
|
53
|
+
.accessibilityLabel(
|
|
54
|
+
"Today usage: \(UsageFormatter.tokenCountString(self.tokenCount)) tokens\(self.costUSD.map { ", \(UsageFormatter.usdString($0))" } ?? "")")
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -89,7 +89,8 @@ struct GlassmorphismStatCardsView: View {
|
|
|
89
89
|
.padding(.vertical, RunicSpacing.xxs)
|
|
90
90
|
.frame(minWidth: self.width, maxWidth: .infinity, alignment: .leading)
|
|
91
91
|
.accessibilityElement(children: .ignore)
|
|
92
|
-
.accessibilityLabel(
|
|
92
|
+
.accessibilityLabel(
|
|
93
|
+
"Peak hour \(self.peakHourLabel), \(self.peakHourTokens). This week \(self.weekTotalTokens)")
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -104,18 +105,18 @@ private struct GlassStatCard: View {
|
|
|
104
105
|
var body: some View {
|
|
105
106
|
VStack(alignment: .leading, spacing: RunicSpacing.xxs) {
|
|
106
107
|
Text(self.title)
|
|
107
|
-
.font(.
|
|
108
|
+
.font(RunicFont.caption2)
|
|
108
109
|
.fontWeight(.medium)
|
|
109
110
|
.foregroundStyle(MenuHighlightStyle.secondary(self.isHighlighted))
|
|
110
111
|
MiniSparklineView(data: self.sparkline, color: self.sparkColor)
|
|
111
112
|
.frame(height: 24)
|
|
112
113
|
Text(self.value)
|
|
113
|
-
.font(.
|
|
114
|
+
.font(RunicFont.title3)
|
|
114
115
|
.fontWeight(.bold)
|
|
115
116
|
.foregroundStyle(MenuHighlightStyle.primary(self.isHighlighted))
|
|
116
117
|
if let detail {
|
|
117
118
|
Text(detail)
|
|
118
|
-
.font(.
|
|
119
|
+
.font(RunicFont.caption2)
|
|
119
120
|
.foregroundStyle(MenuHighlightStyle.secondary(self.isHighlighted))
|
|
120
121
|
}
|
|
121
122
|
}
|
|
@@ -123,12 +124,10 @@ private struct GlassStatCard: View {
|
|
|
123
124
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
124
125
|
.background(
|
|
125
126
|
RoundedRectangle(cornerRadius: RunicCornerRadius.lg, style: .continuous)
|
|
126
|
-
.fill(.ultraThinMaterial)
|
|
127
|
-
)
|
|
127
|
+
.fill(.ultraThinMaterial))
|
|
128
128
|
.overlay(
|
|
129
129
|
RoundedRectangle(cornerRadius: RunicCornerRadius.lg, style: .continuous)
|
|
130
|
-
.stroke(Color(nsColor: .separatorColor).opacity(RunicColors.Opacity.medium), lineWidth: 0.5)
|
|
131
|
-
)
|
|
130
|
+
.stroke(Color(nsColor: .separatorColor).opacity(RunicColors.Opacity.medium), lineWidth: 0.5))
|
|
132
131
|
.shadow(color: .black.opacity(0.08), radius: 4, y: 2)
|
|
133
132
|
.glassShimmer()
|
|
134
133
|
}
|
|
@@ -147,7 +146,9 @@ private struct MiniSparklineView: View {
|
|
|
147
146
|
// Filled gradient area under the line
|
|
148
147
|
Path { path in
|
|
149
148
|
path.move(to: CGPoint(x: points[0].x, y: geo.size.height))
|
|
150
|
-
for point in points {
|
|
149
|
+
for point in points {
|
|
150
|
+
path.addLine(to: point)
|
|
151
|
+
}
|
|
151
152
|
path.addLine(to: CGPoint(x: points.last!.x, y: geo.size.height))
|
|
152
153
|
path.closeSubpath()
|
|
153
154
|
}
|
|
@@ -159,7 +160,9 @@ private struct MiniSparklineView: View {
|
|
|
159
160
|
// Line stroke
|
|
160
161
|
Path { path in
|
|
161
162
|
path.move(to: points[0])
|
|
162
|
-
for point in points.dropFirst() {
|
|
163
|
+
for point in points.dropFirst() {
|
|
164
|
+
path.addLine(to: point)
|
|
165
|
+
}
|
|
163
166
|
}
|
|
164
167
|
.stroke(self.color, style: StrokeStyle(lineWidth: 1.5, lineCap: .round, lineJoin: .round))
|
|
165
168
|
} else if self.data.count == 1, maxVal > 0 {
|
|
@@ -199,7 +202,7 @@ struct UpdatedTimestampView: View {
|
|
|
199
202
|
TimelineView(.periodic(from: .now, by: 5)) { context in
|
|
200
203
|
let text = Self.relativeString(from: self.updatedAt, to: context.date)
|
|
201
204
|
Text(text)
|
|
202
|
-
.font(.
|
|
205
|
+
.font(RunicFont.caption2)
|
|
203
206
|
.foregroundStyle(MenuHighlightStyle.secondary(self.isHighlighted).opacity(0.7))
|
|
204
207
|
}
|
|
205
208
|
.padding(.horizontal, MenuCardMetrics.horizontalPadding)
|
|
@@ -38,19 +38,19 @@ struct HourlyActivityChartMenuView: View {
|
|
|
38
38
|
// Header
|
|
39
39
|
HStack(alignment: .firstTextBaseline) {
|
|
40
40
|
Text("Today by Hour")
|
|
41
|
-
.font(.
|
|
41
|
+
.font(RunicFont.subheadline)
|
|
42
42
|
.fontWeight(.semibold)
|
|
43
43
|
Spacer()
|
|
44
44
|
if let peak = model.peakHour {
|
|
45
45
|
Text("Peak \(peak.label)")
|
|
46
|
-
.font(.
|
|
46
|
+
.font(RunicFont.caption)
|
|
47
47
|
.foregroundStyle(.secondary)
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if model.bars.allSatisfy({ $0.totalTokens == 0 }) {
|
|
52
52
|
Text("No usage recorded today.")
|
|
53
|
-
.font(.
|
|
53
|
+
.font(RunicFont.footnote)
|
|
54
54
|
.foregroundStyle(.secondary)
|
|
55
55
|
.frame(height: 80)
|
|
56
56
|
} else {
|
|
@@ -70,7 +70,7 @@ struct HourlyActivityChartMenuView: View {
|
|
|
70
70
|
.foregroundStyle(Color(nsColor: .labelColor).opacity(0.3))
|
|
71
71
|
.annotation(position: .top, spacing: 4) {
|
|
72
72
|
Text(UsageFormatter.tokenCountString(bar.totalTokens))
|
|
73
|
-
.font(.
|
|
73
|
+
.font(RunicFont.caption2)
|
|
74
74
|
.fontWeight(.medium)
|
|
75
75
|
.padding(.horizontal, 6)
|
|
76
76
|
.padding(.vertical, 2)
|
|
@@ -85,7 +85,7 @@ struct HourlyActivityChartMenuView: View {
|
|
|
85
85
|
AxisValueLabel {
|
|
86
86
|
if let hour = value.as(Int.self) {
|
|
87
87
|
Text(Self.hourAxisLabel(hour))
|
|
88
|
-
.font(.
|
|
88
|
+
.font(RunicFont.caption2)
|
|
89
89
|
.foregroundStyle(Color(nsColor: .tertiaryLabelColor))
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -98,7 +98,7 @@ struct HourlyActivityChartMenuView: View {
|
|
|
98
98
|
AxisValueLabel {
|
|
99
99
|
if let tokens = value.as(Int.self) {
|
|
100
100
|
Text(UsageFormatter.tokenCountString(tokens))
|
|
101
|
-
.font(.
|
|
101
|
+
.font(RunicFont.caption2)
|
|
102
102
|
.foregroundStyle(Color(nsColor: .tertiaryLabelColor))
|
|
103
103
|
}
|
|
104
104
|
}
|
|
@@ -120,27 +120,27 @@ struct HourlyActivityChartMenuView: View {
|
|
|
120
120
|
HStack(spacing: RunicSpacing.md) {
|
|
121
121
|
VStack(alignment: .leading, spacing: RunicSpacing.xxxs) {
|
|
122
122
|
Text("Today")
|
|
123
|
-
.font(.
|
|
123
|
+
.font(RunicFont.caption2)
|
|
124
124
|
.foregroundStyle(.tertiary)
|
|
125
125
|
Text(UsageFormatter.tokenCountString(model.totalTokens))
|
|
126
|
-
.font(.
|
|
126
|
+
.font(RunicFont.caption)
|
|
127
127
|
.fontWeight(.medium)
|
|
128
128
|
}
|
|
129
129
|
VStack(alignment: .leading, spacing: RunicSpacing.xxxs) {
|
|
130
130
|
Text("Active hours")
|
|
131
|
-
.font(.
|
|
131
|
+
.font(RunicFont.caption2)
|
|
132
132
|
.foregroundStyle(.tertiary)
|
|
133
133
|
Text("\(model.activeHours)")
|
|
134
|
-
.font(.
|
|
134
|
+
.font(RunicFont.caption)
|
|
135
135
|
.fontWeight(.medium)
|
|
136
136
|
}
|
|
137
137
|
if model.totalRequests > 0 {
|
|
138
138
|
VStack(alignment: .leading, spacing: RunicSpacing.xxxs) {
|
|
139
139
|
Text("Requests")
|
|
140
|
-
.font(.
|
|
140
|
+
.font(RunicFont.caption2)
|
|
141
141
|
.foregroundStyle(.tertiary)
|
|
142
142
|
Text("\(model.totalRequests)")
|
|
143
|
-
.font(.
|
|
143
|
+
.font(RunicFont.caption)
|
|
144
144
|
.fontWeight(.medium)
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -182,12 +182,12 @@ struct HourlyActivityChartMenuView: View {
|
|
|
182
182
|
let tokens = tokensByHour[hour] ?? 0
|
|
183
183
|
let isPeak = tokens > 0 && tokens == maxTokens
|
|
184
184
|
let bar = HourBar(id: hour, hour: hour, totalTokens: tokens, isPeak: isPeak)
|
|
185
|
-
if isPeak
|
|
185
|
+
if isPeak, tokens > 0 { peakHour = bar }
|
|
186
186
|
return bar
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
let totalTokens = tokensByHour.values.reduce(0, +)
|
|
190
|
-
let activeHours = tokensByHour.values.
|
|
190
|
+
let activeHours = tokensByHour.values.count(where: { $0 > 0 })
|
|
191
191
|
let totalRequests = requestsByHour.values.reduce(0, +)
|
|
192
192
|
|
|
193
193
|
return HourlyModel(
|
|
@@ -15,15 +15,17 @@ struct InlineUsageChartView: View {
|
|
|
15
15
|
|
|
16
16
|
var cutoffInterval: TimeInterval {
|
|
17
17
|
switch self {
|
|
18
|
-
case .threeDays:
|
|
19
|
-
case .sevenDays:
|
|
20
|
-
case .thirtyDays:
|
|
21
|
-
case .quarter:
|
|
22
|
-
case .year:
|
|
18
|
+
case .threeDays: -259_200
|
|
19
|
+
case .sevenDays: -604_800
|
|
20
|
+
case .thirtyDays: -2_592_000
|
|
21
|
+
case .quarter: -7_776_000
|
|
22
|
+
case .year: -31_536_000
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
var usesHourlyData: Bool {
|
|
26
|
+
var usesHourlyData: Bool {
|
|
27
|
+
false
|
|
28
|
+
}
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
private struct ChartPoint: Identifiable {
|
|
@@ -58,7 +60,7 @@ struct InlineUsageChartView: View {
|
|
|
58
60
|
HStack {
|
|
59
61
|
Spacer()
|
|
60
62
|
Text("No data")
|
|
61
|
-
.font(.
|
|
63
|
+
.font(RunicFont.caption2)
|
|
62
64
|
.foregroundStyle(.tertiary)
|
|
63
65
|
Spacer()
|
|
64
66
|
}
|
|
@@ -94,7 +96,7 @@ struct InlineUsageChartView: View {
|
|
|
94
96
|
AxisValueLabel {
|
|
95
97
|
if let tokens = value.as(Int.self) {
|
|
96
98
|
Text(UsageFormatter.tokenCountString(tokens))
|
|
97
|
-
.font(.system(size: 8
|
|
99
|
+
.font(RunicFont.system(size: 8))
|
|
98
100
|
.foregroundStyle(Color(nsColor: .tertiaryLabelColor))
|
|
99
101
|
}
|
|
100
102
|
}
|
|
@@ -103,7 +105,7 @@ struct InlineUsageChartView: View {
|
|
|
103
105
|
.chartXAxis {
|
|
104
106
|
AxisMarks(values: .automatic(desiredCount: 4)) { _ in
|
|
105
107
|
AxisValueLabel(format: self.xAxisFormat)
|
|
106
|
-
.font(.system(size: 8
|
|
108
|
+
.font(RunicFont.system(size: 8))
|
|
107
109
|
.foregroundStyle(Color(nsColor: .tertiaryLabelColor))
|
|
108
110
|
}
|
|
109
111
|
}
|
|
@@ -113,7 +115,7 @@ struct InlineUsageChartView: View {
|
|
|
113
115
|
// Peak badge
|
|
114
116
|
if let peak = points.max(by: { $0.tokens < $1.tokens }), peak.tokens > 0 {
|
|
115
117
|
Text("Peak \(UsageFormatter.tokenCountString(peak.tokens))")
|
|
116
|
-
.font(.system(size: 8, weight: .medium
|
|
118
|
+
.font(RunicFont.system(size: 8, weight: .medium))
|
|
117
119
|
.foregroundStyle(.secondary)
|
|
118
120
|
.padding(.horizontal, 4)
|
|
119
121
|
.padding(.vertical, 1)
|
|
@@ -14,8 +14,8 @@ struct MenuCardEntranceModifier: ViewModifier {
|
|
|
14
14
|
.scaleEffect(self.appeared ? 1 : 0.97, anchor: .top)
|
|
15
15
|
.onAppear {
|
|
16
16
|
withAnimation(
|
|
17
|
-
RunicAnimation.cardEntrance.delay(Double(self.index) * RunicAnimation.cardEntranceStagger)
|
|
18
|
-
|
|
17
|
+
RunicAnimation.cardEntrance.delay(Double(self.index) * RunicAnimation.cardEntranceStagger))
|
|
18
|
+
{
|
|
19
19
|
self.appeared = true
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -41,8 +41,7 @@ struct GlassShimmerModifier: ViewModifier {
|
|
|
41
41
|
.frame(width: geo.size.width, height: geo.size.height)
|
|
42
42
|
.allowsHitTesting(false)
|
|
43
43
|
}
|
|
44
|
-
.clipShape(RoundedRectangle(cornerRadius: RunicCornerRadius.lg, style: .continuous))
|
|
45
|
-
)
|
|
44
|
+
.clipShape(RoundedRectangle(cornerRadius: RunicCornerRadius.lg, style: .continuous)))
|
|
46
45
|
.onAppear {
|
|
47
46
|
withAnimation(.easeInOut(duration: 2.0).delay(0.5)) {
|
|
48
47
|
self.shimmerPhase = 1.2
|
|
@@ -61,29 +61,7 @@ struct ProviderSidebarMenuCardView<Content: View>: View {
|
|
|
61
61
|
let iconProvider: (UsageProvider, CGFloat) -> NSImage
|
|
62
62
|
let weeklyRemainingProvider: (UsageProvider) -> Double?
|
|
63
63
|
let onSelect: (UsageProvider) -> Void
|
|
64
|
-
let content: (CGFloat) -> Content
|
|
65
|
-
|
|
66
|
-
init(
|
|
67
|
-
providers: [UsageProvider],
|
|
68
|
-
selected: UsageProvider?,
|
|
69
|
-
totalWidth: CGFloat,
|
|
70
|
-
showIcons: Bool,
|
|
71
|
-
iconSize: ProviderSwitcherIconSize,
|
|
72
|
-
iconProvider: @escaping (UsageProvider, CGFloat) -> NSImage,
|
|
73
|
-
weeklyRemainingProvider: @escaping (UsageProvider) -> Double?,
|
|
74
|
-
onSelect: @escaping (UsageProvider) -> Void,
|
|
75
|
-
@ViewBuilder content: @escaping (CGFloat) -> Content)
|
|
76
|
-
{
|
|
77
|
-
self.providers = providers
|
|
78
|
-
self.selected = selected
|
|
79
|
-
self.totalWidth = totalWidth
|
|
80
|
-
self.showIcons = showIcons
|
|
81
|
-
self.iconSize = iconSize
|
|
82
|
-
self.iconProvider = iconProvider
|
|
83
|
-
self.weeklyRemainingProvider = weeklyRemainingProvider
|
|
84
|
-
self.onSelect = onSelect
|
|
85
|
-
self.content = content
|
|
86
|
-
}
|
|
64
|
+
@ViewBuilder let content: (CGFloat) -> Content
|
|
87
65
|
|
|
88
66
|
var body: some View {
|
|
89
67
|
let style = MenuCardSidebarMetrics.style(for: self.providers.count, iconSize: self.iconSize)
|
|
@@ -124,7 +102,8 @@ private struct ProviderSidebarRailView: View {
|
|
|
124
102
|
@Environment(\.menuItemHighlighted) private var isHighlighted
|
|
125
103
|
|
|
126
104
|
private var railBackground: LinearGradient {
|
|
127
|
-
let base = Color(nsColor: .controlTextColor)
|
|
105
|
+
let base = Color(nsColor: .controlTextColor)
|
|
106
|
+
.opacity(self.isHighlighted ? RunicColors.Opacity.subtle : RunicColors.Opacity.nano)
|
|
128
107
|
return LinearGradient(
|
|
129
108
|
colors: [base, base.opacity(0.6)],
|
|
130
109
|
startPoint: .top,
|
|
@@ -164,7 +143,8 @@ private struct ProviderSidebarRailView: View {
|
|
|
164
143
|
}
|
|
165
144
|
|
|
166
145
|
Rectangle()
|
|
167
|
-
.fill(Color(nsColor: .separatorColor)
|
|
146
|
+
.fill(Color(nsColor: .separatorColor)
|
|
147
|
+
.opacity(self.isHighlighted ? RunicColors.Opacity.emphasis : RunicColors.Opacity.strong))
|
|
168
148
|
.frame(width: 1)
|
|
169
149
|
.padding(.top, MenuCardMetrics.headerTopPadding + 4)
|
|
170
150
|
.padding(.bottom, MenuCardMetrics.tailPadding)
|
|
@@ -80,7 +80,7 @@ struct MenuCardSkeletonView: View {
|
|
|
80
80
|
/// Computes a repeating phase (0...1) from the timeline date for the sliding gradient.
|
|
81
81
|
private func shimmerPhase(date: Date) -> Double {
|
|
82
82
|
let seconds = date.timeIntervalSinceReferenceDate
|
|
83
|
-
let period
|
|
83
|
+
let period = 1.5
|
|
84
84
|
return (seconds.truncatingRemainder(dividingBy: period)) / period
|
|
85
85
|
}
|
|
86
86
|
|