@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
|
@@ -29,15 +29,20 @@ struct IntegrationsPane: View {
|
|
|
29
29
|
var isRunning: Bool
|
|
30
30
|
var port: Int
|
|
31
31
|
|
|
32
|
-
var statusIndicator: String {
|
|
33
|
-
|
|
32
|
+
var statusIndicator: String {
|
|
33
|
+
"●"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var statusColor: Color {
|
|
37
|
+
self.isRunning ? .green : .red
|
|
38
|
+
}
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
var body: some View {
|
|
37
42
|
PreferencesPane {
|
|
38
43
|
SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
|
|
39
44
|
Text("vaayu Integration")
|
|
40
|
-
.font(.caption)
|
|
45
|
+
.font(RunicFont.caption)
|
|
41
46
|
.foregroundStyle(.secondary)
|
|
42
47
|
.textCase(.uppercase)
|
|
43
48
|
|
|
@@ -50,11 +55,11 @@ struct IntegrationsPane: View {
|
|
|
50
55
|
|
|
51
56
|
if self.vaayuAPIServerEnabled {
|
|
52
57
|
Text("Running on port \(self.vaayuAPIServerPort)")
|
|
53
|
-
.font(.footnote)
|
|
58
|
+
.font(RunicFont.footnote)
|
|
54
59
|
.foregroundStyle(.green)
|
|
55
60
|
} else {
|
|
56
61
|
Text("Stopped")
|
|
57
|
-
.font(.footnote)
|
|
62
|
+
.font(RunicFont.footnote)
|
|
58
63
|
.foregroundStyle(.secondary)
|
|
59
64
|
}
|
|
60
65
|
}
|
|
@@ -62,21 +67,21 @@ struct IntegrationsPane: View {
|
|
|
62
67
|
if self.vaayuAPIServerEnabled {
|
|
63
68
|
VStack(alignment: .leading, spacing: 4) {
|
|
64
69
|
Text("Port number")
|
|
65
|
-
.font(.body)
|
|
70
|
+
.font(RunicFont.body)
|
|
66
71
|
|
|
67
72
|
TextField("Port", value: self.$vaayuAPIServerPort, format: .number)
|
|
68
73
|
.textFieldStyle(.roundedBorder)
|
|
69
74
|
.frame(maxWidth: 150)
|
|
70
75
|
|
|
71
76
|
Text("Default: 3000. Restart required after changing port.")
|
|
72
|
-
.font(.footnote)
|
|
77
|
+
.font(RunicFont.footnote)
|
|
73
78
|
.foregroundStyle(.tertiary)
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
VStack(alignment: .leading, spacing: 4) {
|
|
77
82
|
HStack {
|
|
78
83
|
Text("API Key")
|
|
79
|
-
.font(.body)
|
|
84
|
+
.font(RunicFont.body)
|
|
80
85
|
|
|
81
86
|
Spacer()
|
|
82
87
|
|
|
@@ -99,7 +104,7 @@ struct IntegrationsPane: View {
|
|
|
99
104
|
|
|
100
105
|
if !self.vaayuAPIKey.isEmpty {
|
|
101
106
|
Text(self.maskedAPIKey)
|
|
102
|
-
.font(.footnote.monospaced())
|
|
107
|
+
.font(RunicFont.footnote.monospaced())
|
|
103
108
|
.foregroundStyle(.secondary)
|
|
104
109
|
.padding(RunicSpacing.xs)
|
|
105
110
|
.background(Color(nsColor: .controlBackgroundColor))
|
|
@@ -108,14 +113,14 @@ struct IntegrationsPane: View {
|
|
|
108
113
|
|
|
109
114
|
if let generatedKey = self.generatedAPIKey {
|
|
110
115
|
Text("New key generated: \(generatedKey)")
|
|
111
|
-
.font(.footnote)
|
|
116
|
+
.font(RunicFont.footnote)
|
|
112
117
|
.foregroundStyle(.green)
|
|
113
118
|
}
|
|
114
119
|
}
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
Text("Exposes Runic usage data via REST API for external integrations.")
|
|
118
|
-
.font(.footnote)
|
|
123
|
+
.font(RunicFont.footnote)
|
|
119
124
|
.foregroundStyle(.tertiary)
|
|
120
125
|
}
|
|
121
126
|
}
|
|
@@ -124,14 +129,14 @@ struct IntegrationsPane: View {
|
|
|
124
129
|
|
|
125
130
|
SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
|
|
126
131
|
Text("MCP Servers")
|
|
127
|
-
.font(.caption)
|
|
132
|
+
.font(RunicFont.caption)
|
|
128
133
|
.foregroundStyle(.secondary)
|
|
129
134
|
.textCase(.uppercase)
|
|
130
135
|
|
|
131
136
|
VStack(spacing: RunicSpacing.xs) {
|
|
132
137
|
HStack {
|
|
133
138
|
Text("Configured servers")
|
|
134
|
-
.font(.body)
|
|
139
|
+
.font(RunicFont.body)
|
|
135
140
|
Spacer()
|
|
136
141
|
Button {
|
|
137
142
|
self.showingAddServerSheet = true
|
|
@@ -148,10 +153,10 @@ struct IntegrationsPane: View {
|
|
|
148
153
|
.font(.system(size: 32))
|
|
149
154
|
.foregroundStyle(.tertiary)
|
|
150
155
|
Text("No MCP servers yet")
|
|
151
|
-
.font(.body.weight(.semibold))
|
|
156
|
+
.font(RunicFont.body.weight(.semibold))
|
|
152
157
|
.foregroundStyle(.secondary)
|
|
153
158
|
Text("Add a server to manage connection details")
|
|
154
|
-
.font(.footnote)
|
|
159
|
+
.font(RunicFont.footnote)
|
|
155
160
|
.foregroundStyle(.tertiary)
|
|
156
161
|
}
|
|
157
162
|
.frame(maxWidth: .infinity)
|
|
@@ -161,13 +166,13 @@ struct IntegrationsPane: View {
|
|
|
161
166
|
HStack(spacing: RunicSpacing.sm) {
|
|
162
167
|
Text(server.statusIndicator)
|
|
163
168
|
.foregroundStyle(server.statusColor)
|
|
164
|
-
.font(.title3)
|
|
169
|
+
.font(RunicFont.title3)
|
|
165
170
|
|
|
166
171
|
VStack(alignment: .leading, spacing: RunicSpacing.xxs) {
|
|
167
172
|
Text(server.name)
|
|
168
|
-
.font(.body)
|
|
173
|
+
.font(RunicFont.body)
|
|
169
174
|
Text("Port \(server.port)")
|
|
170
|
-
.font(.footnote)
|
|
175
|
+
.font(RunicFont.footnote)
|
|
171
176
|
.foregroundStyle(.secondary)
|
|
172
177
|
}
|
|
173
178
|
|
|
@@ -206,7 +211,7 @@ struct IntegrationsPane: View {
|
|
|
206
211
|
}
|
|
207
212
|
|
|
208
213
|
Text("MCP servers enable Claude Desktop and other tools to access Runic data.")
|
|
209
|
-
.font(.footnote)
|
|
214
|
+
.font(RunicFont.footnote)
|
|
210
215
|
.foregroundStyle(.tertiary)
|
|
211
216
|
}
|
|
212
217
|
|
|
@@ -214,26 +219,26 @@ struct IntegrationsPane: View {
|
|
|
214
219
|
|
|
215
220
|
SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
|
|
216
221
|
Text("Webhooks")
|
|
217
|
-
.font(.caption)
|
|
222
|
+
.font(RunicFont.caption)
|
|
218
223
|
.foregroundStyle(.secondary)
|
|
219
224
|
.textCase(.uppercase)
|
|
220
225
|
|
|
221
226
|
VStack(alignment: .leading, spacing: RunicSpacing.sm) {
|
|
222
227
|
VStack(alignment: .leading, spacing: 4) {
|
|
223
228
|
Text("Default webhook URL")
|
|
224
|
-
.font(.body)
|
|
229
|
+
.font(RunicFont.body)
|
|
225
230
|
|
|
226
231
|
TextField("https://hooks.slack.com/services/...", text: self.$defaultWebhookURL)
|
|
227
232
|
.textFieldStyle(.roundedBorder)
|
|
228
233
|
|
|
229
234
|
Text("Used for all alerts unless overridden in alert rule settings.")
|
|
230
|
-
.font(.footnote)
|
|
235
|
+
.font(RunicFont.footnote)
|
|
231
236
|
.foregroundStyle(.tertiary)
|
|
232
237
|
}
|
|
233
238
|
|
|
234
239
|
VStack(alignment: .leading, spacing: 4) {
|
|
235
240
|
Text("Webhook format")
|
|
236
|
-
.font(.body)
|
|
241
|
+
.font(RunicFont.body)
|
|
237
242
|
|
|
238
243
|
Picker("", selection: self.$webhookFormat) {
|
|
239
244
|
Text("Slack").tag("slack")
|
|
@@ -244,7 +249,7 @@ struct IntegrationsPane: View {
|
|
|
244
249
|
.frame(maxWidth: 300)
|
|
245
250
|
|
|
246
251
|
Text("Formats webhook payloads for different platforms.")
|
|
247
|
-
.font(.footnote)
|
|
252
|
+
.font(RunicFont.footnote)
|
|
248
253
|
.foregroundStyle(.tertiary)
|
|
249
254
|
}
|
|
250
255
|
|
|
@@ -257,7 +262,7 @@ struct IntegrationsPane: View {
|
|
|
257
262
|
|
|
258
263
|
if let result = self.testWebhookResult {
|
|
259
264
|
Text(result)
|
|
260
|
-
.font(.footnote)
|
|
265
|
+
.font(RunicFont.footnote)
|
|
261
266
|
.foregroundStyle(result.contains("Success") ? .green : .red)
|
|
262
267
|
}
|
|
263
268
|
}
|
|
@@ -268,7 +273,7 @@ struct IntegrationsPane: View {
|
|
|
268
273
|
|
|
269
274
|
SettingsSection(contentSpacing: PreferencesLayoutMetrics.sectionSpacing) {
|
|
270
275
|
Text("GitHub Integration")
|
|
271
|
-
.font(.caption)
|
|
276
|
+
.font(RunicFont.caption)
|
|
272
277
|
.foregroundStyle(.secondary)
|
|
273
278
|
.textCase(.uppercase)
|
|
274
279
|
|
|
@@ -281,7 +286,7 @@ struct IntegrationsPane: View {
|
|
|
281
286
|
if self.githubIntegrationEnabled {
|
|
282
287
|
VStack(alignment: .leading, spacing: 4) {
|
|
283
288
|
Text("Repository path")
|
|
284
|
-
.font(.body)
|
|
289
|
+
.font(RunicFont.body)
|
|
285
290
|
|
|
286
291
|
HStack {
|
|
287
292
|
TextField("/path/to/repo", text: self.$githubRepositoryPath)
|
|
@@ -300,7 +305,7 @@ struct IntegrationsPane: View {
|
|
|
300
305
|
Image(systemName: "checkmark.circle.fill")
|
|
301
306
|
.foregroundStyle(.green)
|
|
302
307
|
Text("Valid Git repository")
|
|
303
|
-
.font(.footnote)
|
|
308
|
+
.font(RunicFont.footnote)
|
|
304
309
|
.foregroundStyle(.green)
|
|
305
310
|
}
|
|
306
311
|
} else {
|
|
@@ -308,7 +313,7 @@ struct IntegrationsPane: View {
|
|
|
308
313
|
Image(systemName: "xmark.circle.fill")
|
|
309
314
|
.foregroundStyle(.red)
|
|
310
315
|
Text("Not a valid Git repository")
|
|
311
|
-
.font(.footnote)
|
|
316
|
+
.font(RunicFont.footnote)
|
|
312
317
|
.foregroundStyle(.red)
|
|
313
318
|
}
|
|
314
319
|
}
|
|
@@ -479,11 +484,11 @@ private struct AddMCPServerSheet: View {
|
|
|
479
484
|
var body: some View {
|
|
480
485
|
VStack(alignment: .leading, spacing: RunicSpacing.lg) {
|
|
481
486
|
Text("Add MCP Server")
|
|
482
|
-
.font(.title2.weight(.semibold))
|
|
487
|
+
.font(RunicFont.title2.weight(.semibold))
|
|
483
488
|
|
|
484
489
|
VStack(alignment: .leading, spacing: RunicSpacing.xs) {
|
|
485
490
|
Text("Name")
|
|
486
|
-
.font(.subheadline.weight(.medium))
|
|
491
|
+
.font(RunicFont.subheadline.weight(.medium))
|
|
487
492
|
TextField("Local MCP Server", text: self.$name)
|
|
488
493
|
.textFieldStyle(.roundedBorder)
|
|
489
494
|
.focused(self.$isNameFocused)
|
|
@@ -491,7 +496,7 @@ private struct AddMCPServerSheet: View {
|
|
|
491
496
|
|
|
492
497
|
VStack(alignment: .leading, spacing: RunicSpacing.xs) {
|
|
493
498
|
Text("Port")
|
|
494
|
-
.font(.subheadline.weight(.medium))
|
|
499
|
+
.font(RunicFont.subheadline.weight(.medium))
|
|
495
500
|
TextField("", value: self.$port, format: .number)
|
|
496
501
|
.textFieldStyle(.roundedBorder)
|
|
497
502
|
.frame(width: 140)
|
|
@@ -523,8 +528,8 @@ private enum VaayuKeychainHelper {
|
|
|
523
528
|
var result: CFTypeRef?
|
|
524
529
|
let query: [String: Any] = [
|
|
525
530
|
kSecClass as String: kSecClassGenericPassword,
|
|
526
|
-
kSecAttrService as String: service,
|
|
527
|
-
kSecAttrAccount as String: account,
|
|
531
|
+
kSecAttrService as String: self.service,
|
|
532
|
+
kSecAttrAccount as String: self.account,
|
|
528
533
|
kSecMatchLimit as String: kSecMatchLimitOne,
|
|
529
534
|
kSecReturnData as String: true,
|
|
530
535
|
kSecUseAuthenticationUI as String: kSecUseAuthenticationUIFail,
|
|
@@ -542,12 +547,12 @@ private enum VaayuKeychainHelper {
|
|
|
542
547
|
|
|
543
548
|
@discardableResult
|
|
544
549
|
static func save(_ value: String) -> Bool {
|
|
545
|
-
delete()
|
|
550
|
+
self.delete()
|
|
546
551
|
let data = Data(value.utf8)
|
|
547
552
|
let query: [String: Any] = [
|
|
548
553
|
kSecClass as String: kSecClassGenericPassword,
|
|
549
|
-
kSecAttrService as String: service,
|
|
550
|
-
kSecAttrAccount as String: account,
|
|
554
|
+
kSecAttrService as String: self.service,
|
|
555
|
+
kSecAttrAccount as String: self.account,
|
|
551
556
|
kSecValueData as String: data,
|
|
552
557
|
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock,
|
|
553
558
|
]
|
|
@@ -558,8 +563,8 @@ private enum VaayuKeychainHelper {
|
|
|
558
563
|
static func delete() -> Bool {
|
|
559
564
|
let query: [String: Any] = [
|
|
560
565
|
kSecClass as String: kSecClassGenericPassword,
|
|
561
|
-
kSecAttrService as String: service,
|
|
562
|
-
kSecAttrAccount as String: account,
|
|
566
|
+
kSecAttrService as String: self.service,
|
|
567
|
+
kSecAttrAccount as String: self.account,
|
|
563
568
|
]
|
|
564
569
|
let status = SecItemDelete(query as CFDictionary)
|
|
565
570
|
return status == errSecSuccess || status == errSecItemNotFound
|
|
@@ -23,17 +23,19 @@ struct PerformancePane: View {
|
|
|
23
23
|
@State private var appeared = false
|
|
24
24
|
|
|
25
25
|
enum QualityRatingFrequency: String, CaseIterable, Identifiable {
|
|
26
|
-
case every
|
|
26
|
+
case every
|
|
27
27
|
case over1000 = "over_1000"
|
|
28
28
|
case over5000 = "over_5000"
|
|
29
29
|
|
|
30
|
-
var id: String {
|
|
30
|
+
var id: String {
|
|
31
|
+
self.rawValue
|
|
32
|
+
}
|
|
31
33
|
|
|
32
34
|
var label: String {
|
|
33
35
|
switch self {
|
|
34
|
-
case .every:
|
|
35
|
-
case .over1000:
|
|
36
|
-
case .over5000:
|
|
36
|
+
case .every: "After every response"
|
|
37
|
+
case .over1000: "Only >1000 tokens"
|
|
38
|
+
case .over5000: "Only >5000 tokens"
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -47,8 +49,9 @@ struct PerformancePane: View {
|
|
|
47
49
|
binding: self.$performanceTrackingEnabled)
|
|
48
50
|
|
|
49
51
|
if !self.performanceTrackingEnabled {
|
|
50
|
-
Text(
|
|
51
|
-
.
|
|
52
|
+
Text(
|
|
53
|
+
"Performance tracking is disabled. Historical data is preserved but new metrics won't be collected.")
|
|
54
|
+
.font(RunicFont.footnote)
|
|
52
55
|
.foregroundStyle(.orange)
|
|
53
56
|
.padding(.vertical, RunicSpacing.xs)
|
|
54
57
|
}
|
|
@@ -59,7 +62,7 @@ struct PerformancePane: View {
|
|
|
59
62
|
VStack(alignment: .leading, spacing: RunicSpacing.sm) {
|
|
60
63
|
VStack(alignment: .leading, spacing: 4) {
|
|
61
64
|
Text("Raw metrics retention")
|
|
62
|
-
.font(.body)
|
|
65
|
+
.font(RunicFont.body)
|
|
63
66
|
|
|
64
67
|
Picker("", selection: self.$rawMetricsRetentionDays) {
|
|
65
68
|
Text("30 days").tag(30)
|
|
@@ -70,13 +73,13 @@ struct PerformancePane: View {
|
|
|
70
73
|
.frame(maxWidth: 300)
|
|
71
74
|
|
|
72
75
|
Text("How long to keep detailed latency and error records.")
|
|
73
|
-
.font(.footnote)
|
|
76
|
+
.font(RunicFont.footnote)
|
|
74
77
|
.foregroundStyle(.tertiary)
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
VStack(alignment: .leading, spacing: 4) {
|
|
78
81
|
Text("Aggregated stats retention")
|
|
79
|
-
.font(.body)
|
|
82
|
+
.font(RunicFont.body)
|
|
80
83
|
|
|
81
84
|
Picker("", selection: self.$aggregatedStatsRetentionYears) {
|
|
82
85
|
Text("1 year").tag(1)
|
|
@@ -87,7 +90,7 @@ struct PerformancePane: View {
|
|
|
87
90
|
.frame(maxWidth: 300)
|
|
88
91
|
|
|
89
92
|
Text("How long to keep daily performance summaries.")
|
|
90
|
-
.font(.footnote)
|
|
93
|
+
.font(RunicFont.footnote)
|
|
91
94
|
.foregroundStyle(.tertiary)
|
|
92
95
|
}
|
|
93
96
|
}
|
|
@@ -104,7 +107,7 @@ struct PerformancePane: View {
|
|
|
104
107
|
if self.qualityRatingPromptsEnabled {
|
|
105
108
|
VStack(alignment: .leading, spacing: 4) {
|
|
106
109
|
Text("Prompt frequency")
|
|
107
|
-
.font(.body)
|
|
110
|
+
.font(RunicFont.body)
|
|
108
111
|
|
|
109
112
|
Picker("", selection: self.$qualityRatingFrequency) {
|
|
110
113
|
ForEach(QualityRatingFrequency.allCases) { freq in
|
|
@@ -115,7 +118,7 @@ struct PerformancePane: View {
|
|
|
115
118
|
.frame(maxWidth: 400)
|
|
116
119
|
|
|
117
120
|
Text("When to show rating prompts based on response size.")
|
|
118
|
-
.font(.footnote)
|
|
121
|
+
.font(RunicFont.footnote)
|
|
119
122
|
.foregroundStyle(.tertiary)
|
|
120
123
|
}
|
|
121
124
|
|
|
@@ -135,9 +138,9 @@ struct PerformancePane: View {
|
|
|
135
138
|
VStack(alignment: .leading, spacing: RunicSpacing.sm) {
|
|
136
139
|
HStack {
|
|
137
140
|
Text("Current database size:")
|
|
138
|
-
.font(.body)
|
|
141
|
+
.font(RunicFont.body)
|
|
139
142
|
Text(self.databaseSize)
|
|
140
|
-
.font(.body.weight(.semibold))
|
|
143
|
+
.font(RunicFont.body.weight(.semibold))
|
|
141
144
|
.foregroundStyle(.secondary)
|
|
142
145
|
}
|
|
143
146
|
|
|
@@ -157,13 +160,13 @@ struct PerformancePane: View {
|
|
|
157
160
|
|
|
158
161
|
if let status = self.vacuumStatus {
|
|
159
162
|
Text(status)
|
|
160
|
-
.font(.footnote)
|
|
163
|
+
.font(RunicFont.footnote)
|
|
161
164
|
.foregroundStyle(status.contains("Success") ? .green : .red)
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
Text("Optimizes database file by reclaiming unused space.")
|
|
166
|
-
.font(.footnote)
|
|
169
|
+
.font(RunicFont.footnote)
|
|
167
170
|
.foregroundStyle(.tertiary)
|
|
168
171
|
|
|
169
172
|
Divider()
|
|
@@ -185,13 +188,13 @@ struct PerformancePane: View {
|
|
|
185
188
|
|
|
186
189
|
if let status = self.clearDataStatus {
|
|
187
190
|
Text(status)
|
|
188
|
-
.font(.footnote)
|
|
191
|
+
.font(RunicFont.footnote)
|
|
189
192
|
.foregroundStyle(status.contains("Success") ? .green : .red)
|
|
190
193
|
}
|
|
191
194
|
}
|
|
192
195
|
|
|
193
196
|
Text("Removes metrics older than configured retention periods.")
|
|
194
|
-
.font(.footnote)
|
|
197
|
+
.font(RunicFont.footnote)
|
|
195
198
|
.foregroundStyle(.tertiary)
|
|
196
199
|
}
|
|
197
200
|
}
|
|
@@ -204,8 +207,9 @@ struct PerformancePane: View {
|
|
|
204
207
|
binding: self.$anonymousUsageStatsEnabled)
|
|
205
208
|
|
|
206
209
|
if self.anonymousUsageStatsEnabled {
|
|
207
|
-
Text(
|
|
208
|
-
.
|
|
210
|
+
Text(
|
|
211
|
+
"Only aggregate statistics are shared. Request IDs, prompts, and responses are never included.")
|
|
212
|
+
.font(RunicFont.footnote)
|
|
209
213
|
.foregroundStyle(.tertiary)
|
|
210
214
|
.padding(.vertical, RunicSpacing.xs)
|
|
211
215
|
}
|
|
@@ -223,8 +227,7 @@ struct PerformancePane: View {
|
|
|
223
227
|
Task {
|
|
224
228
|
let appSupport = FileManager.default.urls(
|
|
225
229
|
for: .applicationSupportDirectory,
|
|
226
|
-
in: .userDomainMask
|
|
227
|
-
).first!
|
|
230
|
+
in: .userDomainMask).first!
|
|
228
231
|
let dbPath = appSupport.appendingPathComponent("Runic/performance.db")
|
|
229
232
|
|
|
230
233
|
if let attributes = try? FileManager.default.attributesOfItem(atPath: dbPath.path),
|