@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
|
@@ -8,7 +8,7 @@ struct CerebrasModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum CerebrasUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.cerebras.ai/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> CerebrasModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension CerebrasModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum CerebrasAPIError: LocalizedError
|
|
60
|
+
enum CerebrasAPIError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -82,7 +82,7 @@ enum ClaudeOAuthUsageFetcher {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
struct OAuthUsageResponse: Decodable
|
|
85
|
+
struct OAuthUsageResponse: Decodable {
|
|
86
86
|
let fiveHour: OAuthUsageWindow?
|
|
87
87
|
let sevenDay: OAuthUsageWindow?
|
|
88
88
|
let sevenDayOAuthApps: OAuthUsageWindow?
|
|
@@ -102,7 +102,7 @@ struct OAuthUsageResponse: Decodable, Sendable {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
struct OAuthUsageWindow: Decodable
|
|
105
|
+
struct OAuthUsageWindow: Decodable {
|
|
106
106
|
let utilization: Double?
|
|
107
107
|
let resetsAt: String?
|
|
108
108
|
|
|
@@ -112,7 +112,7 @@ struct OAuthUsageWindow: Decodable, Sendable {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
struct OAuthExtraUsage: Decodable
|
|
115
|
+
struct OAuthExtraUsage: Decodable {
|
|
116
116
|
let isEnabled: Bool?
|
|
117
117
|
let monthlyLimit: Double?
|
|
118
118
|
let usedCredits: Double?
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -191,7 +191,9 @@ struct ClaudeCLIFetchStrategy: ProviderFetchStrategy {
|
|
|
191
191
|
let kind: ProviderFetchKind = .cli
|
|
192
192
|
let useWebExtras: Bool
|
|
193
193
|
|
|
194
|
-
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
194
|
+
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
195
|
+
true
|
|
196
|
+
}
|
|
195
197
|
|
|
196
198
|
func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
197
199
|
let fetcher = ClaudeUsageFetcher(dataSource: .cli, useWebExtras: self.useWebExtras)
|
|
@@ -326,7 +326,7 @@ public struct ClaudeStatusProbe: Sendable {
|
|
|
326
326
|
return nil
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
/// Collect remaining percentages in the order they appear; used as a backup when labels move/rename.
|
|
330
330
|
private static func allPercents(_ text: String) -> [Int] {
|
|
331
331
|
let pat = #"([0-9]{1,3})\p{Zs}*%\s*(left|used)"#
|
|
332
332
|
guard let regex = try? NSRegularExpression(pattern: pat, options: [.caseInsensitive]) else { return [] }
|
|
@@ -379,7 +379,7 @@ public struct ClaudeStatusProbe: Sendable {
|
|
|
379
379
|
.joined(separator: " ")
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
|
|
382
|
+
/// Capture all "Resets ..." strings to surface in the menu.
|
|
383
383
|
private static func allResets(_ text: String) -> [String] {
|
|
384
384
|
let pat = #"Resets[^\r\n]*"#
|
|
385
385
|
guard let regex = try? NSRegularExpression(pattern: pat, options: [.caseInsensitive]) else { return [] }
|
|
@@ -500,7 +500,7 @@ public struct ClaudeStatusProbe: Sendable {
|
|
|
500
500
|
return nil
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
-
|
|
503
|
+
/// Extract login/plan string from CLI output.
|
|
504
504
|
private static func extractLoginMethod(text: String) -> String? {
|
|
505
505
|
guard !text.isEmpty else { return nil }
|
|
506
506
|
if let explicit = self.extractFirst(pattern: #"(?i)login\s+method:\s*(.+)"#, text: text) {
|
|
@@ -627,7 +627,7 @@ public struct ClaudeStatusProbe: Sendable {
|
|
|
627
627
|
}
|
|
628
628
|
}
|
|
629
629
|
|
|
630
|
-
|
|
630
|
+
/// Run claude CLI inside a PTY so we can respond to interactive permission prompts.
|
|
631
631
|
private static func capture(subcommand: String, binary: String, timeout: TimeInterval) async throws -> String {
|
|
632
632
|
let stopOnSubstrings = subcommand == "/usage" ? ["Current session"] : []
|
|
633
633
|
do {
|
|
@@ -208,7 +208,7 @@ public enum CodexOAuthUsageFetcher {
|
|
|
208
208
|
private static func isAllowedHost(_ url: URL) -> Bool {
|
|
209
209
|
guard url.scheme?.lowercased() == "https" else { return false }
|
|
210
210
|
guard let host = url.host?.lowercased() else { return false }
|
|
211
|
-
return allowedHostSuffixes.contains { host == $0 || host.hasSuffix("." + $0) }
|
|
211
|
+
return self.allowedHostSuffixes.contains { host == $0 || host.hasSuffix("." + $0) }
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
private static func resolveChatGPTBaseURL(env: [String: String], configContents: String?) -> String {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -119,7 +119,9 @@ struct CodexCLIUsageStrategy: ProviderFetchStrategy {
|
|
|
119
119
|
let id: String = "codex.cli"
|
|
120
120
|
let kind: ProviderFetchKind = .cli
|
|
121
121
|
|
|
122
|
-
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
122
|
+
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
123
|
+
true
|
|
124
|
+
}
|
|
123
125
|
|
|
124
126
|
func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
125
127
|
let usage = try await context.fetcher.loadLatestUsage()
|
|
@@ -39,7 +39,7 @@ public struct CodexWebDashboardStrategy: ProviderFetchStrategy {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
private struct OpenAIWebCodexResult
|
|
42
|
+
private struct OpenAIWebCodexResult {
|
|
43
43
|
let usage: UsageSnapshot
|
|
44
44
|
let credits: CreditsSnapshot?
|
|
45
45
|
let dashboard: OpenAIDashboardSnapshot
|
|
@@ -56,7 +56,7 @@ private enum OpenAIWebCodexError: LocalizedError {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
private struct OpenAIWebOptions
|
|
59
|
+
private struct OpenAIWebOptions {
|
|
60
60
|
let timeout: TimeInterval
|
|
61
61
|
let debugDumpHTML: Bool
|
|
62
62
|
let verbose: Bool
|
|
@@ -168,7 +168,9 @@ public struct CodexWebDashboardStrategy: ProviderFetchStrategy {
|
|
|
168
168
|
|
|
169
169
|
public init() {}
|
|
170
170
|
|
|
171
|
-
public func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
171
|
+
public func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
172
|
+
false
|
|
173
|
+
}
|
|
172
174
|
|
|
173
175
|
public func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
174
176
|
throw ProviderFetchError.noAvailableStrategy(.codex)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct CohereAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum CohereSettingsError: LocalizedError
|
|
74
|
+
enum CohereSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -9,7 +9,7 @@ struct CohereModelsResponse: Decodable {
|
|
|
9
9
|
let name: String?
|
|
10
10
|
|
|
11
11
|
var modelID: String? {
|
|
12
|
-
let candidate = id ?? name
|
|
12
|
+
let candidate = self.id ?? self.name
|
|
13
13
|
guard let candidate else { return nil }
|
|
14
14
|
let trimmed = candidate.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
15
15
|
return trimmed.isEmpty ? nil : trimmed
|
|
@@ -17,7 +17,7 @@ struct CohereModelsResponse: Decodable {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
enum CohereUsageFetcher {
|
|
21
21
|
static let apiURL = URL(string: "https://api.cohere.ai/v1/models")!
|
|
22
22
|
|
|
23
23
|
static func fetchModels(apiKey: String) async throws -> CohereModelsResponse {
|
|
@@ -67,7 +67,7 @@ extension CohereModelsResponse {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
enum CohereAPIError: LocalizedError
|
|
70
|
+
enum CohereAPIError: LocalizedError {
|
|
71
71
|
case invalidResponse
|
|
72
72
|
case httpError(statusCode: Int, body: String?)
|
|
73
73
|
|
|
@@ -67,7 +67,7 @@ public enum CopilotGitHubCLITokenReader {
|
|
|
67
67
|
|
|
68
68
|
private static func isLikelyGitHubToken(_ token: String) -> Bool {
|
|
69
69
|
guard !token.isEmpty else { return false }
|
|
70
|
-
return tokenPrefixes.contains { token.hasPrefix($0) }
|
|
70
|
+
return self.tokenPrefixes.contains { token.hasPrefix($0) }
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
private static func candidateHostConfigPaths(environment: [String: String]) -> [URL] {
|
|
@@ -97,9 +97,12 @@ public enum CopilotGitHubCLITokenReader {
|
|
|
97
97
|
|
|
98
98
|
for home in homes {
|
|
99
99
|
let homeURL = URL(fileURLWithPath: home)
|
|
100
|
-
addCandidate(homeURL.appendingPathComponent(".config").appendingPathComponent("gh")
|
|
101
|
-
|
|
102
|
-
addCandidate(homeURL.appendingPathComponent("
|
|
100
|
+
addCandidate(homeURL.appendingPathComponent(".config").appendingPathComponent("gh")
|
|
101
|
+
.appendingPathComponent("hosts.yml"))
|
|
102
|
+
addCandidate(homeURL.appendingPathComponent("Library").appendingPathComponent("Application Support")
|
|
103
|
+
.appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
|
|
104
|
+
addCandidate(homeURL.appendingPathComponent(".local").appendingPathComponent("share")
|
|
105
|
+
.appendingPathComponent("gh").appendingPathComponent("hosts.yml"))
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
return candidates
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -85,11 +85,11 @@ struct CopilotAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
85
85
|
private static func sourceLabel(from source: ProviderTokenSource, sourceKey: String?) -> String {
|
|
86
86
|
switch source {
|
|
87
87
|
case .keychain:
|
|
88
|
-
|
|
88
|
+
sourceKey ?? "keychain"
|
|
89
89
|
case .environment:
|
|
90
|
-
|
|
90
|
+
sourceKey ?? "env"
|
|
91
91
|
case .vscode:
|
|
92
|
-
|
|
92
|
+
sourceKey ?? "vscode"
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -158,7 +158,8 @@ public struct CopilotUsageFetcher: Sendable {
|
|
|
158
158
|
guard httpResponse.statusCode == 200 else {
|
|
159
159
|
let body = self.errorSnippet(from: data)
|
|
160
160
|
if httpResponse.statusCode == 401 || httpResponse.statusCode == 403 {
|
|
161
|
-
throw CopilotUsageFetchError
|
|
161
|
+
throw CopilotUsageFetchError
|
|
162
|
+
.unauthorized(details: "token exchange HTTP \(httpResponse.statusCode). \(body)")
|
|
162
163
|
}
|
|
163
164
|
throw CopilotUsageFetchError.invalidResponse(
|
|
164
165
|
details: "token exchange HTTP \(httpResponse.statusCode). \(body)")
|
|
@@ -253,7 +254,9 @@ public struct CopilotUsageFetcher: Sendable {
|
|
|
253
254
|
.replacingOccurrences(of: "-", with: " ")
|
|
254
255
|
}
|
|
255
256
|
|
|
256
|
-
private func orderedQuotaSnapshots(_ snapshots: CopilotUsageResponse
|
|
257
|
+
private func orderedQuotaSnapshots(_ snapshots: CopilotUsageResponse
|
|
258
|
+
.QuotaSnapshots?) -> [CopilotUsageResponse.QuotaSnapshot]
|
|
259
|
+
{
|
|
257
260
|
guard let snapshots else { return [] }
|
|
258
261
|
let candidates = [snapshots.premiumInteractions, snapshots.completions, snapshots.chat]
|
|
259
262
|
var ordered: [CopilotUsageResponse.QuotaSnapshot] = []
|
|
@@ -287,5 +290,4 @@ public struct CopilotUsageFetcher: Sendable {
|
|
|
287
290
|
let end = text.index(text.startIndex, offsetBy: 220)
|
|
288
291
|
return "\(text[..<end])…"
|
|
289
292
|
}
|
|
290
|
-
|
|
291
293
|
}
|
|
@@ -10,7 +10,7 @@ import CryptoKit
|
|
|
10
10
|
#endif
|
|
11
11
|
|
|
12
12
|
public enum CopilotVSCodeTokenReader {
|
|
13
|
-
private struct VSCodeStoreCandidate
|
|
13
|
+
private struct VSCodeStoreCandidate {
|
|
14
14
|
let databaseURL: URL
|
|
15
15
|
let safeStorageService: String
|
|
16
16
|
}
|
|
@@ -36,9 +36,9 @@ public enum CopilotVSCodeTokenReader {
|
|
|
36
36
|
guard let password = self.readSafeStoragePassword(
|
|
37
37
|
service: candidate.safeStorageService,
|
|
38
38
|
allowUserInteraction: allowUserInteraction),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
let legacyKey = self.deriveLegacyKey(from: password),
|
|
40
|
+
let decryptedJSON = self.decryptSecretPayload(encryptedPayload, legacyKey: legacyKey),
|
|
41
|
+
let token = self.extractToken(fromDecryptedJSON: decryptedJSON)
|
|
42
42
|
else {
|
|
43
43
|
continue
|
|
44
44
|
}
|
|
@@ -217,14 +217,13 @@ public enum CopilotVSCodeTokenReader {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
private static func decryptSecretPayload(_ payload: Data, legacyKey: Data) -> String? {
|
|
220
|
-
let encryptedPayload: Data
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
prefix == "v10" || prefix == "v11"
|
|
220
|
+
let encryptedPayload: Data = if payload.count >= 3,
|
|
221
|
+
let prefix = String(data: payload.prefix(3), encoding: .utf8),
|
|
222
|
+
prefix == "v10" || prefix == "v11"
|
|
224
223
|
{
|
|
225
|
-
|
|
224
|
+
Data(payload.dropFirst(3))
|
|
226
225
|
} else {
|
|
227
|
-
|
|
226
|
+
payload
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
let iv = Data(repeating: 0x20, count: kCCBlockSizeAES128)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -49,7 +49,9 @@ struct CursorStatusFetchStrategy: ProviderFetchStrategy {
|
|
|
49
49
|
let id: String = "cursor.web"
|
|
50
50
|
let kind: ProviderFetchKind = .web
|
|
51
51
|
|
|
52
|
-
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
52
|
+
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
53
|
+
true
|
|
54
|
+
}
|
|
53
55
|
|
|
54
56
|
func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
55
57
|
let probe = CursorStatusProbe()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -72,7 +72,7 @@ struct DeepSeekAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
enum DeepSeekSettingsError: LocalizedError
|
|
75
|
+
enum DeepSeekSettingsError: LocalizedError {
|
|
76
76
|
case missingToken
|
|
77
77
|
|
|
78
78
|
var errorDescription: String? {
|
|
@@ -25,7 +25,7 @@ struct DeepSeekBalanceResponse: Decodable {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
enum DeepSeekUsageFetcher {
|
|
29
29
|
static let apiURL = URL(string: "https://api.deepseek.com/user/balance")!
|
|
30
30
|
|
|
31
31
|
static func fetchBalance(apiKey: String) async throws -> DeepSeekBalanceResponse {
|
|
@@ -90,7 +90,7 @@ extension DeepSeekBalanceResponse {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
enum DeepSeekAPIError: LocalizedError
|
|
93
|
+
enum DeepSeekAPIError: LocalizedError {
|
|
94
94
|
case invalidResponse
|
|
95
95
|
case httpError(statusCode: Int, body: String?)
|
|
96
96
|
|
|
@@ -5,7 +5,7 @@ import SQLite3
|
|
|
5
5
|
|
|
6
6
|
#if os(macOS)
|
|
7
7
|
enum FactoryLocalStorageImporter {
|
|
8
|
-
struct TokenInfo
|
|
8
|
+
struct TokenInfo {
|
|
9
9
|
let refreshToken: String
|
|
10
10
|
let accessToken: String?
|
|
11
11
|
let organizationID: String?
|
|
@@ -61,12 +61,12 @@ enum FactoryLocalStorageImporter {
|
|
|
61
61
|
|
|
62
62
|
// MARK: - Chrome local storage discovery
|
|
63
63
|
|
|
64
|
-
private enum LocalStorageSourceKind
|
|
64
|
+
private enum LocalStorageSourceKind {
|
|
65
65
|
case chromeLevelDB(URL)
|
|
66
66
|
case safariSQLite(URL)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
private struct LocalStorageCandidate
|
|
69
|
+
private struct LocalStorageCandidate {
|
|
70
70
|
let label: String
|
|
71
71
|
let kind: LocalStorageSourceKind
|
|
72
72
|
}
|
|
@@ -207,7 +207,7 @@ enum FactoryLocalStorageImporter {
|
|
|
207
207
|
|
|
208
208
|
// MARK: - Token extraction
|
|
209
209
|
|
|
210
|
-
private struct WorkOSTokenMatch
|
|
210
|
+
private struct WorkOSTokenMatch {
|
|
211
211
|
let refreshToken: String
|
|
212
212
|
let accessToken: String?
|
|
213
213
|
let organizationID: String?
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -49,7 +49,9 @@ struct FactoryStatusFetchStrategy: ProviderFetchStrategy {
|
|
|
49
49
|
let id: String = "factory.web"
|
|
50
50
|
let kind: ProviderFetchKind = .web
|
|
51
51
|
|
|
52
|
-
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
52
|
+
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
53
|
+
true
|
|
54
|
+
}
|
|
53
55
|
|
|
54
56
|
func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
55
57
|
let probe = FactoryStatusProbe()
|
|
@@ -536,7 +536,7 @@ public struct FactoryStatusProbe: Sendable {
|
|
|
536
536
|
"client_01HNM792M5G5G1A2THWPXKFMXB",
|
|
537
537
|
]
|
|
538
538
|
|
|
539
|
-
private struct WorkOSAuthResponse: Decodable
|
|
539
|
+
private struct WorkOSAuthResponse: Decodable {
|
|
540
540
|
let access_token: String
|
|
541
541
|
let refresh_token: String?
|
|
542
542
|
let organization_id: String?
|
|
@@ -578,7 +578,7 @@ public struct FactoryStatusProbe: Sendable {
|
|
|
578
578
|
throw FactoryStatusProbeError.noSessionCookie
|
|
579
579
|
}
|
|
580
580
|
|
|
581
|
-
private enum FetchAttemptResult
|
|
581
|
+
private enum FetchAttemptResult {
|
|
582
582
|
case success(FactoryStatusSnapshot)
|
|
583
583
|
case failure(Error)
|
|
584
584
|
case skipped
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct FireworksAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum FireworksSettingsError: LocalizedError
|
|
74
|
+
enum FireworksSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct FireworksModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum FireworksUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.fireworks.ai/inference/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> FireworksModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension FireworksModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum FireworksAPIError: LocalizedError
|
|
60
|
+
enum FireworksAPIError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -49,7 +49,9 @@ struct GeminiStatusFetchStrategy: ProviderFetchStrategy {
|
|
|
49
49
|
let id: String = "gemini.api"
|
|
50
50
|
let kind: ProviderFetchKind = .apiToken
|
|
51
51
|
|
|
52
|
-
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
52
|
+
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
53
|
+
true
|
|
54
|
+
}
|
|
53
55
|
|
|
54
56
|
func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
55
57
|
let probe = GeminiStatusProbe()
|
|
@@ -21,8 +21,11 @@ public struct GeminiStatusSnapshot: Sendable {
|
|
|
21
21
|
self.modelQuotas.min(by: { $0.percentLeft < $1.percentLeft })?.percentLeft
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
public var dailyPercentLeft: Double? {
|
|
24
|
+
/// Legacy compatibility
|
|
25
|
+
public var dailyPercentLeft: Double? {
|
|
26
|
+
self.lowestPercentLeft
|
|
27
|
+
}
|
|
28
|
+
|
|
26
29
|
public var resetDescription: String? {
|
|
27
30
|
self.modelQuotas.min(by: { $0.percentLeft < $1.percentLeft })?.resetDescription
|
|
28
31
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct GroqAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum GroqSettingsError: LocalizedError
|
|
74
|
+
enum GroqSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct GroqModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum GroqUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.groq.com/openai/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> GroqModelsResponse {
|
|
@@ -53,7 +53,7 @@ extension GroqModelsResponse {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
enum GroqAPIError: LocalizedError
|
|
56
|
+
enum GroqAPIError: LocalizedError {
|
|
57
57
|
case invalidResponse
|
|
58
58
|
case httpError(statusCode: Int)
|
|
59
59
|
case decodingError
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct KimiAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum KimiSettingsError: LocalizedError
|
|
74
|
+
enum KimiSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct KimiModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum KimiUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.moonshot.ai/v1/models")!
|
|
13
13
|
private static let requestTimeout: TimeInterval = 20
|
|
14
14
|
|
|
@@ -59,7 +59,7 @@ extension KimiModelsResponse {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
enum KimiAPIError: LocalizedError
|
|
62
|
+
enum KimiAPIError: LocalizedError {
|
|
63
63
|
case invalidResponse
|
|
64
64
|
case httpError(statusCode: Int, body: String?)
|
|
65
65
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -37,7 +37,10 @@ public enum MiniMaxProviderDescriptor {
|
|
|
37
37
|
noDataMessage: { "MiniMax cost summary is not supported." }),
|
|
38
38
|
fetchPlan: ProviderFetchPlan(
|
|
39
39
|
sourceModes: [.auto, .api, .web],
|
|
40
|
-
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [
|
|
40
|
+
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [
|
|
41
|
+
MiniMaxAPIFetchStrategy(),
|
|
42
|
+
MiniMaxWebFetchStrategy(),
|
|
43
|
+
] })),
|
|
41
44
|
cli: ProviderCLIConfig(
|
|
42
45
|
name: "minimax",
|
|
43
46
|
aliases: ["minimax-api"],
|
|
@@ -49,7 +52,9 @@ struct MiniMaxWebFetchStrategy: ProviderFetchStrategy {
|
|
|
49
52
|
let id: String = "minimax.web"
|
|
50
53
|
let kind: ProviderFetchKind = .web
|
|
51
54
|
|
|
52
|
-
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
55
|
+
func isAvailable(_: ProviderFetchContext) async -> Bool {
|
|
56
|
+
true
|
|
57
|
+
}
|
|
53
58
|
|
|
54
59
|
func fetch(_ context: ProviderFetchContext) async throws -> ProviderFetchResult {
|
|
55
60
|
let fetcher = MiniMaxWebUsageFetcher()
|
|
@@ -78,9 +83,9 @@ struct MiniMaxAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
78
83
|
guard let tokenRes = ProviderTokenResolver.minimaxApiKeyResolution(environment: context.env) else {
|
|
79
84
|
throw ProviderFetchError.missingCredentials
|
|
80
85
|
}
|
|
81
|
-
|
|
86
|
+
|
|
82
87
|
let snapshot = try await MiniMaxUsageFetcher.fetchUsage(apiKey: tokenRes.token)
|
|
83
|
-
|
|
88
|
+
|
|
84
89
|
return self.makeResult(
|
|
85
90
|
usage: snapshot.toUsageSnapshot(),
|
|
86
91
|
sourceLabel: "API")
|