@sriinnu/runic 2.0.0 → 2.11.1

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 +256 -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,694 +0,0 @@
1
- import Foundation
2
- #if canImport(Darwin)
3
- import Darwin
4
- #else
5
- import Glibc
6
- #endif
7
-
8
- public struct RateWindow: Codable, Equatable, Sendable {
9
- public let usedPercent: Double
10
- public let windowMinutes: Int?
11
- public let resetsAt: Date?
12
- /// Optional textual reset description (used by Claude CLI UI scrape).
13
- public let resetDescription: String?
14
- /// Optional label for this quota window (for example, a model name).
15
- public let label: String?
16
-
17
- public init(
18
- usedPercent: Double,
19
- windowMinutes: Int?,
20
- resetsAt: Date?,
21
- resetDescription: String?,
22
- label: String? = nil)
23
- {
24
- self.usedPercent = usedPercent
25
- self.windowMinutes = windowMinutes
26
- self.resetsAt = resetsAt
27
- self.resetDescription = resetDescription
28
- self.label = label
29
- }
30
-
31
- public var remainingPercent: Double {
32
- max(0, 100 - self.usedPercent)
33
- }
34
- }
35
-
36
- public struct ProviderIdentitySnapshot: Codable, Sendable {
37
- public let providerID: UsageProvider?
38
- public let accountEmail: String?
39
- public let accountOrganization: String?
40
- public let loginMethod: String?
41
-
42
- public init(
43
- providerID: UsageProvider?,
44
- accountEmail: String?,
45
- accountOrganization: String?,
46
- loginMethod: String?)
47
- {
48
- self.providerID = providerID
49
- self.accountEmail = accountEmail
50
- self.accountOrganization = accountOrganization
51
- self.loginMethod = loginMethod
52
- }
53
-
54
- public func scoped(to provider: UsageProvider) -> ProviderIdentitySnapshot {
55
- if self.providerID == provider { return self }
56
- return ProviderIdentitySnapshot(
57
- providerID: provider,
58
- accountEmail: self.accountEmail,
59
- accountOrganization: self.accountOrganization,
60
- loginMethod: self.loginMethod)
61
- }
62
- }
63
-
64
- public struct UsageSnapshot: Codable, Sendable {
65
- public let primary: RateWindow
66
- public let secondary: RateWindow?
67
- public let tertiary: RateWindow?
68
- public let providerCost: ProviderCostSnapshot?
69
- public let zaiUsage: ZaiUsageSnapshot?
70
- public let updatedAt: Date
71
- public let identity: ProviderIdentitySnapshot?
72
-
73
- private enum CodingKeys: String, CodingKey {
74
- case primary
75
- case secondary
76
- case tertiary
77
- case providerCost
78
- case updatedAt
79
- case identity
80
- case accountEmail
81
- case accountOrganization
82
- case loginMethod
83
- }
84
-
85
- public init(
86
- primary: RateWindow,
87
- secondary: RateWindow?,
88
- tertiary: RateWindow? = nil,
89
- providerCost: ProviderCostSnapshot? = nil,
90
- zaiUsage: ZaiUsageSnapshot? = nil,
91
- updatedAt: Date,
92
- identity: ProviderIdentitySnapshot? = nil)
93
- {
94
- self.primary = primary
95
- self.secondary = secondary
96
- self.tertiary = tertiary
97
- self.providerCost = providerCost
98
- self.zaiUsage = zaiUsage
99
- self.updatedAt = updatedAt
100
- self.identity = identity
101
- }
102
-
103
- public init(from decoder: Decoder) throws {
104
- let container = try decoder.container(keyedBy: CodingKeys.self)
105
- self.primary = try container.decode(RateWindow.self, forKey: .primary)
106
- self.secondary = try container.decodeIfPresent(RateWindow.self, forKey: .secondary)
107
- self.tertiary = try container.decodeIfPresent(RateWindow.self, forKey: .tertiary)
108
- self.providerCost = try container.decodeIfPresent(ProviderCostSnapshot.self, forKey: .providerCost)
109
- self.zaiUsage = nil // Not persisted, fetched fresh each time
110
- self.updatedAt = try container.decode(Date.self, forKey: .updatedAt)
111
- if let identity = try container.decodeIfPresent(ProviderIdentitySnapshot.self, forKey: .identity) {
112
- self.identity = identity
113
- } else {
114
- let email = try container.decodeIfPresent(String.self, forKey: .accountEmail)
115
- let organization = try container.decodeIfPresent(String.self, forKey: .accountOrganization)
116
- let loginMethod = try container.decodeIfPresent(String.self, forKey: .loginMethod)
117
- if email != nil || organization != nil || loginMethod != nil {
118
- self.identity = ProviderIdentitySnapshot(
119
- providerID: nil,
120
- accountEmail: email,
121
- accountOrganization: organization,
122
- loginMethod: loginMethod)
123
- } else {
124
- self.identity = nil
125
- }
126
- }
127
- }
128
-
129
- public func encode(to encoder: Encoder) throws {
130
- var container = encoder.container(keyedBy: CodingKeys.self)
131
- try container.encode(self.primary, forKey: .primary)
132
- if let secondary = self.secondary {
133
- try container.encode(secondary, forKey: .secondary)
134
- } else {
135
- try container.encodeNil(forKey: .secondary)
136
- }
137
- try container.encodeIfPresent(self.tertiary, forKey: .tertiary)
138
- try container.encodeIfPresent(self.providerCost, forKey: .providerCost)
139
- try container.encode(self.updatedAt, forKey: .updatedAt)
140
- try container.encodeIfPresent(self.identity, forKey: .identity)
141
- try container.encodeIfPresent(self.identity?.accountEmail, forKey: .accountEmail)
142
- try container.encodeIfPresent(self.identity?.accountOrganization, forKey: .accountOrganization)
143
- try container.encodeIfPresent(self.identity?.loginMethod, forKey: .loginMethod)
144
- }
145
-
146
- public func identity(for provider: UsageProvider) -> ProviderIdentitySnapshot? {
147
- guard let identity, identity.providerID == provider else { return nil }
148
- return identity
149
- }
150
-
151
- public func accountEmail(for provider: UsageProvider) -> String? {
152
- self.identity(for: provider)?.accountEmail
153
- }
154
-
155
- public func accountOrganization(for provider: UsageProvider) -> String? {
156
- self.identity(for: provider)?.accountOrganization
157
- }
158
-
159
- public func loginMethod(for provider: UsageProvider) -> String? {
160
- self.identity(for: provider)?.loginMethod
161
- }
162
-
163
- public func scoped(to provider: UsageProvider) -> UsageSnapshot {
164
- guard let identity else { return self }
165
- let scopedIdentity = identity.scoped(to: provider)
166
- if scopedIdentity.providerID == identity.providerID { return self }
167
- return UsageSnapshot(
168
- primary: self.primary,
169
- secondary: self.secondary,
170
- tertiary: self.tertiary,
171
- providerCost: self.providerCost,
172
- zaiUsage: self.zaiUsage,
173
- updatedAt: self.updatedAt,
174
- identity: scopedIdentity)
175
- }
176
- }
177
-
178
- public struct AccountInfo: Equatable, Sendable {
179
- public let email: String?
180
- public let plan: String?
181
-
182
- public init(email: String?, plan: String?) {
183
- self.email = email
184
- self.plan = plan
185
- }
186
- }
187
-
188
- public enum UsageError: LocalizedError, Sendable {
189
- case noSessions
190
- case noRateLimitsFound
191
- case decodeFailed
192
-
193
- public var errorDescription: String? {
194
- switch self {
195
- case .noSessions:
196
- "No Codex sessions found yet. Run at least one Codex prompt first."
197
- case .noRateLimitsFound:
198
- "Found sessions, but no rate limit events yet."
199
- case .decodeFailed:
200
- "Could not parse Codex session log."
201
- }
202
- }
203
- }
204
-
205
- // MARK: - Codex RPC client (local process)
206
-
207
- private struct RPCAccountResponse: Decodable {
208
- let account: RPCAccountDetails?
209
- let requiresOpenaiAuth: Bool?
210
- }
211
-
212
- private enum RPCAccountDetails: Decodable {
213
- case apiKey
214
- case chatgpt(email: String, planType: String)
215
-
216
- enum CodingKeys: String, CodingKey {
217
- case type
218
- case email
219
- case planType
220
- }
221
-
222
- init(from decoder: Decoder) throws {
223
- let container = try decoder.container(keyedBy: CodingKeys.self)
224
- let type = try container.decode(String.self, forKey: .type)
225
- switch type.lowercased() {
226
- case "apikey":
227
- self = .apiKey
228
- case "chatgpt":
229
- let email = try container.decodeIfPresent(String.self, forKey: .email) ?? "unknown"
230
- let plan = try container.decodeIfPresent(String.self, forKey: .planType) ?? "unknown"
231
- self = .chatgpt(email: email, planType: plan)
232
- default:
233
- throw DecodingError.dataCorruptedError(
234
- forKey: .type,
235
- in: container,
236
- debugDescription: "Unknown account type \(type)")
237
- }
238
- }
239
- }
240
-
241
- private struct RPCRateLimitsResponse: Decodable, Encodable {
242
- let rateLimits: RPCRateLimitSnapshot
243
- }
244
-
245
- private struct RPCRateLimitSnapshot: Decodable, Encodable {
246
- let primary: RPCRateLimitWindow?
247
- let secondary: RPCRateLimitWindow?
248
- let credits: RPCCreditsSnapshot?
249
- }
250
-
251
- private struct RPCRateLimitWindow: Decodable, Encodable {
252
- let usedPercent: Double
253
- let windowDurationMins: Int?
254
- let resetsAt: Int?
255
- }
256
-
257
- private struct RPCCreditsSnapshot: Decodable, Encodable {
258
- let hasCredits: Bool
259
- let unlimited: Bool
260
- let balance: String?
261
- }
262
-
263
- private enum RPCWireError: Error, CustomStringConvertible {
264
- case startFailed(String)
265
- case requestFailed(String)
266
- case malformed(String)
267
-
268
- var description: String {
269
- switch self {
270
- case let .startFailed(message):
271
- "Failed to start codex app-server: \(message)"
272
- case let .requestFailed(message):
273
- "RPC request failed: \(message)"
274
- case let .malformed(message):
275
- "Malformed response: \(message)"
276
- }
277
- }
278
- }
279
-
280
- /// RPC helper used on background tasks; safe because we confine it to the owning task.
281
- private final class CodexRPCClient: @unchecked Sendable {
282
- private let process = Process()
283
- private let stdinPipe = Pipe()
284
- private let stdoutPipe = Pipe()
285
- private let stderrPipe = Pipe()
286
- private let stdoutLineStream: AsyncStream<Data>
287
- private let stdoutLineContinuation: AsyncStream<Data>.Continuation
288
- private var nextID = 1
289
- private var processGroup: pid_t?
290
-
291
- private final class LineBuffer: @unchecked Sendable {
292
- private let lock = NSLock()
293
- private var buffer = Data()
294
-
295
- func appendAndDrainLines(_ data: Data) -> [Data] {
296
- self.lock.lock()
297
- defer { self.lock.unlock() }
298
-
299
- self.buffer.append(data)
300
- var out: [Data] = []
301
- while let newline = self.buffer.firstIndex(of: 0x0A) {
302
- let lineData = Data(self.buffer[..<newline])
303
- self.buffer.removeSubrange(...newline)
304
- if !lineData.isEmpty {
305
- out.append(lineData)
306
- }
307
- }
308
- return out
309
- }
310
- }
311
-
312
- private static func debugWriteStderr(_ message: String) {
313
- #if !os(Linux)
314
- fputs(message, stderr)
315
- #endif
316
- }
317
-
318
- init(
319
- executable: String = "codex",
320
- arguments: [String] = ["-s", "read-only", "-a", "untrusted", "app-server"]) throws
321
- {
322
- var stdoutContinuation: AsyncStream<Data>.Continuation!
323
- self.stdoutLineStream = AsyncStream<Data> { continuation in
324
- stdoutContinuation = continuation
325
- }
326
- self.stdoutLineContinuation = stdoutContinuation
327
-
328
- let resolvedExec = BinaryLocator.resolveCodexBinary()
329
- ?? TTYCommandRunner.which(executable)
330
-
331
- guard let resolvedExec else {
332
- throw RPCWireError.startFailed(
333
- "Codex CLI not found. Install with `npm i -g @openai/codex` (or bun) then relaunch Runic.")
334
- }
335
- var env = ProcessInfo.processInfo.environment
336
- env["PATH"] = PathBuilder.effectivePATH(
337
- purposes: [.rpc, .nodeTooling],
338
- env: env)
339
-
340
- self.process.environment = env
341
- self.process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
342
- self.process.arguments = [resolvedExec] + arguments
343
- self.process.standardInput = self.stdinPipe
344
- self.process.standardOutput = self.stdoutPipe
345
- self.process.standardError = self.stderrPipe
346
-
347
- do {
348
- try self.process.run()
349
- } catch {
350
- throw RPCWireError.startFailed(error.localizedDescription)
351
- }
352
-
353
- let pid = self.process.processIdentifier
354
- if setpgid(pid, pid) == 0 {
355
- self.processGroup = pid
356
- }
357
-
358
- let stdoutHandle = self.stdoutPipe.fileHandleForReading
359
- let stdoutLineContinuation = self.stdoutLineContinuation
360
- let stdoutBuffer = LineBuffer()
361
- stdoutHandle.readabilityHandler = { handle in
362
- let data = handle.availableData
363
- if data.isEmpty {
364
- handle.readabilityHandler = nil
365
- stdoutLineContinuation.finish()
366
- return
367
- }
368
-
369
- let lines = stdoutBuffer.appendAndDrainLines(data)
370
-
371
- for lineData in lines {
372
- stdoutLineContinuation.yield(lineData)
373
- }
374
- }
375
-
376
- let stderrHandle = self.stderrPipe.fileHandleForReading
377
- stderrHandle.readabilityHandler = { handle in
378
- let data = handle.availableData
379
- // When the child closes stderr, availableData returns empty and will keep re-firing; clear the handler
380
- // to avoid a busy read loop on the file-descriptor monitoring queue.
381
- if data.isEmpty {
382
- handle.readabilityHandler = nil
383
- return
384
- }
385
- guard let text = String(data: data, encoding: .utf8), !text.isEmpty else { return }
386
- for line in text.split(whereSeparator: \.isNewline) {
387
- Self.debugWriteStderr("[codex stderr] \(line)\n")
388
- }
389
- }
390
- }
391
-
392
- func initialize(clientName: String, clientVersion: String) async throws {
393
- _ = try await self.request(
394
- method: "initialize",
395
- params: ["clientInfo": ["name": clientName, "version": clientVersion]])
396
- try self.sendNotification(method: "initialized")
397
- }
398
-
399
- func fetchAccount() async throws -> RPCAccountResponse {
400
- let message = try await self.request(method: "account/read")
401
- return try self.decodeResult(from: message)
402
- }
403
-
404
- func fetchRateLimits() async throws -> RPCRateLimitsResponse {
405
- let message = try await self.request(method: "account/rateLimits/read")
406
- return try self.decodeResult(from: message)
407
- }
408
-
409
- func shutdown() {
410
- self.stdoutPipe.fileHandleForReading.readabilityHandler = nil
411
- self.stderrPipe.fileHandleForReading.readabilityHandler = nil
412
- if self.process.isRunning {
413
- self.process.terminate()
414
- }
415
- if let pgid = self.processGroup {
416
- kill(-pgid, SIGTERM)
417
- }
418
- let waitDeadline = Date().addingTimeInterval(2.0)
419
- while self.process.isRunning, Date() < waitDeadline {
420
- usleep(100_000)
421
- }
422
- if self.process.isRunning {
423
- if let pgid = self.processGroup {
424
- kill(-pgid, SIGKILL)
425
- }
426
- kill(self.process.processIdentifier, SIGKILL)
427
- }
428
- try? self.stdinPipe.fileHandleForWriting.close()
429
- try? self.stdoutPipe.fileHandleForReading.close()
430
- try? self.stderrPipe.fileHandleForReading.close()
431
- }
432
-
433
- // MARK: - JSON-RPC helpers
434
-
435
- private func request(method: String, params: [String: Any]? = nil) async throws -> [String: Any] {
436
- let id = self.nextID
437
- self.nextID += 1
438
- try self.sendRequest(id: id, method: method, params: params)
439
-
440
- while true {
441
- let message = try await self.readNextMessage()
442
-
443
- if message["id"] == nil, let methodName = message["method"] as? String {
444
- Self.debugWriteStderr("[codex notify] \(methodName)\n")
445
- continue
446
- }
447
-
448
- guard let messageID = self.jsonID(message["id"]), messageID == id else { continue }
449
-
450
- if let error = message["error"] as? [String: Any], let messageText = error["message"] as? String {
451
- throw RPCWireError.requestFailed(messageText)
452
- }
453
-
454
- return message
455
- }
456
- }
457
-
458
- private func sendNotification(method: String, params: [String: Any]? = nil) throws {
459
- let paramsValue: Any = params ?? [:]
460
- try self.sendPayload(["method": method, "params": paramsValue])
461
- }
462
-
463
- private func sendRequest(id: Int, method: String, params: [String: Any]?) throws {
464
- let paramsValue: Any = params ?? [:]
465
- let payload: [String: Any] = ["id": id, "method": method, "params": paramsValue]
466
- try self.sendPayload(payload)
467
- }
468
-
469
- private func sendPayload(_ payload: [String: Any]) throws {
470
- let data = try JSONSerialization.data(withJSONObject: payload)
471
- self.stdinPipe.fileHandleForWriting.write(data)
472
- self.stdinPipe.fileHandleForWriting.write(Data([0x0A]))
473
- }
474
-
475
- private func readNextMessage() async throws -> [String: Any] {
476
- for await lineData in self.stdoutLineStream {
477
- if lineData.isEmpty { continue }
478
- if let json = try? JSONSerialization.jsonObject(with: lineData) as? [String: Any] {
479
- return json
480
- }
481
- }
482
- throw RPCWireError.malformed("codex app-server closed stdout")
483
- }
484
-
485
- private func decodeResult<T: Decodable>(from message: [String: Any]) throws -> T {
486
- guard let result = message["result"] else {
487
- throw RPCWireError.malformed("missing result field")
488
- }
489
- let data = try JSONSerialization.data(withJSONObject: result)
490
- let decoder = JSONDecoder()
491
- return try decoder.decode(T.self, from: data)
492
- }
493
-
494
- private func jsonID(_ value: Any?) -> Int? {
495
- switch value {
496
- case let int as Int:
497
- int
498
- case let number as NSNumber:
499
- number.intValue
500
- default:
501
- nil
502
- }
503
- }
504
- }
505
-
506
- // MARK: - Public fetcher used by the app
507
-
508
- public struct UsageFetcher: Sendable {
509
- private let environment: [String: String]
510
-
511
- public init(environment: [String: String] = ProcessInfo.processInfo.environment) {
512
- self.environment = environment
513
- LoginShellPathCache.shared.captureOnce()
514
- }
515
-
516
- public func loadLatestUsage() async throws -> UsageSnapshot {
517
- try await self.withFallback(primary: self.loadRPCUsage, secondary: self.loadTTYUsage)
518
- }
519
-
520
- private func loadRPCUsage() async throws -> UsageSnapshot {
521
- let rpc = try CodexRPCClient()
522
- defer { rpc.shutdown() }
523
-
524
- try await rpc.initialize(clientName: "runic", clientVersion: "0.5.4")
525
- // The app-server answers on a single stdout stream, so keep requests
526
- // serialized to avoid starving one reader when multiple awaiters race
527
- // for the same pipe.
528
- let limits = try await rpc.fetchRateLimits().rateLimits
529
- let account = try? await rpc.fetchAccount()
530
-
531
- guard let primary = Self.makeWindow(from: limits.primary),
532
- let secondary = Self.makeWindow(from: limits.secondary)
533
- else {
534
- throw UsageError.noRateLimitsFound
535
- }
536
-
537
- let identity = ProviderIdentitySnapshot(
538
- providerID: .codex,
539
- accountEmail: account?.account.flatMap { details in
540
- if case let .chatgpt(email, _) = details { email } else { nil }
541
- },
542
- accountOrganization: nil,
543
- loginMethod: account?.account.flatMap { details in
544
- if case let .chatgpt(_, plan) = details { plan } else { nil }
545
- })
546
- return UsageSnapshot(
547
- primary: primary,
548
- secondary: secondary,
549
- tertiary: nil,
550
- updatedAt: Date(),
551
- identity: identity)
552
- }
553
-
554
- private func loadTTYUsage() async throws -> UsageSnapshot {
555
- let status = try await CodexStatusProbe().fetch()
556
- guard let fiveLeft = status.fiveHourPercentLeft, let weekLeft = status.weeklyPercentLeft else {
557
- throw UsageError.noRateLimitsFound
558
- }
559
-
560
- let primary = RateWindow(
561
- usedPercent: max(0, 100 - Double(fiveLeft)),
562
- windowMinutes: 300,
563
- resetsAt: nil,
564
- resetDescription: status.fiveHourResetDescription)
565
- let secondary = RateWindow(
566
- usedPercent: max(0, 100 - Double(weekLeft)),
567
- windowMinutes: 10080,
568
- resetsAt: nil,
569
- resetDescription: status.weeklyResetDescription)
570
-
571
- return UsageSnapshot(
572
- primary: primary,
573
- secondary: secondary,
574
- tertiary: nil,
575
- updatedAt: Date(),
576
- identity: nil)
577
- }
578
-
579
- public func loadLatestCredits() async throws -> CreditsSnapshot {
580
- try await self.withFallback(primary: self.loadRPCCredits, secondary: self.loadTTYCredits)
581
- }
582
-
583
- private func loadRPCCredits() async throws -> CreditsSnapshot {
584
- let rpc = try CodexRPCClient()
585
- defer { rpc.shutdown() }
586
- try await rpc.initialize(clientName: "runic", clientVersion: "0.5.4")
587
- let limits = try await rpc.fetchRateLimits().rateLimits
588
- guard let credits = limits.credits else { throw UsageError.noRateLimitsFound }
589
- let remaining = Self.parseCredits(credits.balance)
590
- return CreditsSnapshot(remaining: remaining, events: [], updatedAt: Date())
591
- }
592
-
593
- private func loadTTYCredits() async throws -> CreditsSnapshot {
594
- let status = try await CodexStatusProbe().fetch()
595
- guard let credits = status.credits else { throw UsageError.noRateLimitsFound }
596
- return CreditsSnapshot(remaining: credits, events: [], updatedAt: Date())
597
- }
598
-
599
- private func withFallback<T>(
600
- primary: @escaping () async throws -> T,
601
- secondary: @escaping () async throws -> T) async throws -> T
602
- {
603
- do {
604
- return try await primary()
605
- } catch let primaryError {
606
- do {
607
- return try await secondary()
608
- } catch {
609
- // Preserve the original failure so callers see the primary path error.
610
- throw primaryError
611
- }
612
- }
613
- }
614
-
615
- public func debugRawRateLimits() async -> String {
616
- do {
617
- let rpc = try CodexRPCClient()
618
- defer { rpc.shutdown() }
619
- try await rpc.initialize(clientName: "runic", clientVersion: "0.5.4")
620
- let limits = try await rpc.fetchRateLimits()
621
- let data = try JSONEncoder().encode(limits)
622
- return String(data: data, encoding: .utf8) ?? "<unprintable>"
623
- } catch {
624
- return "Codex RPC probe failed: \(error)"
625
- }
626
- }
627
-
628
- public func loadAccountInfo() -> AccountInfo {
629
- // Keep using auth.json for quick startup (non-blocking, no RPC spin-up required).
630
- let authURL = URL(fileURLWithPath: self.environment["CODEX_HOME"] ?? "\(NSHomeDirectory())/.codex")
631
- .appendingPathComponent("auth.json")
632
- guard let data = try? Data(contentsOf: authURL),
633
- let auth = try? JSONDecoder().decode(AuthFile.self, from: data),
634
- let idToken = auth.tokens?.idToken
635
- else {
636
- return AccountInfo(email: nil, plan: nil)
637
- }
638
-
639
- guard let payload = UsageFetcher.parseJWT(idToken) else {
640
- return AccountInfo(email: nil, plan: nil)
641
- }
642
-
643
- let authDict = payload["https://api.openai.com/auth"] as? [String: Any]
644
- let profileDict = payload["https://api.openai.com/profile"] as? [String: Any]
645
-
646
- let plan = (authDict?["chatgpt_plan_type"] as? String)
647
- ?? (payload["chatgpt_plan_type"] as? String)
648
-
649
- let email = (payload["email"] as? String)
650
- ?? (profileDict?["email"] as? String)
651
-
652
- return AccountInfo(email: email, plan: plan)
653
- }
654
-
655
- // MARK: - Helpers
656
-
657
- private static func makeWindow(from rpc: RPCRateLimitWindow?) -> RateWindow? {
658
- guard let rpc else { return nil }
659
- let resetsAtDate = rpc.resetsAt.map { Date(timeIntervalSince1970: TimeInterval($0)) }
660
- let resetDescription = resetsAtDate.map { UsageFormatter.resetDescription(from: $0) }
661
- return RateWindow(
662
- usedPercent: rpc.usedPercent,
663
- windowMinutes: rpc.windowDurationMins,
664
- resetsAt: resetsAtDate,
665
- resetDescription: resetDescription)
666
- }
667
-
668
- private static func parseCredits(_ balance: String?) -> Double {
669
- guard let balance, let val = Double(balance) else { return 0 }
670
- return val
671
- }
672
-
673
- public static func parseJWT(_ token: String) -> [String: Any]? {
674
- let parts = token.split(separator: ".")
675
- guard parts.count >= 2 else { return nil }
676
- let payloadPart = parts[1]
677
-
678
- var padded = String(payloadPart)
679
- .replacingOccurrences(of: "-", with: "+")
680
- .replacingOccurrences(of: "_", with: "/")
681
- while padded.count % 4 != 0 {
682
- padded.append("=")
683
- }
684
- guard let data = Data(base64Encoded: padded) else { return nil }
685
- guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { return nil }
686
- return json
687
- }
688
- }
689
-
690
- /// Minimal auth.json struct preserved from previous implementation
691
- private struct AuthFile: Decodable {
692
- struct Tokens: Decodable { let idToken: String? }
693
- let tokens: Tokens?
694
- }