@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.0 — 2026-03-27
|
|
4
|
+
- Typography: custom font system with 7 bundled families (Fira Code, JetBrains Mono, IBM Plex Mono, Space Mono, Inconsolata, Caveat, SF Pro/Mono)
|
|
5
|
+
- Typography: live font switching from Settings > General — no restart needed
|
|
6
|
+
- Typography: RunicTypography design tokens with dynamic RunicFont scale across 600+ font call sites
|
|
7
|
+
- Typography: drop-in font extensibility — add TTF/OTF to Resources/Fonts, rebuild, auto-discovered
|
|
8
|
+
- Typography: font preview in picker — each choice rendered in its own typeface
|
|
9
|
+
- Typography: NSMenuItem post-processor applies selected font to all plain menu items
|
|
10
|
+
- Typography: xLarge dynamic type for slightly larger text across the app
|
|
11
|
+
- Menu: wider card base width (310→340pt) for monospaced font comfort
|
|
12
|
+
- iOS: RunicFont enum for consistent monospaced typography across widgets and views
|
|
13
|
+
|
|
3
14
|
## 0.16.1 — 2025-12-29
|
|
4
15
|
- Menu: reduce layout thrash when opening menus and sizing charts. Thanks @ibehnam!
|
|
5
16
|
- Packaging: default release notarization builds universal (arm64 + x86_64) zip.
|
package/README.md
CHANGED
|
@@ -77,7 +77,9 @@ Context windows are configurable via `Resources/provider-context-windows.json`.
|
|
|
77
77
|
- Dark / Light / System theme
|
|
78
78
|
- Liquid UI with glass materials and animated progress bars
|
|
79
79
|
- Staggered entrance animations and glass shimmer effects
|
|
80
|
-
- SF
|
|
80
|
+
- Custom font system — 7 bundled families (Fira Code, JetBrains Mono, IBM Plex Mono, Space Mono, Inconsolata, Caveat, SF Pro/Mono) with live switching
|
|
81
|
+
- Drop-in font extensibility — add TTF/OTF to `Resources/Fonts`, rebuild, auto-discovered
|
|
82
|
+
- Design tokens for typography, colors, spacing, corner radius, animation
|
|
81
83
|
- VoiceOver accessible
|
|
82
84
|
- Sparkle auto-updates
|
|
83
85
|
|
|
@@ -107,6 +109,11 @@ All tokens stored in macOS Keychain with no password prompts.
|
|
|
107
109
|
|
|
108
110
|
Zero telemetry. No analytics. No crash reporting. All data stays on your Mac.
|
|
109
111
|
|
|
112
|
+
## Roadmap
|
|
113
|
+
|
|
114
|
+
- Windows desktop app
|
|
115
|
+
- Web app
|
|
116
|
+
|
|
110
117
|
## License
|
|
111
118
|
|
|
112
119
|
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
|
|
3
|
+
/// iOS font scale — mirrors the macOS RunicFont for cross-platform consistency.
|
|
4
|
+
enum RunicFont {
|
|
5
|
+
static let caption2 = Font.system(.caption2, design: .monospaced)
|
|
6
|
+
static let caption = Font.system(.caption, design: .monospaced)
|
|
7
|
+
static let footnote = Font.system(.footnote, design: .monospaced)
|
|
8
|
+
static let callout = Font.system(.callout, design: .monospaced)
|
|
9
|
+
static let body = Font.system(.body, design: .monospaced)
|
|
10
|
+
static let subheadline = Font.system(.subheadline, design: .monospaced)
|
|
11
|
+
static let headline = Font.system(.headline, design: .monospaced)
|
|
12
|
+
static let title3 = Font.system(.title3, design: .monospaced)
|
|
13
|
+
static let title2 = Font.system(.title2, design: .monospaced)
|
|
14
|
+
static let title = Font.system(.title, design: .monospaced)
|
|
15
|
+
static let largeTitle = Font.system(.largeTitle, design: .monospaced)
|
|
16
|
+
|
|
17
|
+
static func system(size: CGFloat) -> Font {
|
|
18
|
+
Font.system(size: size, design: .monospaced)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static func system(size: CGFloat, weight: Font.Weight) -> Font {
|
|
22
|
+
Font.system(size: size, weight: weight, design: .monospaced)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -135,11 +135,11 @@ struct ProviderHeaderView: View {
|
|
|
135
135
|
|
|
136
136
|
VStack(spacing: 4) {
|
|
137
137
|
Text("\(Int(snapshot.primary.usedPercent))%")
|
|
138
|
-
.font(.
|
|
138
|
+
.font(RunicFont.largeTitle.weight(.bold))
|
|
139
139
|
.foregroundStyle(statusColor)
|
|
140
140
|
|
|
141
141
|
Text("Used")
|
|
142
|
-
.font(.caption)
|
|
142
|
+
.font(RunicFont.caption)
|
|
143
143
|
.foregroundStyle(.secondary)
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -148,15 +148,15 @@ struct ProviderHeaderView: View {
|
|
|
148
148
|
// Status message
|
|
149
149
|
if snapshot.primary.usedPercent >= 90 {
|
|
150
150
|
Text("⚠️ Approaching Limit")
|
|
151
|
-
.font(.headline)
|
|
151
|
+
.font(RunicFont.headline)
|
|
152
152
|
.foregroundStyle(.red)
|
|
153
153
|
} else if snapshot.primary.usedPercent >= 75 {
|
|
154
154
|
Text("⚡ High Usage")
|
|
155
|
-
.font(.headline)
|
|
155
|
+
.font(RunicFont.headline)
|
|
156
156
|
.foregroundStyle(.orange)
|
|
157
157
|
} else {
|
|
158
158
|
Text("✓ Healthy")
|
|
159
|
-
.font(.headline)
|
|
159
|
+
.font(RunicFont.headline)
|
|
160
160
|
.foregroundStyle(.green)
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -212,10 +212,10 @@ struct MetricRow: View {
|
|
|
212
212
|
VStack(alignment: .leading, spacing: 6) {
|
|
213
213
|
HStack {
|
|
214
214
|
Text(title)
|
|
215
|
-
.font(.subheadline)
|
|
215
|
+
.font(RunicFont.subheadline)
|
|
216
216
|
Spacer()
|
|
217
217
|
Text("\(Int(value))%")
|
|
218
|
-
.font(.
|
|
218
|
+
.font(RunicFont.headline)
|
|
219
219
|
.foregroundStyle(color)
|
|
220
220
|
}
|
|
221
221
|
|
|
@@ -232,7 +232,7 @@ struct MetricRow: View {
|
|
|
232
232
|
.frame(height: 8)
|
|
233
233
|
|
|
234
234
|
Text(label)
|
|
235
|
-
.font(.caption)
|
|
235
|
+
.font(RunicFont.caption)
|
|
236
236
|
.foregroundStyle(.secondary)
|
|
237
237
|
}
|
|
238
238
|
}
|
|
@@ -283,7 +283,7 @@ struct AccountTypeBadge: View {
|
|
|
283
283
|
|
|
284
284
|
var body: some View {
|
|
285
285
|
Text(type.rawValue.replacingOccurrences(of: "_", with: " ").capitalized)
|
|
286
|
-
.font(.caption)
|
|
286
|
+
.font(RunicFont.caption)
|
|
287
287
|
.padding(.horizontal, 8)
|
|
288
288
|
.padding(.vertical, 4)
|
|
289
289
|
.background(color.opacity(0.2))
|
|
@@ -120,10 +120,10 @@ struct StatView: View {
|
|
|
120
120
|
var body: some View {
|
|
121
121
|
VStack(spacing: 4) {
|
|
122
122
|
Text(value)
|
|
123
|
-
.font(.
|
|
123
|
+
.font(RunicFont.title2.weight(.bold))
|
|
124
124
|
.foregroundStyle(color)
|
|
125
125
|
Text(label)
|
|
126
|
-
.font(.caption)
|
|
126
|
+
.font(RunicFont.caption)
|
|
127
127
|
.foregroundStyle(.secondary)
|
|
128
128
|
}
|
|
129
129
|
.frame(maxWidth: .infinity)
|
|
@@ -147,17 +147,17 @@ struct ProviderRowView: View {
|
|
|
147
147
|
HStack {
|
|
148
148
|
// Provider icon and name
|
|
149
149
|
Image(systemName: iconForProvider(snapshot.provider))
|
|
150
|
-
.font(.title3)
|
|
150
|
+
.font(RunicFont.title3)
|
|
151
151
|
.foregroundStyle(statusColor)
|
|
152
152
|
.frame(width: 32)
|
|
153
153
|
|
|
154
154
|
VStack(alignment: .leading, spacing: 2) {
|
|
155
155
|
Text(snapshot.provider.rawValue.capitalized)
|
|
156
|
-
.font(.headline)
|
|
156
|
+
.font(RunicFont.headline)
|
|
157
157
|
|
|
158
158
|
if let email = snapshot.accountEmail {
|
|
159
159
|
Text(email)
|
|
160
|
-
.font(.caption)
|
|
160
|
+
.font(RunicFont.caption)
|
|
161
161
|
.foregroundStyle(.secondary)
|
|
162
162
|
}
|
|
163
163
|
}
|
|
@@ -166,7 +166,7 @@ struct ProviderRowView: View {
|
|
|
166
166
|
|
|
167
167
|
// Usage percentage
|
|
168
168
|
Text("\(Int(snapshot.primary.usedPercent))%")
|
|
169
|
-
.font(.
|
|
169
|
+
.font(RunicFont.title3.weight(.semibold))
|
|
170
170
|
.foregroundStyle(statusColor)
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -189,9 +189,9 @@ struct ProviderRowView: View {
|
|
|
189
189
|
timeRemaining > 0 {
|
|
190
190
|
HStack {
|
|
191
191
|
Image(systemName: "clock")
|
|
192
|
-
.font(.caption2)
|
|
192
|
+
.font(RunicFont.caption2)
|
|
193
193
|
Text(resetInfo.resetDescription)
|
|
194
|
-
.font(.caption)
|
|
194
|
+
.font(RunicFont.caption)
|
|
195
195
|
}
|
|
196
196
|
.foregroundStyle(.secondary)
|
|
197
197
|
}
|
|
@@ -200,9 +200,9 @@ struct ProviderRowView: View {
|
|
|
200
200
|
if let model = snapshot.primaryModel {
|
|
201
201
|
HStack {
|
|
202
202
|
Image(systemName: "cpu.fill")
|
|
203
|
-
.font(.caption2)
|
|
203
|
+
.font(RunicFont.caption2)
|
|
204
204
|
Text(model.modelName)
|
|
205
|
-
.font(.caption)
|
|
205
|
+
.font(RunicFont.caption)
|
|
206
206
|
}
|
|
207
207
|
.foregroundStyle(.blue)
|
|
208
208
|
}
|
|
@@ -88,18 +88,18 @@ struct LargeWidgetView: View {
|
|
|
88
88
|
// Title and status
|
|
89
89
|
HStack(spacing: 10) {
|
|
90
90
|
Image(systemName: entry.systemStatus.iconName)
|
|
91
|
-
.font(.system(size: 20, weight: .semibold))
|
|
91
|
+
.font(RunicFont.system(size: 20, weight: .semibold))
|
|
92
92
|
.foregroundColor(statusColor)
|
|
93
93
|
|
|
94
94
|
Text("Runic Dashboard")
|
|
95
|
-
.font(.system(size: 18, weight: .bold))
|
|
95
|
+
.font(RunicFont.system(size: 18, weight: .bold))
|
|
96
96
|
.foregroundColor(.white)
|
|
97
97
|
|
|
98
98
|
Spacer()
|
|
99
99
|
|
|
100
100
|
// Last update
|
|
101
101
|
Text("Updated \(relativeTime)")
|
|
102
|
-
.font(.system(size: 11, weight: .medium))
|
|
102
|
+
.font(RunicFont.system(size: 11, weight: .medium))
|
|
103
103
|
.foregroundColor(.white.opacity(0.6))
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -140,15 +140,15 @@ struct LargeWidgetView: View {
|
|
|
140
140
|
) -> some View {
|
|
141
141
|
HStack(spacing: 6) {
|
|
142
142
|
Image(systemName: icon)
|
|
143
|
-
.font(.system(size: 12))
|
|
143
|
+
.font(RunicFont.system(size: 12))
|
|
144
144
|
.foregroundColor(color)
|
|
145
145
|
|
|
146
146
|
Text(value)
|
|
147
|
-
.font(.system(size: 14, weight: .bold
|
|
147
|
+
.font(RunicFont.system(size: 14, weight: .bold))
|
|
148
148
|
.foregroundColor(.white)
|
|
149
149
|
|
|
150
150
|
Text(label)
|
|
151
|
-
.font(.system(size: 11, weight: .medium))
|
|
151
|
+
.font(RunicFont.system(size: 11, weight: .medium))
|
|
152
152
|
.foregroundColor(.white.opacity(0.6))
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -158,7 +158,7 @@ struct LargeWidgetView: View {
|
|
|
158
158
|
private var chartsView: some View {
|
|
159
159
|
VStack(alignment: .leading, spacing: 6) {
|
|
160
160
|
Text("Usage Trend")
|
|
161
|
-
.font(.system(size: 11, weight: .semibold))
|
|
161
|
+
.font(RunicFont.system(size: 11, weight: .semibold))
|
|
162
162
|
.foregroundColor(.white.opacity(0.7))
|
|
163
163
|
|
|
164
164
|
if #available(iOS 16.0, *) {
|
|
@@ -193,7 +193,7 @@ struct LargeWidgetView: View {
|
|
|
193
193
|
.frame(width: 8, height: 8)
|
|
194
194
|
|
|
195
195
|
Text(provider.displayName)
|
|
196
|
-
.font(.system(size: 12, weight: .semibold))
|
|
196
|
+
.font(RunicFont.system(size: 12, weight: .semibold))
|
|
197
197
|
.foregroundColor(.white)
|
|
198
198
|
|
|
199
199
|
Spacer()
|
|
@@ -203,7 +203,7 @@ struct LargeWidgetView: View {
|
|
|
203
203
|
|
|
204
204
|
// Percentage
|
|
205
205
|
Text("\(Int(provider.remainingPercent))%")
|
|
206
|
-
.font(.system(size: 13, weight: .bold
|
|
206
|
+
.font(RunicFont.system(size: 13, weight: .bold))
|
|
207
207
|
.foregroundColor(.white)
|
|
208
208
|
.frame(width: 35, alignment: .trailing)
|
|
209
209
|
}
|
|
@@ -225,7 +225,7 @@ struct LargeWidgetView: View {
|
|
|
225
225
|
if let countdown = provider.resetCountdown {
|
|
226
226
|
HStack {
|
|
227
227
|
Text("Resets \(countdown)")
|
|
228
|
-
.font(.system(size: 9, weight: .medium))
|
|
228
|
+
.font(RunicFont.system(size: 9, weight: .medium))
|
|
229
229
|
.foregroundColor(.white.opacity(0.4))
|
|
230
230
|
|
|
231
231
|
Spacer()
|
|
@@ -255,7 +255,7 @@ struct LargeWidgetView: View {
|
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
return Image(systemName: "\(icon).circle.fill")
|
|
258
|
-
.font(.system(size: 10))
|
|
258
|
+
.font(RunicFont.system(size: 10))
|
|
259
259
|
.foregroundColor(color)
|
|
260
260
|
}
|
|
261
261
|
|
|
@@ -288,9 +288,9 @@ struct LargeWidgetView: View {
|
|
|
288
288
|
@ViewBuilder
|
|
289
289
|
private var emptyStateView: some View {
|
|
290
290
|
VStack(spacing: 12) {
|
|
291
|
-
Image(systemName: "chart.bar.doc.horizontal").font(.system(size: 36)).foregroundColor(.white.opacity(0.3))
|
|
292
|
-
Text("No Data Available").font(.system(size: 16, weight: .semibold)).foregroundColor(.white.opacity(0.6))
|
|
293
|
-
Text("Open Runic to sync your usage data").font(.system(size: 12)).foregroundColor(.white.opacity(0.4))
|
|
291
|
+
Image(systemName: "chart.bar.doc.horizontal").font(RunicFont.system(size: 36)).foregroundColor(.white.opacity(0.3))
|
|
292
|
+
Text("No Data Available").font(RunicFont.system(size: 16, weight: .semibold)).foregroundColor(.white.opacity(0.6))
|
|
293
|
+
Text("Open Runic to sync your usage data").font(RunicFont.system(size: 12)).foregroundColor(.white.opacity(0.4))
|
|
294
294
|
}
|
|
295
295
|
.padding()
|
|
296
296
|
}
|
|
@@ -105,16 +105,16 @@ struct RunicLiveActivity: Widget {
|
|
|
105
105
|
VStack(spacing: 12) {
|
|
106
106
|
HStack {
|
|
107
107
|
Circle().fill(providerColor(context: context)).frame(width: 10, height: 10)
|
|
108
|
-
Text(context.state.providerName).font(.system(size: 15, weight: .semibold)).foregroundColor(.white)
|
|
108
|
+
Text(context.state.providerName).font(RunicFont.system(size: 15, weight: .semibold)).foregroundColor(.white)
|
|
109
109
|
Spacer()
|
|
110
110
|
statusBadge(for: context.state.status)
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
VStack(spacing: 6) {
|
|
114
114
|
HStack {
|
|
115
|
-
Text("Session Usage").font(.system(size: 12, weight: .medium)).foregroundColor(.white.opacity(0.7))
|
|
115
|
+
Text("Session Usage").font(RunicFont.system(size: 12, weight: .medium)).foregroundColor(.white.opacity(0.7))
|
|
116
116
|
Spacer()
|
|
117
|
-
Text("\(Int(context.state.remainingPercent))% remaining").font(.system(size: 12, weight: .semibold)).foregroundColor(.white)
|
|
117
|
+
Text("\(Int(context.state.remainingPercent))% remaining").font(RunicFont.system(size: 12, weight: .semibold)).foregroundColor(.white)
|
|
118
118
|
}
|
|
119
119
|
GeometryReader { geometry in
|
|
120
120
|
ZStack(alignment: .leading) {
|
|
@@ -128,20 +128,20 @@ struct RunicLiveActivity: Widget {
|
|
|
128
128
|
|
|
129
129
|
HStack {
|
|
130
130
|
HStack(spacing: 4) {
|
|
131
|
-
Image(systemName: "clock.fill").font(.system(size: 10)).foregroundColor(.white.opacity(0.6))
|
|
132
|
-
Text(sessionDuration(from: context.state.sessionStartTime)).font(.system(size: 11, weight: .medium)).foregroundColor(.white.opacity(0.8))
|
|
131
|
+
Image(systemName: "clock.fill").font(RunicFont.system(size: 10)).foregroundColor(.white.opacity(0.6))
|
|
132
|
+
Text(sessionDuration(from: context.state.sessionStartTime)).font(RunicFont.system(size: 11, weight: .medium)).foregroundColor(.white.opacity(0.8))
|
|
133
133
|
}
|
|
134
134
|
Spacer()
|
|
135
135
|
if let tokens = context.state.sessionTokens {
|
|
136
136
|
HStack(spacing: 4) {
|
|
137
|
-
Image(systemName: "number").font(.system(size: 10)).foregroundColor(.white.opacity(0.6))
|
|
138
|
-
Text(UsageFormatter.tokenCountString(tokens)).font(.system(size: 11, weight: .medium)).foregroundColor(.white.opacity(0.8))
|
|
137
|
+
Image(systemName: "number").font(RunicFont.system(size: 10)).foregroundColor(.white.opacity(0.6))
|
|
138
|
+
Text(UsageFormatter.tokenCountString(tokens)).font(RunicFont.system(size: 11, weight: .medium)).foregroundColor(.white.opacity(0.8))
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
if let cost = context.state.estimatedCost {
|
|
142
142
|
HStack(spacing: 4) {
|
|
143
|
-
Image(systemName: "dollarsign.circle.fill").font(.system(size: 10)).foregroundColor(.white.opacity(0.6))
|
|
144
|
-
Text(UsageFormatter.usdString(cost)).font(.system(size: 11, weight: .medium)).foregroundColor(.white.opacity(0.8))
|
|
143
|
+
Image(systemName: "dollarsign.circle.fill").font(RunicFont.system(size: 10)).foregroundColor(.white.opacity(0.6))
|
|
144
|
+
Text(UsageFormatter.usdString(cost)).font(RunicFont.system(size: 11, weight: .medium)).foregroundColor(.white.opacity(0.8))
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
}
|
|
@@ -154,10 +154,10 @@ struct RunicLiveActivity: Widget {
|
|
|
154
154
|
func expandedLeading(context: ActivityViewContext<RunicLiveActivityAttributes>) -> some View {
|
|
155
155
|
VStack(alignment: .leading, spacing: 4) {
|
|
156
156
|
Text(context.state.providerName)
|
|
157
|
-
.font(.system(size: 14, weight: .semibold))
|
|
157
|
+
.font(RunicFont.system(size: 14, weight: .semibold))
|
|
158
158
|
|
|
159
159
|
Text(sessionDuration(from: context.state.sessionStartTime))
|
|
160
|
-
.font(.system(size: 12, weight: .medium))
|
|
160
|
+
.font(RunicFont.system(size: 12, weight: .medium))
|
|
161
161
|
.foregroundColor(.secondary)
|
|
162
162
|
}
|
|
163
163
|
}
|
|
@@ -166,10 +166,10 @@ struct RunicLiveActivity: Widget {
|
|
|
166
166
|
func expandedTrailing(context: ActivityViewContext<RunicLiveActivityAttributes>) -> some View {
|
|
167
167
|
VStack(alignment: .trailing, spacing: 4) {
|
|
168
168
|
Text("\(Int(context.state.remainingPercent))%")
|
|
169
|
-
.font(.system(size: 18, weight: .bold
|
|
169
|
+
.font(RunicFont.system(size: 18, weight: .bold))
|
|
170
170
|
|
|
171
171
|
Text("remaining")
|
|
172
|
-
.font(.system(size: 11, weight: .medium))
|
|
172
|
+
.font(RunicFont.system(size: 11, weight: .medium))
|
|
173
173
|
.foregroundColor(.secondary)
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -196,7 +196,7 @@ struct RunicLiveActivity: Widget {
|
|
|
196
196
|
if let cost = context.state.estimatedCost { statItem(icon: "dollarsign.circle", value: UsageFormatter.usdString(cost)) }
|
|
197
197
|
Spacer()
|
|
198
198
|
}
|
|
199
|
-
.font(.system(size: 11))
|
|
199
|
+
.font(RunicFont.system(size: 11))
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
@@ -210,7 +210,7 @@ struct RunicLiveActivity: Widget {
|
|
|
210
210
|
@ViewBuilder
|
|
211
211
|
func compactTrailing(context: ActivityViewContext<RunicLiveActivityAttributes>) -> some View {
|
|
212
212
|
Text("\(Int(context.state.remainingPercent))%")
|
|
213
|
-
.font(.system(size: 12, weight: .bold
|
|
213
|
+
.font(RunicFont.system(size: 12, weight: .bold))
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
@ViewBuilder
|
|
@@ -229,8 +229,8 @@ struct RunicLiveActivity: Widget {
|
|
|
229
229
|
("Complete", Color.blue, "checkmark.circle.fill")
|
|
230
230
|
|
|
231
231
|
return HStack(spacing: 4) {
|
|
232
|
-
Image(systemName: icon).font(.system(size: 10))
|
|
233
|
-
Text(text).font(.system(size: 11, weight: .semibold))
|
|
232
|
+
Image(systemName: icon).font(RunicFont.system(size: 10))
|
|
233
|
+
Text(text).font(RunicFont.system(size: 11, weight: .semibold))
|
|
234
234
|
}
|
|
235
235
|
.foregroundColor(color)
|
|
236
236
|
.padding(.horizontal, 8).padding(.vertical, 4)
|
|
@@ -240,8 +240,8 @@ struct RunicLiveActivity: Widget {
|
|
|
240
240
|
|
|
241
241
|
private func statItem(icon: String, value: String) -> some View {
|
|
242
242
|
HStack(spacing: 4) {
|
|
243
|
-
Image(systemName: icon).font(.system(size: 10)).foregroundColor(.secondary)
|
|
244
|
-
Text(value).font(.system(size: 11, weight: .medium))
|
|
243
|
+
Image(systemName: icon).font(RunicFont.system(size: 10)).foregroundColor(.secondary)
|
|
244
|
+
Text(value).font(RunicFont.system(size: 11, weight: .medium))
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
|
|
@@ -78,10 +78,10 @@ struct LockScreenCircularView: View {
|
|
|
78
78
|
// Center content
|
|
79
79
|
VStack(spacing: 1) {
|
|
80
80
|
Text("\(Int(provider.remainingPercent))")
|
|
81
|
-
.font(.system(size: 18, weight: .bold
|
|
81
|
+
.font(RunicFont.system(size: 18, weight: .bold))
|
|
82
82
|
|
|
83
83
|
Text("%")
|
|
84
|
-
.font(.system(size: 10, weight: .semibold))
|
|
84
|
+
.font(RunicFont.system(size: 10, weight: .semibold))
|
|
85
85
|
.opacity(0.8)
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -93,7 +93,7 @@ struct LockScreenCircularView: View {
|
|
|
93
93
|
.stroke(Color.white.opacity(0.2), lineWidth: 3)
|
|
94
94
|
|
|
95
95
|
Image(systemName: "exclamationmark.triangle")
|
|
96
|
-
.font(.system(size: 16))
|
|
96
|
+
.font(RunicFont.system(size: 16))
|
|
97
97
|
.opacity(0.5)
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -127,12 +127,12 @@ struct LockScreenRectangularView: View {
|
|
|
127
127
|
// Provider name and percentage
|
|
128
128
|
HStack {
|
|
129
129
|
Text(provider.displayName)
|
|
130
|
-
.font(.system(size: 13, weight: .semibold))
|
|
130
|
+
.font(RunicFont.system(size: 13, weight: .semibold))
|
|
131
131
|
|
|
132
132
|
Spacer()
|
|
133
133
|
|
|
134
134
|
Text("\(Int(provider.remainingPercent))%")
|
|
135
|
-
.font(.system(size: 13, weight: .bold
|
|
135
|
+
.font(RunicFont.system(size: 13, weight: .bold))
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// Progress bar
|
|
@@ -151,11 +151,11 @@ struct LockScreenRectangularView: View {
|
|
|
151
151
|
// Reset countdown
|
|
152
152
|
if let countdown = provider.resetCountdown {
|
|
153
153
|
Text("Resets \(countdown)")
|
|
154
|
-
.font(.system(size: 11, weight: .medium))
|
|
154
|
+
.font(RunicFont.system(size: 11, weight: .medium))
|
|
155
155
|
.opacity(0.7)
|
|
156
156
|
} else {
|
|
157
157
|
Text("Updated \(relativeTime(from: provider.updatedAt))")
|
|
158
|
-
.font(.system(size: 11, weight: .medium))
|
|
158
|
+
.font(RunicFont.system(size: 11, weight: .medium))
|
|
159
159
|
.opacity(0.7)
|
|
160
160
|
}
|
|
161
161
|
}
|
|
@@ -165,14 +165,14 @@ struct LockScreenRectangularView: View {
|
|
|
165
165
|
VStack(alignment: .leading, spacing: 4) {
|
|
166
166
|
HStack {
|
|
167
167
|
Image(systemName: "exclamationmark.triangle")
|
|
168
|
-
.font(.system(size: 12))
|
|
168
|
+
.font(RunicFont.system(size: 12))
|
|
169
169
|
|
|
170
170
|
Text("No Data")
|
|
171
|
-
.font(.system(size: 13, weight: .semibold))
|
|
171
|
+
.font(RunicFont.system(size: 13, weight: .semibold))
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
Text("Open Runic to sync")
|
|
175
|
-
.font(.system(size: 11))
|
|
175
|
+
.font(RunicFont.system(size: 11))
|
|
176
176
|
.opacity(0.6)
|
|
177
177
|
}
|
|
178
178
|
}
|
|
@@ -214,21 +214,21 @@ struct LockScreenInlineView: View {
|
|
|
214
214
|
if let provider = primaryProvider {
|
|
215
215
|
HStack(spacing: 4) {
|
|
216
216
|
Image(systemName: statusIcon(for: provider))
|
|
217
|
-
.font(.system(size: 12))
|
|
217
|
+
.font(RunicFont.system(size: 12))
|
|
218
218
|
|
|
219
219
|
Text("\(provider.displayName):")
|
|
220
|
-
.font(.system(size: 12, weight: .medium))
|
|
220
|
+
.font(RunicFont.system(size: 12, weight: .medium))
|
|
221
221
|
|
|
222
222
|
Text("\(Int(provider.remainingPercent))% left")
|
|
223
|
-
.font(.system(size: 12, weight: .semibold))
|
|
223
|
+
.font(RunicFont.system(size: 12, weight: .semibold))
|
|
224
224
|
}
|
|
225
225
|
} else {
|
|
226
226
|
HStack(spacing: 4) {
|
|
227
227
|
Image(systemName: "exclamationmark.triangle")
|
|
228
|
-
.font(.system(size: 12))
|
|
228
|
+
.font(RunicFont.system(size: 12))
|
|
229
229
|
|
|
230
230
|
Text("Runic: No data")
|
|
231
|
-
.font(.system(size: 12, weight: .medium))
|
|
231
|
+
.font(RunicFont.system(size: 12, weight: .medium))
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
}
|
|
@@ -80,18 +80,18 @@ struct MediumWidgetView: View {
|
|
|
80
80
|
HStack(spacing: 8) {
|
|
81
81
|
// Status icon
|
|
82
82
|
Image(systemName: entry.systemStatus.iconName)
|
|
83
|
-
.font(.system(size: 16, weight: .semibold))
|
|
83
|
+
.font(RunicFont.system(size: 16, weight: .semibold))
|
|
84
84
|
.foregroundColor(statusColor)
|
|
85
85
|
|
|
86
86
|
Text("Runic")
|
|
87
|
-
.font(.system(size: 16, weight: .bold))
|
|
87
|
+
.font(RunicFont.system(size: 16, weight: .bold))
|
|
88
88
|
.foregroundColor(.white)
|
|
89
89
|
|
|
90
90
|
Spacer()
|
|
91
91
|
|
|
92
92
|
// Provider count
|
|
93
93
|
Text("\(providers.count) active")
|
|
94
|
-
.font(.system(size: 12, weight: .medium))
|
|
94
|
+
.font(RunicFont.system(size: 12, weight: .medium))
|
|
95
95
|
.foregroundColor(.white.opacity(0.7))
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -110,18 +110,18 @@ struct MediumWidgetView: View {
|
|
|
110
110
|
.frame(width: 10, height: 10)
|
|
111
111
|
|
|
112
112
|
Text(provider.displayName)
|
|
113
|
-
.font(.system(size: 13, weight: .semibold))
|
|
113
|
+
.font(RunicFont.system(size: 13, weight: .semibold))
|
|
114
114
|
.foregroundColor(.white)
|
|
115
115
|
|
|
116
116
|
Spacer()
|
|
117
117
|
|
|
118
118
|
// Remaining percentage
|
|
119
119
|
Text("\(Int(provider.remainingPercent))%")
|
|
120
|
-
.font(.system(size: 15, weight: .bold
|
|
120
|
+
.font(RunicFont.system(size: 15, weight: .bold))
|
|
121
121
|
.foregroundColor(.white)
|
|
122
122
|
|
|
123
123
|
Text("left")
|
|
124
|
-
.font(.system(size: 11, weight: .medium))
|
|
124
|
+
.font(RunicFont.system(size: 11, weight: .medium))
|
|
125
125
|
.foregroundColor(.white.opacity(0.6))
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -144,7 +144,7 @@ struct MediumWidgetView: View {
|
|
|
144
144
|
if let countdown = provider.resetCountdown {
|
|
145
145
|
HStack {
|
|
146
146
|
Text("Resets \(countdown)")
|
|
147
|
-
.font(.system(size: 10, weight: .medium))
|
|
147
|
+
.font(RunicFont.system(size: 10, weight: .medium))
|
|
148
148
|
.foregroundColor(.white.opacity(0.5))
|
|
149
149
|
|
|
150
150
|
Spacer()
|
|
@@ -228,16 +228,16 @@ struct MediumWidgetView: View {
|
|
|
228
228
|
private var emptyStateView: some View {
|
|
229
229
|
HStack(spacing: 12) {
|
|
230
230
|
Image(systemName: "chart.bar.xaxis")
|
|
231
|
-
.font(.system(size: 28))
|
|
231
|
+
.font(RunicFont.system(size: 28))
|
|
232
232
|
.foregroundColor(.white.opacity(0.4))
|
|
233
233
|
|
|
234
234
|
VStack(alignment: .leading, spacing: 4) {
|
|
235
235
|
Text("No Providers Active")
|
|
236
|
-
.font(.system(size: 14, weight: .semibold))
|
|
236
|
+
.font(RunicFont.system(size: 14, weight: .semibold))
|
|
237
237
|
.foregroundColor(.white.opacity(0.7))
|
|
238
238
|
|
|
239
239
|
Text("Open Runic to enable providers")
|
|
240
|
-
.font(.system(size: 11))
|
|
240
|
+
.font(RunicFont.system(size: 11))
|
|
241
241
|
.foregroundColor(.white.opacity(0.5))
|
|
242
242
|
}
|
|
243
243
|
|
|
@@ -142,11 +142,11 @@ struct UsageProgressRing: View {
|
|
|
142
142
|
// Center content
|
|
143
143
|
VStack(spacing: size * 0.05) {
|
|
144
144
|
Text("\(Int(provider.remainingPercent))%")
|
|
145
|
-
.font(.system(size: size * 0.25, weight: .bold
|
|
145
|
+
.font(RunicFont.system(size: size * 0.25, weight: .bold))
|
|
146
146
|
.foregroundColor(.white)
|
|
147
147
|
|
|
148
148
|
Text("left")
|
|
149
|
-
.font(.system(size: size * 0.12, weight: .medium))
|
|
149
|
+
.font(RunicFont.system(size: size * 0.12, weight: .medium))
|
|
150
150
|
.foregroundColor(.white.opacity(0.7))
|
|
151
151
|
}
|
|
152
152
|
}
|
|
@@ -184,7 +184,7 @@ struct ProviderHeader: View {
|
|
|
184
184
|
.frame(width: iconSize, height: iconSize)
|
|
185
185
|
|
|
186
186
|
Text(provider.displayName)
|
|
187
|
-
.font(.system(size: iconSize * 0.8, weight: .semibold))
|
|
187
|
+
.font(RunicFont.system(size: iconSize * 0.8, weight: .semibold))
|
|
188
188
|
.foregroundColor(.white)
|
|
189
189
|
|
|
190
190
|
Spacer()
|
|
@@ -201,13 +201,13 @@ struct CompactUsageBar: View {
|
|
|
201
201
|
VStack(alignment: .leading, spacing: 4) {
|
|
202
202
|
HStack {
|
|
203
203
|
Text(provider.displayName)
|
|
204
|
-
.font(.system(size: 12, weight: .medium))
|
|
204
|
+
.font(RunicFont.system(size: 12, weight: .medium))
|
|
205
205
|
.foregroundColor(.white)
|
|
206
206
|
|
|
207
207
|
Spacer()
|
|
208
208
|
|
|
209
209
|
Text("\(Int(provider.remainingPercent))%")
|
|
210
|
-
.font(.system(size: 12, weight: .bold
|
|
210
|
+
.font(RunicFont.system(size: 12, weight: .bold))
|
|
211
211
|
.foregroundColor(.white)
|
|
212
212
|
}
|
|
213
213
|
|