@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.
Files changed (610) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/LICENSE +373 -21
  3. package/README.md +96 -89
  4. package/THIRD-PARTY-NOTICES.md +651 -0
  5. package/package.json +14 -4
  6. package/.swiftformat +0 -50
  7. package/.swiftlint.yml +0 -160
  8. package/CONTRIBUTING.md +0 -456
  9. package/Icon.icns +0 -0
  10. package/Icon.icon/Assets/runic.png +0 -0
  11. package/Icon.icon/icon.json +0 -36
  12. package/Package.resolved +0 -51
  13. package/Package.swift +0 -136
  14. package/Packages/Helix/LICENSE +0 -21
  15. package/Packages/Helix/Package.swift +0 -29
  16. package/Packages/Helix/README.md +0 -976
  17. package/Packages/Helix/Sources/Helix/Binding.swift +0 -111
  18. package/Packages/Helix/Sources/Helix/CommandParser.swift +0 -160
  19. package/Packages/Helix/Sources/Helix/CommandSignature.swift +0 -117
  20. package/Packages/Helix/Sources/Helix/ExpressibleFromArgument.swift +0 -72
  21. package/Packages/Helix/Sources/Helix/HelpGenerator.swift +0 -175
  22. package/Packages/Helix/Sources/Helix/NameSpecification.swift +0 -98
  23. package/Packages/Helix/Sources/Helix/ParsableCommand.swift +0 -204
  24. package/Packages/Helix/Sources/Helix/Platform/DarwinPlatformContext.swift +0 -44
  25. package/Packages/Helix/Sources/Helix/Platform/LinuxPlatformContext.swift +0 -34
  26. package/Packages/Helix/Sources/Helix/Platform/PlatformContext+Default.swift +0 -91
  27. package/Packages/Helix/Sources/Helix/Platform/PlatformContext.swift +0 -94
  28. package/Packages/Helix/Sources/Helix/Platform/PlatformPath.swift +0 -167
  29. package/Packages/Helix/Sources/Helix/Platform/Stdio.swift +0 -99
  30. package/Packages/Helix/Sources/Helix/Platform/WebPlatformContext.swift +0 -146
  31. package/Packages/Helix/Sources/Helix/Platform/WindowsPlatformContext.swift +0 -97
  32. package/Packages/Helix/Sources/Helix/Program.swift +0 -204
  33. package/Packages/Helix/Sources/Helix/PropertyWrappers.swift +0 -367
  34. package/Packages/Silo/LICENSE +0 -21
  35. package/Packages/Silo/Package.swift +0 -34
  36. package/Packages/Silo/README.md +0 -466
  37. package/Packages/Silo/Sources/Silo/BinaryCookiesReader.swift +0 -169
  38. package/Packages/Silo/Sources/Silo/BrowserCookieAnalytics.swift +0 -365
  39. package/Packages/Silo/Sources/Silo/BrowserCookieBackends.swift +0 -594
  40. package/Packages/Silo/Sources/Silo/BrowserCookieClient.swift +0 -326
  41. package/Packages/Silo/Sources/Silo/BrowserCookieExport.swift +0 -154
  42. package/Packages/Silo/Sources/Silo/BrowserCookieImport.swift +0 -119
  43. package/Packages/Silo/Sources/Silo/BrowserCookieMockStore.swift +0 -121
  44. package/Packages/Silo/Sources/Silo/BrowserCookieModels.swift +0 -391
  45. package/Packages/Silo/Sources/Silo/ChromiumCookieReader.swift +0 -240
  46. package/Packages/Silo/Sources/Silo/CryptoSupport.swift +0 -86
  47. package/Packages/Silo/Sources/Silo/FirefoxCookieReader.swift +0 -172
  48. package/Packages/Silo/Sources/Silo/LinuxChromiumCookieReader.swift +0 -172
  49. package/Packages/Silo/Sources/Silo/LinuxSecretService.swift +0 -105
  50. package/Packages/Silo/Sources/Silo/MacOSChromiumCookieReader.swift +0 -191
  51. package/Packages/Silo/Sources/Silo/SQLiteSnapshot.swift +0 -41
  52. package/Packages/Silo/Sources/Silo/WindowsChromiumCookieReader.swift +0 -110
  53. package/RuniciOS/App/RuniciOSApp.swift +0 -105
  54. package/RuniciOS/Core/RunicTypographyiOS.swift +0 -24
  55. package/RuniciOS/Core/iOSUsageStore.swift +0 -192
  56. package/RuniciOS/Views/ProviderDetailView.swift +0 -312
  57. package/RuniciOS/Views/ProviderListView.swift +0 -228
  58. package/RuniciOS/Widgets/LargeWidget.swift +0 -367
  59. package/RuniciOS/Widgets/LiveActivity.swift +0 -342
  60. package/RuniciOS/Widgets/LockScreenWidget.swift +0 -273
  61. package/RuniciOS/Widgets/MediumWidget.swift +0 -370
  62. package/RuniciOS/Widgets/RunicWidget.swift +0 -274
  63. package/RuniciOS/Widgets/SmallWidget.swift +0 -281
  64. package/RuniciOS/Widgets/WidgetModels.swift +0 -285
  65. package/RuniciOS/Widgets/WidgetTimeline.swift +0 -270
  66. package/Scripts/CREATION-SUMMARY.md +0 -367
  67. package/Scripts/DIRECTORY-STRUCTURE.md +0 -358
  68. package/Scripts/GETTING-STARTED-CHECKLIST.md +0 -364
  69. package/Scripts/INDEX.md +0 -365
  70. package/Scripts/QUICK-REFERENCE.md +0 -164
  71. package/Scripts/README-SCRIPTS.md +0 -926
  72. package/Scripts/build-android.sh +0 -526
  73. package/Scripts/build-ios.sh +0 -529
  74. package/Scripts/build-macos.sh +0 -603
  75. package/Scripts/build-windows.sh +0 -504
  76. package/Scripts/build_icon.sh +0 -49
  77. package/Scripts/changelog-to-html.sh +0 -89
  78. package/Scripts/check-release-assets.sh +0 -10
  79. package/Scripts/ci-config.yml +0 -474
  80. package/Scripts/compile_and_run.sh +0 -219
  81. package/Scripts/compile_and_run_adhoc.sh +0 -4
  82. package/Scripts/docs-list.mjs +0 -119
  83. package/Scripts/make_appcast.sh +0 -58
  84. package/Scripts/package_app.sh +0 -409
  85. package/Scripts/release-lib.sh +0 -214
  86. package/Scripts/release.sh +0 -76
  87. package/Scripts/setup-all.sh +0 -387
  88. package/Scripts/setup-ios.sh +0 -404
  89. package/Scripts/setup-react-native.sh +0 -523
  90. package/Scripts/sign-and-notarize.sh +0 -122
  91. package/Scripts/test_live_update.sh +0 -38
  92. package/Scripts/validate_changelog.sh +0 -23
  93. package/Scripts/verify_appcast.sh +0 -92
  94. package/Sources/Runic/About.swift +0 -93
  95. package/Sources/Runic/AppNotifications.swift +0 -117
  96. package/Sources/Runic/Controllers/StatusItemController+Actions.swift +0 -670
  97. package/Sources/Runic/Controllers/StatusItemController+Animation.swift +0 -519
  98. package/Sources/Runic/Controllers/StatusItemController+ChartSubmenus.swift +0 -824
  99. package/Sources/Runic/Controllers/StatusItemController+CustomProviders.swift +0 -90
  100. package/Sources/Runic/Controllers/StatusItemController+Menu.swift +0 -1412
  101. package/Sources/Runic/Controllers/StatusItemController+MenuCards.swift +0 -339
  102. package/Sources/Runic/Controllers/StatusItemController+MenuHelpers.swift +0 -423
  103. package/Sources/Runic/Controllers/StatusItemController.swift +0 -360
  104. package/Sources/Runic/Core/BudgetNotificationManager.swift +0 -81
  105. package/Sources/Runic/Core/Login/ClaudeLoginRunner.swift +0 -103
  106. package/Sources/Runic/Core/Login/CodexLoginRunner.swift +0 -154
  107. package/Sources/Runic/Core/Login/CursorLoginRunner.swift +0 -206
  108. package/Sources/Runic/Core/Login/GeminiLoginRunner.swift +0 -92
  109. package/Sources/Runic/Core/Rendering/IconRenderer.swift +0 -1222
  110. package/Sources/Runic/Core/Rendering/IconView.swift +0 -122
  111. package/Sources/Runic/Core/Rendering/ProviderBrandIcon.swift +0 -71
  112. package/Sources/Runic/Core/RunicAnimation.swift +0 -53
  113. package/Sources/Runic/Core/RunicColors.swift +0 -73
  114. package/Sources/Runic/Core/RunicCornerRadius.swift +0 -15
  115. package/Sources/Runic/Core/RunicSpacing.swift +0 -68
  116. package/Sources/Runic/Core/RunicTypography.swift +0 -206
  117. package/Sources/Runic/Core/Stores/AuggieTokenStore.swift +0 -117
  118. package/Sources/Runic/Core/Stores/AzureOpenAITokenStore.swift +0 -117
  119. package/Sources/Runic/Core/Stores/CerebrasTokenStore.swift +0 -117
  120. package/Sources/Runic/Core/Stores/CohereTokenStore.swift +0 -117
  121. package/Sources/Runic/Core/Stores/CopilotTokenStore.swift +0 -117
  122. package/Sources/Runic/Core/Stores/CustomProviderStore.swift +0 -158
  123. package/Sources/Runic/Core/Stores/DeepSeekTokenStore.swift +0 -117
  124. package/Sources/Runic/Core/Stores/FireworksTokenStore.swift +0 -117
  125. package/Sources/Runic/Core/Stores/GroqTokenStore.swift +0 -117
  126. package/Sources/Runic/Core/Stores/KimiTokenStore.swift +0 -117
  127. package/Sources/Runic/Core/Stores/MiniMaxCookieHeaderStore.swift +0 -117
  128. package/Sources/Runic/Core/Stores/MiniMaxGroupIDStore.swift +0 -117
  129. package/Sources/Runic/Core/Stores/MiniMaxTokenStore.swift +0 -117
  130. package/Sources/Runic/Core/Stores/MistralTokenStore.swift +0 -117
  131. package/Sources/Runic/Core/Stores/OpenRouterTokenStore.swift +0 -117
  132. package/Sources/Runic/Core/Stores/PerplexityTokenStore.swift +0 -117
  133. package/Sources/Runic/Core/Stores/ProviderToggleStore.swift +0 -30
  134. package/Sources/Runic/Core/Stores/QwenTokenStore.swift +0 -117
  135. package/Sources/Runic/Core/Stores/SambaNovaTokenStore.swift +0 -117
  136. package/Sources/Runic/Core/Stores/SettingsStore.swift +0 -1749
  137. package/Sources/Runic/Core/Stores/TogetherTokenStore.swift +0 -117
  138. package/Sources/Runic/Core/Stores/UsageStore+Accessors.swift +0 -33
  139. package/Sources/Runic/Core/Stores/UsageStore+Status.swift +0 -189
  140. package/Sources/Runic/Core/Stores/UsageStore+TokenCost.swift +0 -33
  141. package/Sources/Runic/Core/Stores/UsageStore+WidgetSnapshot.swift +0 -67
  142. package/Sources/Runic/Core/Stores/UsageStore.swift +0 -3631
  143. package/Sources/Runic/Core/Stores/XAITokenStore.swift +0 -117
  144. package/Sources/Runic/Core/Stores/ZaiTokenStore.swift +0 -117
  145. package/Sources/Runic/Core/UsageExporter.swift +0 -197
  146. package/Sources/Runic/Date+RelativeDescription.swift +0 -21
  147. package/Sources/Runic/HiddenWindowView.swift +0 -32
  148. package/Sources/Runic/InstallOrigin.swift +0 -9
  149. package/Sources/Runic/KeyboardShortcuts+Names.swift +0 -6
  150. package/Sources/Runic/MouseLocationReader.swift +0 -65
  151. package/Sources/Runic/Notifications+Runic.swift +0 -6
  152. package/Sources/Runic/OpenAICreditsPurchaseWindowController.swift +0 -503
  153. package/Sources/Runic/ProviderRegistry.swift +0 -100
  154. package/Sources/Runic/ProviderSwitcherButtons.swift +0 -267
  155. package/Sources/Runic/Providers/Antigravity/AntigravityLoginFlow.swift +0 -11
  156. package/Sources/Runic/Providers/Antigravity/AntigravityProviderImplementation.swift +0 -14
  157. package/Sources/Runic/Providers/Auggie/AuggieProviderImplementation.swift +0 -24
  158. package/Sources/Runic/Providers/Azure/AzureProviderImplementation.swift +0 -52
  159. package/Sources/Runic/Providers/Bedrock/BedrockProviderImplementation.swift +0 -42
  160. package/Sources/Runic/Providers/Cerebras/CerebrasProviderImplementation.swift +0 -24
  161. package/Sources/Runic/Providers/Claude/ClaudeLoginFlow.swift +0 -26
  162. package/Sources/Runic/Providers/Claude/ClaudeProviderImplementation.swift +0 -14
  163. package/Sources/Runic/Providers/Codex/CodexLoginFlow.swift +0 -18
  164. package/Sources/Runic/Providers/Codex/CodexProviderImplementation.swift +0 -15
  165. package/Sources/Runic/Providers/Cohere/CohereProviderImplementation.swift +0 -24
  166. package/Sources/Runic/Providers/Copilot/CopilotLoginFlow.swift +0 -193
  167. package/Sources/Runic/Providers/Copilot/CopilotProviderImplementation.swift +0 -110
  168. package/Sources/Runic/Providers/Cursor/CursorLoginFlow.swift +0 -28
  169. package/Sources/Runic/Providers/Cursor/CursorProviderImplementation.swift +0 -15
  170. package/Sources/Runic/Providers/DeepSeek/DeepSeekProviderImplementation.swift +0 -24
  171. package/Sources/Runic/Providers/Factory/FactoryLoginFlow.swift +0 -12
  172. package/Sources/Runic/Providers/Factory/FactoryProviderImplementation.swift +0 -15
  173. package/Sources/Runic/Providers/Fireworks/FireworksProviderImplementation.swift +0 -24
  174. package/Sources/Runic/Providers/Gemini/GeminiLoginFlow.swift +0 -20
  175. package/Sources/Runic/Providers/Gemini/GeminiProviderImplementation.swift +0 -15
  176. package/Sources/Runic/Providers/Groq/GroqProviderImplementation.swift +0 -24
  177. package/Sources/Runic/Providers/Kimi/KimiProviderImplementation.swift +0 -24
  178. package/Sources/Runic/Providers/MiniMax/MiniMaxProviderImplementation.swift +0 -32
  179. package/Sources/Runic/Providers/Mistral/MistralProviderImplementation.swift +0 -24
  180. package/Sources/Runic/Providers/OpenRouter/OpenRouterProviderImplementation.swift +0 -24
  181. package/Sources/Runic/Providers/Perplexity/PerplexityProviderImplementation.swift +0 -24
  182. package/Sources/Runic/Providers/SambaNova/SambaNovaProviderImplementation.swift +0 -24
  183. package/Sources/Runic/Providers/Shared/ProviderCatalog.swift +0 -15
  184. package/Sources/Runic/Providers/Shared/ProviderImplementation.swift +0 -51
  185. package/Sources/Runic/Providers/Shared/ProviderImplementationRegistry.swift +0 -66
  186. package/Sources/Runic/Providers/Shared/ProviderLoginFlow.swift +0 -12
  187. package/Sources/Runic/Providers/Shared/ProviderSettingsDescriptors.swift +0 -99
  188. package/Sources/Runic/Providers/Shared/SystemSettingsLinks.swift +0 -18
  189. package/Sources/Runic/Providers/Together/TogetherProviderImplementation.swift +0 -24
  190. package/Sources/Runic/Providers/XAI/XAIProviderImplementation.swift +0 -24
  191. package/Sources/Runic/Providers/Zai/ZaiProviderImplementation.swift +0 -24
  192. package/Sources/Runic/Resources/Fonts/Caveat-Bold.ttf +0 -0
  193. package/Sources/Runic/Resources/Fonts/Caveat-Regular.ttf +0 -0
  194. package/Sources/Runic/Resources/Fonts/FiraCode-Bold.ttf +0 -0
  195. package/Sources/Runic/Resources/Fonts/FiraCode-Light.ttf +0 -0
  196. package/Sources/Runic/Resources/Fonts/FiraCode-Medium.ttf +0 -0
  197. package/Sources/Runic/Resources/Fonts/FiraCode-Regular.ttf +0 -0
  198. package/Sources/Runic/Resources/Fonts/FiraCode-SemiBold.ttf +0 -0
  199. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Bold.ttf +0 -0
  200. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Medium.ttf +0 -0
  201. package/Sources/Runic/Resources/Fonts/IBMPlexMono-Regular.ttf +0 -0
  202. package/Sources/Runic/Resources/Fonts/IBMPlexMono-SemiBold.ttf +0 -0
  203. package/Sources/Runic/Resources/Fonts/Inconsolata-Bold.ttf +0 -0
  204. package/Sources/Runic/Resources/Fonts/Inconsolata-Medium.ttf +0 -0
  205. package/Sources/Runic/Resources/Fonts/Inconsolata-Regular.ttf +0 -0
  206. package/Sources/Runic/Resources/Fonts/Inconsolata-SemiBold.ttf +0 -0
  207. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Bold.ttf +0 -0
  208. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Medium.ttf +0 -0
  209. package/Sources/Runic/Resources/Fonts/JetBrainsMono-Regular.ttf +0 -0
  210. package/Sources/Runic/Resources/Fonts/JetBrainsMono-SemiBold.ttf +0 -0
  211. package/Sources/Runic/Resources/Fonts/SpaceMono-Bold.ttf +0 -0
  212. package/Sources/Runic/Resources/Fonts/SpaceMono-Regular.ttf +0 -0
  213. package/Sources/Runic/Resources/ProviderIcon-antigravity.svg +0 -2
  214. package/Sources/Runic/Resources/ProviderIcon-auggie.svg +0 -3
  215. package/Sources/Runic/Resources/ProviderIcon-azure.svg +0 -5
  216. package/Sources/Runic/Resources/ProviderIcon-bedrock.svg +0 -7
  217. package/Sources/Runic/Resources/ProviderIcon-cerebras.svg +0 -3
  218. package/Sources/Runic/Resources/ProviderIcon-claude.svg +0 -1
  219. package/Sources/Runic/Resources/ProviderIcon-codex.svg +0 -1
  220. package/Sources/Runic/Resources/ProviderIcon-cohere.svg +0 -3
  221. package/Sources/Runic/Resources/ProviderIcon-copilot.svg +0 -1
  222. package/Sources/Runic/Resources/ProviderIcon-cursor.svg +0 -3
  223. package/Sources/Runic/Resources/ProviderIcon-deepseek.svg +0 -4
  224. package/Sources/Runic/Resources/ProviderIcon-factory.svg +0 -3
  225. package/Sources/Runic/Resources/ProviderIcon-fireworks.svg +0 -3
  226. package/Sources/Runic/Resources/ProviderIcon-gemini.svg +0 -1
  227. package/Sources/Runic/Resources/ProviderIcon-groq.svg +0 -1
  228. package/Sources/Runic/Resources/ProviderIcon-kimi.svg +0 -4
  229. package/Sources/Runic/Resources/ProviderIcon-minimax.svg +0 -1
  230. package/Sources/Runic/Resources/ProviderIcon-mistral.svg +0 -5
  231. package/Sources/Runic/Resources/ProviderIcon-openrouter.svg +0 -7
  232. package/Sources/Runic/Resources/ProviderIcon-perplexity.svg +0 -4
  233. package/Sources/Runic/Resources/ProviderIcon-qwen.svg +0 -9
  234. package/Sources/Runic/Resources/ProviderIcon-sambanova.svg +0 -4
  235. package/Sources/Runic/Resources/ProviderIcon-together.svg +0 -5
  236. package/Sources/Runic/Resources/ProviderIcon-vertexai.svg +0 -17
  237. package/Sources/Runic/Resources/ProviderIcon-xai.svg +0 -3
  238. package/Sources/Runic/Resources/ProviderIcon-zai.svg +0 -5
  239. package/Sources/Runic/Resources/RunicMenubarIcon.svg +0 -7
  240. package/Sources/Runic/Resources/provider-context-windows.json +0 -20
  241. package/Sources/Runic/RunicApp.swift +0 -367
  242. package/Sources/Runic/SessionQuotaNotifications.swift +0 -58
  243. package/Sources/Runic/UsagePaceText.swift +0 -52
  244. package/Sources/Runic/UsageProgressBar.swift +0 -228
  245. package/Sources/Runic/Utilities/DisplayLink.swift +0 -96
  246. package/Sources/Runic/Utilities/LoadingPattern.swift +0 -62
  247. package/Sources/Runic/Utilities/PerformanceConstants.swift +0 -85
  248. package/Sources/Runic/Views/Menu/AlertsMenuView.swift +0 -254
  249. package/Sources/Runic/Views/Menu/ChartPanelStyle.swift +0 -22
  250. package/Sources/Runic/Views/Menu/CostComparativeChartMenuView.swift +0 -275
  251. package/Sources/Runic/Views/Menu/CostHistoryChartMenuView.swift +0 -377
  252. package/Sources/Runic/Views/Menu/CreditsHistoryChartMenuView.swift +0 -312
  253. package/Sources/Runic/Views/Menu/EfficiencyMetricsMenuView.swift +0 -311
  254. package/Sources/Runic/Views/Menu/HeroStatCardsMenuView.swift +0 -231
  255. package/Sources/Runic/Views/Menu/HourlyActivityChartMenuView.swift +0 -228
  256. package/Sources/Runic/Views/Menu/InlineUsageChartView.swift +0 -157
  257. package/Sources/Runic/Views/Menu/MenuCardEntranceModifier.swift +0 -63
  258. package/Sources/Runic/Views/Menu/MenuCardSidebarView.swift +0 -248
  259. package/Sources/Runic/Views/Menu/MenuCardSkeletonView.swift +0 -104
  260. package/Sources/Runic/Views/Menu/MenuCardView.swift +0 -1889
  261. package/Sources/Runic/Views/Menu/MenuContent.swift +0 -153
  262. package/Sources/Runic/Views/Menu/MenuDescriptor.swift +0 -371
  263. package/Sources/Runic/Views/Menu/MenuHighlightStyle.swift +0 -35
  264. package/Sources/Runic/Views/Menu/ModelBreakdownMenuView.swift +0 -241
  265. package/Sources/Runic/Views/Menu/OverviewMenuView.swift +0 -281
  266. package/Sources/Runic/Views/Menu/ProjectBreakdownMenuView.swift +0 -214
  267. package/Sources/Runic/Views/Menu/ProjectBudgetMenuView.swift +0 -220
  268. package/Sources/Runic/Views/Menu/ProviderTabBarView.swift +0 -86
  269. package/Sources/Runic/Views/Menu/SubscriptionUtilizationChartMenuView.swift +0 -214
  270. package/Sources/Runic/Views/Menu/UsageBreakdownChartMenuView.swift +0 -398
  271. package/Sources/Runic/Views/Menu/UsageHeatmapMenuView.swift +0 -231
  272. package/Sources/Runic/Views/Menu/UsageTimelineChartMenuView.swift +0 -369
  273. package/Sources/Runic/Views/Menu/UsageWindowComparisonChartMenuView.swift +0 -191
  274. package/Sources/Runic/Views/Menu/WeeklyActivityChartMenuView.swift +0 -132
  275. package/Sources/Runic/Views/Performance/PerformanceDashboardView.swift +0 -621
  276. package/Sources/Runic/Views/Preferences/LiquidComponents.swift +0 -306
  277. package/Sources/Runic/Views/Preferences/PreferencesAboutPane.swift +0 -271
  278. package/Sources/Runic/Views/Preferences/PreferencesAdvancedPane.swift +0 -268
  279. package/Sources/Runic/Views/Preferences/PreferencesAlertsPane.swift +0 -418
  280. package/Sources/Runic/Views/Preferences/PreferencesAnalyticsPane.swift +0 -637
  281. package/Sources/Runic/Views/Preferences/PreferencesBudgetsPane.swift +0 -344
  282. package/Sources/Runic/Views/Preferences/PreferencesComponents.swift +0 -230
  283. package/Sources/Runic/Views/Preferences/PreferencesCustomProvidersPane.swift +0 -321
  284. package/Sources/Runic/Views/Preferences/PreferencesDebugPane.swift +0 -469
  285. package/Sources/Runic/Views/Preferences/PreferencesGeneralPane.swift +0 -250
  286. package/Sources/Runic/Views/Preferences/PreferencesHelpPane.swift +0 -50
  287. package/Sources/Runic/Views/Preferences/PreferencesIntegrationsPane.swift +0 -572
  288. package/Sources/Runic/Views/Preferences/PreferencesPerformancePane.swift +0 -291
  289. package/Sources/Runic/Views/Preferences/PreferencesProvidersPane.swift +0 -3480
  290. package/Sources/Runic/Views/Preferences/PreferencesSelection.swift +0 -29
  291. package/Sources/Runic/Views/Preferences/PreferencesSyncPane.swift +0 -61
  292. package/Sources/Runic/Views/Preferences/PreferencesView.swift +0 -213
  293. package/Sources/Runic/Views/Rating/QualityRatingView.swift +0 -238
  294. package/Sources/Runic/Views/Team/TeamDashboardView.swift +0 -376
  295. package/Sources/Runic/Views/Team/TeamInviteSheet.swift +0 -175
  296. package/Sources/Runic/Views/Team/TeamManagementView.swift +0 -762
  297. package/Sources/Runic/Views/Team/TeamMemberRow.swift +0 -181
  298. package/Sources/RunicCLI/CLIEntry.swift +0 -983
  299. package/Sources/RunicCLI/CLIRenderer.swift +0 -87
  300. package/Sources/RunicCLI/Commands/EnhancedUsageCommand.swift +0 -588
  301. package/Sources/RunicCLI/Commands/ModelsCommand.swift +0 -363
  302. package/Sources/RunicCLI/Commands/ProjectsCommand.swift +0 -453
  303. package/Sources/RunicCLI/Commands/ResetCommand.swift +0 -430
  304. package/Sources/RunicCLI/Commands/UsageLedgerSourceFactory.swift +0 -167
  305. package/Sources/RunicClaudeWatchdog/main.swift +0 -122
  306. package/Sources/RunicClaudeWebProbe/main.swift +0 -62
  307. package/Sources/RunicCore/AlertRuleStore.swift +0 -187
  308. package/Sources/RunicCore/BrowserCookieImportOrder.swift +0 -25
  309. package/Sources/RunicCore/CopilotUsageModels.swift +0 -84
  310. package/Sources/RunicCore/CostUsageFetcher.swift +0 -119
  311. package/Sources/RunicCore/CostUsageModels.swift +0 -479
  312. package/Sources/RunicCore/CreditsModels.swift +0 -50
  313. package/Sources/RunicCore/CustomProviders/CustomProviderModels.swift +0 -268
  314. package/Sources/RunicCore/CustomProviders/GenericProviderFetcher.swift +0 -631
  315. package/Sources/RunicCore/CustomProviders/ProviderTemplates.swift +0 -444
  316. package/Sources/RunicCore/Host/PTY/TTYCommandRunner.swift +0 -679
  317. package/Sources/RunicCore/Host/Process/SubprocessRunner.swift +0 -135
  318. package/Sources/RunicCore/Integrations/GitHubIntegration.swift +0 -173
  319. package/Sources/RunicCore/Logging/JSONStderrLogHandler.swift +0 -79
  320. package/Sources/RunicCore/Logging/OSLogLogHandler.swift +0 -86
  321. package/Sources/RunicCore/Logging/RunicLog.swift +0 -123
  322. package/Sources/RunicCore/Models/EnhancedUsageModels.swift +0 -370
  323. package/Sources/RunicCore/OpenAIDashboardModels.swift +0 -210
  324. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardBrowserCookieImporter.swift +0 -676
  325. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardFetcher.swift +0 -492
  326. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardNavigationDelegate.swift +0 -51
  327. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardParser.swift +0 -483
  328. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardScrapeScript.swift +0 -558
  329. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardWebViewCache.swift +0 -204
  330. package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardWebsiteDataStore.swift +0 -78
  331. package/Sources/RunicCore/PathEnvironment.swift +0 -482
  332. package/Sources/RunicCore/Performance/PerformanceModels.swift +0 -371
  333. package/Sources/RunicCore/Performance/PerformanceStorageImpl.swift +0 -426
  334. package/Sources/RunicCore/Policy/UsagePolicyEngine.swift +0 -178
  335. package/Sources/RunicCore/ProjectBudgetStore.swift +0 -102
  336. package/Sources/RunicCore/ProviderCostSnapshot.swift +0 -29
  337. package/Sources/RunicCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +0 -68
  338. package/Sources/RunicCore/Providers/Antigravity/AntigravityStatusProbe.swift +0 -685
  339. package/Sources/RunicCore/Providers/Auggie/AuggieProviderDescriptor.swift +0 -83
  340. package/Sources/RunicCore/Providers/Auggie/AuggieUsageFetcher.swift +0 -142
  341. package/Sources/RunicCore/Providers/Azure/AzureProviderDescriptor.swift +0 -141
  342. package/Sources/RunicCore/Providers/Azure/AzureUsageFetcher.swift +0 -188
  343. package/Sources/RunicCore/Providers/Bedrock/BedrockProviderDescriptor.swift +0 -126
  344. package/Sources/RunicCore/Providers/Bedrock/BedrockUsageFetcher.swift +0 -164
  345. package/Sources/RunicCore/Providers/Cerebras/CerebrasProviderDescriptor.swift +0 -84
  346. package/Sources/RunicCore/Providers/Cerebras/CerebrasUsageFetcher.swift +0 -75
  347. package/Sources/RunicCore/Providers/Claude/ClaudeCLISession.swift +0 -332
  348. package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthCredentials.swift +0 -180
  349. package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthUsageFetcher.swift +0 -137
  350. package/Sources/RunicCore/Providers/Claude/ClaudeProviderDescriptor.swift +0 -209
  351. package/Sources/RunicCore/Providers/Claude/ClaudeStatusProbe.swift +0 -654
  352. package/Sources/RunicCore/Providers/Claude/ClaudeUsageDataSource.swift +0 -30
  353. package/Sources/RunicCore/Providers/Claude/ClaudeUsageFetcher.swift +0 -480
  354. package/Sources/RunicCore/Providers/Claude/ClaudeWeb/ClaudeWebAPIFetcher.swift +0 -780
  355. package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthCredentials.swift +0 -147
  356. package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift +0 -280
  357. package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexTokenRefresher.swift +0 -100
  358. package/Sources/RunicCore/Providers/Codex/CodexProviderDescriptor.swift +0 -245
  359. package/Sources/RunicCore/Providers/Codex/CodexStatusProbe.swift +0 -125
  360. package/Sources/RunicCore/Providers/Codex/CodexUsageDataSource.swift +0 -26
  361. package/Sources/RunicCore/Providers/Codex/CodexWebDashboardStrategy.swift +0 -183
  362. package/Sources/RunicCore/Providers/Cohere/CohereProviderDescriptor.swift +0 -83
  363. package/Sources/RunicCore/Providers/Cohere/CohereUsageFetcher.swift +0 -85
  364. package/Sources/RunicCore/Providers/Copilot/CopilotDeviceFlow.swift +0 -123
  365. package/Sources/RunicCore/Providers/Copilot/CopilotGitHubCLITokenReader.swift +0 -117
  366. package/Sources/RunicCore/Providers/Copilot/CopilotProviderDescriptor.swift +0 -100
  367. package/Sources/RunicCore/Providers/Copilot/CopilotUsageFetcher.swift +0 -293
  368. package/Sources/RunicCore/Providers/Copilot/CopilotVSCodeTokenReader.swift +0 -385
  369. package/Sources/RunicCore/Providers/Cursor/CursorProviderDescriptor.swift +0 -67
  370. package/Sources/RunicCore/Providers/Cursor/CursorStatusProbe.swift +0 -595
  371. package/Sources/RunicCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift +0 -85
  372. package/Sources/RunicCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift +0 -108
  373. package/Sources/RunicCore/Providers/Factory/FactoryLocalStorageImporter.swift +0 -398
  374. package/Sources/RunicCore/Providers/Factory/FactoryProviderDescriptor.swift +0 -67
  375. package/Sources/RunicCore/Providers/Factory/FactoryStatusProbe.swift +0 -1276
  376. package/Sources/RunicCore/Providers/Fireworks/FireworksProviderDescriptor.swift +0 -84
  377. package/Sources/RunicCore/Providers/Fireworks/FireworksUsageFetcher.swift +0 -75
  378. package/Sources/RunicCore/Providers/Gemini/GeminiProviderDescriptor.swift +0 -67
  379. package/Sources/RunicCore/Providers/Gemini/GeminiStatusProbe.swift +0 -839
  380. package/Sources/RunicCore/Providers/Groq/GroqProviderDescriptor.swift +0 -83
  381. package/Sources/RunicCore/Providers/Groq/GroqUsageFetcher.swift +0 -71
  382. package/Sources/RunicCore/Providers/Kimi/KimiProviderDescriptor.swift +0 -83
  383. package/Sources/RunicCore/Providers/Kimi/KimiUsageFetcher.swift +0 -77
  384. package/Sources/RunicCore/Providers/MiniMax/MiniMaxProviderDescriptor.swift +0 -97
  385. package/Sources/RunicCore/Providers/MiniMax/MiniMaxSettingsReader.swift +0 -54
  386. package/Sources/RunicCore/Providers/MiniMax/MiniMaxUsageFetcher.swift +0 -168
  387. package/Sources/RunicCore/Providers/MiniMax/MiniMaxWebUsageFetcher.swift +0 -911
  388. package/Sources/RunicCore/Providers/Mistral/MistralProviderDescriptor.swift +0 -84
  389. package/Sources/RunicCore/Providers/Mistral/MistralUsageFetcher.swift +0 -75
  390. package/Sources/RunicCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift +0 -87
  391. package/Sources/RunicCore/Providers/OpenRouter/OpenRouterUsageFetcher.swift +0 -216
  392. package/Sources/RunicCore/Providers/Perplexity/PerplexityProviderDescriptor.swift +0 -84
  393. package/Sources/RunicCore/Providers/Perplexity/PerplexityUsageFetcher.swift +0 -75
  394. package/Sources/RunicCore/Providers/ProviderBranding.swift +0 -25
  395. package/Sources/RunicCore/Providers/ProviderCLIConfig.swift +0 -17
  396. package/Sources/RunicCore/Providers/ProviderDescriptor.swift +0 -129
  397. package/Sources/RunicCore/Providers/ProviderFetchPlan.swift +0 -263
  398. package/Sources/RunicCore/Providers/ProviderSettingsSnapshot.swift +0 -98
  399. package/Sources/RunicCore/Providers/ProviderTokenResolver.swift +0 -501
  400. package/Sources/RunicCore/Providers/ProviderVersionDetector.swift +0 -68
  401. package/Sources/RunicCore/Providers/Providers.swift +0 -184
  402. package/Sources/RunicCore/Providers/Qwen/QwenProviderDescriptor.swift +0 -86
  403. package/Sources/RunicCore/Providers/Qwen/QwenSettingsReader.swift +0 -30
  404. package/Sources/RunicCore/Providers/Qwen/QwenUsageStats.swift +0 -328
  405. package/Sources/RunicCore/Providers/SambaNova/SambaNovaProviderDescriptor.swift +0 -84
  406. package/Sources/RunicCore/Providers/SambaNova/SambaNovaUsageFetcher.swift +0 -75
  407. package/Sources/RunicCore/Providers/Together/TogetherProviderDescriptor.swift +0 -83
  408. package/Sources/RunicCore/Providers/Together/TogetherUsageFetcher.swift +0 -75
  409. package/Sources/RunicCore/Providers/VertexAI/VertexAIProviderDescriptor.swift +0 -123
  410. package/Sources/RunicCore/Providers/VertexAI/VertexAISettingsReader.swift +0 -48
  411. package/Sources/RunicCore/Providers/VertexAI/VertexAIUsageFetcher.swift +0 -144
  412. package/Sources/RunicCore/Providers/XAI/XAIProviderDescriptor.swift +0 -83
  413. package/Sources/RunicCore/Providers/XAI/XAIUsageFetcher.swift +0 -75
  414. package/Sources/RunicCore/Providers/Zai/ZaiProviderDescriptor.swift +0 -74
  415. package/Sources/RunicCore/Providers/Zai/ZaiSettingsReader.swift +0 -41
  416. package/Sources/RunicCore/Providers/Zai/ZaiUsageStats.swift +0 -745
  417. package/Sources/RunicCore/Sync/BackgroundSyncManager.swift +0 -384
  418. package/Sources/RunicCore/Sync/SyncConflictResolver.swift +0 -307
  419. package/Sources/RunicCore/Sync/SyncProtocol.swift +0 -287
  420. package/Sources/RunicCore/Sync/SyncRecord.swift +0 -402
  421. package/Sources/RunicCore/Sync/SyncUsageExample.swift +0 -288
  422. package/Sources/RunicCore/Sync/TeamSyncRecords.swift +0 -768
  423. package/Sources/RunicCore/Sync/iCloudSyncEngine.swift +0 -338
  424. package/Sources/RunicCore/Team/TeamModels.swift +0 -584
  425. package/Sources/RunicCore/Team/TeamShowbackExporter.swift +0 -495
  426. package/Sources/RunicCore/Team/TeamStore.swift +0 -809
  427. package/Sources/RunicCore/TextParsing.swift +0 -55
  428. package/Sources/RunicCore/UsageFetcher.swift +0 -694
  429. package/Sources/RunicCore/UsageFormatter.swift +0 -410
  430. package/Sources/RunicCore/UsageLedger/ClaudeUsageLogSource.swift +0 -441
  431. package/Sources/RunicCore/UsageLedger/CodexUsageLogSource.swift +0 -502
  432. package/Sources/RunicCore/UsageLedger/LedgerCache.swift +0 -161
  433. package/Sources/RunicCore/UsageLedger/OTelGenAILedgerAdapter.swift +0 -550
  434. package/Sources/RunicCore/UsageLedger/UsageLedger.swift +0 -29
  435. package/Sources/RunicCore/UsageLedger/UsageLedgerAggregator.swift +0 -675
  436. package/Sources/RunicCore/UsageLedger/UsageLedgerInsightsAdvisor.swift +0 -209
  437. package/Sources/RunicCore/UsageLedger/UsageLedgerModels.swift +0 -417
  438. package/Sources/RunicCore/UsageLedger/UsageLedgerProjectIdentity.swift +0 -284
  439. package/Sources/RunicCore/UsagePace.swift +0 -81
  440. package/Sources/RunicCore/Vendored/CostUsage/CostUsageCache.swift +0 -73
  441. package/Sources/RunicCore/Vendored/CostUsage/CostUsageJsonl.swift +0 -74
  442. package/Sources/RunicCore/Vendored/CostUsage/CostUsagePricing.swift +0 -208
  443. package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner+Claude.swift +0 -455
  444. package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner+Timestamp.swift +0 -132
  445. package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner.swift +0 -589
  446. package/Sources/RunicCore/WidgetSnapshot.swift +0 -183
  447. package/Sources/RunicMacroSupport/ProviderRegistrationMacros.swift +0 -14
  448. package/Sources/RunicMacros/ProviderRegistrationMacros.swift +0 -216
  449. package/Sources/RunicWidget/RunicWidgetBundle.swift +0 -79
  450. package/Sources/RunicWidget/RunicWidgetProvider.swift +0 -283
  451. package/Sources/RunicWidget/RunicWidgetViews.swift +0 -680
  452. package/Tests/RunicTests/AntigravityStatusProbeTests.swift +0 -50
  453. package/Tests/RunicTests/AppDelegateTests.swift +0 -48
  454. package/Tests/RunicTests/BrowserCookieOrderLabelTests.swift +0 -21
  455. package/Tests/RunicTests/CLIArgumentParsingTests.swift +0 -69
  456. package/Tests/RunicTests/CLICostTests.swift +0 -64
  457. package/Tests/RunicTests/CLIProviderSelectionTests.swift +0 -21
  458. package/Tests/RunicTests/CLISnapshotTests.swift +0 -71
  459. package/Tests/RunicTests/CLIWebFallbackTests.swift +0 -57
  460. package/Tests/RunicTests/ClaudeOAuthTests.swift +0 -163
  461. package/Tests/RunicTests/ClaudeResilienceTests.swift +0 -29
  462. package/Tests/RunicTests/ClaudeUsageTests.swift +0 -369
  463. package/Tests/RunicTests/CodexOAuthTests.swift +0 -121
  464. package/Tests/RunicTests/CodexUsageLogSourceTests.swift +0 -80
  465. package/Tests/RunicTests/CopilotTokenResolverTests.swift +0 -74
  466. package/Tests/RunicTests/CopilotVSCodeTokenReaderTests.swift +0 -74
  467. package/Tests/RunicTests/CostUsageDecodingTests.swift +0 -392
  468. package/Tests/RunicTests/CostUsagePricingTests.swift +0 -48
  469. package/Tests/RunicTests/CostUsageScannerTests.swift +0 -698
  470. package/Tests/RunicTests/CursorStatusProbeTests.swift +0 -322
  471. package/Tests/RunicTests/FactoryStatusProbeTests.swift +0 -67
  472. package/Tests/RunicTests/GeminiAPITestHelpers.swift +0 -94
  473. package/Tests/RunicTests/GeminiLoginAlertTests.swift +0 -27
  474. package/Tests/RunicTests/GeminiStatusProbeAPITests.swift +0 -283
  475. package/Tests/RunicTests/GeminiStatusProbePlanTests.swift +0 -279
  476. package/Tests/RunicTests/GeminiStatusProbeTests.swift +0 -232
  477. package/Tests/RunicTests/GeminiTestEnvironment.swift +0 -87
  478. package/Tests/RunicTests/GoogleWorkspaceStatusTests.swift +0 -72
  479. package/Tests/RunicTests/InstallOriginTests.swift +0 -17
  480. package/Tests/RunicTests/KeyboardShortcutsBundleTests.swift +0 -9
  481. package/Tests/RunicTests/LiveAccountTests.swift +0 -24
  482. package/Tests/RunicTests/LoadingPatternTests.swift +0 -34
  483. package/Tests/RunicTests/MenuCardModelTests.swift +0 -544
  484. package/Tests/RunicTests/MiniMaxCookieHeaderStoreTestSupport.swift +0 -11
  485. package/Tests/RunicTests/MiniMaxGroupIDStoreTestSupport.swift +0 -11
  486. package/Tests/RunicTests/MiniMaxParsingTests.swift +0 -67
  487. package/Tests/RunicTests/MiniMaxTokenStoreTestSupport.swift +0 -11
  488. package/Tests/RunicTests/OTelGenAILedgerAdapterTests.swift +0 -110
  489. package/Tests/RunicTests/OpenAIDashboardBrowserCookieImporterTests.swift +0 -16
  490. package/Tests/RunicTests/OpenAIDashboardFetcherCreditsWaitTests.swift +0 -74
  491. package/Tests/RunicTests/OpenAIDashboardOffscreenHostTests.swift +0 -26
  492. package/Tests/RunicTests/OpenAIDashboardParserTests.swift +0 -133
  493. package/Tests/RunicTests/OpenAIWebAccountSwitchTests.swift +0 -64
  494. package/Tests/RunicTests/OpenRouterTokenStoreTestSupport.swift +0 -131
  495. package/Tests/RunicTests/PathBuilderTests.swift +0 -236
  496. package/Tests/RunicTests/ProviderFetchPipelineTests.swift +0 -159
  497. package/Tests/RunicTests/ProviderIconResourcesTests.swift +0 -37
  498. package/Tests/RunicTests/ProviderMetadataStatusLinkTests.swift +0 -15
  499. package/Tests/RunicTests/ProviderRegistryTests.swift +0 -29
  500. package/Tests/RunicTests/ProviderSettingsDescriptorTests.swift +0 -236
  501. package/Tests/RunicTests/ProviderToggleStoreTests.swift +0 -50
  502. package/Tests/RunicTests/RunicTests.swift +0 -119
  503. package/Tests/RunicTests/SessionQuotaNotificationLogicTests.swift +0 -35
  504. package/Tests/RunicTests/SettingsStoreTests.swift +0 -265
  505. package/Tests/RunicTests/StatusItemAnimationTests.swift +0 -54
  506. package/Tests/RunicTests/StatusMenuTests.swift +0 -475
  507. package/Tests/RunicTests/StatusProbeTests.swift +0 -376
  508. package/Tests/RunicTests/SubprocessRunnerTests.swift +0 -18
  509. package/Tests/RunicTests/SubscriptionDetectionTests.swift +0 -64
  510. package/Tests/RunicTests/TTYCommandRunnerTests.swift +0 -147
  511. package/Tests/RunicTests/TTYIntegrationTests.swift +0 -41
  512. package/Tests/RunicTests/TeamShowbackExporterTests.swift +0 -157
  513. package/Tests/RunicTests/TextParsingTests.swift +0 -11
  514. package/Tests/RunicTests/UsageFormatterTests.swift +0 -111
  515. package/Tests/RunicTests/UsageLedgerAnomalyDetectionTests.swift +0 -170
  516. package/Tests/RunicTests/UsageLedgerForecastTests.swift +0 -211
  517. package/Tests/RunicTests/UsageLedgerInsightsAdvisorTests.swift +0 -81
  518. package/Tests/RunicTests/UsageLedgerProjectNameTests.swift +0 -168
  519. package/Tests/RunicTests/UsagePaceTests.swift +0 -76
  520. package/Tests/RunicTests/UsagePaceTextTests.swift +0 -108
  521. package/Tests/RunicTests/UsagePolicyEngineTests.swift +0 -89
  522. package/Tests/RunicTests/WidgetSnapshotTests.swift +0 -43
  523. package/Tests/RunicTests/ZaiProviderTests.swift +0 -59
  524. package/Tests/RunicTests/ZaiTokenStoreTestSupport.swift +0 -9
  525. package/TestsLinux/PlatformGatingTests.swift +0 -46
  526. package/appcast.xml +0 -104
  527. package/assets/logo-concept-stack.svg +0 -24
  528. package/assets/logo-minimal-bars.svg +0 -15
  529. package/assets/logo.svg +0 -20
  530. package/assets/logo2.svg +0 -43
  531. package/bin/docs-list +0 -5
  532. package/build-and-run.sh +0 -369
  533. package/docs/.nojekyll +0 -1
  534. package/docs/CNAME +0 -1
  535. package/docs/antigravity.md +0 -75
  536. package/docs/architecture.md +0 -32
  537. package/docs/claude.md +0 -93
  538. package/docs/cli-commands/integration_guide.md +0 -371
  539. package/docs/cli-commands/quick_reference.md +0 -362
  540. package/docs/cli-commands/readme.md +0 -361
  541. package/docs/cli.md +0 -156
  542. package/docs/cloudkit_sync_guide.md +0 -495
  543. package/docs/codebase_review.md +0 -288
  544. package/docs/codex-oauth.md +0 -635
  545. package/docs/codex.md +0 -104
  546. package/docs/codexbar.png +0 -0
  547. package/docs/copilot.md +0 -44
  548. package/docs/cursor.md +0 -46
  549. package/docs/design/designcomparisonchart.md +0 -510
  550. package/docs/design/implementationguide.md +0 -792
  551. package/docs/design/menubaricondesignconcepts.md +0 -796
  552. package/docs/design/mockups/hybridiconconcept.svg +0 -62
  553. package/docs/design/mockups/infinityiconconcept.svg +0 -41
  554. package/docs/design/mockups/infinityiconstates.svg +0 -129
  555. package/docs/design/mockups/wavelogorefined.svg +0 -48
  556. package/docs/design/quick_summary.md +0 -426
  557. package/docs/design/readme.md +0 -478
  558. package/docs/design/sizespecifications.md +0 -575
  559. package/docs/design-system.md +0 -836
  560. package/docs/factory.md +0 -103
  561. package/docs/gemini.md +0 -73
  562. package/docs/icon.md +0 -37
  563. package/docs/icon.png +0 -0
  564. package/docs/index.html +0 -175
  565. package/docs/keychain_fix.md +0 -274
  566. package/docs/minimax.md +0 -71
  567. package/docs/packaging.md +0 -25
  568. package/docs/progress-bar-improvements.md +0 -240
  569. package/docs/progress-bar-quick-reference.md +0 -283
  570. package/docs/progress-bar-technical-details.md +0 -432
  571. package/docs/progress-bar-visual-test.swift +0 -375
  572. package/docs/provider.md +0 -202
  573. package/docs/providers.md +0 -86
  574. package/docs/refactor/macros.md +0 -35
  575. package/docs/refresh-loop.md +0 -22
  576. package/docs/releasing-homebrew.md +0 -35
  577. package/docs/releasing.md +0 -121
  578. package/docs/research/concrete_todo_2026-02-22.md +0 -47
  579. package/docs/research/core-feature-research.md +0 -248
  580. package/docs/research/feature_uiux_roadmap_2026-02-22.md +0 -202
  581. package/docs/research/parity_matrix.md +0 -49
  582. package/docs/research/provider_expansion_candidates_2026-02-22.md +0 -80
  583. package/docs/research/provider_model_token_project_matrix_2026-02-23.md +0 -46
  584. package/docs/research/release_gate_checklist.md +0 -57
  585. package/docs/site.css +0 -505
  586. package/docs/sparkle.md +0 -28
  587. package/docs/status.md +0 -28
  588. package/docs/sync/implementation.md +0 -393
  589. package/docs/sync/readme.md +0 -317
  590. package/docs/sync_files_summary.md +0 -391
  591. package/docs/sync_quick_reference.md +0 -225
  592. package/docs/todo.md +0 -11
  593. package/docs/ui.md +0 -29
  594. package/docs/web-integration.md +0 -9
  595. package/docs/widgets.md +0 -85
  596. package/docs/workflows/error-handling-improvements.md +0 -434
  597. package/docs/workflows/folder_structure.md +0 -299
  598. package/docs/workflows/loading_states.md +0 -446
  599. package/docs/workflows/loading_states_examples.md +0 -565
  600. package/docs/workflows/loading_states_flow.md +0 -430
  601. package/docs/workflows/performance_optimizations.md +0 -457
  602. package/docs/workflows/phase1-cli-testing-report.md +0 -313
  603. package/docs/workflows/quick_reference.md +0 -228
  604. package/docs/workflows/readme.md +0 -59
  605. package/docs/workflows/recent_improvements.md +0 -275
  606. package/docs/workflows/sync_enablement_summary.md +0 -400
  607. package/docs/zai.md +0 -43
  608. package/runic.png +0 -0
  609. package/runic.svg +0 -15
  610. package/version.env +0 -2
