@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,51 +1,51 @@
|
|
|
1
1
|
import AppKit
|
|
2
|
-
import RunicCore
|
|
3
2
|
import Observation
|
|
4
3
|
import QuartzCore
|
|
4
|
+
import RunicCore
|
|
5
5
|
import SwiftUI
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
7
|
+
// **StatusItemController** - Manages macOS menubar status item and dropdown menu
|
|
8
|
+
//
|
|
9
|
+
// **Purpose:**
|
|
10
|
+
// Coordinates the menubar icon, animations, menu construction, and user interactions.
|
|
11
|
+
// Acts as the bridge between AppKit (NSStatusItem) and SwiftUI (menu cards).
|
|
12
|
+
//
|
|
13
|
+
// **Responsibilities:**
|
|
14
|
+
// - Create and manage NSStatusItem in menubar
|
|
15
|
+
// - Coordinate icon rendering via IconRenderer
|
|
16
|
+
// - Build rich NSMenu with embedded SwiftUI views
|
|
17
|
+
// - Handle animation lifecycle (60 FPS during pings)
|
|
18
|
+
// - Schedule background "ping" operations when menu opens
|
|
19
|
+
// - Manage keyboard shortcuts and user actions
|
|
20
|
+
//
|
|
21
|
+
// **Architecture Pattern:**
|
|
22
|
+
// This file is split across 4 files via extensions:
|
|
23
|
+
// - `StatusItemController.swift` - Core setup (318 lines)
|
|
24
|
+
// - `StatusItemController+Menu.swift` - Menu construction (1878 lines)
|
|
25
|
+
// - `StatusItemController+Actions.swift` - User actions (200 lines)
|
|
26
|
+
// - `StatusItemController+Animation.swift` - Animation system (469 lines)
|
|
27
|
+
//
|
|
28
|
+
// **Performance:**
|
|
29
|
+
// - **60 FPS cap** during active pings (PerformanceConstants.menubarFPS)
|
|
30
|
+
// - **Auto-stop animations** when data loaded or error encountered
|
|
31
|
+
// - **1.2s delay** before background ping when menu opens (reduce perceived lag)
|
|
32
|
+
//
|
|
33
|
+
// **Dependencies:**
|
|
34
|
+
// - `UsageStore` - Data source
|
|
35
|
+
// - `SettingsStore` - User preferences
|
|
36
|
+
// - `IconRenderer` - Icon generation
|
|
37
|
+
// - `MenuCardView` - SwiftUI menu content
|
|
38
|
+
//
|
|
39
|
+
// **Usage:**
|
|
40
|
+
// ```swift
|
|
41
|
+
// let controller = StatusItemController(
|
|
42
|
+
// store: usageStore,
|
|
43
|
+
// settings: settingsStore,
|
|
44
|
+
// account: accountInfo,
|
|
45
|
+
// updater: updater,
|
|
46
|
+
// preferencesSelection: selection
|
|
47
|
+
// )
|
|
48
|
+
// ```
|
|
49
49
|
|
|
50
50
|
// MARK: - Status item controller (AppKit-hosted icons, SwiftUI popovers)
|
|
51
51
|
|
|
@@ -59,7 +59,8 @@ final class BudgetNotificationManager {
|
|
|
59
59
|
let title = "Budget Alert: \(projectName)"
|
|
60
60
|
let body = "Projected to exceed \(limitStr) limit by \(overshootStr) this month"
|
|
61
61
|
|
|
62
|
-
self.logger.info(
|
|
62
|
+
self.logger.info(
|
|
63
|
+
"posting budget breach notification",
|
|
63
64
|
metadata: [
|
|
64
65
|
"provider": provider.rawValue,
|
|
65
66
|
"project": projectKey,
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import AppKit
|
|
2
|
-
import RunicCore
|
|
3
2
|
import Foundation
|
|
3
|
+
import RunicCore
|
|
4
4
|
import WebKit
|
|
5
5
|
|
|
6
6
|
/// Handles Cursor login flow using a WebKit-based browser window.
|
|
7
7
|
/// Captures session cookies after successful authentication.
|
|
8
8
|
@MainActor
|
|
9
9
|
final class CursorLoginRunner: NSObject {
|
|
10
|
-
enum Phase
|
|
10
|
+
enum Phase {
|
|
11
11
|
case loading
|
|
12
12
|
case waitingLogin
|
|
13
13
|
case success
|
|
14
14
|
case failed(String)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
struct Result
|
|
18
|
-
enum Outcome
|
|
17
|
+
struct Result {
|
|
18
|
+
enum Outcome {
|
|
19
19
|
case success
|
|
20
20
|
case cancelled
|
|
21
21
|
case failed(String)
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
import AppKit
|
|
2
2
|
import RunicCore
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
enum IconAppearance
|
|
40
|
-
case template
|
|
41
|
-
case vibrant
|
|
4
|
+
// **IconRenderer** - Generates menubar status item icons with usage visualization
|
|
5
|
+
//
|
|
6
|
+
// **Purpose:**
|
|
7
|
+
// Creates pixel-perfect 18×18pt (36×36px @2x) template images for the macOS menubar.
|
|
8
|
+
// Renders usage bars, stale indicators, and provider status into the icon.
|
|
9
|
+
//
|
|
10
|
+
// **Responsibilities:**
|
|
11
|
+
// - Generate icons showing session/weekly usage patterns
|
|
12
|
+
// - Apply stale data dimming when data is > 5 minutes old
|
|
13
|
+
// - Cache rendered icons for performance (64 icon cache, 512 morph cache)
|
|
14
|
+
// - Support template (adapts to menubar theme) and vibrant appearances
|
|
15
|
+
// - Render loading animations and error states
|
|
16
|
+
//
|
|
17
|
+
// **Performance:**
|
|
18
|
+
// - **O(1) icon cache lookup** via IconCacheKey hash
|
|
19
|
+
// - **O(1) morph cache** for animation frames
|
|
20
|
+
// - Cap cache sizes via `PerformanceConstants`
|
|
21
|
+
// - All rendering happens off main thread in `dispatchPrecondition(condition: .notOnQueue(.main))`
|
|
22
|
+
//
|
|
23
|
+
// **Dependencies:**
|
|
24
|
+
// - `PerformanceConstants` - Cache sizes and timing
|
|
25
|
+
// - `UsageProvider` - Provider-specific rendering
|
|
26
|
+
// - `AppKit/CoreGraphics` - Image generation
|
|
27
|
+
//
|
|
28
|
+
// **Usage:**
|
|
29
|
+
// ```swift
|
|
30
|
+
// let icon = IconRenderer.render(
|
|
31
|
+
// state: .usage(snap, status),
|
|
32
|
+
// indicator: .none,
|
|
33
|
+
// appearance: .template,
|
|
34
|
+
// dataMode: .remaining
|
|
35
|
+
// )
|
|
36
|
+
// statusItem.button?.image = icon
|
|
37
|
+
// ```
|
|
38
|
+
|
|
39
|
+
enum IconAppearance {
|
|
40
|
+
case template // Adapts to menubar theme (light/dark mode)
|
|
41
|
+
case vibrant // Full color rendering
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
enum IconDataMode
|
|
45
|
-
case remaining
|
|
46
|
-
case used
|
|
44
|
+
enum IconDataMode {
|
|
45
|
+
case remaining // Show remaining quota
|
|
46
|
+
case used // Show used quota
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
enum IconRenderer {
|
|
@@ -53,17 +53,18 @@ enum IconRenderer {
|
|
|
53
53
|
private static let outputSize = NSSize(width: 38, height: 22)
|
|
54
54
|
private static let outputScale: CGFloat = 2
|
|
55
55
|
private static let canvasPx = Int(outputSize.width * outputScale)
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
|
|
57
|
+
/// Infinity symbol base template - loaded lazily from Resources
|
|
58
58
|
private static let waveLogoTemplate: NSImage? = {
|
|
59
59
|
guard let url = Bundle.main.url(forResource: "RunicMenubarIcon", withExtension: "svg"),
|
|
60
|
-
let image = NSImage(contentsOf: url)
|
|
60
|
+
let image = NSImage(contentsOf: url)
|
|
61
|
+
else {
|
|
61
62
|
return nil
|
|
62
63
|
}
|
|
63
64
|
return image
|
|
64
65
|
}()
|
|
65
66
|
|
|
66
|
-
private struct PixelGrid
|
|
67
|
+
private struct PixelGrid {
|
|
67
68
|
let scale: CGFloat
|
|
68
69
|
|
|
69
70
|
func pt(_ px: Int) -> CGFloat {
|
|
@@ -142,14 +143,19 @@ enum IconRenderer {
|
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
private struct RectPx: Hashable
|
|
146
|
+
private struct RectPx: Hashable {
|
|
146
147
|
let x: Int
|
|
147
148
|
let y: Int
|
|
148
149
|
let w: Int
|
|
149
150
|
let h: Int
|
|
150
151
|
|
|
151
|
-
var midXPx: Int {
|
|
152
|
-
|
|
152
|
+
var midXPx: Int {
|
|
153
|
+
self.x + self.w / 2
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
var midYPx: Int {
|
|
157
|
+
self.y + self.h / 2
|
|
158
|
+
}
|
|
153
159
|
|
|
154
160
|
func rect() -> CGRect {
|
|
155
161
|
Self.grid.rect(x: self.x, y: self.y, w: self.w, h: self.h)
|
|
@@ -215,13 +221,13 @@ enum IconRenderer {
|
|
|
215
221
|
dataMode: dataMode)
|
|
216
222
|
let accentColor = Self.vibrantAccentColor(pressure: pressure, stale: stale)
|
|
217
223
|
let baseColor = appearance == .template ? NSColor.labelColor : accentColor
|
|
218
|
-
|
|
224
|
+
|
|
219
225
|
// Disable blink effect to prevent flicker
|
|
220
226
|
let opacityMultiplier = 1.0
|
|
221
|
-
|
|
227
|
+
|
|
222
228
|
let fillColor = baseColor.withAlphaComponent((stale ? 0.55 : 1.0) * opacityMultiplier)
|
|
223
229
|
let baseAlpha: CGFloat = (stale ? 0.18 : (appearance == .template ? 0.28 : 0.38)) * opacityMultiplier
|
|
224
|
-
|
|
230
|
+
|
|
225
231
|
let fillPercent = Self.iconFillPercent(
|
|
226
232
|
primary: topValue,
|
|
227
233
|
weekly: bottomValue,
|
|
@@ -265,33 +271,33 @@ enum IconRenderer {
|
|
|
265
271
|
|
|
266
272
|
private static func sigilStyle(for style: IconStyle) -> SigilStyle {
|
|
267
273
|
switch style {
|
|
268
|
-
case .codex:
|
|
269
|
-
case .claude:
|
|
270
|
-
case .zai:
|
|
271
|
-
case .gemini:
|
|
272
|
-
case .antigravity:
|
|
273
|
-
case .cursor:
|
|
274
|
-
case .factory:
|
|
275
|
-
case .copilot:
|
|
276
|
-
case .minimax:
|
|
277
|
-
case .openrouter:
|
|
278
|
-
case .groq:
|
|
279
|
-
case .deepseek:
|
|
280
|
-
case .fireworks:
|
|
281
|
-
case .mistral:
|
|
282
|
-
case .perplexity:
|
|
283
|
-
case .kimi:
|
|
284
|
-
case .auggie:
|
|
285
|
-
case .together:
|
|
286
|
-
case .cohere:
|
|
287
|
-
case .xai:
|
|
288
|
-
case .cerebras:
|
|
289
|
-
case .sambanova:
|
|
290
|
-
case .azure:
|
|
291
|
-
case .bedrock:
|
|
292
|
-
case .vertexai:
|
|
293
|
-
case .qwen:
|
|
294
|
-
case .combined:
|
|
274
|
+
case .codex: .codex
|
|
275
|
+
case .claude: .claude
|
|
276
|
+
case .zai: .zai
|
|
277
|
+
case .gemini: .gemini
|
|
278
|
+
case .antigravity: .antigravity
|
|
279
|
+
case .cursor: .cursor
|
|
280
|
+
case .factory: .factory
|
|
281
|
+
case .copilot: .copilot
|
|
282
|
+
case .minimax: .minimax
|
|
283
|
+
case .openrouter: .openrouter
|
|
284
|
+
case .groq: .groq
|
|
285
|
+
case .deepseek: .deepseek
|
|
286
|
+
case .fireworks: .fireworks
|
|
287
|
+
case .mistral: .mistral
|
|
288
|
+
case .perplexity: .perplexity
|
|
289
|
+
case .kimi: .kimi
|
|
290
|
+
case .auggie: .auggie
|
|
291
|
+
case .together: .together
|
|
292
|
+
case .cohere: .cohere
|
|
293
|
+
case .xai: .xai
|
|
294
|
+
case .cerebras: .cerebras
|
|
295
|
+
case .sambanova: .sambanova
|
|
296
|
+
case .azure: .azure
|
|
297
|
+
case .bedrock: .bedrock
|
|
298
|
+
case .vertexai: .vertexai
|
|
299
|
+
case .qwen: .qwen
|
|
300
|
+
case .combined: .combined
|
|
295
301
|
}
|
|
296
302
|
}
|
|
297
303
|
|
|
@@ -515,7 +521,7 @@ enum IconRenderer {
|
|
|
515
521
|
let barHeightPx = 6
|
|
516
522
|
let totalWidth = barWidthPx * 3 + barGapPx * 2
|
|
517
523
|
let startX = centerXPx - totalWidth / 2
|
|
518
|
-
for idx in 0
|
|
524
|
+
for idx in 0..<3 {
|
|
519
525
|
let x = startX + idx * (barWidthPx + barGapPx)
|
|
520
526
|
let rect = Self.grid.rect(
|
|
521
527
|
x: x,
|
|
@@ -835,7 +841,8 @@ enum IconRenderer {
|
|
|
835
841
|
fillColor: NSColor)
|
|
836
842
|
{
|
|
837
843
|
guard let waveLogo = self.waveLogoTemplate,
|
|
838
|
-
let ctx = NSGraphicsContext.current?.cgContext
|
|
844
|
+
let ctx = NSGraphicsContext.current?.cgContext
|
|
845
|
+
else {
|
|
839
846
|
return
|
|
840
847
|
}
|
|
841
848
|
|
|
@@ -867,7 +874,7 @@ enum IconRenderer {
|
|
|
867
874
|
credits: Double?,
|
|
868
875
|
dataMode: IconDataMode) -> Double
|
|
869
876
|
{
|
|
870
|
-
let values = [primary, weekly, credits].compactMap
|
|
877
|
+
let values = [primary, weekly, credits].compactMap(\.self)
|
|
871
878
|
guard !values.isEmpty else { return 0 }
|
|
872
879
|
let normalized = values.map { max(0, min($0 / 100, 1)) }
|
|
873
880
|
switch dataMode {
|
|
@@ -884,11 +891,10 @@ enum IconRenderer {
|
|
|
884
891
|
let safe = NSColor(calibratedRed: 0.12, green: 0.86, blue: 0.78, alpha: 1)
|
|
885
892
|
let warn = NSColor(calibratedRed: 1.00, green: 0.72, blue: 0.30, alpha: 1)
|
|
886
893
|
let hot = NSColor(calibratedRed: 1.00, green: 0.31, blue: 0.44, alpha: 1)
|
|
887
|
-
let color: NSColor
|
|
888
|
-
|
|
889
|
-
color = self.mixColor(safe, warn, p: clamped / 0.5)
|
|
894
|
+
let color: NSColor = if clamped <= 0.5 {
|
|
895
|
+
self.mixColor(safe, warn, p: clamped / 0.5)
|
|
890
896
|
} else {
|
|
891
|
-
|
|
897
|
+
self.mixColor(warn, hot, p: (clamped - 0.5) / 0.5)
|
|
892
898
|
}
|
|
893
899
|
if stale {
|
|
894
900
|
return color.withAlphaComponent(0.72)
|
|
@@ -19,7 +19,9 @@ struct IconView: View {
|
|
|
19
19
|
private let cycleIntervalTicks = 20
|
|
20
20
|
private let patterns = LoadingPattern.allCases
|
|
21
21
|
|
|
22
|
-
private var isLoading: Bool {
|
|
22
|
+
private var isLoading: Bool {
|
|
23
|
+
self.showLoadingAnimation && self.snapshot == nil
|
|
24
|
+
}
|
|
23
25
|
|
|
24
26
|
var body: some View {
|
|
25
27
|
Group {
|
|
@@ -14,12 +14,12 @@ enum RunicColors {
|
|
|
14
14
|
/// Ordered palette for chart series. Colors chosen for distinguishability in
|
|
15
15
|
/// both light and dark mode and for common color-vision deficiencies.
|
|
16
16
|
static let chartPalette: [Color] = [
|
|
17
|
-
Color(red: 0.26, green: 0.55, blue: 0.96),
|
|
18
|
-
Color(red: 0.94, green: 0.53, blue: 0.18),
|
|
19
|
-
Color(red: 0.46, green: 0.75, blue: 0.36),
|
|
20
|
-
Color(red: 0.80, green: 0.45, blue: 0.92),
|
|
21
|
-
Color(red: 0.26, green: 0.78, blue: 0.86),
|
|
22
|
-
Color(red: 0.94, green: 0.74, blue: 0.26),
|
|
17
|
+
Color(red: 0.26, green: 0.55, blue: 0.96), // blue
|
|
18
|
+
Color(red: 0.94, green: 0.53, blue: 0.18), // orange
|
|
19
|
+
Color(red: 0.46, green: 0.75, blue: 0.36), // green
|
|
20
|
+
Color(red: 0.80, green: 0.45, blue: 0.92), // purple
|
|
21
|
+
Color(red: 0.26, green: 0.78, blue: 0.86), // teal
|
|
22
|
+
Color(red: 0.94, green: 0.74, blue: 0.26), // yellow
|
|
23
23
|
]
|
|
24
24
|
|
|
25
25
|
/// Returns a chart color for the given index, wrapping around if needed.
|
|
@@ -33,16 +33,16 @@ enum RunicSpacing {
|
|
|
33
33
|
// MARK: - Semantic Spacing
|
|
34
34
|
|
|
35
35
|
/// Horizontal padding for menu content
|
|
36
|
-
static let menuHorizontalPadding: CGFloat = sm
|
|
36
|
+
static let menuHorizontalPadding: CGFloat = sm // 12pt
|
|
37
37
|
|
|
38
38
|
/// Vertical padding for menu content
|
|
39
|
-
static let menuVerticalPadding: CGFloat = xs
|
|
39
|
+
static let menuVerticalPadding: CGFloat = xs // 8pt
|
|
40
40
|
|
|
41
41
|
/// Spacing between cards in menu
|
|
42
|
-
static let cardSpacing: CGFloat = xs
|
|
42
|
+
static let cardSpacing: CGFloat = xs // 8pt
|
|
43
43
|
|
|
44
44
|
/// Spacing between major sections
|
|
45
|
-
static let sectionSpacing: CGFloat = lg
|
|
45
|
+
static let sectionSpacing: CGFloat = lg // 24pt
|
|
46
46
|
|
|
47
47
|
// MARK: - Preferences Spacing
|
|
48
48
|
|
|
@@ -50,13 +50,13 @@ enum RunicSpacing {
|
|
|
50
50
|
static let compact: CGFloat = 6
|
|
51
51
|
|
|
52
52
|
/// Standardized spacing for toggle rows
|
|
53
|
-
static let toggleRowSpacing: CGFloat = xs
|
|
53
|
+
static let toggleRowSpacing: CGFloat = xs // 8pt
|
|
54
54
|
|
|
55
55
|
/// Spacing after section headers
|
|
56
|
-
static let sectionHeaderSpacing: CGFloat = md
|
|
56
|
+
static let sectionHeaderSpacing: CGFloat = md // 16pt
|
|
57
57
|
|
|
58
58
|
/// Spacing within stepper controls
|
|
59
|
-
static let stepperControlSpacing: CGFloat = xs
|
|
59
|
+
static let stepperControlSpacing: CGFloat = xs // 8pt
|
|
60
60
|
|
|
61
61
|
// MARK: - Chart Metrics
|
|
62
62
|
|