@sriinnu/runic 2.0.0 → 2.11.2
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 +261 -0
- package/LICENSE +373 -21
- package/README.md +96 -89
- package/THIRD-PARTY-NOTICES.md +651 -0
- package/package.json +14 -4
- package/.swiftformat +0 -50
- package/.swiftlint.yml +0 -160
- package/CONTRIBUTING.md +0 -456
- package/Icon.icns +0 -0
- package/Icon.icon/Assets/runic.png +0 -0
- package/Icon.icon/icon.json +0 -36
- package/Package.resolved +0 -51
- package/Package.swift +0 -136
- package/Packages/Helix/LICENSE +0 -21
- package/Packages/Helix/Package.swift +0 -29
- package/Packages/Helix/README.md +0 -976
- package/Packages/Helix/Sources/Helix/Binding.swift +0 -111
- package/Packages/Helix/Sources/Helix/CommandParser.swift +0 -160
- package/Packages/Helix/Sources/Helix/CommandSignature.swift +0 -117
- package/Packages/Helix/Sources/Helix/ExpressibleFromArgument.swift +0 -72
- package/Packages/Helix/Sources/Helix/HelpGenerator.swift +0 -175
- package/Packages/Helix/Sources/Helix/NameSpecification.swift +0 -98
- package/Packages/Helix/Sources/Helix/ParsableCommand.swift +0 -204
- package/Packages/Helix/Sources/Helix/Platform/DarwinPlatformContext.swift +0 -44
- package/Packages/Helix/Sources/Helix/Platform/LinuxPlatformContext.swift +0 -34
- package/Packages/Helix/Sources/Helix/Platform/PlatformContext+Default.swift +0 -91
- package/Packages/Helix/Sources/Helix/Platform/PlatformContext.swift +0 -94
- package/Packages/Helix/Sources/Helix/Platform/PlatformPath.swift +0 -167
- package/Packages/Helix/Sources/Helix/Platform/Stdio.swift +0 -99
- package/Packages/Helix/Sources/Helix/Platform/WebPlatformContext.swift +0 -146
- package/Packages/Helix/Sources/Helix/Platform/WindowsPlatformContext.swift +0 -97
- package/Packages/Helix/Sources/Helix/Program.swift +0 -204
- package/Packages/Helix/Sources/Helix/PropertyWrappers.swift +0 -367
- package/Packages/Silo/LICENSE +0 -21
- package/Packages/Silo/Package.swift +0 -34
- package/Packages/Silo/README.md +0 -466
- package/Packages/Silo/Sources/Silo/BinaryCookiesReader.swift +0 -169
- package/Packages/Silo/Sources/Silo/BrowserCookieAnalytics.swift +0 -365
- package/Packages/Silo/Sources/Silo/BrowserCookieBackends.swift +0 -594
- package/Packages/Silo/Sources/Silo/BrowserCookieClient.swift +0 -326
- package/Packages/Silo/Sources/Silo/BrowserCookieExport.swift +0 -154
- package/Packages/Silo/Sources/Silo/BrowserCookieImport.swift +0 -119
- package/Packages/Silo/Sources/Silo/BrowserCookieMockStore.swift +0 -121
- package/Packages/Silo/Sources/Silo/BrowserCookieModels.swift +0 -391
- package/Packages/Silo/Sources/Silo/ChromiumCookieReader.swift +0 -240
- package/Packages/Silo/Sources/Silo/CryptoSupport.swift +0 -86
- package/Packages/Silo/Sources/Silo/FirefoxCookieReader.swift +0 -172
- package/Packages/Silo/Sources/Silo/LinuxChromiumCookieReader.swift +0 -172
- package/Packages/Silo/Sources/Silo/LinuxSecretService.swift +0 -105
- package/Packages/Silo/Sources/Silo/MacOSChromiumCookieReader.swift +0 -191
- package/Packages/Silo/Sources/Silo/SQLiteSnapshot.swift +0 -41
- package/Packages/Silo/Sources/Silo/WindowsChromiumCookieReader.swift +0 -110
- package/RuniciOS/App/RuniciOSApp.swift +0 -105
- package/RuniciOS/Core/RunicTypographyiOS.swift +0 -24
- package/RuniciOS/Core/iOSUsageStore.swift +0 -192
- package/RuniciOS/Views/ProviderDetailView.swift +0 -312
- package/RuniciOS/Views/ProviderListView.swift +0 -228
- package/RuniciOS/Widgets/LargeWidget.swift +0 -367
- package/RuniciOS/Widgets/LiveActivity.swift +0 -342
- package/RuniciOS/Widgets/LockScreenWidget.swift +0 -273
- package/RuniciOS/Widgets/MediumWidget.swift +0 -370
- package/RuniciOS/Widgets/RunicWidget.swift +0 -274
- package/RuniciOS/Widgets/SmallWidget.swift +0 -281
- package/RuniciOS/Widgets/WidgetModels.swift +0 -285
- package/RuniciOS/Widgets/WidgetTimeline.swift +0 -270
- package/Scripts/CREATION-SUMMARY.md +0 -367
- package/Scripts/DIRECTORY-STRUCTURE.md +0 -358
- package/Scripts/GETTING-STARTED-CHECKLIST.md +0 -364
- package/Scripts/INDEX.md +0 -365
- package/Scripts/QUICK-REFERENCE.md +0 -164
- package/Scripts/README-SCRIPTS.md +0 -926
- package/Scripts/build-android.sh +0 -526
- package/Scripts/build-ios.sh +0 -529
- package/Scripts/build-macos.sh +0 -603
- package/Scripts/build-windows.sh +0 -504
- package/Scripts/build_icon.sh +0 -49
- package/Scripts/changelog-to-html.sh +0 -89
- package/Scripts/check-release-assets.sh +0 -10
- package/Scripts/ci-config.yml +0 -474
- package/Scripts/compile_and_run.sh +0 -219
- package/Scripts/compile_and_run_adhoc.sh +0 -4
- package/Scripts/docs-list.mjs +0 -119
- package/Scripts/make_appcast.sh +0 -58
- package/Scripts/package_app.sh +0 -409
- package/Scripts/release-lib.sh +0 -214
- package/Scripts/release.sh +0 -76
- package/Scripts/setup-all.sh +0 -387
- package/Scripts/setup-ios.sh +0 -404
- package/Scripts/setup-react-native.sh +0 -523
- package/Scripts/sign-and-notarize.sh +0 -122
- package/Scripts/test_live_update.sh +0 -38
- package/Scripts/validate_changelog.sh +0 -23
- package/Scripts/verify_appcast.sh +0 -92
- package/Sources/Runic/About.swift +0 -93
- package/Sources/Runic/AppNotifications.swift +0 -117
- package/Sources/Runic/Controllers/StatusItemController+Actions.swift +0 -670
- package/Sources/Runic/Controllers/StatusItemController+Animation.swift +0 -519
- package/Sources/Runic/Controllers/StatusItemController+ChartSubmenus.swift +0 -824
- package/Sources/Runic/Controllers/StatusItemController+CustomProviders.swift +0 -90
- package/Sources/Runic/Controllers/StatusItemController+Menu.swift +0 -1412
- package/Sources/Runic/Controllers/StatusItemController+MenuCards.swift +0 -339
- package/Sources/Runic/Controllers/StatusItemController+MenuHelpers.swift +0 -423
- package/Sources/Runic/Controllers/StatusItemController.swift +0 -360
- package/Sources/Runic/Core/BudgetNotificationManager.swift +0 -81
- package/Sources/Runic/Core/Login/ClaudeLoginRunner.swift +0 -103
- package/Sources/Runic/Core/Login/CodexLoginRunner.swift +0 -154
- package/Sources/Runic/Core/Login/CursorLoginRunner.swift +0 -206
- package/Sources/Runic/Core/Login/GeminiLoginRunner.swift +0 -92
- package/Sources/Runic/Core/Rendering/IconRenderer.swift +0 -1222
- package/Sources/Runic/Core/Rendering/IconView.swift +0 -122
- package/Sources/Runic/Core/Rendering/ProviderBrandIcon.swift +0 -71
- package/Sources/Runic/Core/RunicAnimation.swift +0 -53
- package/Sources/Runic/Core/RunicColors.swift +0 -73
- package/Sources/Runic/Core/RunicCornerRadius.swift +0 -15
- package/Sources/Runic/Core/RunicSpacing.swift +0 -68
- package/Sources/Runic/Core/RunicTypography.swift +0 -206
- package/Sources/Runic/Core/Stores/AuggieTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/AzureOpenAITokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/CerebrasTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/CohereTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/CopilotTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/CustomProviderStore.swift +0 -158
- package/Sources/Runic/Core/Stores/DeepSeekTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/FireworksTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/GroqTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/KimiTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/MiniMaxCookieHeaderStore.swift +0 -117
- package/Sources/Runic/Core/Stores/MiniMaxGroupIDStore.swift +0 -117
- package/Sources/Runic/Core/Stores/MiniMaxTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/MistralTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/OpenRouterTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/PerplexityTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/ProviderToggleStore.swift +0 -30
- package/Sources/Runic/Core/Stores/QwenTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/SambaNovaTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/SettingsStore.swift +0 -1749
- package/Sources/Runic/Core/Stores/TogetherTokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/UsageStore+Accessors.swift +0 -33
- package/Sources/Runic/Core/Stores/UsageStore+Status.swift +0 -189
- package/Sources/Runic/Core/Stores/UsageStore+TokenCost.swift +0 -33
- package/Sources/Runic/Core/Stores/UsageStore+WidgetSnapshot.swift +0 -67
- package/Sources/Runic/Core/Stores/UsageStore.swift +0 -3631
- package/Sources/Runic/Core/Stores/XAITokenStore.swift +0 -117
- package/Sources/Runic/Core/Stores/ZaiTokenStore.swift +0 -117
- package/Sources/Runic/Core/UsageExporter.swift +0 -197
- package/Sources/Runic/Date+RelativeDescription.swift +0 -21
- package/Sources/Runic/HiddenWindowView.swift +0 -32
- package/Sources/Runic/InstallOrigin.swift +0 -9
- package/Sources/Runic/KeyboardShortcuts+Names.swift +0 -6
- package/Sources/Runic/MouseLocationReader.swift +0 -65
- package/Sources/Runic/Notifications+Runic.swift +0 -6
- package/Sources/Runic/OpenAICreditsPurchaseWindowController.swift +0 -503
- package/Sources/Runic/ProviderRegistry.swift +0 -100
- package/Sources/Runic/ProviderSwitcherButtons.swift +0 -267
- package/Sources/Runic/Providers/Antigravity/AntigravityLoginFlow.swift +0 -11
- package/Sources/Runic/Providers/Antigravity/AntigravityProviderImplementation.swift +0 -14
- package/Sources/Runic/Providers/Auggie/AuggieProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Azure/AzureProviderImplementation.swift +0 -52
- package/Sources/Runic/Providers/Bedrock/BedrockProviderImplementation.swift +0 -42
- package/Sources/Runic/Providers/Cerebras/CerebrasProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Claude/ClaudeLoginFlow.swift +0 -26
- package/Sources/Runic/Providers/Claude/ClaudeProviderImplementation.swift +0 -14
- package/Sources/Runic/Providers/Codex/CodexLoginFlow.swift +0 -18
- package/Sources/Runic/Providers/Codex/CodexProviderImplementation.swift +0 -15
- package/Sources/Runic/Providers/Cohere/CohereProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Copilot/CopilotLoginFlow.swift +0 -193
- package/Sources/Runic/Providers/Copilot/CopilotProviderImplementation.swift +0 -110
- package/Sources/Runic/Providers/Cursor/CursorLoginFlow.swift +0 -28
- package/Sources/Runic/Providers/Cursor/CursorProviderImplementation.swift +0 -15
- package/Sources/Runic/Providers/DeepSeek/DeepSeekProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Factory/FactoryLoginFlow.swift +0 -12
- package/Sources/Runic/Providers/Factory/FactoryProviderImplementation.swift +0 -15
- package/Sources/Runic/Providers/Fireworks/FireworksProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Gemini/GeminiLoginFlow.swift +0 -20
- package/Sources/Runic/Providers/Gemini/GeminiProviderImplementation.swift +0 -15
- package/Sources/Runic/Providers/Groq/GroqProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Kimi/KimiProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/MiniMax/MiniMaxProviderImplementation.swift +0 -32
- package/Sources/Runic/Providers/Mistral/MistralProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/OpenRouter/OpenRouterProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Perplexity/PerplexityProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/SambaNova/SambaNovaProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Shared/ProviderCatalog.swift +0 -15
- package/Sources/Runic/Providers/Shared/ProviderImplementation.swift +0 -51
- package/Sources/Runic/Providers/Shared/ProviderImplementationRegistry.swift +0 -66
- package/Sources/Runic/Providers/Shared/ProviderLoginFlow.swift +0 -12
- package/Sources/Runic/Providers/Shared/ProviderSettingsDescriptors.swift +0 -99
- package/Sources/Runic/Providers/Shared/SystemSettingsLinks.swift +0 -18
- package/Sources/Runic/Providers/Together/TogetherProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/XAI/XAIProviderImplementation.swift +0 -24
- package/Sources/Runic/Providers/Zai/ZaiProviderImplementation.swift +0 -24
- 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/Resources/ProviderIcon-antigravity.svg +0 -2
- package/Sources/Runic/Resources/ProviderIcon-auggie.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-azure.svg +0 -5
- package/Sources/Runic/Resources/ProviderIcon-bedrock.svg +0 -7
- package/Sources/Runic/Resources/ProviderIcon-cerebras.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-claude.svg +0 -1
- package/Sources/Runic/Resources/ProviderIcon-codex.svg +0 -1
- package/Sources/Runic/Resources/ProviderIcon-cohere.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-copilot.svg +0 -1
- package/Sources/Runic/Resources/ProviderIcon-cursor.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-deepseek.svg +0 -4
- package/Sources/Runic/Resources/ProviderIcon-factory.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-fireworks.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-gemini.svg +0 -1
- package/Sources/Runic/Resources/ProviderIcon-groq.svg +0 -1
- package/Sources/Runic/Resources/ProviderIcon-kimi.svg +0 -4
- package/Sources/Runic/Resources/ProviderIcon-minimax.svg +0 -1
- package/Sources/Runic/Resources/ProviderIcon-mistral.svg +0 -5
- package/Sources/Runic/Resources/ProviderIcon-openrouter.svg +0 -7
- package/Sources/Runic/Resources/ProviderIcon-perplexity.svg +0 -4
- package/Sources/Runic/Resources/ProviderIcon-qwen.svg +0 -9
- package/Sources/Runic/Resources/ProviderIcon-sambanova.svg +0 -4
- package/Sources/Runic/Resources/ProviderIcon-together.svg +0 -5
- package/Sources/Runic/Resources/ProviderIcon-vertexai.svg +0 -17
- package/Sources/Runic/Resources/ProviderIcon-xai.svg +0 -3
- package/Sources/Runic/Resources/ProviderIcon-zai.svg +0 -5
- package/Sources/Runic/Resources/RunicMenubarIcon.svg +0 -7
- package/Sources/Runic/Resources/provider-context-windows.json +0 -20
- package/Sources/Runic/RunicApp.swift +0 -367
- package/Sources/Runic/SessionQuotaNotifications.swift +0 -58
- package/Sources/Runic/UsagePaceText.swift +0 -52
- package/Sources/Runic/UsageProgressBar.swift +0 -228
- package/Sources/Runic/Utilities/DisplayLink.swift +0 -96
- package/Sources/Runic/Utilities/LoadingPattern.swift +0 -62
- package/Sources/Runic/Utilities/PerformanceConstants.swift +0 -85
- package/Sources/Runic/Views/Menu/AlertsMenuView.swift +0 -254
- package/Sources/Runic/Views/Menu/ChartPanelStyle.swift +0 -22
- package/Sources/Runic/Views/Menu/CostComparativeChartMenuView.swift +0 -275
- package/Sources/Runic/Views/Menu/CostHistoryChartMenuView.swift +0 -377
- package/Sources/Runic/Views/Menu/CreditsHistoryChartMenuView.swift +0 -312
- package/Sources/Runic/Views/Menu/EfficiencyMetricsMenuView.swift +0 -311
- package/Sources/Runic/Views/Menu/HeroStatCardsMenuView.swift +0 -231
- package/Sources/Runic/Views/Menu/HourlyActivityChartMenuView.swift +0 -228
- package/Sources/Runic/Views/Menu/InlineUsageChartView.swift +0 -157
- package/Sources/Runic/Views/Menu/MenuCardEntranceModifier.swift +0 -63
- package/Sources/Runic/Views/Menu/MenuCardSidebarView.swift +0 -248
- package/Sources/Runic/Views/Menu/MenuCardSkeletonView.swift +0 -104
- package/Sources/Runic/Views/Menu/MenuCardView.swift +0 -1889
- package/Sources/Runic/Views/Menu/MenuContent.swift +0 -153
- package/Sources/Runic/Views/Menu/MenuDescriptor.swift +0 -371
- package/Sources/Runic/Views/Menu/MenuHighlightStyle.swift +0 -35
- package/Sources/Runic/Views/Menu/ModelBreakdownMenuView.swift +0 -241
- package/Sources/Runic/Views/Menu/OverviewMenuView.swift +0 -281
- package/Sources/Runic/Views/Menu/ProjectBreakdownMenuView.swift +0 -214
- package/Sources/Runic/Views/Menu/ProjectBudgetMenuView.swift +0 -220
- package/Sources/Runic/Views/Menu/ProviderTabBarView.swift +0 -86
- package/Sources/Runic/Views/Menu/SubscriptionUtilizationChartMenuView.swift +0 -214
- package/Sources/Runic/Views/Menu/UsageBreakdownChartMenuView.swift +0 -398
- package/Sources/Runic/Views/Menu/UsageHeatmapMenuView.swift +0 -231
- package/Sources/Runic/Views/Menu/UsageTimelineChartMenuView.swift +0 -369
- package/Sources/Runic/Views/Menu/UsageWindowComparisonChartMenuView.swift +0 -191
- package/Sources/Runic/Views/Menu/WeeklyActivityChartMenuView.swift +0 -132
- package/Sources/Runic/Views/Performance/PerformanceDashboardView.swift +0 -621
- package/Sources/Runic/Views/Preferences/LiquidComponents.swift +0 -306
- package/Sources/Runic/Views/Preferences/PreferencesAboutPane.swift +0 -271
- package/Sources/Runic/Views/Preferences/PreferencesAdvancedPane.swift +0 -268
- package/Sources/Runic/Views/Preferences/PreferencesAlertsPane.swift +0 -418
- package/Sources/Runic/Views/Preferences/PreferencesAnalyticsPane.swift +0 -637
- package/Sources/Runic/Views/Preferences/PreferencesBudgetsPane.swift +0 -344
- package/Sources/Runic/Views/Preferences/PreferencesComponents.swift +0 -230
- package/Sources/Runic/Views/Preferences/PreferencesCustomProvidersPane.swift +0 -321
- package/Sources/Runic/Views/Preferences/PreferencesDebugPane.swift +0 -469
- package/Sources/Runic/Views/Preferences/PreferencesGeneralPane.swift +0 -250
- package/Sources/Runic/Views/Preferences/PreferencesHelpPane.swift +0 -50
- package/Sources/Runic/Views/Preferences/PreferencesIntegrationsPane.swift +0 -572
- package/Sources/Runic/Views/Preferences/PreferencesPerformancePane.swift +0 -291
- package/Sources/Runic/Views/Preferences/PreferencesProvidersPane.swift +0 -3480
- package/Sources/Runic/Views/Preferences/PreferencesSelection.swift +0 -29
- package/Sources/Runic/Views/Preferences/PreferencesSyncPane.swift +0 -61
- package/Sources/Runic/Views/Preferences/PreferencesView.swift +0 -213
- package/Sources/Runic/Views/Rating/QualityRatingView.swift +0 -238
- package/Sources/Runic/Views/Team/TeamDashboardView.swift +0 -376
- package/Sources/Runic/Views/Team/TeamInviteSheet.swift +0 -175
- package/Sources/Runic/Views/Team/TeamManagementView.swift +0 -762
- package/Sources/Runic/Views/Team/TeamMemberRow.swift +0 -181
- package/Sources/RunicCLI/CLIEntry.swift +0 -983
- package/Sources/RunicCLI/CLIRenderer.swift +0 -87
- package/Sources/RunicCLI/Commands/EnhancedUsageCommand.swift +0 -588
- package/Sources/RunicCLI/Commands/ModelsCommand.swift +0 -363
- package/Sources/RunicCLI/Commands/ProjectsCommand.swift +0 -453
- package/Sources/RunicCLI/Commands/ResetCommand.swift +0 -430
- package/Sources/RunicCLI/Commands/UsageLedgerSourceFactory.swift +0 -167
- package/Sources/RunicClaudeWatchdog/main.swift +0 -122
- package/Sources/RunicClaudeWebProbe/main.swift +0 -62
- package/Sources/RunicCore/AlertRuleStore.swift +0 -187
- package/Sources/RunicCore/BrowserCookieImportOrder.swift +0 -25
- package/Sources/RunicCore/CopilotUsageModels.swift +0 -84
- package/Sources/RunicCore/CostUsageFetcher.swift +0 -119
- package/Sources/RunicCore/CostUsageModels.swift +0 -479
- package/Sources/RunicCore/CreditsModels.swift +0 -50
- package/Sources/RunicCore/CustomProviders/CustomProviderModels.swift +0 -268
- package/Sources/RunicCore/CustomProviders/GenericProviderFetcher.swift +0 -631
- package/Sources/RunicCore/CustomProviders/ProviderTemplates.swift +0 -444
- package/Sources/RunicCore/Host/PTY/TTYCommandRunner.swift +0 -679
- package/Sources/RunicCore/Host/Process/SubprocessRunner.swift +0 -135
- package/Sources/RunicCore/Integrations/GitHubIntegration.swift +0 -173
- package/Sources/RunicCore/Logging/JSONStderrLogHandler.swift +0 -79
- package/Sources/RunicCore/Logging/OSLogLogHandler.swift +0 -86
- package/Sources/RunicCore/Logging/RunicLog.swift +0 -123
- package/Sources/RunicCore/Models/EnhancedUsageModels.swift +0 -370
- package/Sources/RunicCore/OpenAIDashboardModels.swift +0 -210
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardBrowserCookieImporter.swift +0 -676
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardFetcher.swift +0 -492
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardNavigationDelegate.swift +0 -51
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardParser.swift +0 -483
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardScrapeScript.swift +0 -558
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardWebViewCache.swift +0 -204
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardWebsiteDataStore.swift +0 -78
- package/Sources/RunicCore/PathEnvironment.swift +0 -482
- package/Sources/RunicCore/Performance/PerformanceModels.swift +0 -371
- package/Sources/RunicCore/Performance/PerformanceStorageImpl.swift +0 -426
- package/Sources/RunicCore/Policy/UsagePolicyEngine.swift +0 -178
- package/Sources/RunicCore/ProjectBudgetStore.swift +0 -102
- package/Sources/RunicCore/ProviderCostSnapshot.swift +0 -29
- package/Sources/RunicCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +0 -68
- package/Sources/RunicCore/Providers/Antigravity/AntigravityStatusProbe.swift +0 -685
- package/Sources/RunicCore/Providers/Auggie/AuggieProviderDescriptor.swift +0 -83
- package/Sources/RunicCore/Providers/Auggie/AuggieUsageFetcher.swift +0 -142
- package/Sources/RunicCore/Providers/Azure/AzureProviderDescriptor.swift +0 -141
- package/Sources/RunicCore/Providers/Azure/AzureUsageFetcher.swift +0 -188
- package/Sources/RunicCore/Providers/Bedrock/BedrockProviderDescriptor.swift +0 -126
- package/Sources/RunicCore/Providers/Bedrock/BedrockUsageFetcher.swift +0 -164
- package/Sources/RunicCore/Providers/Cerebras/CerebrasProviderDescriptor.swift +0 -84
- package/Sources/RunicCore/Providers/Cerebras/CerebrasUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/Claude/ClaudeCLISession.swift +0 -332
- package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthCredentials.swift +0 -180
- package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthUsageFetcher.swift +0 -137
- package/Sources/RunicCore/Providers/Claude/ClaudeProviderDescriptor.swift +0 -209
- package/Sources/RunicCore/Providers/Claude/ClaudeStatusProbe.swift +0 -654
- package/Sources/RunicCore/Providers/Claude/ClaudeUsageDataSource.swift +0 -30
- package/Sources/RunicCore/Providers/Claude/ClaudeUsageFetcher.swift +0 -480
- package/Sources/RunicCore/Providers/Claude/ClaudeWeb/ClaudeWebAPIFetcher.swift +0 -780
- package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthCredentials.swift +0 -147
- package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift +0 -280
- package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexTokenRefresher.swift +0 -100
- package/Sources/RunicCore/Providers/Codex/CodexProviderDescriptor.swift +0 -245
- package/Sources/RunicCore/Providers/Codex/CodexStatusProbe.swift +0 -125
- package/Sources/RunicCore/Providers/Codex/CodexUsageDataSource.swift +0 -26
- package/Sources/RunicCore/Providers/Codex/CodexWebDashboardStrategy.swift +0 -183
- package/Sources/RunicCore/Providers/Cohere/CohereProviderDescriptor.swift +0 -83
- package/Sources/RunicCore/Providers/Cohere/CohereUsageFetcher.swift +0 -85
- package/Sources/RunicCore/Providers/Copilot/CopilotDeviceFlow.swift +0 -123
- package/Sources/RunicCore/Providers/Copilot/CopilotGitHubCLITokenReader.swift +0 -117
- package/Sources/RunicCore/Providers/Copilot/CopilotProviderDescriptor.swift +0 -100
- package/Sources/RunicCore/Providers/Copilot/CopilotUsageFetcher.swift +0 -293
- package/Sources/RunicCore/Providers/Copilot/CopilotVSCodeTokenReader.swift +0 -385
- package/Sources/RunicCore/Providers/Cursor/CursorProviderDescriptor.swift +0 -67
- package/Sources/RunicCore/Providers/Cursor/CursorStatusProbe.swift +0 -595
- package/Sources/RunicCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift +0 -85
- package/Sources/RunicCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift +0 -108
- package/Sources/RunicCore/Providers/Factory/FactoryLocalStorageImporter.swift +0 -398
- package/Sources/RunicCore/Providers/Factory/FactoryProviderDescriptor.swift +0 -67
- package/Sources/RunicCore/Providers/Factory/FactoryStatusProbe.swift +0 -1276
- package/Sources/RunicCore/Providers/Fireworks/FireworksProviderDescriptor.swift +0 -84
- package/Sources/RunicCore/Providers/Fireworks/FireworksUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/Gemini/GeminiProviderDescriptor.swift +0 -67
- package/Sources/RunicCore/Providers/Gemini/GeminiStatusProbe.swift +0 -839
- package/Sources/RunicCore/Providers/Groq/GroqProviderDescriptor.swift +0 -83
- package/Sources/RunicCore/Providers/Groq/GroqUsageFetcher.swift +0 -71
- package/Sources/RunicCore/Providers/Kimi/KimiProviderDescriptor.swift +0 -83
- package/Sources/RunicCore/Providers/Kimi/KimiUsageFetcher.swift +0 -77
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxProviderDescriptor.swift +0 -97
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxSettingsReader.swift +0 -54
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxUsageFetcher.swift +0 -168
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxWebUsageFetcher.swift +0 -911
- package/Sources/RunicCore/Providers/Mistral/MistralProviderDescriptor.swift +0 -84
- package/Sources/RunicCore/Providers/Mistral/MistralUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift +0 -87
- package/Sources/RunicCore/Providers/OpenRouter/OpenRouterUsageFetcher.swift +0 -216
- package/Sources/RunicCore/Providers/Perplexity/PerplexityProviderDescriptor.swift +0 -84
- package/Sources/RunicCore/Providers/Perplexity/PerplexityUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/ProviderBranding.swift +0 -25
- package/Sources/RunicCore/Providers/ProviderCLIConfig.swift +0 -17
- package/Sources/RunicCore/Providers/ProviderDescriptor.swift +0 -129
- package/Sources/RunicCore/Providers/ProviderFetchPlan.swift +0 -263
- package/Sources/RunicCore/Providers/ProviderSettingsSnapshot.swift +0 -98
- package/Sources/RunicCore/Providers/ProviderTokenResolver.swift +0 -501
- package/Sources/RunicCore/Providers/ProviderVersionDetector.swift +0 -68
- package/Sources/RunicCore/Providers/Providers.swift +0 -184
- package/Sources/RunicCore/Providers/Qwen/QwenProviderDescriptor.swift +0 -86
- package/Sources/RunicCore/Providers/Qwen/QwenSettingsReader.swift +0 -30
- package/Sources/RunicCore/Providers/Qwen/QwenUsageStats.swift +0 -328
- package/Sources/RunicCore/Providers/SambaNova/SambaNovaProviderDescriptor.swift +0 -84
- package/Sources/RunicCore/Providers/SambaNova/SambaNovaUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/Together/TogetherProviderDescriptor.swift +0 -83
- package/Sources/RunicCore/Providers/Together/TogetherUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/VertexAI/VertexAIProviderDescriptor.swift +0 -123
- package/Sources/RunicCore/Providers/VertexAI/VertexAISettingsReader.swift +0 -48
- package/Sources/RunicCore/Providers/VertexAI/VertexAIUsageFetcher.swift +0 -144
- package/Sources/RunicCore/Providers/XAI/XAIProviderDescriptor.swift +0 -83
- package/Sources/RunicCore/Providers/XAI/XAIUsageFetcher.swift +0 -75
- package/Sources/RunicCore/Providers/Zai/ZaiProviderDescriptor.swift +0 -74
- package/Sources/RunicCore/Providers/Zai/ZaiSettingsReader.swift +0 -41
- package/Sources/RunicCore/Providers/Zai/ZaiUsageStats.swift +0 -745
- package/Sources/RunicCore/Sync/BackgroundSyncManager.swift +0 -384
- package/Sources/RunicCore/Sync/SyncConflictResolver.swift +0 -307
- package/Sources/RunicCore/Sync/SyncProtocol.swift +0 -287
- package/Sources/RunicCore/Sync/SyncRecord.swift +0 -402
- package/Sources/RunicCore/Sync/SyncUsageExample.swift +0 -288
- package/Sources/RunicCore/Sync/TeamSyncRecords.swift +0 -768
- package/Sources/RunicCore/Sync/iCloudSyncEngine.swift +0 -338
- package/Sources/RunicCore/Team/TeamModels.swift +0 -584
- package/Sources/RunicCore/Team/TeamShowbackExporter.swift +0 -495
- package/Sources/RunicCore/Team/TeamStore.swift +0 -809
- package/Sources/RunicCore/TextParsing.swift +0 -55
- package/Sources/RunicCore/UsageFetcher.swift +0 -694
- package/Sources/RunicCore/UsageFormatter.swift +0 -410
- package/Sources/RunicCore/UsageLedger/ClaudeUsageLogSource.swift +0 -441
- package/Sources/RunicCore/UsageLedger/CodexUsageLogSource.swift +0 -502
- package/Sources/RunicCore/UsageLedger/LedgerCache.swift +0 -161
- package/Sources/RunicCore/UsageLedger/OTelGenAILedgerAdapter.swift +0 -550
- package/Sources/RunicCore/UsageLedger/UsageLedger.swift +0 -29
- package/Sources/RunicCore/UsageLedger/UsageLedgerAggregator.swift +0 -675
- package/Sources/RunicCore/UsageLedger/UsageLedgerInsightsAdvisor.swift +0 -209
- package/Sources/RunicCore/UsageLedger/UsageLedgerModels.swift +0 -417
- package/Sources/RunicCore/UsageLedger/UsageLedgerProjectIdentity.swift +0 -284
- package/Sources/RunicCore/UsagePace.swift +0 -81
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageCache.swift +0 -73
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageJsonl.swift +0 -74
- package/Sources/RunicCore/Vendored/CostUsage/CostUsagePricing.swift +0 -208
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner+Claude.swift +0 -455
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner+Timestamp.swift +0 -132
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner.swift +0 -589
- package/Sources/RunicCore/WidgetSnapshot.swift +0 -183
- package/Sources/RunicMacroSupport/ProviderRegistrationMacros.swift +0 -14
- package/Sources/RunicMacros/ProviderRegistrationMacros.swift +0 -216
- package/Sources/RunicWidget/RunicWidgetBundle.swift +0 -79
- package/Sources/RunicWidget/RunicWidgetProvider.swift +0 -283
- package/Sources/RunicWidget/RunicWidgetViews.swift +0 -680
- package/Tests/RunicTests/AntigravityStatusProbeTests.swift +0 -50
- package/Tests/RunicTests/AppDelegateTests.swift +0 -48
- package/Tests/RunicTests/BrowserCookieOrderLabelTests.swift +0 -21
- package/Tests/RunicTests/CLIArgumentParsingTests.swift +0 -69
- package/Tests/RunicTests/CLICostTests.swift +0 -64
- package/Tests/RunicTests/CLIProviderSelectionTests.swift +0 -21
- package/Tests/RunicTests/CLISnapshotTests.swift +0 -71
- package/Tests/RunicTests/CLIWebFallbackTests.swift +0 -57
- package/Tests/RunicTests/ClaudeOAuthTests.swift +0 -163
- package/Tests/RunicTests/ClaudeResilienceTests.swift +0 -29
- package/Tests/RunicTests/ClaudeUsageTests.swift +0 -369
- package/Tests/RunicTests/CodexOAuthTests.swift +0 -121
- package/Tests/RunicTests/CodexUsageLogSourceTests.swift +0 -80
- package/Tests/RunicTests/CopilotTokenResolverTests.swift +0 -74
- package/Tests/RunicTests/CopilotVSCodeTokenReaderTests.swift +0 -74
- package/Tests/RunicTests/CostUsageDecodingTests.swift +0 -392
- package/Tests/RunicTests/CostUsagePricingTests.swift +0 -48
- package/Tests/RunicTests/CostUsageScannerTests.swift +0 -698
- package/Tests/RunicTests/CursorStatusProbeTests.swift +0 -322
- package/Tests/RunicTests/FactoryStatusProbeTests.swift +0 -67
- package/Tests/RunicTests/GeminiAPITestHelpers.swift +0 -94
- package/Tests/RunicTests/GeminiLoginAlertTests.swift +0 -27
- package/Tests/RunicTests/GeminiStatusProbeAPITests.swift +0 -283
- package/Tests/RunicTests/GeminiStatusProbePlanTests.swift +0 -279
- package/Tests/RunicTests/GeminiStatusProbeTests.swift +0 -232
- package/Tests/RunicTests/GeminiTestEnvironment.swift +0 -87
- package/Tests/RunicTests/GoogleWorkspaceStatusTests.swift +0 -72
- package/Tests/RunicTests/InstallOriginTests.swift +0 -17
- package/Tests/RunicTests/KeyboardShortcutsBundleTests.swift +0 -9
- package/Tests/RunicTests/LiveAccountTests.swift +0 -24
- package/Tests/RunicTests/LoadingPatternTests.swift +0 -34
- package/Tests/RunicTests/MenuCardModelTests.swift +0 -544
- package/Tests/RunicTests/MiniMaxCookieHeaderStoreTestSupport.swift +0 -11
- package/Tests/RunicTests/MiniMaxGroupIDStoreTestSupport.swift +0 -11
- package/Tests/RunicTests/MiniMaxParsingTests.swift +0 -67
- package/Tests/RunicTests/MiniMaxTokenStoreTestSupport.swift +0 -11
- package/Tests/RunicTests/OTelGenAILedgerAdapterTests.swift +0 -110
- package/Tests/RunicTests/OpenAIDashboardBrowserCookieImporterTests.swift +0 -16
- package/Tests/RunicTests/OpenAIDashboardFetcherCreditsWaitTests.swift +0 -74
- package/Tests/RunicTests/OpenAIDashboardOffscreenHostTests.swift +0 -26
- package/Tests/RunicTests/OpenAIDashboardParserTests.swift +0 -133
- package/Tests/RunicTests/OpenAIWebAccountSwitchTests.swift +0 -64
- package/Tests/RunicTests/OpenRouterTokenStoreTestSupport.swift +0 -131
- package/Tests/RunicTests/PathBuilderTests.swift +0 -236
- package/Tests/RunicTests/ProviderFetchPipelineTests.swift +0 -159
- package/Tests/RunicTests/ProviderIconResourcesTests.swift +0 -37
- package/Tests/RunicTests/ProviderMetadataStatusLinkTests.swift +0 -15
- package/Tests/RunicTests/ProviderRegistryTests.swift +0 -29
- package/Tests/RunicTests/ProviderSettingsDescriptorTests.swift +0 -236
- package/Tests/RunicTests/ProviderToggleStoreTests.swift +0 -50
- package/Tests/RunicTests/RunicTests.swift +0 -119
- package/Tests/RunicTests/SessionQuotaNotificationLogicTests.swift +0 -35
- package/Tests/RunicTests/SettingsStoreTests.swift +0 -265
- package/Tests/RunicTests/StatusItemAnimationTests.swift +0 -54
- package/Tests/RunicTests/StatusMenuTests.swift +0 -475
- package/Tests/RunicTests/StatusProbeTests.swift +0 -376
- package/Tests/RunicTests/SubprocessRunnerTests.swift +0 -18
- package/Tests/RunicTests/SubscriptionDetectionTests.swift +0 -64
- package/Tests/RunicTests/TTYCommandRunnerTests.swift +0 -147
- package/Tests/RunicTests/TTYIntegrationTests.swift +0 -41
- package/Tests/RunicTests/TeamShowbackExporterTests.swift +0 -157
- package/Tests/RunicTests/TextParsingTests.swift +0 -11
- package/Tests/RunicTests/UsageFormatterTests.swift +0 -111
- package/Tests/RunicTests/UsageLedgerAnomalyDetectionTests.swift +0 -170
- package/Tests/RunicTests/UsageLedgerForecastTests.swift +0 -211
- package/Tests/RunicTests/UsageLedgerInsightsAdvisorTests.swift +0 -81
- package/Tests/RunicTests/UsageLedgerProjectNameTests.swift +0 -168
- package/Tests/RunicTests/UsagePaceTests.swift +0 -76
- package/Tests/RunicTests/UsagePaceTextTests.swift +0 -108
- package/Tests/RunicTests/UsagePolicyEngineTests.swift +0 -89
- package/Tests/RunicTests/WidgetSnapshotTests.swift +0 -43
- package/Tests/RunicTests/ZaiProviderTests.swift +0 -59
- package/Tests/RunicTests/ZaiTokenStoreTestSupport.swift +0 -9
- package/TestsLinux/PlatformGatingTests.swift +0 -46
- package/appcast.xml +0 -104
- package/assets/logo-concept-stack.svg +0 -24
- package/assets/logo-minimal-bars.svg +0 -15
- package/assets/logo.svg +0 -20
- package/assets/logo2.svg +0 -43
- package/bin/docs-list +0 -5
- package/build-and-run.sh +0 -369
- package/docs/.nojekyll +0 -1
- package/docs/CNAME +0 -1
- package/docs/antigravity.md +0 -75
- package/docs/architecture.md +0 -32
- package/docs/claude.md +0 -93
- package/docs/cli-commands/integration_guide.md +0 -371
- package/docs/cli-commands/quick_reference.md +0 -362
- package/docs/cli-commands/readme.md +0 -361
- package/docs/cli.md +0 -156
- package/docs/cloudkit_sync_guide.md +0 -495
- package/docs/codebase_review.md +0 -288
- package/docs/codex-oauth.md +0 -635
- package/docs/codex.md +0 -104
- package/docs/codexbar.png +0 -0
- package/docs/copilot.md +0 -44
- package/docs/cursor.md +0 -46
- package/docs/design/designcomparisonchart.md +0 -510
- package/docs/design/implementationguide.md +0 -792
- package/docs/design/menubaricondesignconcepts.md +0 -796
- package/docs/design/mockups/hybridiconconcept.svg +0 -62
- package/docs/design/mockups/infinityiconconcept.svg +0 -41
- package/docs/design/mockups/infinityiconstates.svg +0 -129
- package/docs/design/mockups/wavelogorefined.svg +0 -48
- package/docs/design/quick_summary.md +0 -426
- package/docs/design/readme.md +0 -478
- package/docs/design/sizespecifications.md +0 -575
- package/docs/design-system.md +0 -836
- package/docs/factory.md +0 -103
- package/docs/gemini.md +0 -73
- package/docs/icon.md +0 -37
- package/docs/icon.png +0 -0
- package/docs/index.html +0 -175
- package/docs/keychain_fix.md +0 -274
- package/docs/minimax.md +0 -71
- package/docs/packaging.md +0 -25
- package/docs/progress-bar-improvements.md +0 -240
- package/docs/progress-bar-quick-reference.md +0 -283
- package/docs/progress-bar-technical-details.md +0 -432
- package/docs/progress-bar-visual-test.swift +0 -375
- package/docs/provider.md +0 -202
- package/docs/providers.md +0 -86
- package/docs/refactor/macros.md +0 -35
- package/docs/refresh-loop.md +0 -22
- package/docs/releasing-homebrew.md +0 -35
- package/docs/releasing.md +0 -121
- package/docs/research/concrete_todo_2026-02-22.md +0 -47
- package/docs/research/core-feature-research.md +0 -248
- package/docs/research/feature_uiux_roadmap_2026-02-22.md +0 -202
- package/docs/research/parity_matrix.md +0 -49
- package/docs/research/provider_expansion_candidates_2026-02-22.md +0 -80
- package/docs/research/provider_model_token_project_matrix_2026-02-23.md +0 -46
- package/docs/research/release_gate_checklist.md +0 -57
- package/docs/site.css +0 -505
- package/docs/sparkle.md +0 -28
- package/docs/status.md +0 -28
- package/docs/sync/implementation.md +0 -393
- package/docs/sync/readme.md +0 -317
- package/docs/sync_files_summary.md +0 -391
- package/docs/sync_quick_reference.md +0 -225
- package/docs/todo.md +0 -11
- package/docs/ui.md +0 -29
- package/docs/web-integration.md +0 -9
- package/docs/widgets.md +0 -85
- package/docs/workflows/error-handling-improvements.md +0 -434
- package/docs/workflows/folder_structure.md +0 -299
- package/docs/workflows/loading_states.md +0 -446
- package/docs/workflows/loading_states_examples.md +0 -565
- package/docs/workflows/loading_states_flow.md +0 -430
- package/docs/workflows/performance_optimizations.md +0 -457
- package/docs/workflows/phase1-cli-testing-report.md +0 -313
- package/docs/workflows/quick_reference.md +0 -228
- package/docs/workflows/readme.md +0 -59
- package/docs/workflows/recent_improvements.md +0 -275
- package/docs/workflows/sync_enablement_summary.md +0 -400
- package/docs/zai.md +0 -43
- package/runic.png +0 -0
- package/runic.svg +0 -15
- package/version.env +0 -2
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import RunicCore
|
|
2
|
-
import SwiftUI
|
|
3
|
-
|
|
4
|
-
@MainActor
|
|
5
|
-
struct IconView: View {
|
|
6
|
-
let snapshot: UsageSnapshot?
|
|
7
|
-
let creditsRemaining: Double?
|
|
8
|
-
let isStale: Bool
|
|
9
|
-
let showLoadingAnimation: Bool
|
|
10
|
-
let style: IconStyle
|
|
11
|
-
@State private var phase: CGFloat = 0
|
|
12
|
-
@State private var displayLink = DisplayLinkDriver()
|
|
13
|
-
@State private var pattern: LoadingPattern = .knightRider
|
|
14
|
-
@State private var debugCycle = false
|
|
15
|
-
@State private var cycleIndex = 0
|
|
16
|
-
@State private var cycleCounter = 0
|
|
17
|
-
private let loadingFPS: Double = 12
|
|
18
|
-
// Advance to next pattern every N ticks when debug cycling.
|
|
19
|
-
private let cycleIntervalTicks = 20
|
|
20
|
-
private let patterns = LoadingPattern.allCases
|
|
21
|
-
|
|
22
|
-
private var isLoading: Bool {
|
|
23
|
-
self.showLoadingAnimation && self.snapshot == nil
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
var body: some View {
|
|
27
|
-
Group {
|
|
28
|
-
if let snapshot {
|
|
29
|
-
Image(nsImage: IconRenderer.makeIcon(
|
|
30
|
-
primaryRemaining: snapshot.primary.remainingPercent,
|
|
31
|
-
weeklyRemaining: snapshot.secondary?.remainingPercent,
|
|
32
|
-
creditsRemaining: self.creditsRemaining,
|
|
33
|
-
stale: self.isStale,
|
|
34
|
-
style: self.style))
|
|
35
|
-
.renderingMode(.original)
|
|
36
|
-
.interpolation(.none)
|
|
37
|
-
.frame(width: 20, height: 18, alignment: .center)
|
|
38
|
-
.padding(.horizontal, RunicSpacing.xxxs)
|
|
39
|
-
} else if self.showLoadingAnimation {
|
|
40
|
-
// Loading: animate bars with the current pattern until data arrives.
|
|
41
|
-
Image(nsImage: self.loadingImage)
|
|
42
|
-
.renderingMode(.original)
|
|
43
|
-
.interpolation(.none)
|
|
44
|
-
.frame(width: 20, height: 18, alignment: .center)
|
|
45
|
-
.padding(.horizontal, RunicSpacing.xxxs)
|
|
46
|
-
.onChange(of: self.displayLink.tick) { _, _ in
|
|
47
|
-
self.phase += 0.09 // half-speed animation
|
|
48
|
-
if self.debugCycle {
|
|
49
|
-
self.cycleCounter += 1
|
|
50
|
-
if self.cycleCounter >= self.cycleIntervalTicks {
|
|
51
|
-
self.cycleCounter = 0
|
|
52
|
-
self.cycleIndex = (self.cycleIndex + 1) % self.patterns.count
|
|
53
|
-
self.pattern = self.patterns[self.cycleIndex]
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
// No animation when usage/account is unavailable; show empty tracks.
|
|
59
|
-
Image(nsImage: IconRenderer.makeIcon(
|
|
60
|
-
primaryRemaining: nil,
|
|
61
|
-
weeklyRemaining: nil,
|
|
62
|
-
creditsRemaining: self.creditsRemaining,
|
|
63
|
-
stale: self.isStale,
|
|
64
|
-
style: self.style))
|
|
65
|
-
.renderingMode(.original)
|
|
66
|
-
.interpolation(.none)
|
|
67
|
-
.frame(width: 20, height: 18, alignment: .center)
|
|
68
|
-
.padding(.horizontal, RunicSpacing.xxxs)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
.onChange(of: self.isLoading, initial: true) { _, isLoading in
|
|
72
|
-
if isLoading {
|
|
73
|
-
self.displayLink.start(fps: self.loadingFPS)
|
|
74
|
-
if !self.debugCycle {
|
|
75
|
-
self.pattern = self.patterns.randomElement() ?? .knightRider
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
78
|
-
self.displayLink.stop()
|
|
79
|
-
self.debugCycle = false
|
|
80
|
-
self.phase = 0
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
.onDisappear { self.displayLink.stop() }
|
|
84
|
-
.onReceive(NotificationCenter.default.publisher(for: .runicDebugReplayAllAnimations)) { notification in
|
|
85
|
-
if let raw = notification.userInfo?["pattern"] as? String,
|
|
86
|
-
let selected = LoadingPattern(rawValue: raw)
|
|
87
|
-
{
|
|
88
|
-
self.debugCycle = false
|
|
89
|
-
self.pattern = selected
|
|
90
|
-
self.cycleIndex = self.patterns.firstIndex(of: selected) ?? 0
|
|
91
|
-
} else {
|
|
92
|
-
self.debugCycle = true
|
|
93
|
-
self.cycleIndex = 0
|
|
94
|
-
self.pattern = self.patterns.first ?? .knightRider
|
|
95
|
-
}
|
|
96
|
-
self.cycleCounter = 0
|
|
97
|
-
self.phase = 0
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private var loadingPrimary: Double {
|
|
102
|
-
self.pattern.value(phase: Double(self.phase))
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private var loadingSecondary: Double {
|
|
106
|
-
self.pattern.value(phase: Double(self.phase + self.pattern.secondaryOffset))
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
private var loadingImage: NSImage {
|
|
110
|
-
if self.pattern == .unbraid {
|
|
111
|
-
let progress = self.loadingPrimary / 100
|
|
112
|
-
return IconRenderer.makeMorphIcon(progress: progress, style: self.style)
|
|
113
|
-
} else {
|
|
114
|
-
return IconRenderer.makeIcon(
|
|
115
|
-
primaryRemaining: self.loadingPrimary,
|
|
116
|
-
weeklyRemaining: self.loadingSecondary,
|
|
117
|
-
creditsRemaining: nil,
|
|
118
|
-
stale: false,
|
|
119
|
-
style: self.style)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import AppKit
|
|
2
|
-
import RunicCore
|
|
3
|
-
|
|
4
|
-
@MainActor
|
|
5
|
-
enum ProviderBrandIcon {
|
|
6
|
-
private static let cache = NSCache<NSString, NSImage>()
|
|
7
|
-
|
|
8
|
-
static func image(for provider: UsageProvider, size: CGFloat = 16) -> NSImage? {
|
|
9
|
-
let cacheSize = Int(size.rounded())
|
|
10
|
-
let key = "\(provider.rawValue)-\(cacheSize)" as NSString
|
|
11
|
-
if let cached = self.cache.object(forKey: key) {
|
|
12
|
-
return cached
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let baseName = ProviderDescriptorRegistry.descriptor(for: provider).branding.iconResourceName
|
|
16
|
-
guard let url = Bundle.main.url(forResource: baseName, withExtension: "svg"),
|
|
17
|
-
let image = NSImage(contentsOf: url)
|
|
18
|
-
else {
|
|
19
|
-
return nil
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let targetSize = NSSize(width: size, height: size)
|
|
23
|
-
image.size = targetSize
|
|
24
|
-
image.isTemplate = true
|
|
25
|
-
let tinted = self.tintedImage(image, color: self.brandColor(for: provider), size: targetSize)
|
|
26
|
-
self.cache.setObject(tinted, forKey: key)
|
|
27
|
-
return tinted
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static func templateImage(for provider: UsageProvider, size: CGFloat = 16) -> NSImage? {
|
|
31
|
-
let cacheSize = Int(size.rounded())
|
|
32
|
-
let key = "\(provider.rawValue)-\(cacheSize)-template" as NSString
|
|
33
|
-
if let cached = self.cache.object(forKey: key) {
|
|
34
|
-
return cached
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
let baseName = ProviderDescriptorRegistry.descriptor(for: provider).branding.iconResourceName
|
|
38
|
-
guard let url = Bundle.main.url(forResource: baseName, withExtension: "svg"),
|
|
39
|
-
let image = NSImage(contentsOf: url)
|
|
40
|
-
else {
|
|
41
|
-
return nil
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
image.size = NSSize(width: size, height: size)
|
|
45
|
-
image.isTemplate = true
|
|
46
|
-
self.cache.setObject(image, forKey: key)
|
|
47
|
-
return image
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private static func brandColor(for provider: UsageProvider) -> NSColor {
|
|
51
|
-
let color = ProviderDescriptorRegistry.descriptor(for: provider).branding.color
|
|
52
|
-
return NSColor(
|
|
53
|
-
calibratedRed: CGFloat(color.red),
|
|
54
|
-
green: CGFloat(color.green),
|
|
55
|
-
blue: CGFloat(color.blue),
|
|
56
|
-
alpha: 1)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private static func tintedImage(_ image: NSImage, color: NSColor, size: NSSize) -> NSImage {
|
|
60
|
-
let rect = NSRect(origin: .zero, size: size)
|
|
61
|
-
// Use drawingHandler instead of deprecated lockFocus/unlockFocus.
|
|
62
|
-
let tinted = NSImage(size: size, flipped: false) { _ in
|
|
63
|
-
color.setFill()
|
|
64
|
-
rect.fill()
|
|
65
|
-
image.draw(in: rect, from: .zero, operation: .destinationIn, fraction: 1.0)
|
|
66
|
-
return true
|
|
67
|
-
}
|
|
68
|
-
tinted.isTemplate = false
|
|
69
|
-
return tinted
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
/// Animation presets used across the Runic UI.
|
|
4
|
-
enum RunicAnimation {
|
|
5
|
-
// MARK: - Spring Presets
|
|
6
|
-
|
|
7
|
-
/// Standard appear animation for progress bars and chart elements.
|
|
8
|
-
static let barAppear: Animation = .spring(response: 0.6, dampingFraction: 0.75)
|
|
9
|
-
|
|
10
|
-
/// Value-change animation for progress bars.
|
|
11
|
-
static let barUpdate: Animation = .spring(response: 0.5, dampingFraction: 0.8)
|
|
12
|
-
|
|
13
|
-
/// Menu content fade when switching providers.
|
|
14
|
-
static let providerSwitch: Animation = .easeInOut(duration: 0.25)
|
|
15
|
-
|
|
16
|
-
/// Highlight state transitions on menu items.
|
|
17
|
-
static let highlight: Animation = .easeOut(duration: 0.12)
|
|
18
|
-
|
|
19
|
-
// MARK: - Transition Durations
|
|
20
|
-
|
|
21
|
-
/// Duration for sheen / gloss sweeps on progress bars.
|
|
22
|
-
static let sheenDuration: Double = 0.9
|
|
23
|
-
|
|
24
|
-
/// Delay before sheen resets after sweeping.
|
|
25
|
-
static let sheenResetDelay: Duration = .seconds(1.1)
|
|
26
|
-
|
|
27
|
-
/// Duration for copy-confirmation checkmark display.
|
|
28
|
-
static let copyFeedbackDuration: Duration = .seconds(0.9)
|
|
29
|
-
|
|
30
|
-
/// Fade-out duration for copy confirmation revert.
|
|
31
|
-
static let copyFeedbackFadeOut: Animation = .easeOut(duration: 0.2)
|
|
32
|
-
|
|
33
|
-
// MARK: - Skeleton / Loading
|
|
34
|
-
|
|
35
|
-
/// Continuous shimmer animation for loading skeletons.
|
|
36
|
-
static let shimmer: Animation = .easeInOut(duration: 1.5).repeatForever(autoreverses: false)
|
|
37
|
-
|
|
38
|
-
/// Subtle hover feedback on interactive elements.
|
|
39
|
-
static let hoverFeedback: Animation = .easeInOut(duration: 0.15)
|
|
40
|
-
|
|
41
|
-
// MARK: - Chart Interaction
|
|
42
|
-
|
|
43
|
-
/// Fade animation for chart interaction hints.
|
|
44
|
-
static let chartHintFade: Animation = .easeOut(duration: 0.4)
|
|
45
|
-
|
|
46
|
-
// MARK: - Menu Card Entrance
|
|
47
|
-
|
|
48
|
-
/// Staggered spring entrance for menu card sections.
|
|
49
|
-
static let cardEntrance: Animation = .spring(response: 0.45, dampingFraction: 0.82)
|
|
50
|
-
|
|
51
|
-
/// Base delay between staggered card section entrances.
|
|
52
|
-
static let cardEntranceStagger: Double = 0.06
|
|
53
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
/// Semantic color tokens for consistent theming across the Runic UI.
|
|
4
|
-
enum RunicColors {
|
|
5
|
-
// MARK: - Status Colors
|
|
6
|
-
|
|
7
|
-
static let success = Color(nsColor: .systemGreen)
|
|
8
|
-
static let warning = Color(nsColor: .systemOrange)
|
|
9
|
-
static let error = Color(nsColor: .systemRed)
|
|
10
|
-
static let info = Color(nsColor: .systemBlue)
|
|
11
|
-
|
|
12
|
-
// MARK: - Chart Palette (6 accessible colors)
|
|
13
|
-
|
|
14
|
-
/// Ordered palette for chart series. Colors chosen for distinguishability in
|
|
15
|
-
/// both light and dark mode and for common color-vision deficiencies.
|
|
16
|
-
static let chartPalette: [Color] = [
|
|
17
|
-
Color(red: 0.26, green: 0.55, blue: 0.96), // blue
|
|
18
|
-
Color(red: 0.94, green: 0.53, blue: 0.18), // orange
|
|
19
|
-
Color(red: 0.46, green: 0.75, blue: 0.36), // green
|
|
20
|
-
Color(red: 0.80, green: 0.45, blue: 0.92), // purple
|
|
21
|
-
Color(red: 0.26, green: 0.78, blue: 0.86), // teal
|
|
22
|
-
Color(red: 0.94, green: 0.74, blue: 0.26), // yellow
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
/// Returns a chart color for the given index, wrapping around if needed.
|
|
26
|
-
static func chartColor(at index: Int) -> Color {
|
|
27
|
-
self.chartPalette[index % self.chartPalette.count]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// MARK: - Model Family Colors
|
|
31
|
-
|
|
32
|
-
/// Color for Claude/Anthropic model family.
|
|
33
|
-
static let modelFamilyClaude = Color(red: 0.80, green: 0.45, blue: 0.30)
|
|
34
|
-
/// Color for GPT/OpenAI model family.
|
|
35
|
-
static let modelFamilyGPT = Color(red: 0.30, green: 0.70, blue: 0.40)
|
|
36
|
-
/// Color for Gemini/Google model family.
|
|
37
|
-
static let modelFamilyGemini = Color(red: 0.26, green: 0.55, blue: 0.96)
|
|
38
|
-
/// Default color for unknown model families.
|
|
39
|
-
static let modelFamilyDefault = Color(red: 0.55, green: 0.55, blue: 0.60)
|
|
40
|
-
|
|
41
|
-
/// Returns a color appropriate for the given model name based on its family.
|
|
42
|
-
static func colorForModel(_ model: String) -> Color {
|
|
43
|
-
let lower = model.lowercased()
|
|
44
|
-
if lower.contains("claude") || lower.contains("sonnet") || lower.contains("opus") || lower.contains("haiku") {
|
|
45
|
-
return self.modelFamilyClaude
|
|
46
|
-
}
|
|
47
|
-
if lower.contains("gpt") || lower.contains("o1") || lower.contains("o3") || lower.contains("o4") {
|
|
48
|
-
return self.modelFamilyGPT
|
|
49
|
-
}
|
|
50
|
-
if lower.contains("gemini") {
|
|
51
|
-
return self.modelFamilyGemini
|
|
52
|
-
}
|
|
53
|
-
return self.modelFamilyDefault
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// MARK: - Named Chart Colors
|
|
57
|
-
|
|
58
|
-
/// Credits history chart bar color
|
|
59
|
-
static let creditsChartBar = Color(red: 73 / 255, green: 163 / 255, blue: 176 / 255)
|
|
60
|
-
|
|
61
|
-
// MARK: - Opacity Tokens
|
|
62
|
-
|
|
63
|
-
enum Opacity {
|
|
64
|
-
static let nano: Double = 0.045
|
|
65
|
-
static let subtle: Double = 0.08
|
|
66
|
-
static let light: Double = 0.12
|
|
67
|
-
static let medium: Double = 0.22
|
|
68
|
-
static let strong: Double = 0.35
|
|
69
|
-
static let emphasis: Double = 0.55
|
|
70
|
-
static let prominent: Double = 0.70
|
|
71
|
-
static let vivid: Double = 0.90
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
|
|
3
|
-
/// Corner radius tokens replacing scattered literal values throughout the UI.
|
|
4
|
-
enum RunicCornerRadius {
|
|
5
|
-
/// 4pt — badges, small tags, inline controls
|
|
6
|
-
static let xs: CGFloat = 4
|
|
7
|
-
/// 6pt — list rows, compact cards, buttons
|
|
8
|
-
static let sm: CGFloat = 6
|
|
9
|
-
/// 8pt — standard cards, menu sections
|
|
10
|
-
static let md: CGFloat = 8
|
|
11
|
-
/// 12pt — prominent panels, avatar frames, provider cards
|
|
12
|
-
static let lg: CGFloat = 12
|
|
13
|
-
/// 16pt — large icons, about pane, hero elements
|
|
14
|
-
static let xl: CGFloat = 16
|
|
15
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
|
|
3
|
-
/// **Runic Spacing System**
|
|
4
|
-
/// Defines global spacing constants following a 4pt grid system.
|
|
5
|
-
/// All spacing values are multiples of 4 for consistent visual rhythm.
|
|
6
|
-
enum RunicSpacing {
|
|
7
|
-
// MARK: - Base Spacing Scale
|
|
8
|
-
|
|
9
|
-
/// Extra extra extra small spacing (2pt)
|
|
10
|
-
static let xxxs: CGFloat = 2
|
|
11
|
-
|
|
12
|
-
/// Extra extra small spacing (4pt)
|
|
13
|
-
static let xxs: CGFloat = 4
|
|
14
|
-
|
|
15
|
-
/// Extra small spacing (8pt)
|
|
16
|
-
static let xs: CGFloat = 8
|
|
17
|
-
|
|
18
|
-
/// Small spacing (12pt)
|
|
19
|
-
static let sm: CGFloat = 12
|
|
20
|
-
|
|
21
|
-
/// Medium spacing (16pt)
|
|
22
|
-
static let md: CGFloat = 16
|
|
23
|
-
|
|
24
|
-
/// Large spacing (24pt)
|
|
25
|
-
static let lg: CGFloat = 24
|
|
26
|
-
|
|
27
|
-
/// Extra large spacing (32pt)
|
|
28
|
-
static let xl: CGFloat = 32
|
|
29
|
-
|
|
30
|
-
/// Extra extra large spacing (48pt)
|
|
31
|
-
static let xxl: CGFloat = 48
|
|
32
|
-
|
|
33
|
-
// MARK: - Semantic Spacing
|
|
34
|
-
|
|
35
|
-
/// Horizontal padding for menu content
|
|
36
|
-
static let menuHorizontalPadding: CGFloat = sm // 12pt
|
|
37
|
-
|
|
38
|
-
/// Vertical padding for menu content
|
|
39
|
-
static let menuVerticalPadding: CGFloat = xs // 8pt
|
|
40
|
-
|
|
41
|
-
/// Spacing between cards in menu
|
|
42
|
-
static let cardSpacing: CGFloat = xs // 8pt
|
|
43
|
-
|
|
44
|
-
/// Spacing between major sections
|
|
45
|
-
static let sectionSpacing: CGFloat = lg // 24pt
|
|
46
|
-
|
|
47
|
-
// MARK: - Preferences Spacing
|
|
48
|
-
|
|
49
|
-
/// Compact spacing (6pt) - Used between sm and xs, common in preference toggles
|
|
50
|
-
static let compact: CGFloat = 6
|
|
51
|
-
|
|
52
|
-
/// Standardized spacing for toggle rows
|
|
53
|
-
static let toggleRowSpacing: CGFloat = xs // 8pt
|
|
54
|
-
|
|
55
|
-
/// Spacing after section headers
|
|
56
|
-
static let sectionHeaderSpacing: CGFloat = md // 16pt
|
|
57
|
-
|
|
58
|
-
/// Spacing within stepper controls
|
|
59
|
-
static let stepperControlSpacing: CGFloat = xs // 8pt
|
|
60
|
-
|
|
61
|
-
// MARK: - Chart Metrics
|
|
62
|
-
|
|
63
|
-
/// Standard height for chart views in menus
|
|
64
|
-
static let chartHeight: CGFloat = 130
|
|
65
|
-
|
|
66
|
-
/// Diameter for legend dot indicators
|
|
67
|
-
static let chartLegendDot: CGFloat = 7
|
|
68
|
-
}
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import CoreText
|
|
2
|
-
import SwiftUI
|
|
3
|
-
|
|
4
|
-
// MARK: - Typography tokens
|
|
5
|
-
|
|
6
|
-
/// App-wide font design token.
|
|
7
|
-
enum RunicTypography {
|
|
8
|
-
static let typeSize: DynamicTypeSize = .xLarge
|
|
9
|
-
|
|
10
|
-
/// Register all TTF/OTF fonts found in the app bundle's Fonts directory.
|
|
11
|
-
/// Call once at launch before any UI is created.
|
|
12
|
-
static func registerFonts() {
|
|
13
|
-
guard let fontsURL = Bundle.main.url(forResource: "Fonts", withExtension: nil)
|
|
14
|
-
?? Bundle.main.resourceURL?.appendingPathComponent("Fonts")
|
|
15
|
-
else { return }
|
|
16
|
-
guard let enumerator = FileManager.default.enumerator(
|
|
17
|
-
at: fontsURL,
|
|
18
|
-
includingPropertiesForKeys: nil,
|
|
19
|
-
options: [.skipsHiddenFiles])
|
|
20
|
-
else { return }
|
|
21
|
-
for case let fileURL as URL in enumerator
|
|
22
|
-
where fileURL.pathExtension.lowercased() == "ttf" || fileURL.pathExtension.lowercased() == "otf"
|
|
23
|
-
{
|
|
24
|
-
CTFontManagerRegisterFontsForURL(fileURL as CFURL, .process, nil)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/// Discover bundled font family names from the Fonts directory.
|
|
29
|
-
static func discoverBundledFontFamilies() -> [String] {
|
|
30
|
-
guard let fontsURL = Bundle.main.url(forResource: "Fonts", withExtension: nil)
|
|
31
|
-
?? Bundle.main.resourceURL?.appendingPathComponent("Fonts")
|
|
32
|
-
else { return [] }
|
|
33
|
-
guard let enumerator = FileManager.default.enumerator(
|
|
34
|
-
at: fontsURL,
|
|
35
|
-
includingPropertiesForKeys: nil,
|
|
36
|
-
options: [.skipsHiddenFiles])
|
|
37
|
-
else { return [] }
|
|
38
|
-
var families = Set<String>()
|
|
39
|
-
for case let fileURL as URL in enumerator
|
|
40
|
-
where fileURL.pathExtension.lowercased() == "ttf" || fileURL.pathExtension.lowercased() == "otf"
|
|
41
|
-
{
|
|
42
|
-
if let descriptors = CTFontManagerCreateFontDescriptorsFromURL(fileURL as CFURL) as? [CTFontDescriptor] {
|
|
43
|
-
for desc in descriptors {
|
|
44
|
-
if let name = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute) as? String {
|
|
45
|
-
families.insert(name)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return families.sorted()
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// MARK: - Available font choices
|
|
55
|
-
|
|
56
|
-
/// A selectable font option shown in preferences.
|
|
57
|
-
struct RunicFontChoice: Identifiable, Hashable {
|
|
58
|
-
let id: String
|
|
59
|
-
let displayName: String
|
|
60
|
-
|
|
61
|
-
/// System fonts — always available, no bundling.
|
|
62
|
-
static let sfPro = RunicFontChoice(id: "__sf_pro__", displayName: "SF Pro")
|
|
63
|
-
static let sfMono = RunicFontChoice(id: "__sf_mono__", displayName: "SF Mono")
|
|
64
|
-
|
|
65
|
-
/// Font used to render this choice's name in the picker (preview in its own typeface).
|
|
66
|
-
var previewFont: Font {
|
|
67
|
-
switch self.id {
|
|
68
|
-
case Self.sfPro.id: .system(.body)
|
|
69
|
-
case Self.sfMono.id: .system(.body, design: .monospaced)
|
|
70
|
-
default: Font.custom(self.id, fixedSize: 13)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/// Build the full list: system fonts first, then bundled custom fonts.
|
|
75
|
-
static func availableChoices() -> [RunicFontChoice] {
|
|
76
|
-
var choices: [RunicFontChoice] = [.sfPro, .sfMono]
|
|
77
|
-
for family in RunicTypography.discoverBundledFontFamilies() {
|
|
78
|
-
choices.append(RunicFontChoice(id: family, displayName: family))
|
|
79
|
-
}
|
|
80
|
-
return choices
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// MARK: - Dynamic SwiftUI Font Scale
|
|
85
|
-
|
|
86
|
-
@MainActor
|
|
87
|
-
enum RunicFont {
|
|
88
|
-
/// The active font family identifier. Updated from SettingsStore.
|
|
89
|
-
static var family: String = "Fira Code"
|
|
90
|
-
|
|
91
|
-
private static var isSystemFont: Bool {
|
|
92
|
-
family.hasPrefix("__")
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/// Font design used by `.runicTypography()` for system-font fallback.
|
|
96
|
-
static var systemFallbackDesign: Font.Design {
|
|
97
|
-
family == RunicFontChoice.sfPro.id ? .default : .monospaced
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// MARK: Semantic sizes
|
|
101
|
-
|
|
102
|
-
static var caption2: Font {
|
|
103
|
-
makeFont(size: 10, relativeTo: .caption2)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static var caption: Font {
|
|
107
|
-
makeFont(size: 11, relativeTo: .caption)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
static var footnote: Font {
|
|
111
|
-
makeFont(size: 12, relativeTo: .footnote)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
static var callout: Font {
|
|
115
|
-
makeFont(size: 13, relativeTo: .callout)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
static var body: Font {
|
|
119
|
-
makeFont(size: 13, relativeTo: .body)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
static var subheadline: Font {
|
|
123
|
-
makeFont(size: 12, relativeTo: .subheadline)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
static var headline: Font {
|
|
127
|
-
makeFont(size: 13, relativeTo: .headline).weight(.bold)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
static var title3: Font {
|
|
131
|
-
makeFont(size: 15, relativeTo: .title3)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
static var title2: Font {
|
|
135
|
-
makeFont(size: 17, relativeTo: .title2)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
static var title: Font {
|
|
139
|
-
makeFont(size: 22, relativeTo: .title)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
static var largeTitle: Font {
|
|
143
|
-
makeFont(size: 26, relativeTo: .largeTitle)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/// Custom fixed size.
|
|
147
|
-
static func system(size: CGFloat) -> Font {
|
|
148
|
-
switch self.family {
|
|
149
|
-
case RunicFontChoice.sfPro.id: .system(size: size)
|
|
150
|
-
case RunicFontChoice.sfMono.id: .system(size: size, design: .monospaced)
|
|
151
|
-
default: Font.custom(self.family, fixedSize: size)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/// Custom fixed size with weight.
|
|
156
|
-
static func system(size: CGFloat, weight: Font.Weight) -> Font {
|
|
157
|
-
switch self.family {
|
|
158
|
-
case RunicFontChoice.sfPro.id: .system(size: size, weight: weight)
|
|
159
|
-
case RunicFontChoice.sfMono.id: .system(size: size, weight: weight, design: .monospaced)
|
|
160
|
-
default: Font.custom(self.family, fixedSize: size).weight(weight)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// MARK: Private
|
|
165
|
-
|
|
166
|
-
private static func makeFont(size: CGFloat, relativeTo style: Font.TextStyle) -> Font {
|
|
167
|
-
switch self.family {
|
|
168
|
-
case RunicFontChoice.sfPro.id: .system(style)
|
|
169
|
-
case RunicFontChoice.sfMono.id: .system(style, design: .monospaced)
|
|
170
|
-
default: Font.custom(self.family, size: size, relativeTo: style)
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// MARK: - AppKit NSFont
|
|
176
|
-
|
|
177
|
-
extension RunicFont {
|
|
178
|
-
static func nsFont(size: CGFloat, weight: NSFont.Weight = .regular) -> NSFont {
|
|
179
|
-
switch self.family {
|
|
180
|
-
case RunicFontChoice.sfPro.id:
|
|
181
|
-
return .systemFont(ofSize: size, weight: weight)
|
|
182
|
-
case RunicFontChoice.sfMono.id:
|
|
183
|
-
return .monospacedSystemFont(ofSize: size, weight: weight)
|
|
184
|
-
default:
|
|
185
|
-
let traits: [NSFontDescriptor.TraitKey: Any] = [.weight: weight]
|
|
186
|
-
let descriptor = NSFontDescriptor(fontAttributes: [
|
|
187
|
-
.family: family,
|
|
188
|
-
.traits: traits,
|
|
189
|
-
])
|
|
190
|
-
return NSFont(descriptor: descriptor, size: size)
|
|
191
|
-
?? .monospacedSystemFont(ofSize: size, weight: weight)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// MARK: - View modifier
|
|
197
|
-
|
|
198
|
-
extension View {
|
|
199
|
-
/// Apply the selected font as the default, with system fallback design and xLarge dynamic type.
|
|
200
|
-
func runicTypography() -> some View {
|
|
201
|
-
self
|
|
202
|
-
.font(RunicFont.body)
|
|
203
|
-
.fontDesign(RunicFont.systemFallbackDesign)
|
|
204
|
-
.dynamicTypeSize(RunicTypography.typeSize)
|
|
205
|
-
}
|
|
206
|
-
}
|