@@ -1,67 +0,0 @@
1
- import Foundation
2
- import RunicMacroSupport
3
-
4
- @ProviderDescriptorRegistration
5
- @ProviderDescriptorDefinition
6
- public enum CursorProviderDescriptor {
7
- static func makeDescriptor() -> ProviderDescriptor {
8
- ProviderDescriptor(
9
- id: .cursor,
10
- metadata: ProviderMetadata(
11
- id: .cursor,
12
- displayName: "Cursor",
13
- sessionLabel: "Plan",
14
- weeklyLabel: "On-Demand",
15
- opusLabel: nil,
16
- supportsOpus: false,
17
- supportsCredits: true,
18
- creditsHint: "On-demand usage beyond included plan limits.",
19
- toggleTitle: "Show Cursor usage",
20
- cliName: "cursor",
21
- defaultEnabled: false,
22
- isPrimaryProvider: false,
23
- usesAccountFallback: false,
24
- browserCookieOrder: ProviderBrowserCookieDefaults.defaultImportOrder,
25
- dashboardURL: "https://cursor.com/dashboard?tab=usage",
26
- statusPageURL: "https://status.cursor.com",
27
- statusLinkURL: nil,
28
- usageCoverage: ProviderUsageCoverage(
29
- supportsModelBreakdown: false,
30
- supportsTokenMetrics: false,
31
- supportsProjectAttribution: false)),
32
- branding: ProviderBranding(
33
- iconStyle: .cursor,
34
- iconResourceName: "ProviderIcon-cursor",
35
- color: ProviderColor(red: 0 / 255, green: 191 / 255, blue: 165 / 255)),
36
- tokenCost: ProviderTokenCostConfig(
37
- supportsTokenCost: false,
38
- noDataMessage: { "Cursor cost summary is not supported." }),
39
- fetchPlan: ProviderFetchPlan(
40
- sourceModes: [.auto, .cli],
41
- pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [CursorStatusFetchStrategy()] })),
42
- cli: ProviderCLIConfig(
43
- name: "cursor",
44
- versionDetector: nil))
45
- }
46
- }
47
-
48
- struct CursorStatusFetchStrategy: ProviderFetchStrategy {
49
- let id: String = "cursor.web"
50
- let kind: ProviderFetchKind = .web
51
-
52
- func isAvailable(_: ProviderFetchContext) async -> Bool {
53
- true
54
- }
55
-
56
- func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
57
- let probe = CursorStatusProbe()
58
- let snap = try await probe.fetch()
59
- return self.makeResult(
60
- usage: snap.toUsageSnapshot(),
61
- sourceLabel: "web")
62
- }
63
-
64
- func shouldFallback(on _: Error, context _: ProviderFetchContext) -> Bool {
65
- false
66
- }
67
- }
@@ -1,595 +0,0 @@
1
- import Foundation
2
- import Silo
3
-
4
- #if os(macOS)
5
-
6
- private let cursorCookieImportOrder: BrowserCookieImportOrder =
7
- ProviderDefaults.metadata[.cursor]?.browserCookieOrder ?? Browser.defaultImportOrder
8
-
9
- // MARK: - Cursor Cookie Importer
10
-
11
- /// Imports Cursor session cookies from browser cookies.
12
- public enum CursorCookieImporter {
13
- private static let cookieClient = BrowserCookieClient()
14
- private static let sessionCookieNames: Set<String> = [
15
- "WorkosCursorSessionToken",
16
- "__Secure-next-auth.session-token",
17
- "next-auth.session-token",
18
- ]
19
-
20
- public struct SessionInfo: Sendable {
21
- public let cookies: [HTTPCookie]
22
- public let sourceLabel: String
23
-
24
- public init(cookies: [HTTPCookie], sourceLabel: String) {
25
- self.cookies = cookies
26
- self.sourceLabel = sourceLabel
27
- }
28
-
29
- public var cookieHeader: String {
30
- self.cookies.map { "\($0.name)=\($0.value)" }.joined(separator: "; ")
31
- }
32
- }
33
-
34
- /// Attempts to import Cursor cookies using the standard browser import order.
35
- public static func importSession(logger: ((String) -> Void)? = nil) throws -> SessionInfo {
36
- let log: (String) -> Void = { msg in logger?("[cursor-cookie] \(msg)") }
37
-
38
- let cookieDomains = ["cursor.com", "cursor.sh"]
39
- for browserSource in cursorCookieImportOrder {
40
- do {
41
- let query = BrowserCookieQuery(domains: cookieDomains)
42
- let sources = try Self.cookieClient.records(
43
- matching: query,
44
- in: browserSource)
45
- for source in sources where !source.records.isEmpty {
46
- let httpCookies = BrowserCookieClient.makeHTTPCookies(source.records, origin: query.origin)
47
- if httpCookies.contains(where: { Self.sessionCookieNames.contains($0.name) }) {
48
- log("Found \(httpCookies.count) Cursor cookies in \(source.label)")
49
- return SessionInfo(cookies: httpCookies, sourceLabel: source.label)
50
- } else {
51
- log("\(source.label) cookies found, but no Cursor session cookie present")
52
- }
53
- }
54
- } catch {
55
- log("\(browserSource.displayName) cookie import failed: \(error.localizedDescription)")
56
- }
57
- }
58
-
59
- throw CursorStatusProbeError.noSessionCookie
60
- }
61
-
62
- /// Check if Cursor session cookies are available
63
- public static func hasSession(logger: ((String) -> Void)? = nil) -> Bool {
64
- do {
65
- let session = try self.importSession(logger: logger)
66
- return !session.cookies.isEmpty
67
- } catch {
68
- return false
69
- }
70
- }
71
- }
72
-
73
- // MARK: - Cursor API Models
74
-
75
- public struct CursorUsageSummary: Codable, Sendable {
76
- public let billingCycleStart: String?
77
- public let billingCycleEnd: String?
78
- public let membershipType: String?
79
- public let limitType: String?
80
- public let isUnlimited: Bool?
81
- public let autoModelSelectedDisplayMessage: String?
82
- public let namedModelSelectedDisplayMessage: String?
83
- public let individualUsage: CursorIndividualUsage?
84
- public let teamUsage: CursorTeamUsage?
85
- }
86
-
87
- public struct CursorIndividualUsage: Codable, Sendable {
88
- public let plan: CursorPlanUsage?
89
- public let onDemand: CursorOnDemandUsage?
90
- }
91
-
92
- public struct CursorPlanUsage: Codable, Sendable {
93
- public let enabled: Bool?
94
- /// Usage in cents (e.g., 2000 = $20.00)
95
- public let used: Int?
96
- /// Limit in cents (e.g., 2000 = $20.00)
97
- public let limit: Int?
98
- /// Remaining in cents
99
- public let remaining: Int?
100
- public let breakdown: CursorPlanBreakdown?
101
- public let autoPercentUsed: Double?
102
- public let apiPercentUsed: Double?
103
- public let totalPercentUsed: Double?
104
- }
105
-
106
- public struct CursorPlanBreakdown: Codable, Sendable {
107
- public let included: Int?
108
- public let bonus: Int?
109
- public let total: Int?
110
- }
111
-
112
- public struct CursorOnDemandUsage: Codable, Sendable {
113
- public let enabled: Bool?
114
- /// Usage in cents
115
- public let used: Int?
116
- /// Limit in cents (nil if unlimited)
117
- public let limit: Int?
118
- /// Remaining in cents (nil if unlimited)
119
- public let remaining: Int?
120
- }
121
-
122
- public struct CursorTeamUsage: Codable, Sendable {
123
- public let onDemand: CursorOnDemandUsage?
124
- }
125
-
126
- public struct CursorUserInfo: Codable, Sendable {
127
- public let email: String?
128
- public let emailVerified: Bool?
129
- public let name: String?
130
- public let sub: String?
131
- public let createdAt: String?
132
- public let updatedAt: String?
133
- public let picture: String?
134
-
135
- enum CodingKeys: String, CodingKey {
136
- case email
137
- case emailVerified = "email_verified"
138
- case name
139
- case sub
140
- case createdAt = "created_at"
141
- case updatedAt = "updated_at"
142
- case picture
143
- }
144
- }
145
-
146
- // MARK: - Cursor Status Snapshot
147
-
148
- public struct CursorStatusSnapshot: Sendable {
149
- /// Percentage of included plan usage (0-100)
150
- public let planPercentUsed: Double
151
- /// Included plan usage in USD
152
- public let planUsedUSD: Double
153
- /// Included plan limit in USD
154
- public let planLimitUSD: Double
155
- /// On-demand usage in USD
156
- public let onDemandUsedUSD: Double
157
- /// On-demand limit in USD (nil if unlimited)
158
- public let onDemandLimitUSD: Double?
159
- /// Team on-demand usage in USD (for team plans)
160
- public let teamOnDemandUsedUSD: Double?
161
- /// Team on-demand limit in USD
162
- public let teamOnDemandLimitUSD: Double?
163
- /// Billing cycle reset date
164
- public let billingCycleEnd: Date?
165
- /// Membership type (e.g., "enterprise", "pro", "hobby")
166
- public let membershipType: String?
167
- /// User email
168
- public let accountEmail: String?
169
- /// User name
170
- public let accountName: String?
171
- /// Raw API response for debugging
172
- public let rawJSON: String?
173
-
174
- public init(
175
- planPercentUsed: Double,
176
- planUsedUSD: Double,
177
- planLimitUSD: Double,
178
- onDemandUsedUSD: Double,
179
- onDemandLimitUSD: Double?,
180
- teamOnDemandUsedUSD: Double?,
181
- teamOnDemandLimitUSD: Double?,
182
- billingCycleEnd: Date?,
183
- membershipType: String?,
184
- accountEmail: String?,
185
- accountName: String?,
186
- rawJSON: String?)
187
- {
188
- self.planPercentUsed = planPercentUsed
189
- self.planUsedUSD = planUsedUSD
190
- self.planLimitUSD = planLimitUSD
191
- self.onDemandUsedUSD = onDemandUsedUSD
192
- self.onDemandLimitUSD = onDemandLimitUSD
193
- self.teamOnDemandUsedUSD = teamOnDemandUsedUSD
194
- self.teamOnDemandLimitUSD = teamOnDemandLimitUSD
195
- self.billingCycleEnd = billingCycleEnd
196
- self.membershipType = membershipType
197
- self.accountEmail = accountEmail
198
- self.accountName = accountName
199
- self.rawJSON = rawJSON
200
- }
201
-
202
- /// Convert to UsageSnapshot for the common provider interface
203
- public func toUsageSnapshot() -> UsageSnapshot {
204
- // Primary: Plan usage percentage
205
- let primary = RateWindow(
206
- usedPercent: self.planPercentUsed,
207
- windowMinutes: nil,
208
- resetsAt: self.billingCycleEnd,
209
- resetDescription: self.billingCycleEnd.map { Self.formatResetDate($0) })
210
-
211
- let resolvedOnDemandUsed: Double
212
- let resolvedOnDemandLimit: Double?
213
-
214
- if let teamLimit = self.teamOnDemandLimitUSD,
215
- let teamUsed = self.teamOnDemandUsedUSD
216
- {
217
- resolvedOnDemandUsed = teamUsed
218
- resolvedOnDemandLimit = teamLimit
219
- } else {
220
- resolvedOnDemandUsed = self.onDemandUsedUSD
221
- resolvedOnDemandLimit = self.onDemandLimitUSD
222
- }
223
-
224
- // Secondary: On-demand usage as percentage of limit (team when present, else individual)
225
- let secondary: RateWindow? = if let limit = resolvedOnDemandLimit,
226
- limit > 0
227
- {
228
- RateWindow(
229
- usedPercent: (resolvedOnDemandUsed / limit) * 100,
230
- windowMinutes: nil,
231
- resetsAt: self.billingCycleEnd,
232
- resetDescription: self.billingCycleEnd.map { Self.formatResetDate($0) })
233
- } else {
234
- nil
235
- }
236
-
237
- // Provider cost snapshot for on-demand usage
238
- let providerCost: ProviderCostSnapshot? = if resolvedOnDemandUsed > 0 {
239
- ProviderCostSnapshot(
240
- used: resolvedOnDemandUsed,
241
- limit: resolvedOnDemandLimit ?? 0,
242
- currencyCode: "USD",
243
- period: "monthly",
244
- resetsAt: self.billingCycleEnd,
245
- updatedAt: Date())
246
- } else {
247
- nil
248
- }
249
-
250
- let identity = ProviderIdentitySnapshot(
251
- providerID: .cursor,
252
- accountEmail: self.accountEmail,
253
- accountOrganization: nil,
254
- loginMethod: self.membershipType.map { Self.formatMembershipType($0) })
255
- return UsageSnapshot(
256
- primary: primary,
257
- secondary: secondary,
258
- tertiary: nil,
259
- providerCost: providerCost,
260
- updatedAt: Date(),
261
- identity: identity)
262
- }
263
-
264
- private static func formatResetDate(_ date: Date) -> String {
265
- let formatter = DateFormatter()
266
- formatter.dateFormat = "MMM d 'at' h:mma"
267
- formatter.locale = Locale(identifier: "en_US_POSIX")
268
- return "Resets " + formatter.string(from: date)
269
- }
270
-
271
- private static func formatMembershipType(_ type: String) -> String {
272
- switch type.lowercased() {
273
- case "enterprise":
274
- "Cursor Enterprise"
275
- case "pro":
276
- "Cursor Pro"
277
- case "hobby":
278
- "Cursor Hobby"
279
- case "team":
280
- "Cursor Team"
281
- default:
282
- "Cursor \(type.capitalized)"
283
- }
284
- }
285
- }
286
-
287
- // MARK: - Cursor Status Probe Error
288
-
289
- public enum CursorStatusProbeError: LocalizedError, Sendable {
290
- case notLoggedIn
291
- case networkError(String)
292
- case parseFailed(String)
293
- case noSessionCookie
294
-
295
- public var errorDescription: String? {
296
- switch self {
297
- case .notLoggedIn:
298
- "Not logged in to Cursor. Please log in via the Runic menu."
299
- case let .networkError(msg):
300
- "Cursor API error: \(msg)"
301
- case let .parseFailed(msg):
302
- "Could not parse Cursor usage: \(msg)"
303
- case .noSessionCookie:
304
- "No Cursor session found. Please log in to cursor.com in \(cursorCookieImportOrder.loginHint)."
305
- }
306
- }
307
- }
308
-
309
- // MARK: - Cursor Session Store
310
-
311
- public actor CursorSessionStore {
312
- public static let shared = CursorSessionStore()
313
-
314
- private var sessionCookies: [HTTPCookie] = []
315
- private let fileURL: URL
316
-
317
- private init() {
318
- let fm = FileManager.default
319
- let appSupport = fm.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
320
- ?? fm.temporaryDirectory
321
- let dir = appSupport.appendingPathComponent("Runic", isDirectory: true)
322
- try? fm.createDirectory(at: dir, withIntermediateDirectories: true)
323
- self.fileURL = dir.appendingPathComponent("cursor-session.json")
324
-
325
- // Load saved cookies on init
326
- Task { await self.loadFromDisk() }
327
- }
328
-
329
- public func setCookies(_ cookies: [HTTPCookie]) {
330
- self.sessionCookies = cookies
331
- self.saveToDisk()
332
- }
333
-
334
- public func getCookies() -> [HTTPCookie] {
335
- self.sessionCookies
336
- }
337
-
338
- public func clearCookies() {
339
- self.sessionCookies = []
340
- try? FileManager.default.removeItem(at: self.fileURL)
341
- }
342
-
343
- public func hasValidSession() -> Bool {
344
- !self.sessionCookies.isEmpty
345
- }
346
-
347
- private func saveToDisk() {
348
- // Convert cookie properties to JSON-serializable format
349
- // Date values must be converted to TimeInterval (Double)
350
- let cookieData = self.sessionCookies.compactMap { cookie -> [String: Any]? in
351
- guard let props = cookie.properties else { return nil }
352
- var serializable: [String: Any] = [:]
353
- for (key, value) in props {
354
- let keyString = key.rawValue
355
- if let date = value as? Date {
356
- // Convert Date to TimeInterval for JSON compatibility
357
- serializable[keyString] = date.timeIntervalSince1970
358
- serializable[keyString + "_isDate"] = true
359
- } else if let url = value as? URL {
360
- serializable[keyString] = url.absoluteString
361
- serializable[keyString + "_isURL"] = true
362
- } else if JSONSerialization.isValidJSONObject([value]) ||
363
- value is String ||
364
- value is Bool ||
365
- value is NSNumber
366
- {
367
- serializable[keyString] = value
368
- }
369
- }
370
- return serializable
371
- }
372
- guard !cookieData.isEmpty,
373
- let data = try? JSONSerialization.data(withJSONObject: cookieData, options: [.prettyPrinted])
374
- else {
375
- return
376
- }
377
- try? data.write(to: self.fileURL)
378
- try? FileManager.default.setAttributes([.posixPermissions: 0o600], ofItemAtPath: self.fileURL.path)
379
- }
380
-
381
- private func loadFromDisk() {
382
- guard let data = try? Data(contentsOf: self.fileURL),
383
- let cookieArray = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]]
384
- else { return }
385
-
386
- self.sessionCookies = cookieArray.compactMap { props in
387
- // Convert back to HTTPCookiePropertyKey dictionary
388
- var cookieProps: [HTTPCookiePropertyKey: Any] = [:]
389
- for (key, value) in props {
390
- // Skip marker keys
391
- if key.hasSuffix("_isDate") || key.hasSuffix("_isURL") { continue }
392
-
393
- let propKey = HTTPCookiePropertyKey(key)
394
-
395
- // Check if this was a Date
396
- if props[key + "_isDate"] as? Bool == true, let interval = value as? TimeInterval {
397
- cookieProps[propKey] = Date(timeIntervalSince1970: interval)
398
- }
399
- // Check if this was a URL
400
- else if props[key + "_isURL"] as? Bool == true, let urlString = value as? String {
401
- cookieProps[propKey] = URL(string: urlString)
402
- } else {
403
- cookieProps[propKey] = value
404
- }
405
- }
406
- return HTTPCookie(properties: cookieProps)
407
- }
408
- }
409
- }
410
-
411
- // MARK: - Cursor Status Probe
412
-
413
- public struct CursorStatusProbe: Sendable {
414
- public let baseURL: URL
415
- public var timeout: TimeInterval = 15.0
416
-
417
- public init(baseURL: URL = URL(string: "https://cursor.com")!, timeout: TimeInterval = 15.0) {
418
- self.baseURL = baseURL
419
- self.timeout = timeout
420
- }
421
-
422
- /// Fetch Cursor usage using browser cookies with fallback to stored session.
423
- public func fetch(logger: ((String) -> Void)? = nil) async throws -> CursorStatusSnapshot {
424
- let log: (String) -> Void = { msg in logger?("[cursor] \(msg)") }
425
-
426
- // Try importing cookies from the configured browser order first.
427
- do {
428
- let session = try CursorCookieImporter.importSession(logger: log)
429
- log("Using cookies from \(session.sourceLabel)")
430
- return try await self.fetchWithCookieHeader(session.cookieHeader)
431
- } catch {
432
- log("Browser cookie import failed: \(error.localizedDescription)")
433
- }
434
-
435
- // Fall back to stored session cookies (from "Add Account" login flow)
436
- let storedCookies = await CursorSessionStore.shared.getCookies()
437
- if !storedCookies.isEmpty {
438
- log("Using stored session cookies")
439
- let cookieHeader = storedCookies.map { "\($0.name)=\($0.value)" }.joined(separator: "; ")
440
- do {
441
- return try await self.fetchWithCookieHeader(cookieHeader)
442
- } catch {
443
- if case CursorStatusProbeError.notLoggedIn = error {
444
- // Clear only when auth is invalid; keep for transient failures.
445
- await CursorSessionStore.shared.clearCookies()
446
- log("Stored session invalid, cleared")
447
- } else {
448
- log("Stored session failed: \(error.localizedDescription)")
449
- }
450
- }
451
- }
452
-
453
- throw CursorStatusProbeError.noSessionCookie
454
- }
455
-
456
- private func fetchWithCookieHeader(_ cookieHeader: String) async throws -> CursorStatusSnapshot {
457
- async let usageSummaryTask = self.fetchUsageSummary(cookieHeader: cookieHeader)
458
- async let userInfoTask = self.fetchUserInfo(cookieHeader: cookieHeader)
459
-
460
- let usageSummary = try await usageSummaryTask
461
- let userInfo = try? await userInfoTask
462
-
463
- return self.parseUsageSummary(usageSummary, userInfo: userInfo)
464
- }
465
-
466
- private func fetchUsageSummary(cookieHeader: String) async throws -> CursorUsageSummary {
467
- let url = self.baseURL.appendingPathComponent("/api/usage-summary")
468
- var request = URLRequest(url: url)
469
- request.timeoutInterval = self.timeout
470
- request.setValue("application/json", forHTTPHeaderField: "Accept")
471
- request.setValue(cookieHeader, forHTTPHeaderField: "Cookie")
472
-
473
- let (data, response) = try await URLSession.shared.data(for: request)
474
-
475
- guard let httpResponse = response as? HTTPURLResponse else {
476
- throw CursorStatusProbeError.networkError("Invalid response")
477
- }
478
-
479
- if httpResponse.statusCode == 401 || httpResponse.statusCode == 403 {
480
- throw CursorStatusProbeError.notLoggedIn
481
- }
482
-
483
- guard httpResponse.statusCode == 200 else {
484
- throw CursorStatusProbeError.networkError("HTTP \(httpResponse.statusCode)")
485
- }
486
-
487
- do {
488
- let decoder = JSONDecoder()
489
- return try decoder.decode(CursorUsageSummary.self, from: data)
490
- } catch {
491
- let rawJSON = String(data: data, encoding: .utf8) ?? "<binary>"
492
- throw CursorStatusProbeError
493
- .parseFailed("JSON decode failed: \(error.localizedDescription). Raw: \(rawJSON.prefix(200))")
494
- }
495
- }
496
-
497
- private func fetchUserInfo(cookieHeader: String) async throws -> CursorUserInfo {
498
- let url = self.baseURL.appendingPathComponent("/api/auth/me")
499
- var request = URLRequest(url: url)
500
- request.timeoutInterval = self.timeout
501
- request.setValue("application/json", forHTTPHeaderField: "Accept")
502
- request.setValue(cookieHeader, forHTTPHeaderField: "Cookie")
503
-
504
- let (data, response) = try await URLSession.shared.data(for: request)
505
-
506
- guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
507
- throw CursorStatusProbeError.networkError("Failed to fetch user info")
508
- }
509
-
510
- let decoder = JSONDecoder()
511
- return try decoder.decode(CursorUserInfo.self, from: data)
512
- }
513
-
514
- func parseUsageSummary(_ summary: CursorUsageSummary, userInfo: CursorUserInfo?) -> CursorStatusSnapshot {
515
- // Parse billing cycle end date
516
- let billingCycleEnd: Date? = summary.billingCycleEnd.flatMap { dateString in
517
- let formatter = ISO8601DateFormatter()
518
- formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
519
- return formatter.date(from: dateString) ?? ISO8601DateFormatter().date(from: dateString)
520
- }
521
-
522
- // Convert cents to USD (plan percent derives from raw values to avoid percent unit mismatches).
523
- let planUsedRaw = Double(summary.individualUsage?.plan?.used ?? 0)
524
- let planLimitRaw = Double(summary.individualUsage?.plan?.limit ?? 0)
525
- let planUsed = planUsedRaw / 100.0
526
- let planLimit = planLimitRaw / 100.0
527
- let planPercentUsed: Double = if planLimitRaw > 0 {
528
- (planUsedRaw / planLimitRaw) * 100
529
- } else if let totalPercentUsed = summary.individualUsage?.plan?.totalPercentUsed {
530
- totalPercentUsed <= 1 ? totalPercentUsed * 100 : totalPercentUsed
531
- } else {
532
- 0
533
- }
534
-
535
- let onDemandUsed = Double(summary.individualUsage?.onDemand?.used ?? 0) / 100.0
536
- let onDemandLimit: Double? = summary.individualUsage?.onDemand?.limit.map { Double($0) / 100.0 }
537
-
538
- let teamOnDemandUsed: Double? = summary.teamUsage?.onDemand?.used.map { Double($0) / 100.0 }
539
- let teamOnDemandLimit: Double? = summary.teamUsage?.onDemand?.limit.map { Double($0) / 100.0 }
540
-
541
- return CursorStatusSnapshot(
542
- planPercentUsed: planPercentUsed,
543
- planUsedUSD: planUsed,
544
- planLimitUSD: planLimit,
545
- onDemandUsedUSD: onDemandUsed,
546
- onDemandLimitUSD: onDemandLimit,
547
- teamOnDemandUsedUSD: teamOnDemandUsed,
548
- teamOnDemandLimitUSD: teamOnDemandLimit,
549
- billingCycleEnd: billingCycleEnd,
550
- membershipType: summary.membershipType,
551
- accountEmail: userInfo?.email,
552
- accountName: userInfo?.name,
553
- rawJSON: nil)
554
- }
555
- }
556
-
557
- #else
558
-
559
- // MARK: - Cursor (Unsupported)
560
-
561
- public enum CursorStatusProbeError: LocalizedError, Sendable {
562
- case notSupported
563
-
564
- public var errorDescription: String? {
565
- "Cursor is only supported on macOS."
566
- }
567
- }
568
-
569
- public struct CursorStatusSnapshot: Sendable {
570
- public init() {}
571
-
572
- public func toUsageSnapshot() -> UsageSnapshot {
573
- UsageSnapshot(
574
- primary: RateWindow(usedPercent: 0, windowMinutes: nil, resetsAt: nil, resetDescription: nil),
575
- secondary: nil,
576
- tertiary: nil,
577
- providerCost: nil,
578
- updatedAt: Date(),
579
- identity: nil)
580
- }
581
- }
582
-
583
- public struct CursorStatusProbe: Sendable {
584
- public init(baseURL: URL = URL(string: "https://cursor.com")!, timeout: TimeInterval = 15.0) {
585
- _ = baseURL
586
- _ = timeout
587
- }
588
-
589
- public func fetch(logger: ((String) -> Void)? = nil) async throws -> CursorStatusSnapshot {
590
- _ = logger
591
- throw CursorStatusProbeError.notSupported
592
- }
593
- }
594
-
595
- #endif