@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
package/docs/cli.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
summary: "Runic CLI for fetching usage from the command line."
|
|
3
|
-
read_when:
|
|
4
|
-
- "You want to call Runic data from scripts or a terminal."
|
|
5
|
-
- "Adding or modifying Helix-based CLI commands."
|
|
6
|
-
- "Aligning menubar and CLI output/behavior."
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Runic CLI
|
|
10
|
-
|
|
11
|
-
A lightweight Helix-based CLI that mirrors the menubar app’s data paths (Codex web/RPC → PTY fallback; Claude web by default with CLI fallback and OAuth debug).
|
|
12
|
-
Use it when you need usage numbers in scripts, CI, or dashboards without UI.
|
|
13
|
-
|
|
14
|
-
## Install
|
|
15
|
-
- In the app: **Preferences → Advanced → Install CLI**. This symlinks `RunicCLI` to `/usr/local/bin/runic` and `/opt/homebrew/bin/runic`.
|
|
16
|
-
- From the repo: `./bin/install-runic-cli.sh` (same symlink targets).
|
|
17
|
-
- Manual: `ln -sf "/Applications/Runic.app/Contents/Helpers/RunicCLI" /usr/local/bin/runic`.
|
|
18
|
-
|
|
19
|
-
### Linux install
|
|
20
|
-
- Download `RunicCLI-<tag>-linux-<arch>.tar.gz` from GitHub Releases (x86_64 + aarch64).
|
|
21
|
-
- Extract; run `./runic` (symlink) or `./RunicCLI`.
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
tar -xzf RunicCLI-0.14.1-linux-x86_64.tar.gz
|
|
25
|
-
./runic --version
|
|
26
|
-
./runic usage --format json --pretty
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Build
|
|
30
|
-
- `./Scripts/package_app.sh` (or `./Scripts/compile_and_run.sh`) bundles `RunicCLI` into `Runic.app/Contents/Helpers/RunicCLI`.
|
|
31
|
-
- Standalone: `swift build -c release --product RunicCLI` (binary at `./.build/release/RunicCLI`).
|
|
32
|
-
- Dependencies: Swift 6.2+, Helix package (`https://github.com/sriinnu/Helix`).
|
|
33
|
-
|
|
34
|
-
## Command
|
|
35
|
-
- `runic` defaults to the `usage` command.
|
|
36
|
-
- `--format text|json` (default: text).
|
|
37
|
-
- `runic cost` prints local token cost usage (Claude + Codex) without web/CLI access.
|
|
38
|
-
- `--format text|json` (default: text).
|
|
39
|
-
- `--refresh` ignores cached scans.
|
|
40
|
-
- `--provider codex|claude|zai|gemini|antigravity|cursor|factory|copilot|both|all` (default: your in-app toggles; falls back to Codex).
|
|
41
|
-
- `--no-credits` (hide Codex credits in text output).
|
|
42
|
-
- `--pretty` (pretty-print JSON).
|
|
43
|
-
- `--status` (fetch provider status pages and include them in output).
|
|
44
|
-
- `--antigravity-plan-debug` (debug: print Antigravity planInfo fields to stderr).
|
|
45
|
-
- `--source <auto|web|cli|oauth>` (default: `auto`).
|
|
46
|
-
- `auto` (macOS only): uses browser cookies for Codex + Claude, with CLI fallback only when cookies are missing.
|
|
47
|
-
- `web` (macOS only): web-only; no CLI fallback.
|
|
48
|
-
- `cli`: CLI-only (Codex RPC → PTY fallback; Claude PTY).
|
|
49
|
-
- `oauth`: Claude OAuth only (debug); no fallback. Not supported for Codex.
|
|
50
|
-
- Output `source` reflects the strategy actually used (`openai-web`, `web`, `oauth`, `api`, `local`, or provider CLI label).
|
|
51
|
-
- Codex web: OpenAI web dashboard (usage limits, credits remaining, code review remaining, usage breakdown).
|
|
52
|
-
- `--web-timeout <seconds>` (default: 60)
|
|
53
|
-
- `--web-debug-dump-html` (writes HTML snapshots to `/tmp` when data is missing)
|
|
54
|
-
- Claude web: claude.ai API (session + weekly usage, plus account metadata when available).
|
|
55
|
-
- Linux: `web/auto` are not supported; CLI prints an error and exits non-zero.
|
|
56
|
-
- Global flags: `-h/--help`, `-V/--version`, `-v/--verbose`, `--no-color`, `--log-level <trace|verbose|debug|info|warning|error|critical>`, `--json-output`.
|
|
57
|
-
|
|
58
|
-
### Cost JSON payload
|
|
59
|
-
`runic cost --format json` emits an array of payloads (one per provider).
|
|
60
|
-
- `provider`, `source`, `updatedAt`
|
|
61
|
-
- `sessionTokens`, `sessionCostUSD`
|
|
62
|
-
- `last30DaysTokens`, `last30DaysCostUSD`
|
|
63
|
-
- `daily[]`: `date`, `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheCreationTokens`, `totalTokens`, `totalCost`, `modelsUsed`, `modelBreakdowns[]` (`modelName`, `cost`)
|
|
64
|
-
- `totals`: `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheCreationTokens`, `totalTokens`, `totalCost`
|
|
65
|
-
|
|
66
|
-
## Example usage
|
|
67
|
-
```
|
|
68
|
-
runic # text, respects app toggles
|
|
69
|
-
runic --provider claude # force Claude
|
|
70
|
-
runic --provider all # query all providers (honors your logins/toggles)
|
|
71
|
-
runic --format json --pretty # machine output
|
|
72
|
-
runic --format json --provider both
|
|
73
|
-
runic cost # local cost usage (last 30 days + today)
|
|
74
|
-
runic cost --provider claude --format json --pretty
|
|
75
|
-
COPILOT_API_TOKEN=... runic --provider copilot --format json --pretty
|
|
76
|
-
runic --status # include status page indicator/description
|
|
77
|
-
runic --provider codex --source web --format json --pretty
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Sample output (text)
|
|
81
|
-
```
|
|
82
|
-
Codex 0.6.0 (codex-cli)
|
|
83
|
-
Session: 72% left
|
|
84
|
-
Resets today at 2:15 PM
|
|
85
|
-
Weekly: 41% left
|
|
86
|
-
Resets Fri at 9:00 AM
|
|
87
|
-
Credits: 112.4 left
|
|
88
|
-
|
|
89
|
-
Claude Code 2.0.58 (web)
|
|
90
|
-
Session: 88% left
|
|
91
|
-
Resets tomorrow at 1:00 AM
|
|
92
|
-
Weekly: 63% left
|
|
93
|
-
Resets Sat at 6:00 AM
|
|
94
|
-
Sonnet: 95% left
|
|
95
|
-
Account: user@example.com
|
|
96
|
-
Plan: Pro
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Sample output (JSON, pretty)
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"provider": "codex",
|
|
103
|
-
"version": "0.6.0",
|
|
104
|
-
"source": "openai-web",
|
|
105
|
-
"status": { "indicator": "none", "description": "Operational", "updatedAt": "2025-12-04T17:55:00Z", "url": "https://status.openai.com/" },
|
|
106
|
-
"usage": {
|
|
107
|
-
"primary": { "usedPercent": 28, "windowMinutes": 300, "resetsAt": "2025-12-04T19:15:00Z" },
|
|
108
|
-
"secondary": { "usedPercent": 59, "windowMinutes": 10080, "resetsAt": "2025-12-05T17:00:00Z" },
|
|
109
|
-
"tertiary": null,
|
|
110
|
-
"updatedAt": "2025-12-04T18:10:22Z",
|
|
111
|
-
"identity": {
|
|
112
|
-
"providerID": "codex",
|
|
113
|
-
"accountEmail": "user@example.com",
|
|
114
|
-
"accountOrganization": null,
|
|
115
|
-
"loginMethod": "plus"
|
|
116
|
-
},
|
|
117
|
-
"accountEmail": "user@example.com",
|
|
118
|
-
"accountOrganization": null,
|
|
119
|
-
"loginMethod": "plus"
|
|
120
|
-
},
|
|
121
|
-
"credits": { "remaining": 112.4, "updatedAt": "2025-12-04T18:10:21Z" },
|
|
122
|
-
"antigravityPlanInfo": null,
|
|
123
|
-
"openaiDashboard": {
|
|
124
|
-
"signedInEmail": "user@example.com",
|
|
125
|
-
"codeReviewRemainingPercent": 100,
|
|
126
|
-
"creditEvents": [
|
|
127
|
-
{ "id": "00000000-0000-0000-0000-000000000000", "date": "2025-12-04T00:00:00Z", "service": "CLI", "creditsUsed": 123.45 }
|
|
128
|
-
],
|
|
129
|
-
"dailyBreakdown": [
|
|
130
|
-
{
|
|
131
|
-
"day": "2025-12-04",
|
|
132
|
-
"services": [{ "service": "CLI", "creditsUsed": 123.45 }],
|
|
133
|
-
"totalCreditsUsed": 123.45
|
|
134
|
-
}
|
|
135
|
-
],
|
|
136
|
-
"updatedAt": "2025-12-04T18:10:21Z"
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Exit codes
|
|
142
|
-
- 0: success
|
|
143
|
-
- 2: provider missing (binary not on PATH)
|
|
144
|
-
- 3: parse/format error
|
|
145
|
-
- 4: CLI timeout
|
|
146
|
-
- 1: unexpected failure
|
|
147
|
-
|
|
148
|
-
## Notes
|
|
149
|
-
- CLI reuses menubar toggles when present (prefers `com.sriinnu.athena.runic{,.debug}` defaults), otherwise defaults to Codex only.
|
|
150
|
-
- Text output uses ANSI colors when stdout is a rich TTY; disable with `--no-color` or `NO_COLOR`/`TERM=dumb`.
|
|
151
|
-
- Copilot CLI queries require `COPILOT_API_TOKEN` (GitHub OAuth token).
|
|
152
|
-
- Prefer Codex RPC first, then PTY fallback; Claude defaults to web with CLI fallback when cookies are missing.
|
|
153
|
-
- OpenAI web requires a signed-in `chatgpt.com` session in Safari, Chrome, or Firefox. No passwords are stored; Runic reuses cookies.
|
|
154
|
-
- Safari cookie import may require granting Runic Full Disk Access (System Settings → Privacy & Security → Full Disk Access).
|
|
155
|
-
- The `openaiDashboard` JSON field is normally sourced from the app’s cached dashboard snapshot; `--source auto|web` refreshes it live via WebKit using a per-account cookie store.
|
|
156
|
-
- Future: optional `--from-cache` flag to read the menubar app’s persisted snapshot (if/when that file lands).
|
|
@@ -1,495 +0,0 @@
|
|
|
1
|
-
# CloudKit Sync Integration Guide
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Runic now includes a complete iCloud CloudKit synchronization infrastructure that enables cross-device syncing of usage data, user preferences, and alert configurations. This guide explains how to enable and use the sync functionality.
|
|
6
|
-
|
|
7
|
-
## Architecture
|
|
8
|
-
|
|
9
|
-
The sync infrastructure consists of 6 main components:
|
|
10
|
-
|
|
11
|
-
### 1. **SyncProtocol.swift** - Core Protocol Definitions
|
|
12
|
-
Defines the fundamental protocols and types for synchronization:
|
|
13
|
-
- `SyncEngine` - Main protocol for sync operations (sync, push, fetch, delete)
|
|
14
|
-
- `SyncableRecord` - Protocol for objects that can be synchronized
|
|
15
|
-
- `SyncConflictResolverProtocol` - Protocol for conflict resolution
|
|
16
|
-
- `SyncObserver` - Protocol for observing sync events
|
|
17
|
-
- Supporting types: `SyncOptions`, `SyncResult`, `ConflictResolutionStrategy`, `SyncError`
|
|
18
|
-
|
|
19
|
-
### 2. **SyncRecord.swift** - CloudKit Record Types
|
|
20
|
-
Defines three syncable record types with CloudKit conversion:
|
|
21
|
-
- `UsageSnapshotSyncRecord` - Syncs usage data across devices
|
|
22
|
-
- `UserPreferencesSyncRecord` - Syncs user settings and preferences
|
|
23
|
-
- `AlertConfigurationSyncRecord` - Syncs alert thresholds and notification settings
|
|
24
|
-
- Includes encryption helpers for sensitive data (email addresses)
|
|
25
|
-
|
|
26
|
-
### 3. **iCloudSyncEngine.swift** - CloudKit Implementation
|
|
27
|
-
Actor-based CloudKit sync engine with:
|
|
28
|
-
- Bidirectional sync (push and fetch)
|
|
29
|
-
- Offline queue for pending operations
|
|
30
|
-
- Retry logic with exponential backoff
|
|
31
|
-
- Device identification for conflict resolution
|
|
32
|
-
- Support for incremental sync with change tokens
|
|
33
|
-
|
|
34
|
-
### 4. **SyncConflictResolver.swift** - Conflict Resolution
|
|
35
|
-
Implements multiple conflict resolution strategies:
|
|
36
|
-
- **Last-write-wins** - Most recently modified record wins (default)
|
|
37
|
-
- **Prefer local** - Always keep local version
|
|
38
|
-
- **Prefer remote** - Always keep remote version
|
|
39
|
-
- **Highest version** - Keep record with highest version number
|
|
40
|
-
- **Merge** - Custom merge logic per record type
|
|
41
|
-
- Tracks conflict statistics for diagnostics
|
|
42
|
-
|
|
43
|
-
### 5. **BackgroundSyncManager.swift** - Automatic Sync
|
|
44
|
-
Manages background synchronization with:
|
|
45
|
-
- Configurable sync intervals (active: 5 min, background: 1 hour)
|
|
46
|
-
- Lifecycle-aware sync (app launch, foreground, background)
|
|
47
|
-
- Observer pattern for sync status notifications
|
|
48
|
-
- Sync history and statistics tracking
|
|
49
|
-
- iOS background task support
|
|
50
|
-
|
|
51
|
-
### 6. **SyncUsageExample.swift** - Integration Examples
|
|
52
|
-
Contains comprehensive examples of:
|
|
53
|
-
- Basic setup and configuration
|
|
54
|
-
- Syncing different record types
|
|
55
|
-
- Manual vs automatic sync
|
|
56
|
-
- Custom conflict resolution
|
|
57
|
-
- Observer pattern usage
|
|
58
|
-
- Error handling
|
|
59
|
-
- Statistics and monitoring
|
|
60
|
-
|
|
61
|
-
## CloudKit Record Types
|
|
62
|
-
|
|
63
|
-
The sync engine uses three CloudKit record types that must be configured in your iCloud container:
|
|
64
|
-
|
|
65
|
-
### 1. UsageSnapshot
|
|
66
|
-
```
|
|
67
|
-
Record Type: UsageSnapshot
|
|
68
|
-
Fields:
|
|
69
|
-
- version: Int64
|
|
70
|
-
- modifiedAt: Date/Time
|
|
71
|
-
- lastModifiedDeviceID: String (optional)
|
|
72
|
-
- providerID: String
|
|
73
|
-
- primaryUsed: Int64
|
|
74
|
-
- primaryLimit: Int64 (optional)
|
|
75
|
-
- secondaryUsed: Int64 (optional)
|
|
76
|
-
- secondaryLimit: Int64 (optional)
|
|
77
|
-
- costUSD: Double (optional)
|
|
78
|
-
- accountEmail: String (encrypted, optional)
|
|
79
|
-
- updatedAt: Date/Time
|
|
80
|
-
- deviceName: String
|
|
81
|
-
- platform: String
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### 2. UserPreferences
|
|
85
|
-
```
|
|
86
|
-
Record Type: UserPreferences
|
|
87
|
-
Fields:
|
|
88
|
-
- version: Int64
|
|
89
|
-
- modifiedAt: Date/Time
|
|
90
|
-
- lastModifiedDeviceID: String (optional)
|
|
91
|
-
- refreshInterval: Double
|
|
92
|
-
- enabledProviders: List<String>
|
|
93
|
-
- notificationsEnabled: Int64 (0 or 1)
|
|
94
|
-
- autoRefreshEnabled: Int64 (0 or 1)
|
|
95
|
-
- theme: String
|
|
96
|
-
- displayFormat: String
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### 3. AlertConfiguration
|
|
100
|
-
```
|
|
101
|
-
Record Type: AlertConfiguration
|
|
102
|
-
Fields:
|
|
103
|
-
- version: Int64
|
|
104
|
-
- modifiedAt: Date/Time
|
|
105
|
-
- lastModifiedDeviceID: String (optional)
|
|
106
|
-
- providerID: String
|
|
107
|
-
- warningThreshold: Double
|
|
108
|
-
- criticalThreshold: Double
|
|
109
|
-
- notificationChannels: List<String>
|
|
110
|
-
- enabled: Int64 (0 or 1)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Enabling CloudKit
|
|
114
|
-
|
|
115
|
-
### 1. Add CloudKit Capability
|
|
116
|
-
|
|
117
|
-
You need to add CloudKit capability to your app. This requires an entitlements file:
|
|
118
|
-
|
|
119
|
-
**Create `Runic.entitlements`:**
|
|
120
|
-
```xml
|
|
121
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
122
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
123
|
-
<plist version="1.0">
|
|
124
|
-
<dict>
|
|
125
|
-
<key>com.apple.developer.icloud-container-identifiers</key>
|
|
126
|
-
<array>
|
|
127
|
-
<string>iCloud.com.yourcompany.runic</string>
|
|
128
|
-
</array>
|
|
129
|
-
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
|
|
130
|
-
<string>$(TeamIdentifierPrefix)com.yourcompany.runic</string>
|
|
131
|
-
<key>com.apple.developer.icloud-services</key>
|
|
132
|
-
<array>
|
|
133
|
-
<string>CloudKit</string>
|
|
134
|
-
</array>
|
|
135
|
-
</dict>
|
|
136
|
-
</plist>
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### 2. Configure CloudKit Container
|
|
140
|
-
|
|
141
|
-
1. Sign in to [Apple Developer](https://developer.apple.com)
|
|
142
|
-
2. Go to Certificates, Identifiers & Profiles
|
|
143
|
-
3. Select your App ID
|
|
144
|
-
4. Enable iCloud capability
|
|
145
|
-
5. Create or select a CloudKit container (e.g., `iCloud.com.yourcompany.runic`)
|
|
146
|
-
|
|
147
|
-
### 3. Create CloudKit Schema
|
|
148
|
-
|
|
149
|
-
In the CloudKit Dashboard:
|
|
150
|
-
|
|
151
|
-
1. Go to [CloudKit Console](https://icloud.developer.apple.com)
|
|
152
|
-
2. Select your container
|
|
153
|
-
3. Create the three record types listed above
|
|
154
|
-
4. Set appropriate indexes and security settings:
|
|
155
|
-
- **Security**: Set all record types to "Readable and writable by the creator"
|
|
156
|
-
- **Indexes**: Add indexes on `modifiedAt` for efficient querying
|
|
157
|
-
|
|
158
|
-
### 4. Update Package.swift (Already Done)
|
|
159
|
-
|
|
160
|
-
The Sync directory exclusion has been removed from Package.swift, enabling the sync infrastructure.
|
|
161
|
-
|
|
162
|
-
## Integration Steps
|
|
163
|
-
|
|
164
|
-
### 1. Basic Setup
|
|
165
|
-
|
|
166
|
-
```swift
|
|
167
|
-
import RunicCore
|
|
168
|
-
|
|
169
|
-
// Initialize sync engine
|
|
170
|
-
let syncEngine = iCloudSyncEngine(
|
|
171
|
-
containerIdentifier: "iCloud.com.yourcompany.runic"
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
// Create sync manager with default configuration
|
|
175
|
-
let syncManager = BackgroundSyncManager(
|
|
176
|
-
syncEngine: syncEngine,
|
|
177
|
-
config: .default
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
// Start automatic background sync
|
|
181
|
-
await syncManager.start()
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### 2. Custom Configuration
|
|
185
|
-
|
|
186
|
-
```swift
|
|
187
|
-
let config = SyncConfiguration(
|
|
188
|
-
activeSyncInterval: 180, // 3 minutes when app is active
|
|
189
|
-
backgroundSyncInterval: 1800, // 30 minutes in background
|
|
190
|
-
syncOnForeground: true, // Sync when app comes to foreground
|
|
191
|
-
syncOnBackground: true, // Sync when app goes to background
|
|
192
|
-
defaultSyncOptions: SyncOptions(
|
|
193
|
-
forceFullSync: false,
|
|
194
|
-
batchSize: 50,
|
|
195
|
-
conflictStrategy: .lastWriteWins,
|
|
196
|
-
backgroundMode: true,
|
|
197
|
-
timeout: 30.0,
|
|
198
|
-
encryptSensitiveData: true
|
|
199
|
-
)
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
let syncManager = BackgroundSyncManager(
|
|
203
|
-
syncEngine: syncEngine,
|
|
204
|
-
config: config
|
|
205
|
-
)
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### 3. Sync Usage Data
|
|
209
|
-
|
|
210
|
-
```swift
|
|
211
|
-
// Create usage snapshot record
|
|
212
|
-
let usageRecord = UsageSnapshotSyncRecord(
|
|
213
|
-
providerID: "claude",
|
|
214
|
-
primaryUsed: 75000,
|
|
215
|
-
primaryLimit: 100000,
|
|
216
|
-
secondaryUsed: 50,
|
|
217
|
-
secondaryLimit: 100,
|
|
218
|
-
costUSD: 3.75,
|
|
219
|
-
accountEmail: "user@example.com",
|
|
220
|
-
updatedAt: Date(),
|
|
221
|
-
deviceName: "MacBook Pro",
|
|
222
|
-
platform: "macOS"
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
// Queue for high-priority sync
|
|
226
|
-
await syncEngine.enqueue(usageRecord, priority: .high)
|
|
227
|
-
|
|
228
|
-
// Or push immediately
|
|
229
|
-
let result = await syncEngine.push(records: [usageRecord])
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### 4. Add Sync Observer
|
|
233
|
-
|
|
234
|
-
```swift
|
|
235
|
-
class MySyncObserver: SyncObserver {
|
|
236
|
-
func syncDidStart() {
|
|
237
|
-
print("Sync started")
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
func syncDidProgress(current: Int, total: Int) {
|
|
241
|
-
let percentage = (Double(current) / Double(total)) * 100
|
|
242
|
-
print("Progress: \(Int(percentage))%")
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
func syncDidComplete(result: SyncResult) {
|
|
246
|
-
print("Synced \(result.pushedCount + result.fetchedCount) records")
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
func syncDidFail(error: SyncError) {
|
|
250
|
-
print("Sync failed: \(error.localizedDescription)")
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
let observer = MySyncObserver()
|
|
255
|
-
await syncManager.addObserver(observer)
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### 5. Manual Sync
|
|
259
|
-
|
|
260
|
-
```swift
|
|
261
|
-
// Perform manual sync with custom options
|
|
262
|
-
let options = SyncOptions(
|
|
263
|
-
forceFullSync: true,
|
|
264
|
-
conflictStrategy: .lastWriteWins
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
let result = await syncManager.syncNow(options: options)
|
|
268
|
-
|
|
269
|
-
switch result {
|
|
270
|
-
case .success(let syncResult):
|
|
271
|
-
print("Pushed: \(syncResult.pushedCount)")
|
|
272
|
-
print("Fetched: \(syncResult.fetchedCount)")
|
|
273
|
-
print("Conflicts: \(syncResult.conflictsResolved)")
|
|
274
|
-
|
|
275
|
-
case .failure(let error):
|
|
276
|
-
print("Sync failed: \(error)")
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### 6. Monitor Sync Statistics
|
|
281
|
-
|
|
282
|
-
```swift
|
|
283
|
-
let stats = await syncManager.statistics
|
|
284
|
-
|
|
285
|
-
print("Total syncs: \(stats.totalSyncs)")
|
|
286
|
-
print("Success rate: \(stats.successRate)%")
|
|
287
|
-
print("Average duration: \(stats.averageDuration)s")
|
|
288
|
-
print("Last sync: \(stats.lastSyncDate?.description ?? "Never")")
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
## Conflict Resolution
|
|
292
|
-
|
|
293
|
-
### Default Strategies
|
|
294
|
-
|
|
295
|
-
1. **Last-write-wins** (default) - Most recently modified record wins
|
|
296
|
-
2. **Prefer local** - Always keep local version
|
|
297
|
-
3. **Prefer remote** - Always keep remote version
|
|
298
|
-
4. **Highest version** - Keep record with highest version number
|
|
299
|
-
5. **Merge** - Custom merge logic
|
|
300
|
-
|
|
301
|
-
### Custom Merge Handlers
|
|
302
|
-
|
|
303
|
-
The sync engine includes smart merge handlers for each record type:
|
|
304
|
-
|
|
305
|
-
**UsageSnapshot**: Prefers record with most recent usage data
|
|
306
|
-
**UserPreferences**: Merges enabled providers (union of both sets)
|
|
307
|
-
**AlertConfiguration**: Uses most conservative thresholds, merges notification channels
|
|
308
|
-
|
|
309
|
-
You can register custom merge handlers:
|
|
310
|
-
|
|
311
|
-
```swift
|
|
312
|
-
let resolver = SyncConflictResolver()
|
|
313
|
-
await resolver.registerDefaultMergeHandlers()
|
|
314
|
-
|
|
315
|
-
// Custom merge handler for usage snapshots
|
|
316
|
-
await resolver.registerMergeHandler(for: CloudKitRecordType.usageSnapshot) { local, remote in
|
|
317
|
-
guard let localUsage = local as? UsageSnapshotSyncRecord,
|
|
318
|
-
let remoteUsage = remote as? UsageSnapshotSyncRecord else {
|
|
319
|
-
return local
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Custom logic: prefer record with higher usage
|
|
323
|
-
return localUsage.primaryUsed > remoteUsage.primaryUsed ? local : remote
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Security
|
|
328
|
-
|
|
329
|
-
### Encryption
|
|
330
|
-
|
|
331
|
-
Sensitive data (email addresses) is automatically encrypted using AES-GCM before syncing to CloudKit. The encryption key is stored securely in the Keychain.
|
|
332
|
-
|
|
333
|
-
### Privacy
|
|
334
|
-
|
|
335
|
-
- All data is stored in the user's private CloudKit database
|
|
336
|
-
- Only the user can access their own data
|
|
337
|
-
- CloudKit records use user authentication
|
|
338
|
-
|
|
339
|
-
## Error Handling
|
|
340
|
-
|
|
341
|
-
The sync engine handles common errors gracefully:
|
|
342
|
-
|
|
343
|
-
```swift
|
|
344
|
-
switch syncError {
|
|
345
|
-
case .iCloudAccountUnavailable:
|
|
346
|
-
// User not signed in to iCloud
|
|
347
|
-
|
|
348
|
-
case .networkUnavailable:
|
|
349
|
-
// Network not available - changes queued for later
|
|
350
|
-
|
|
351
|
-
case .quotaExceeded:
|
|
352
|
-
// iCloud storage full
|
|
353
|
-
|
|
354
|
-
case .timeout:
|
|
355
|
-
// Sync operation timed out
|
|
356
|
-
|
|
357
|
-
case .conflictResolutionFailed(let details):
|
|
358
|
-
// Could not resolve conflict
|
|
359
|
-
|
|
360
|
-
case .cloudKitError(let ckError):
|
|
361
|
-
// CloudKit-specific error
|
|
362
|
-
|
|
363
|
-
default:
|
|
364
|
-
// Other errors
|
|
365
|
-
}
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
## Testing
|
|
369
|
-
|
|
370
|
-
### Prerequisites
|
|
371
|
-
|
|
372
|
-
1. Sign in to iCloud on your test device/simulator
|
|
373
|
-
2. Enable iCloud Drive in System Settings
|
|
374
|
-
3. Ensure network connectivity
|
|
375
|
-
|
|
376
|
-
### Manual Testing
|
|
377
|
-
|
|
378
|
-
1. Install app on Device A
|
|
379
|
-
2. Create some usage data
|
|
380
|
-
3. Wait for sync or trigger manual sync
|
|
381
|
-
4. Install app on Device B (same iCloud account)
|
|
382
|
-
5. Verify data appears after sync
|
|
383
|
-
|
|
384
|
-
### Verifying CloudKit Data
|
|
385
|
-
|
|
386
|
-
1. Open CloudKit Console
|
|
387
|
-
2. Select your container
|
|
388
|
-
3. Go to Data > Records
|
|
389
|
-
4. View synced records
|
|
390
|
-
|
|
391
|
-
## Performance Considerations
|
|
392
|
-
|
|
393
|
-
### Sync Intervals
|
|
394
|
-
|
|
395
|
-
- **Active sync**: Every 5 minutes when app is active
|
|
396
|
-
- **Background sync**: Every hour when app is in background
|
|
397
|
-
- **Foreground sync**: When app comes to foreground (if last sync > 5 min ago)
|
|
398
|
-
|
|
399
|
-
### Batch Sizes
|
|
400
|
-
|
|
401
|
-
Default batch size is 100 records. Adjust based on your data volume:
|
|
402
|
-
|
|
403
|
-
```swift
|
|
404
|
-
SyncOptions(batchSize: 50) // For smaller syncs
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Offline Queue
|
|
408
|
-
|
|
409
|
-
Records are automatically queued when offline and synced when connection is restored.
|
|
410
|
-
|
|
411
|
-
## Troubleshooting
|
|
412
|
-
|
|
413
|
-
### Common Issues
|
|
414
|
-
|
|
415
|
-
1. **"iCloud account unavailable"**
|
|
416
|
-
- Check Settings > Apple ID > iCloud
|
|
417
|
-
- Enable iCloud Drive
|
|
418
|
-
|
|
419
|
-
2. **"Network unavailable"**
|
|
420
|
-
- Check internet connection
|
|
421
|
-
- Changes will sync when online
|
|
422
|
-
|
|
423
|
-
3. **"Quota exceeded"**
|
|
424
|
-
- User needs more iCloud storage
|
|
425
|
-
- Upgrade iCloud plan
|
|
426
|
-
|
|
427
|
-
4. **Records not syncing**
|
|
428
|
-
- Check CloudKit Console for errors
|
|
429
|
-
- Verify entitlements are correct
|
|
430
|
-
- Ensure container identifier matches
|
|
431
|
-
|
|
432
|
-
### Debug Logging
|
|
433
|
-
|
|
434
|
-
Enable detailed sync logging in DEBUG builds:
|
|
435
|
-
|
|
436
|
-
```swift
|
|
437
|
-
#if DEBUG
|
|
438
|
-
print("Sync engine: \(syncEngine)")
|
|
439
|
-
print("Pending operations: \(await syncEngine.pendingOperationCount)")
|
|
440
|
-
#endif
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
## Migration Notes
|
|
444
|
-
|
|
445
|
-
If you have existing local data, you'll need to:
|
|
446
|
-
|
|
447
|
-
1. Create sync records from local data
|
|
448
|
-
2. Push to CloudKit on first launch
|
|
449
|
-
3. Set appropriate version numbers
|
|
450
|
-
4. Handle conflicts carefully during initial sync
|
|
451
|
-
|
|
452
|
-
## Best Practices
|
|
453
|
-
|
|
454
|
-
1. **Start sync early** - Initialize sync engine at app launch
|
|
455
|
-
2. **Monitor conflicts** - Check conflict statistics regularly
|
|
456
|
-
3. **Handle errors gracefully** - Queue operations when offline
|
|
457
|
-
4. **Use appropriate priorities** - Critical data should use `.high` priority
|
|
458
|
-
5. **Test thoroughly** - Test on multiple devices with same iCloud account
|
|
459
|
-
6. **Monitor quota** - Be mindful of CloudKit storage limits
|
|
460
|
-
|
|
461
|
-
## Compilation Status
|
|
462
|
-
|
|
463
|
-
✅ **Build Status**: Successfully compiles
|
|
464
|
-
- All sync files integrated into RunicCore module
|
|
465
|
-
- CloudKit imports working correctly
|
|
466
|
-
- Actor isolation properly implemented
|
|
467
|
-
- Strict concurrency enabled
|
|
468
|
-
|
|
469
|
-
### Warnings (Non-critical)
|
|
470
|
-
|
|
471
|
-
- Codable warnings on `recordType` fields (by design - these are constants)
|
|
472
|
-
- Timer isolation warnings (handled with @MainActor)
|
|
473
|
-
|
|
474
|
-
## Next Steps
|
|
475
|
-
|
|
476
|
-
1. Create entitlements file for your app
|
|
477
|
-
2. Configure CloudKit container in Developer Portal
|
|
478
|
-
3. Create CloudKit schema in CloudKit Console
|
|
479
|
-
4. Integrate sync manager into your app
|
|
480
|
-
5. Test on multiple devices
|
|
481
|
-
6. Monitor sync statistics and errors
|
|
482
|
-
|
|
483
|
-
## Support
|
|
484
|
-
|
|
485
|
-
For issues or questions about the sync infrastructure:
|
|
486
|
-
1. Check CloudKit Console for server-side errors
|
|
487
|
-
2. Review sync statistics for client-side issues
|
|
488
|
-
3. Enable debug logging for detailed diagnostics
|
|
489
|
-
4. Consult SyncUsageExample.swift for integration patterns
|
|
490
|
-
|
|
491
|
-
---
|
|
492
|
-
|
|
493
|
-
**Version**: 1.0
|
|
494
|
-
**Last Updated**: 2026-01-31
|
|
495
|
-
**Status**: Production Ready
|