@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1 → 2.0.0-alpha.4

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 (384) hide show
  1. package/LICENSE +0 -0
  2. package/native-manifest.json +1088 -134
  3. package/package.json +160 -1
  4. package/plugins/UPSTREAM-LICENSES.md +113 -0
  5. package/plugins/_provider-icons/LICENSE +21 -0
  6. package/plugins/_provider-icons/NOTICE +12 -0
  7. package/plugins/_provider-icons/licenses/CodexBar-MIT.txt +21 -0
  8. package/plugins/_provider-icons/licenses/LobeHub-MIT.txt +21 -0
  9. package/plugins/_provider-icons/licenses/UsageStat-Bar-MIT.txt +21 -0
  10. package/plugins/_provider-icons/manifest.json +1219 -0
  11. package/plugins/_provider-icons/provenance.json +269 -0
  12. package/plugins/_provider-icons/source.json +4 -0
  13. package/plugins/abacus-ai/icon-color.svg +18 -0
  14. package/plugins/abacus-ai/icon.svg +0 -0
  15. package/plugins/abacus-ai/plugin.js +0 -0
  16. package/plugins/abacus-ai/plugin.json +0 -0
  17. package/plugins/aiand/icon.svg +6 -0
  18. package/plugins/aiand/plugin.js +108 -0
  19. package/plugins/aiand/plugin.json +22 -0
  20. package/plugins/aixy/LICENSE +21 -0
  21. package/plugins/aixy/plugin.js +261 -0
  22. package/plugins/aixy/plugin.json +24 -0
  23. package/plugins/alibaba/icon-color.svg +0 -0
  24. package/plugins/alibaba/icon.svg +0 -0
  25. package/plugins/alibaba/plugin.js +0 -0
  26. package/plugins/alibaba/plugin.json +0 -0
  27. package/plugins/alibaba-token-plan/icon-color.svg +0 -0
  28. package/plugins/alibaba-token-plan/icon.svg +0 -0
  29. package/plugins/alibaba-token-plan/plugin.js +0 -0
  30. package/plugins/alibaba-token-plan/plugin.json +0 -0
  31. package/plugins/amp/icon-color.svg +0 -0
  32. package/plugins/amp/icon-conflict.svg +0 -0
  33. package/plugins/amp/icon.svg +0 -0
  34. package/plugins/amp/plugin.js +0 -0
  35. package/plugins/amp/plugin.json +0 -0
  36. package/plugins/antigravity/icon-color.svg +0 -0
  37. package/plugins/antigravity/icon-conflict.svg +0 -0
  38. package/plugins/antigravity/icon.svg +0 -0
  39. package/plugins/antigravity/plugin.js +136 -46
  40. package/plugins/antigravity/plugin.json +0 -0
  41. package/plugins/antigravity-cli/icon-color.svg +1 -0
  42. package/plugins/antigravity-cli/icon.svg +1 -3
  43. package/plugins/antigravity-cli/plugin.js +11 -15
  44. package/plugins/antigravity-cli/plugin.json +0 -0
  45. package/plugins/antigravity-ide/icon-color.svg +1 -0
  46. package/plugins/antigravity-ide/icon.svg +1 -3
  47. package/plugins/antigravity-ide/plugin.js +0 -0
  48. package/plugins/antigravity-ide/plugin.json +0 -0
  49. package/plugins/atlascloud/LICENSE +21 -0
  50. package/plugins/atlascloud/icon-color.svg +1 -0
  51. package/plugins/atlascloud/icon.svg +1 -0
  52. package/plugins/atlascloud/plugin.js +49 -0
  53. package/plugins/atlascloud/plugin.json +23 -0
  54. package/plugins/augment/icon-color.svg +14 -0
  55. package/plugins/augment/icon.svg +0 -0
  56. package/plugins/augment/plugin.js +0 -0
  57. package/plugins/augment/plugin.json +0 -0
  58. package/plugins/aws-bedrock/icon-color.svg +0 -0
  59. package/plugins/aws-bedrock/icon.svg +0 -0
  60. package/plugins/aws-bedrock/plugin.js +0 -0
  61. package/plugins/aws-bedrock/plugin.json +0 -0
  62. package/plugins/azure-openai/icon-color.svg +0 -0
  63. package/plugins/azure-openai/icon.svg +0 -0
  64. package/plugins/azure-openai/plugin.js +0 -0
  65. package/plugins/azure-openai/plugin.json +0 -0
  66. package/plugins/bifrost/LICENSE +21 -0
  67. package/plugins/bifrost/plugin.js +361 -0
  68. package/plugins/bifrost/plugin.json +23 -0
  69. package/plugins/chutes/icon.svg +0 -0
  70. package/plugins/chutes/plugin.js +0 -0
  71. package/plugins/chutes/plugin.json +0 -0
  72. package/plugins/claude/icon-color.svg +0 -0
  73. package/plugins/claude/icon.svg +0 -0
  74. package/plugins/claude/plugin.js +358 -161
  75. package/plugins/claude/plugin.json +1 -1
  76. package/plugins/clawrouter/icon.svg +7 -0
  77. package/plugins/clawrouter/plugin.js +45 -0
  78. package/plugins/clawrouter/plugin.json +22 -0
  79. package/plugins/clinepass/icon.svg +4 -0
  80. package/plugins/clinepass/plugin.js +87 -0
  81. package/plugins/clinepass/plugin.json +23 -0
  82. package/plugins/codebuddy/plugin.js +331 -0
  83. package/plugins/codebuddy/plugin.json +30 -0
  84. package/plugins/codebuff/icon-color.svg +92 -0
  85. package/plugins/codebuff/icon.svg +0 -0
  86. package/plugins/codebuff/plugin.js +0 -0
  87. package/plugins/codebuff/plugin.json +0 -0
  88. package/plugins/coderabbit/plugin.js +25 -0
  89. package/plugins/coderabbit/plugin.json +12 -0
  90. package/plugins/codex/icon-color.svg +0 -0
  91. package/plugins/codex/icon.svg +0 -0
  92. package/plugins/codex/plugin.js +8 -2
  93. package/plugins/codex/plugin.json +0 -0
  94. package/plugins/command-code/icon-color.svg +3 -0
  95. package/plugins/command-code/icon.svg +0 -0
  96. package/plugins/command-code/plugin.js +14 -3
  97. package/plugins/command-code/plugin.json +0 -0
  98. package/plugins/copilot/icon-color.svg +0 -0
  99. package/plugins/copilot/icon.svg +1 -1
  100. package/plugins/copilot/plugin.js +61 -9
  101. package/plugins/copilot/plugin.json +4 -1
  102. package/plugins/crof/icon-color.svg +3 -0
  103. package/plugins/crof/icon.svg +0 -0
  104. package/plugins/crof/plugin.js +0 -0
  105. package/plugins/crof/plugin.json +0 -0
  106. package/plugins/crofai/icon-color.svg +3 -0
  107. package/plugins/crofai/icon.svg +2 -15
  108. package/plugins/crofai/plugin.js +0 -0
  109. package/plugins/crofai/plugin.json +0 -0
  110. package/plugins/cursor/icon-color.svg +1 -0
  111. package/plugins/cursor/icon-conflict.svg +0 -0
  112. package/plugins/cursor/icon.svg +0 -0
  113. package/plugins/cursor/plugin.js +46 -9
  114. package/plugins/cursor/plugin.json +3 -2
  115. package/plugins/cursor-nightly/icon.png +0 -0
  116. package/plugins/cursor-nightly/plugin.js +45 -8
  117. package/plugins/cursor-nightly/plugin.json +3 -2
  118. package/plugins/deepgram/icon.svg +0 -0
  119. package/plugins/deepgram/plugin.js +0 -0
  120. package/plugins/deepgram/plugin.json +0 -0
  121. package/plugins/deepinfra/icon-color.svg +1 -0
  122. package/plugins/deepinfra/icon.svg +1 -0
  123. package/plugins/deepinfra/plugin.js +97 -0
  124. package/plugins/deepinfra/plugin.json +28 -0
  125. package/plugins/deepseek/icon-color.svg +0 -0
  126. package/plugins/deepseek/icon.svg +0 -0
  127. package/plugins/deepseek/plugin.js +150 -59
  128. package/plugins/deepseek/plugin.json +3 -1
  129. package/plugins/devin/icon.svg +0 -0
  130. package/plugins/devin/plugin.js +114 -0
  131. package/plugins/devin/plugin.json +2 -1
  132. package/plugins/devpass/LICENSE +21 -0
  133. package/plugins/devpass/plugin.js +115 -0
  134. package/plugins/devpass/plugin.json +23 -0
  135. package/plugins/doubao/icon-color.svg +0 -0
  136. package/plugins/doubao/icon.svg +0 -0
  137. package/plugins/doubao/plugin.js +0 -0
  138. package/plugins/doubao/plugin.json +0 -0
  139. package/plugins/droid/icon.svg +0 -0
  140. package/plugins/droid/plugin.json +2 -1
  141. package/plugins/elevenlabs/icon-color.svg +4 -0
  142. package/plugins/elevenlabs/icon.svg +0 -0
  143. package/plugins/elevenlabs/plugin.js +17 -2
  144. package/plugins/elevenlabs/plugin.json +0 -0
  145. package/plugins/factory/icon-color.svg +1 -0
  146. package/plugins/factory/icon-conflict.svg +0 -0
  147. package/plugins/factory/icon.svg +0 -0
  148. package/plugins/factory/plugin.js +38 -14
  149. package/plugins/factory/plugin.json +2 -1
  150. package/plugins/fireworks-ai/icon-color.svg +1 -0
  151. package/plugins/fireworks-ai/icon.svg +1 -6
  152. package/plugins/fireworks-ai/plugin.js +0 -0
  153. package/plugins/fireworks-ai/plugin.json +0 -0
  154. package/plugins/gemini/icon-color.svg +0 -0
  155. package/plugins/gemini/icon.svg +0 -0
  156. package/plugins/gemini/plugin.js +0 -0
  157. package/plugins/gemini/plugin.json +0 -0
  158. package/plugins/gemini-apps/LICENSE +22 -0
  159. package/plugins/gemini-apps/icon-color.svg +1 -0
  160. package/plugins/gemini-apps/icon.svg +1 -0
  161. package/plugins/gemini-apps/plugin.js +470 -0
  162. package/plugins/gemini-apps/plugin.json +19 -0
  163. package/plugins/gitkraken/LICENSE +21 -0
  164. package/plugins/gitkraken/plugin.js +153 -0
  165. package/plugins/gitkraken/plugin.json +24 -0
  166. package/plugins/grok/icon-color.svg +1 -0
  167. package/plugins/grok/icon.svg +0 -0
  168. package/plugins/grok/plugin.js +30 -5
  169. package/plugins/grok/plugin.json +3 -1
  170. package/plugins/groqcloud/icon-color.svg +1 -0
  171. package/plugins/groqcloud/icon.svg +0 -0
  172. package/plugins/groqcloud/plugin.js +0 -0
  173. package/plugins/groqcloud/plugin.json +0 -0
  174. package/plugins/helmcode/LICENSE +21 -0
  175. package/plugins/helmcode/plugin.js +188 -0
  176. package/plugins/helmcode/plugin.json +24 -0
  177. package/plugins/huggingface/LICENSE +21 -0
  178. package/plugins/huggingface/icon-color.svg +1 -0
  179. package/plugins/huggingface/icon.svg +1 -0
  180. package/plugins/huggingface/plugin.js +293 -0
  181. package/plugins/huggingface/plugin.json +25 -0
  182. package/plugins/hyper/LICENSE +21 -0
  183. package/plugins/hyper/plugin.js +131 -0
  184. package/plugins/hyper/plugin.json +26 -0
  185. package/plugins/ibmbob/icon.svg +23 -0
  186. package/plugins/ibmbob/plugin.js +61 -0
  187. package/plugins/ibmbob/plugin.json +22 -0
  188. package/plugins/jetbrains-ai-assistant/icon-color.svg +0 -0
  189. package/plugins/jetbrains-ai-assistant/icon-conflict.svg +0 -0
  190. package/plugins/jetbrains-ai-assistant/icon.svg +0 -0
  191. package/plugins/jetbrains-ai-assistant/plugin.js +0 -0
  192. package/plugins/jetbrains-ai-assistant/plugin.json +0 -0
  193. package/plugins/kilo/icon-color.svg +1 -0
  194. package/plugins/kilo/icon.svg +0 -0
  195. package/plugins/kilo/plugin.js +0 -0
  196. package/plugins/kilo/plugin.json +0 -0
  197. package/plugins/kimi/icon-color.svg +0 -0
  198. package/plugins/kimi/icon-conflict.svg +0 -0
  199. package/plugins/kimi/icon.svg +0 -0
  200. package/plugins/kimi/plugin.js +122 -141
  201. package/plugins/kimi/plugin.json +5 -2
  202. package/plugins/kimi-k2/icon-color.svg +0 -0
  203. package/plugins/kimi-k2/icon.svg +0 -0
  204. package/plugins/kimi-k2/plugin.js +0 -0
  205. package/plugins/kimi-k2/plugin.json +0 -0
  206. package/plugins/kiro/icon-color.svg +0 -0
  207. package/plugins/kiro/icon-conflict.svg +0 -0
  208. package/plugins/kiro/icon.svg +0 -0
  209. package/plugins/kiro/plugin.js +49 -10
  210. package/plugins/kiro/plugin.json +3 -1
  211. package/plugins/litellm/icon.svg +0 -0
  212. package/plugins/litellm/plugin.js +54 -3
  213. package/plugins/litellm/plugin.json +0 -0
  214. package/plugins/llm-proxy/icon.svg +0 -0
  215. package/plugins/llm-proxy/plugin.js +0 -0
  216. package/plugins/llm-proxy/plugin.json +0 -0
  217. package/plugins/llmman/LICENSE +21 -0
  218. package/plugins/llmman/plugin.js +133 -0
  219. package/plugins/llmman/plugin.json +23 -0
  220. package/plugins/longcat/icon-color.svg +1 -0
  221. package/plugins/longcat/icon.svg +1 -0
  222. package/plugins/longcat/plugin.js +182 -0
  223. package/plugins/longcat/plugin.json +23 -0
  224. package/plugins/manus/icon-color.svg +6 -0
  225. package/plugins/manus/icon.svg +0 -0
  226. package/plugins/manus/plugin.js +0 -0
  227. package/plugins/manus/plugin.json +0 -0
  228. package/plugins/mimo/icon-color.svg +4 -0
  229. package/plugins/mimo/icon.svg +4 -1
  230. package/plugins/mimo/plugin.js +0 -0
  231. package/plugins/mimo/plugin.json +0 -0
  232. package/plugins/minimax/icon-color.svg +0 -0
  233. package/plugins/minimax/icon-conflict.svg +0 -0
  234. package/plugins/minimax/icon.svg +0 -0
  235. package/plugins/minimax/plugin.js +25 -31
  236. package/plugins/minimax/plugin.json +0 -0
  237. package/plugins/mistral/icon-color.svg +0 -0
  238. package/plugins/mistral/icon.svg +0 -0
  239. package/plugins/mistral/plugin.js +110 -5
  240. package/plugins/mistral/plugin.json +0 -0
  241. package/plugins/moonshot/icon-color.svg +1 -0
  242. package/plugins/moonshot/icon.svg +0 -0
  243. package/plugins/moonshot/plugin.js +8 -6
  244. package/plugins/moonshot/plugin.json +0 -0
  245. package/plugins/muse/LICENSE +21 -0
  246. package/plugins/muse/plugin.js +319 -0
  247. package/plugins/muse/plugin.json +26 -0
  248. package/plugins/nanogpt/icon-color.svg +0 -0
  249. package/plugins/nanogpt/icon.svg +0 -0
  250. package/plugins/nanogpt/plugin.js +0 -0
  251. package/plugins/nanogpt/plugin.json +0 -0
  252. package/plugins/neuralwatt/icon.svg +0 -0
  253. package/plugins/neuralwatt/plugin.js +0 -0
  254. package/plugins/neuralwatt/plugin.json +0 -0
  255. package/plugins/notion/icon.svg +1 -0
  256. package/plugins/notion/plugin.js +282 -0
  257. package/plugins/notion/plugin.json +29 -0
  258. package/plugins/nous/LICENSE +21 -0
  259. package/plugins/nous/icon-color.svg +1 -0
  260. package/plugins/nous/icon.svg +1 -0
  261. package/plugins/nous/plugin.js +124 -0
  262. package/plugins/nous/plugin.json +24 -0
  263. package/plugins/ollama/icon-color.svg +1 -0
  264. package/plugins/ollama/icon.svg +0 -0
  265. package/plugins/ollama/plugin.js +257 -56
  266. package/plugins/ollama/plugin.json +6 -3
  267. package/plugins/openai-api/icon-color.svg +1 -0
  268. package/plugins/openai-api/icon.svg +0 -0
  269. package/plugins/openai-api/plugin.js +0 -0
  270. package/plugins/openai-api/plugin.json +0 -0
  271. package/plugins/opencode/icon-color.svg +1 -0
  272. package/plugins/opencode/icon.svg +0 -0
  273. package/plugins/opencode/plugin.js +0 -0
  274. package/plugins/opencode/plugin.json +0 -0
  275. package/plugins/opencode-go/icon-color.svg +1 -0
  276. package/plugins/opencode-go/icon-conflict.svg +0 -0
  277. package/plugins/opencode-go/icon.svg +0 -0
  278. package/plugins/opencode-go/plugin.js +103 -17
  279. package/plugins/opencode-go/plugin.json +5 -2
  280. package/plugins/openrouter/icon-color.svg +1 -0
  281. package/plugins/openrouter/icon.svg +0 -0
  282. package/plugins/openrouter/plugin.js +371 -114
  283. package/plugins/openrouter/plugin.json +6 -0
  284. package/plugins/perplexity/icon-color.svg +0 -0
  285. package/plugins/perplexity/icon-conflict.svg +0 -0
  286. package/plugins/perplexity/icon.svg +0 -0
  287. package/plugins/perplexity/plugin.js +0 -0
  288. package/plugins/perplexity/plugin.json +0 -0
  289. package/plugins/pi/plugin.js +113 -0
  290. package/plugins/pi/plugin.json +11 -0
  291. package/plugins/poe/icon.svg +0 -0
  292. package/plugins/poe/plugin.js +24 -18
  293. package/plugins/poe/plugin.json +2 -0
  294. package/plugins/qoder/icon.svg +3 -0
  295. package/plugins/qoder/plugin.js +227 -0
  296. package/plugins/qoder/plugin.json +23 -0
  297. package/plugins/qwencloud/icon-color.svg +1 -0
  298. package/plugins/qwencloud/icon.svg +1 -0
  299. package/plugins/qwencloud/plugin.js +677 -0
  300. package/plugins/qwencloud/plugin.json +29 -0
  301. package/plugins/raycast/LICENSE +21 -0
  302. package/plugins/raycast/plugin.js +174 -0
  303. package/plugins/raycast/plugin.json +24 -0
  304. package/plugins/replicate/LICENSE +21 -0
  305. package/plugins/replicate/icon-color.svg +1 -0
  306. package/plugins/replicate/icon.svg +1 -0
  307. package/plugins/replicate/plugin.js +165 -0
  308. package/plugins/replicate/plugin.json +24 -0
  309. package/plugins/sakana/icon.svg +5 -0
  310. package/plugins/sakana/plugin.js +156 -0
  311. package/plugins/sakana/plugin.json +23 -0
  312. package/plugins/stepfun/icon-color.svg +0 -0
  313. package/plugins/stepfun/icon.svg +0 -0
  314. package/plugins/stepfun/plugin.js +0 -0
  315. package/plugins/stepfun/plugin.json +0 -0
  316. package/plugins/sub2api/icon.svg +4 -0
  317. package/plugins/sub2api/plugin.js +191 -0
  318. package/plugins/sub2api/plugin.json +16 -0
  319. package/plugins/synthetic/icon-color.svg +14 -0
  320. package/plugins/synthetic/icon-conflict.svg +0 -0
  321. package/plugins/synthetic/icon.svg +0 -0
  322. package/plugins/synthetic/plugin.js +0 -0
  323. package/plugins/synthetic/plugin.json +0 -0
  324. package/plugins/t3chat/icon-color.svg +0 -0
  325. package/plugins/t3chat/icon.svg +0 -0
  326. package/plugins/t3chat/plugin.js +0 -0
  327. package/plugins/t3chat/plugin.json +0 -0
  328. package/plugins/typesafe/LICENSE +21 -0
  329. package/plugins/typesafe/plugin.js +225 -0
  330. package/plugins/typesafe/plugin.json +24 -0
  331. package/plugins/v0/LICENSE +21 -0
  332. package/plugins/v0/icon-color.svg +1 -0
  333. package/plugins/v0/icon.svg +1 -0
  334. package/plugins/v0/plugin.js +214 -0
  335. package/plugins/v0/plugin.json +24 -0
  336. package/plugins/venice/icon-color.svg +0 -0
  337. package/plugins/venice/icon.svg +0 -0
  338. package/plugins/venice/plugin.js +50 -1
  339. package/plugins/venice/plugin.json +2 -1
  340. package/plugins/vercel/LICENSE +21 -0
  341. package/plugins/vercel/icon-color.svg +1 -0
  342. package/plugins/vercel/icon.svg +1 -0
  343. package/plugins/vercel/plugin.js +55 -0
  344. package/plugins/vercel/plugin.json +23 -0
  345. package/plugins/vertex-ai/icon-color.svg +0 -0
  346. package/plugins/vertex-ai/icon.svg +0 -0
  347. package/plugins/vertex-ai/plugin.js +0 -0
  348. package/plugins/vertex-ai/plugin.json +0 -0
  349. package/plugins/warp/icon-color.svg +0 -0
  350. package/plugins/warp/icon.svg +0 -0
  351. package/plugins/warp/plugin.js +0 -0
  352. package/plugins/warp/plugin.json +0 -0
  353. package/plugins/wayfinder/icon.svg +5 -0
  354. package/plugins/wayfinder/plugin.js +47 -0
  355. package/plugins/wayfinder/plugin.json +16 -0
  356. package/plugins/windsurf/icon-color.svg +1 -0
  357. package/plugins/windsurf/icon-conflict.svg +0 -0
  358. package/plugins/windsurf/icon.svg +0 -0
  359. package/plugins/windsurf/plugin.js +0 -0
  360. package/plugins/windsurf/plugin.json +0 -0
  361. package/plugins/xai/icon-color.svg +1 -0
  362. package/plugins/xai/icon.svg +1 -0
  363. package/plugins/xai/plugin.js +162 -0
  364. package/plugins/xai/plugin.json +28 -0
  365. package/plugins/xkiro/LICENSE +21 -0
  366. package/plugins/xkiro/plugin.js +99 -0
  367. package/plugins/xkiro/plugin.json +23 -0
  368. package/plugins/zai/icon-color.svg +1 -0
  369. package/plugins/zai/icon-conflict.svg +0 -0
  370. package/plugins/zai/icon.svg +0 -0
  371. package/plugins/zai/plugin.js +111 -161
  372. package/plugins/zai/plugin.json +4 -1
  373. package/plugins/zed/icon.svg +0 -0
  374. package/plugins/zed/plugin.js +0 -0
  375. package/plugins/zed/plugin.json +0 -0
  376. package/plugins/zenmux/icon-color.svg +1 -0
  377. package/plugins/zenmux/icon.svg +1 -0
  378. package/plugins/zenmux/plugin.js +102 -0
  379. package/plugins/zenmux/plugin.json +23 -0
  380. package/plugins/zoommate/icon.svg +1 -0
  381. package/plugins/zoommate/plugin.js +244 -0
  382. package/plugins/zoommate/plugin.json +29 -0
  383. package/usagestat +0 -0
  384. package/usagestatd +0 -0
@@ -0,0 +1,25 @@
1
+ (function () {
2
+ function probe(ctx) {
3
+ const response = ctx.host.command.run({program: 'coderabbit', args: ['usage'], timeoutMs: 15000});
4
+ const text = (response.stdout + '\n' + response.stderr).replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, '');
5
+ if (/not authenticated|please log in|auth login|authentication required|unauthorized|no session found/i.test(text))
6
+ throw {code: 'missing-auth', message: 'Run coderabbit auth login to sign in.'};
7
+ if (response.status !== 0) throw 'CodeRabbit usage command failed (exit ' + response.status + ').';
8
+ const fields = Object.create(null);
9
+ for (const line of text.split(/\r?\n/)) {
10
+ const colon = line.indexOf(':');
11
+ if (colon < 0) continue;
12
+ const label = line.slice(0, colon).trim().toLowerCase(), value = line.slice(colon + 1).trim();
13
+ if (value && !fields[label]) fields[label] = value;
14
+ }
15
+ const lines = [];
16
+ if (/^\d+$/.test(fields['your reviews'] || '') && Number.isSafeInteger(Number(fields['your reviews'])))
17
+ lines.push(ctx.line.text({label: 'Reviews', value: fields['your reviews']}));
18
+ for (const [key, label] of [['usage billing', 'Usage billing'], ['period resets', 'Period resets']])
19
+ if (fields[key]) lines.push(ctx.line.text({label, value: fields[key]}));
20
+ if (!lines.length) throw 'CodeRabbit did not report review counts or billing information.';
21
+ if (fields.organization) lines.push(ctx.line.text({label: 'Organization', value: fields.organization}));
22
+ return {displayName: 'CodeRabbit', source: 'cli', plan: fields.plan, lines};
23
+ }
24
+ globalThis.__usagestat_plugin = {id: 'coderabbit', probe};
25
+ })();
@@ -0,0 +1,12 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "coderabbit",
4
+ "name": "CodeRabbit",
5
+ "version": "0.1.0",
6
+ "entry": "plugin.js",
7
+ "enabledByDefault": false,
8
+ "supportedModes": ["cli"],
9
+ "autoMode": "cli",
10
+ "usageDashboardUrl": "https://app.coderabbit.ai",
11
+ "envVars": ["CODERABBIT_CLI_PATH"]
12
+ }
File without changes
File without changes
@@ -377,6 +377,7 @@
377
377
  if (!rawPlan) return null
378
378
  if (rawPlan.toLowerCase() === "prolite") return "Pro 5x"
379
379
  if (rawPlan.toLowerCase() === "pro") return "Pro 20x"
380
+ if (rawPlan.toLowerCase() === "self_serve_business_prolite") return "Business Premium"
380
381
  return ctx.fmt.planLabel(rawPlan) || null
381
382
  }
382
383
 
@@ -691,6 +692,7 @@
691
692
  let didReloadAuth = false
692
693
  try {
693
694
  resp = ctx.util.retryOnceOnAuth({
695
+ isAuthStatus: (status) => status === 401,
694
696
  request: (token) => {
695
697
  try {
696
698
  return fetchUsage(ctx, token || accessToken, accountId)
@@ -727,7 +729,7 @@
727
729
  throw ERR_USAGE_CONNECTION
728
730
  }
729
731
 
730
- if (didReloadAuth && ctx.util.isAuthStatus(resp.status)) {
732
+ if (didReloadAuth && resp.status === 401) {
731
733
  ctx.host.log.info("reloaded auth returned 401, attempting refresh")
732
734
  didRefresh = true
733
735
  const refreshed = refreshToken(ctx, authState)
@@ -741,11 +743,15 @@
741
743
  }
742
744
  }
743
745
 
744
- if (ctx.util.isAuthStatus(resp.status)) {
746
+ if (resp.status === 401) {
745
747
  ctx.host.log.error("usage returned auth error after all retries: status=" + resp.status)
746
748
  throw ERR_TOKEN_EXPIRED
747
749
  }
748
750
 
751
+ if (resp.status === 403) {
752
+ throw "Codex usage access denied (HTTP 403). Check this account's permissions."
753
+ }
754
+
749
755
  if (resp.status < 200 || resp.status >= 300) {
750
756
  ctx.host.log.error("usage returned error: status=" + resp.status)
751
757
  throw "Usage request failed (HTTP " + String(resp.status) + "). Try again later."
File without changes
@@ -0,0 +1,3 @@
1
+ <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M38 38H27C20.925 38 16 33.075 16 27C16 20.925 20.925 16 27 16C33.075 16 38 20.925 38 27V73C38 79.075 33.075 84 27 84C20.925 84 16 79.075 16 73C16 66.925 20.925 62 27 62H73C79.075 62 84 66.925 84 73C84 79.075 79.075 84 73 84C66.925 84 62 79.075 62 73V27C62 20.925 66.925 16 73 16C79.075 16 84 20.925 84 27C84 33.075 79.075 38 73 38H38V62" stroke="currentColor" stroke-width="9" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
File without changes
@@ -5,6 +5,11 @@
5
5
 
6
6
  var PLAN_LABELS = {
7
7
  "individual-go": "Individual Go",
8
+ "individual-goat": "GOAT",
9
+ "individual-pro": "Pro",
10
+ "individual-pro-v1": "Pro",
11
+ "individual-max": "Max",
12
+ "individual-ultra": "Ultra",
8
13
  "individual": "Individual",
9
14
  "pro": "Pro",
10
15
  "team": "Team",
@@ -12,6 +17,8 @@
12
17
  };
13
18
 
14
19
  function readNumber(value) {
20
+ if (typeof value !== "number" && typeof value !== "string") return null;
21
+ if (typeof value === "string" && !value.trim()) return null;
15
22
  var n = Number(value);
16
23
  return Number.isFinite(n) ? n : null;
17
24
  }
@@ -139,9 +146,11 @@
139
146
  }
140
147
 
141
148
  var lines = [];
142
- if (creditsRemaining !== null && monthlyUsed !== null) {
143
- var totalPlan = monthlyUsed + Math.max(0, creditsRemaining);
144
- var usedPercent = totalPlan > 0 ? (monthlyUsed / totalPlan) * 100 : 100;
149
+ var grants = { 'individual-go':10, 'individual-goat':70, 'individual-pro':30, 'individual-pro-v1':80, 'individual-max':150, 'individual-ultra':300 };
150
+ var totalPlan = readNumber(creditsResp && creditsResp.credits && creditsResp.credits.monthlyCreditsGranted);
151
+ if (!(totalPlan > 0)) totalPlan = subResp && subResp.success && subResp.data ? grants[subResp.data.planId] : null;
152
+ if (creditsRemaining !== null && totalPlan > 0) {
153
+ var usedPercent = Math.max(0, totalPlan - creditsRemaining) / totalPlan * 100;
145
154
  lines.push(ctx.line.progress({
146
155
  label: "Monthly credits",
147
156
  used: Math.max(0, Math.min(100, Math.round(usedPercent * 10) / 10)),
@@ -149,6 +158,8 @@
149
158
  format: { kind: "percent" },
150
159
  periodDurationMs: 30 * 24 * 60 * 60 * 1000,
151
160
  }));
161
+ } else if (creditsRemaining !== null) {
162
+ lines.push(ctx.line.text({label:'Monthly credits',value:'$'+Math.max(0,creditsRemaining).toFixed(2)+' remaining'}));
152
163
  }
153
164
 
154
165
  if (totalCost !== null && totalCost > 0) {
File without changes
File without changes
@@ -1 +1 @@
1
- <svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>GithubCopilot</title><path d="M19.245 5.364c1.322 1.36 1.877 3.216 2.11 5.817.622 0 1.2.135 1.592.654l.73.964c.21.278.323.61.323.955v2.62c0 .339-.173.669-.453.868C20.239 19.602 16.157 21.5 12 21.5c-4.6 0-9.205-2.583-11.547-4.258-.28-.2-.452-.53-.453-.868v-2.62c0-.345.113-.679.321-.956l.73-.963c.392-.517.974-.654 1.593-.654l.029-.297c.25-2.446.81-4.213 2.082-5.52 2.461-2.54 5.71-2.851 7.146-2.864h.198c1.436.013 4.685.323 7.146 2.864zm-7.244 4.328c-.284 0-.613.016-.962.05-.123.447-.305.85-.57 1.108-1.05 1.023-2.316 1.18-2.994 1.18-.638 0-1.306-.13-1.851-.464-.516.165-1.012.403-1.044.996a65.882 65.882 0 00-.063 2.884l-.002.48c-.002.563-.005 1.126-.013 1.69.002.326.204.63.51.765 2.482 1.102 4.83 1.657 6.99 1.657 2.156 0 4.504-.555 6.985-1.657a.854.854 0 00.51-.766c.03-1.682.006-3.372-.076-5.053-.031-.596-.528-.83-1.046-.996-.546.333-1.212.464-1.85.464-.677 0-1.942-.157-2.993-1.18-.266-.258-.447-.661-.57-1.108-.32-.032-.64-.049-.96-.05zm-2.525 4.013c.539 0 .976.426.976.95v1.753c0 .525-.437.95-.976.95a.964.964 0 01-.976-.95v-1.752c0-.525.437-.951.976-.951zm5 0c.539 0 .976.426.976.95v1.753c0 .525-.437.95-.976.95a.964.964 0 01-.976-.95v-1.752c0-.525.437-.951.976-.951zM7.635 5.087c-1.05.102-1.935.438-2.385.906-.975 1.037-.765 3.668-.21 4.224.405.394 1.17.657 1.995.657h.09c.649-.013 1.785-.176 2.73-1.11.435-.41.705-1.433.675-2.47-.03-.834-.27-1.52-.63-1.813-.39-.336-1.275-.482-2.265-.394zm6.465.394c-.36.292-.6.98-.63 1.813-.03 1.037.24 2.06.675 2.47.968.957 2.136 1.104 2.776 1.11h.044c.825 0 1.59-.263 1.995-.657.555-.556.765-3.187-.21-4.224-.45-.468-1.335-.804-2.385-.906-.99-.088-1.875.058-2.265.394zM12 7.615c-.24 0-.525.015-.84.044.03.16.045.336.06.526l-.001.159a2.94 2.94 0 01-.014.25c.225-.022.425-.027.612-.028h.366c.187 0 .387.006.612.028-.015-.146-.015-.277-.015-.409.015-.19.03-.365.06-.526a9.29 9.29 0 00-.84-.044z"></path></svg>
1
+ <svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Copilot</title><path d="M9 23l.073-.001a2.53 2.53 0 01-2.347-1.838l-.697-2.433a2.529 2.529 0 00-2.426-1.839h-.497l-.104-.002c-4.485 0-2.935-5.278-1.75-9.225l.162-.525C2.412 3.99 3.883 1 6.25 1h8.86c1.12 0 2.106.745 2.422 1.829l.715 2.453a2.53 2.53 0 002.247 1.823l.147.005.534.001c3.557.115 3.088 3.745 2.156 7.206l-.113.413c-.154.548-.315 1.089-.47 1.607l-.163.525C21.588 20.01 20.116 23 17.75 23h-8.75zm8.22-15.89l-3.856.001a2.526 2.526 0 00-2.35 1.615L9.21 15.04a2.529 2.529 0 01-2.43 1.847l3.853.002c1.056 0 1.992-.661 2.361-1.644l1.796-6.287a2.529 2.529 0 012.43-1.848z"></path></svg>
@@ -526,16 +526,18 @@
526
526
  }
527
527
 
528
528
  function makeProgressLine(ctx, label, snapshot, resetDate) {
529
- if (!snapshot || typeof snapshot.percent_remaining !== "number")
530
- return null;
531
- const usedPercent = Math.min(100, Math.max(0, 100 - snapshot.percent_remaining));
529
+ if (!snapshot || snapshot.unlimited === true || snapshot.entitlement === -1 || snapshot.remaining === -1 || snapshot.entitlement === 0) return null;
530
+ let percentRemaining = snapshot.percent_remaining;
531
+ if (!Number.isFinite(percentRemaining) && Number.isFinite(snapshot.entitlement) && snapshot.entitlement > 0 && Number.isFinite(snapshot.remaining)) percentRemaining = snapshot.remaining / snapshot.entitlement * 100;
532
+ if (!Number.isFinite(percentRemaining)) return null;
533
+ const usedPercent = Math.min(100, Math.max(0, 100 - percentRemaining));
532
534
  return ctx.line.progress({
533
535
  label: label,
534
536
  used: usedPercent,
535
537
  limit: 100,
536
538
  format: { kind: "percent" },
537
539
  resetsAt: ctx.util.toIso(resetDate),
538
- periodDurationMs: 30 * 24 * 60 * 60 * 1000,
540
+ periodDurationMs: calendarMonthDuration(ctx, resetDate),
539
541
  });
540
542
  }
541
543
 
@@ -550,10 +552,43 @@
550
552
  limit: 100,
551
553
  format: { kind: "percent" },
552
554
  resetsAt: ctx.util.toIso(resetDate),
553
- periodDurationMs: 30 * 24 * 60 * 60 * 1000,
555
+ periodDurationMs: calendarMonthDuration(ctx, resetDate),
554
556
  });
555
557
  }
556
558
 
559
+ function calendarMonthDuration(ctx, resetDate) {
560
+ const end = ctx.util.parseDateMs(resetDate);
561
+ if (!Number.isFinite(end)) return undefined;
562
+ const start = new Date(end);
563
+ start.setUTCMonth(start.getUTCMonth() - 1);
564
+ return end - start.getTime();
565
+ }
566
+
567
+ function fetchOrgBillingLines(ctx, token) {
568
+ const deadline = Date.now() + 3000;
569
+ function get(path) {
570
+ const remaining = deadline - Date.now();
571
+ if (remaining <= 0) return null;
572
+ const result = ctx.util.requestJson({ method: "GET", url: "https://api.github.com" + path,
573
+ headers: { Authorization: "token " + token, Accept: "application/vnd.github+json", "User-Agent": "usagestat", "X-GitHub-Api-Version": "2022-11-28" }, timeoutMs: remaining });
574
+ return result.resp.status === 200 ? result.json : null;
575
+ }
576
+ const selected = ctx.provider && ctx.provider.workspaceId;
577
+ const orgs = selected ? [{ login: selected }] : get("/user/orgs?per_page=100");
578
+ if (!Array.isArray(orgs)) return [];
579
+ const result = [];
580
+ for (const org of orgs.slice(0, 5)) {
581
+ if (!org || typeof org.login !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9-]*$/.test(org.login)) continue;
582
+ const body = get("/orgs/" + encodeURIComponent(org.login) + "/settings/billing/usage/summary");
583
+ if (!body || !Array.isArray(body.usageItems)) continue;
584
+ const items = body.usageItems.filter((item) => item && String(item.product).toLowerCase() === "copilot" && ["ai-units", "ai-credits"].includes(String(item.unitType).toLowerCase()));
585
+ if (!items.length || items.some((item) => !Number.isFinite(item.grossQuantity) || item.grossQuantity < 0 || !Number.isFinite(item.netAmount) || item.netAmount < 0)) continue;
586
+ result.push(ctx.line.text({ label: "Org Credits", value: String(items.reduce((n, item) => n + item.grossQuantity, 0)) + " credits", subtitle: org.login + " - organization total" }));
587
+ result.push(ctx.line.text({ label: "Org Spend", value: "$" + items.reduce((n, item) => n + item.netAmount, 0).toFixed(2), subtitle: org.login + " - this month" }));
588
+ }
589
+ return result;
590
+ }
591
+
557
592
  function probe(ctx) {
558
593
  const cred = loadToken(ctx);
559
594
  if (!cred) {
@@ -630,11 +665,15 @@
630
665
  if (snapshots) {
631
666
  const premiumLine = makeProgressLine(
632
667
  ctx,
633
- "Premium",
668
+ "Credits",
634
669
  snapshots.premium_interactions,
635
670
  data.quota_reset_date,
636
671
  );
637
- if (premiumLine) lines.push(premiumLine);
672
+ if (premiumLine) {
673
+ lines.push(premiumLine);
674
+ const premium = snapshots.premium_interactions;
675
+ if (premium.overage_permitted === true && Number.isFinite(premium.overage_count) && premium.overage_count >= 0) lines.push(ctx.line.text({ label: "Extra Usage", value: String(premium.overage_count) }));
676
+ }
638
677
 
639
678
  const chatLine = makeProgressLine(
640
679
  ctx,
@@ -643,10 +682,12 @@
643
682
  data.quota_reset_date,
644
683
  );
645
684
  if (chatLine) lines.push(chatLine);
685
+ const completionsLine = makeProgressLine(ctx, "Completions", snapshots.completions, data.quota_reset_date);
686
+ if (completionsLine) lines.push(completionsLine);
646
687
  }
647
688
 
648
689
  // Free tier: limited_user_quotas
649
- if (data.limited_user_quotas && data.monthly_quotas) {
690
+ if (!lines.length && data.limited_user_quotas && data.monthly_quotas) {
650
691
  const lq = data.limited_user_quotas;
651
692
  const mq = data.monthly_quotas;
652
693
  const resetDate = data.limited_user_reset_date;
@@ -658,6 +699,17 @@
658
699
  if (completionsLine) lines.push(completionsLine);
659
700
  }
660
701
 
702
+ const orgManaged = !lines.length && data.token_based_billing === true;
703
+ if (orgManaged) {
704
+ const credits = snapshots && snapshots.premium_interactions && snapshots.premium_interactions.credits_used;
705
+ if (Number.isFinite(credits) && credits > 0) lines.push(ctx.line.text({ label: "Credits", value: String(credits) + " credits" }));
706
+ try {
707
+ lines.push(...fetchOrgBillingLines(ctx, token));
708
+ } catch (_) {
709
+ ctx.host.log.warn("Copilot organization billing unavailable for this token");
710
+ }
711
+ }
712
+
661
713
  try {
662
714
  const budgetLines = fetchBudgetLines(ctx);
663
715
  for (let i = 0; i < budgetLines.length; i += 1) {
@@ -677,7 +729,7 @@
677
729
  );
678
730
  }
679
731
 
680
- return { plan: plan, lines: lines };
732
+ return { plan: plan, lines: lines, source: "api" };
681
733
  }
682
734
 
683
735
  globalThis.__openusage_plugin = { id: "copilot", probe };
@@ -9,7 +9,10 @@
9
9
  "supportedModes": ["oauth", "local", "cli"],
10
10
  "autoMode": "local",
11
11
  "lines": [
12
- { "type": "progress", "label": "Premium", "scope": "overview", "primaryOrder": 1 },
12
+ { "type": "progress", "label": "Credits", "scope": "overview", "primaryOrder": 1 },
13
+ { "type": "text", "label": "Extra Usage", "scope": "detail" },
14
+ { "type": "text", "label": "Org Credits", "scope": "detail" },
15
+ { "type": "text", "label": "Org Spend", "scope": "detail" },
13
16
  { "type": "progress", "label": "Chat", "scope": "overview", "primaryOrder": 2 },
14
17
  { "type": "progress", "label": "Completions", "scope": "overview" },
15
18
  { "type": "progress", "label": "Budget - Copilot", "scope": "detail" },
@@ -0,0 +1,3 @@
1
+ <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M44.2 8.5H82.4C85.6 8.5 88.1 11.1 87.8 14.2C87.7 15.5 87.2 16.7 86.4 17.8L73.3 35.5C69.7 40.3 64.1 43.1 58.1 43.1H28.1L40.2 60.1H68.4C72.8 60.1 76.9 62.1 79.6 65.6L88.2 76.9C89.8 79.1 89.7 82.1 87.8 84.2C86.6 85.5 84.9 86.3 83.1 86.3H45.1C36.5 86.3 28.5 82.1 23.6 75L8.9 53.6C5.2 48.2 5.3 41 9.2 35.7L20.6 20.1C26.1 12.8 34.8 8.5 44.2 8.5ZM28.1 43.1H15.4C13.5 43.1 12.4 45.2 13.5 46.8L27.3 66.9C31.3 72.8 38 76.3 45.1 76.3H75L68.6 68.1C67.2 66.3 65.1 65.2 62.8 65.2H38.6C34.4 65.2 30.5 63.2 28.1 59.8L19.7 48.1C18.2 45.9 19.8 43.1 22.5 43.1H28.1Z" fill="currentColor"/>
3
+ </svg>
File without changes
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M44.2 8.5H82.4C85.6 8.5 88.1 11.1 87.8 14.2C87.7 15.5 87.2 16.7 86.4 17.8L73.3 35.5C69.7 40.3 64.1 43.1 58.1 43.1H28.1L40.2 60.1H68.4C72.8 60.1 76.9 62.1 79.6 65.6L88.2 76.9C89.8 79.1 89.7 82.1 87.8 84.2C86.6 85.5 84.9 86.3 83.1 86.3H45.1C36.5 86.3 28.5 82.1 23.6 75L8.9 53.6C5.2 48.2 5.3 41 9.2 35.7L20.6 20.1C26.1 12.8 34.8 8.5 44.2 8.5ZM28.1 43.1H15.4C13.5 43.1 12.4 45.2 13.5 46.8L27.3 66.9C31.3 72.8 38 76.3 45.1 76.3H75L68.6 68.1C67.2 66.3 65.1 65.2 62.8 65.2H38.6C34.4 65.2 30.5 63.2 28.1 59.8L19.7 48.1C18.2 45.9 19.8 43.1 22.5 43.1H28.1Z" fill="currentColor"/>
3
+ </svg>
@@ -1,16 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 388 388" role="img" aria-label="CrofAI logo">
2
- <path fill="currentColor" d="
3
- M 103 107
4
- H 161
5
- V 135
6
- C 173 114, 195 103, 226 103
7
- C 264 103, 285 131, 285 185
8
- V 294
9
- H 226
10
- V 189
11
- C 226 159, 215 146, 194 146
12
- C 172 146, 161 163, 161 193
13
- V 294
14
- H 103
15
- Z"/>
1
+ <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M44.2 8.5H82.4C85.6 8.5 88.1 11.1 87.8 14.2C87.7 15.5 87.2 16.7 86.4 17.8L73.3 35.5C69.7 40.3 64.1 43.1 58.1 43.1H28.1L40.2 60.1H68.4C72.8 60.1 76.9 62.1 79.6 65.6L88.2 76.9C89.8 79.1 89.7 82.1 87.8 84.2C86.6 85.5 84.9 86.3 83.1 86.3H45.1C36.5 86.3 28.5 82.1 23.6 75L8.9 53.6C5.2 48.2 5.3 41 9.2 35.7L20.6 20.1C26.1 12.8 34.8 8.5 44.2 8.5ZM28.1 43.1H15.4C13.5 43.1 12.4 45.2 13.5 46.8L27.3 66.9C31.3 72.8 38 76.3 45.1 76.3H75L68.6 68.1C67.2 66.3 65.1 65.2 62.8 65.2H38.6C34.4 65.2 30.5 63.2 28.1 59.8L19.7 48.1C18.2 45.9 19.8 43.1 22.5 43.1H28.1Z" fill="currentColor"/>
16
3
  </svg>
File without changes
File without changes
@@ -0,0 +1 @@
1
+ <svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Cursor</title><path d="M22.106 5.68L12.5.135a.998.998 0 00-.998 0L1.893 5.68a.84.84 0 00-.419.726v11.186c0 .3.16.577.42.727l9.607 5.547a.999.999 0 00.998 0l9.608-5.547a.84.84 0 00.42-.727V6.407a.84.84 0 00-.42-.726zm-.603 1.176L12.228 22.92c-.063.108-.228.064-.228-.061V12.34a.59.59 0 00-.295-.51l-9.11-5.26c-.107-.062-.063-.228.062-.228h18.55c.264 0 .428.286.296.514z"></path></svg>
File without changes
File without changes
@@ -1,9 +1,10 @@
1
- globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1
+ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor";
2
2
  (function () {
3
3
  const KEYCHAIN_ACCESS_TOKEN_SERVICE = "cursor-access-token"
4
4
  const KEYCHAIN_REFRESH_TOKEN_SERVICE = "cursor-refresh-token"
5
5
  const BASE_URL = "https://api2.cursor.sh"
6
6
  const USAGE_URL = BASE_URL + "/aiserver.v1.DashboardService/GetCurrentPeriodUsage"
7
+ const GROK_BOT_USAGE_URL = BASE_URL + "/aiserver.v1.DashboardService/GetSandUsageStatus"
7
8
  const PLAN_URL = BASE_URL + "/aiserver.v1.DashboardService/GetPlanInfo"
8
9
  const REFRESH_URL = BASE_URL + "/oauth/token"
9
10
  const CREDITS_URL = BASE_URL + "/aiserver.v1.DashboardService/GetCreditGrantsBalance"
@@ -282,13 +283,13 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
282
283
  format: { kind: "count", suffix: " req" },
283
284
  }),
284
285
  ctx.line.progress({
285
- label: "Auto usage",
286
+ label: "Cursor Models",
286
287
  used: 18,
287
288
  limit: 100,
288
289
  format: { kind: "percent" },
289
290
  }),
290
291
  ctx.line.progress({
291
- label: "API usage",
292
+ label: "Other Models",
292
293
  used: 7,
293
294
  limit: 50,
294
295
  format: { kind: "percent" },
@@ -414,7 +415,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
414
415
  }
415
416
  }
416
417
 
417
- function connectPost(ctx, url, token) {
418
+ function connectPost(ctx, url, token, timeoutMs) {
418
419
  return ctx.util.request({
419
420
  method: "POST",
420
421
  url: url,
@@ -426,7 +427,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
426
427
  "User-Agent": CONNECT_CLIENT_USER_AGENT,
427
428
  },
428
429
  bodyText: "{}",
429
- timeoutMs: 10000,
430
+ timeoutMs: timeoutMs || 10000,
430
431
  })
431
432
  }
432
433
 
@@ -762,7 +763,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
762
763
 
763
764
  if (typeof pu.autoPercentUsed === "number" && Number.isFinite(pu.autoPercentUsed)) {
764
765
  lines.push(ctx.line.progress({
765
- label: "Auto usage",
766
+ label: "Cursor Models",
766
767
  used: pu.autoPercentUsed,
767
768
  limit: 100,
768
769
  format: { kind: "percent" },
@@ -773,7 +774,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
773
774
 
774
775
  if (typeof pu.apiPercentUsed === "number" && Number.isFinite(pu.apiPercentUsed)) {
775
776
  lines.push(ctx.line.progress({
776
- label: "API usage",
777
+ label: "Other Models",
777
778
  used: pu.apiPercentUsed,
778
779
  limit: 100,
779
780
  format: { kind: "percent" },
@@ -1106,7 +1107,40 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1106
1107
  return result
1107
1108
  }
1108
1109
 
1109
- function probeImpl(ctx) {
1110
+ function attachGrokBotUsage(ctx, result, accessToken) {
1111
+ if (!result || !Array.isArray(result.lines) || !accessToken) return result
1112
+ try {
1113
+ const resp = connectPost(ctx, GROK_BOT_USAGE_URL, accessToken, 3000)
1114
+ if (resp.status < 200 || resp.status >= 300) return result
1115
+ const usage = ctx.util.tryParseJson(resp.bodyText)
1116
+ if (!usage || usage.usesPooledEnterpriseAllowance === true ||
1117
+ usage.hasNonZeroIncludedLimit === false || usage.includedLimitZero === true) return result
1118
+ const percent = readFiniteNumber(usage.usagePercent)
1119
+ if (!Number.isFinite(percent) || percent < 0) return result
1120
+ const resetMs = ctx.util.parseDateMs(usage.nextResetTimestampUtc)
1121
+ const startMs = ctx.util.parseDateMs(usage.currentPeriodStart)
1122
+ const line = ctx.line.progress({
1123
+ label: "Grok Bot usage",
1124
+ used: Math.min(100, percent),
1125
+ limit: 100,
1126
+ format: { kind: "percent" },
1127
+ resetsAt: Number.isFinite(resetMs) ? ctx.util.toIso(resetMs) : undefined,
1128
+ periodDurationMs: Number.isFinite(startMs) && Number.isFinite(resetMs) && resetMs > startMs
1129
+ ? resetMs - startMs : 7 * 24 * 60 * 60 * 1000,
1130
+ })
1131
+ let insertAt = result.lines.length
1132
+ for (const label of ["Other Models", "Cursor Models", "Total usage"]) {
1133
+ const index = result.lines.findIndex((item) => item.label === label)
1134
+ if (index >= 0) { insertAt = index + 1; break }
1135
+ }
1136
+ result.lines.splice(insertAt, 0, line)
1137
+ } catch (_) {
1138
+ ctx.host.log.warn("Cursor Grok Bot quota unavailable")
1139
+ }
1140
+ return result
1141
+ }
1142
+
1143
+ function probeImpl(ctx, state) {
1110
1144
  const authState = loadAuthState(ctx)
1111
1145
  let accessToken = authState.accessToken
1112
1146
  const refreshTokenValue = authState.refreshToken
@@ -1176,6 +1210,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1176
1210
  throw "Usage request failed. Check your connection."
1177
1211
  }
1178
1212
 
1213
+ state.accessToken = accessToken
1179
1214
  if (ctx.util.isAuthStatus(usageResp.status)) {
1180
1215
  ctx.host.log.error("usage returned auth error after all retries: status=" + usageResp.status)
1181
1216
  throw "Token expired. " + LOGIN_HINT
@@ -1368,7 +1403,9 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1368
1403
  }
1369
1404
 
1370
1405
  function probe(ctx) {
1371
- var result = probeImpl(ctx)
1406
+ var state = {}
1407
+ var result = probeImpl(ctx, state)
1408
+ result = attachGrokBotUsage(ctx, result, state.accessToken)
1372
1409
  result = attachCursorTranscriptActivity(ctx, result)
1373
1410
  result = attachCursorBillingDaily(ctx, result)
1374
1411
  return attachCursorMtdUsage(ctx, result)
@@ -16,8 +16,9 @@
16
16
  { "type": "progress", "label": "Credits", "scope": "overview", "primaryOrder": 2 },
17
17
  { "type": "progress", "label": "Total usage", "scope": "overview", "primaryOrder": 1 },
18
18
  { "type": "progress", "label": "Requests", "scope": "overview", "primaryOrder": 3 },
19
- { "type": "progress", "label": "Auto usage", "scope": "detail" },
20
- { "type": "progress", "label": "API usage", "scope": "detail" },
19
+ { "type": "progress", "label": "Cursor Models", "scope": "detail" },
20
+ { "type": "progress", "label": "Other Models", "scope": "detail" },
21
+ { "type": "progress", "label": "Grok Bot usage", "scope": "detail" },
21
22
  { "type": "progress", "label": "On-demand", "scope": "detail" }
22
23
  ]
23
24
  }
File without changes
@@ -4,6 +4,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
4
4
  const KEYCHAIN_REFRESH_TOKEN_SERVICE = "cursor-refresh-token"
5
5
  const BASE_URL = "https://api2.cursor.sh"
6
6
  const USAGE_URL = BASE_URL + "/aiserver.v1.DashboardService/GetCurrentPeriodUsage"
7
+ const GROK_BOT_USAGE_URL = BASE_URL + "/aiserver.v1.DashboardService/GetSandUsageStatus"
7
8
  const PLAN_URL = BASE_URL + "/aiserver.v1.DashboardService/GetPlanInfo"
8
9
  const REFRESH_URL = BASE_URL + "/oauth/token"
9
10
  const CREDITS_URL = BASE_URL + "/aiserver.v1.DashboardService/GetCreditGrantsBalance"
@@ -282,13 +283,13 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
282
283
  format: { kind: "count", suffix: " req" },
283
284
  }),
284
285
  ctx.line.progress({
285
- label: "Auto usage",
286
+ label: "Cursor Models",
286
287
  used: 18,
287
288
  limit: 100,
288
289
  format: { kind: "percent" },
289
290
  }),
290
291
  ctx.line.progress({
291
- label: "API usage",
292
+ label: "Other Models",
292
293
  used: 7,
293
294
  limit: 50,
294
295
  format: { kind: "percent" },
@@ -414,7 +415,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
414
415
  }
415
416
  }
416
417
 
417
- function connectPost(ctx, url, token) {
418
+ function connectPost(ctx, url, token, timeoutMs) {
418
419
  return ctx.util.request({
419
420
  method: "POST",
420
421
  url: url,
@@ -426,7 +427,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
426
427
  "User-Agent": CONNECT_CLIENT_USER_AGENT,
427
428
  },
428
429
  bodyText: "{}",
429
- timeoutMs: 10000,
430
+ timeoutMs: timeoutMs || 10000,
430
431
  })
431
432
  }
432
433
 
@@ -762,7 +763,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
762
763
 
763
764
  if (typeof pu.autoPercentUsed === "number" && Number.isFinite(pu.autoPercentUsed)) {
764
765
  lines.push(ctx.line.progress({
765
- label: "Auto usage",
766
+ label: "Cursor Models",
766
767
  used: pu.autoPercentUsed,
767
768
  limit: 100,
768
769
  format: { kind: "percent" },
@@ -773,7 +774,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
773
774
 
774
775
  if (typeof pu.apiPercentUsed === "number" && Number.isFinite(pu.apiPercentUsed)) {
775
776
  lines.push(ctx.line.progress({
776
- label: "API usage",
777
+ label: "Other Models",
777
778
  used: pu.apiPercentUsed,
778
779
  limit: 100,
779
780
  format: { kind: "percent" },
@@ -1106,7 +1107,40 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1106
1107
  return result
1107
1108
  }
1108
1109
 
1109
- function probeImpl(ctx) {
1110
+ function attachGrokBotUsage(ctx, result, accessToken) {
1111
+ if (!result || !Array.isArray(result.lines) || !accessToken) return result
1112
+ try {
1113
+ const resp = connectPost(ctx, GROK_BOT_USAGE_URL, accessToken, 3000)
1114
+ if (resp.status < 200 || resp.status >= 300) return result
1115
+ const usage = ctx.util.tryParseJson(resp.bodyText)
1116
+ if (!usage || usage.usesPooledEnterpriseAllowance === true ||
1117
+ usage.hasNonZeroIncludedLimit === false || usage.includedLimitZero === true) return result
1118
+ const percent = readFiniteNumber(usage.usagePercent)
1119
+ if (!Number.isFinite(percent) || percent < 0) return result
1120
+ const resetMs = ctx.util.parseDateMs(usage.nextResetTimestampUtc)
1121
+ const startMs = ctx.util.parseDateMs(usage.currentPeriodStart)
1122
+ const line = ctx.line.progress({
1123
+ label: "Grok Bot usage",
1124
+ used: Math.min(100, percent),
1125
+ limit: 100,
1126
+ format: { kind: "percent" },
1127
+ resetsAt: Number.isFinite(resetMs) ? ctx.util.toIso(resetMs) : undefined,
1128
+ periodDurationMs: Number.isFinite(startMs) && Number.isFinite(resetMs) && resetMs > startMs
1129
+ ? resetMs - startMs : 7 * 24 * 60 * 60 * 1000,
1130
+ })
1131
+ let insertAt = result.lines.length
1132
+ for (const label of ["Other Models", "Cursor Models", "Total usage"]) {
1133
+ const index = result.lines.findIndex((item) => item.label === label)
1134
+ if (index >= 0) { insertAt = index + 1; break }
1135
+ }
1136
+ result.lines.splice(insertAt, 0, line)
1137
+ } catch (_) {
1138
+ ctx.host.log.warn("Cursor Grok Bot quota unavailable")
1139
+ }
1140
+ return result
1141
+ }
1142
+
1143
+ function probeImpl(ctx, state) {
1110
1144
  const authState = loadAuthState(ctx)
1111
1145
  let accessToken = authState.accessToken
1112
1146
  const refreshTokenValue = authState.refreshToken
@@ -1176,6 +1210,7 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1176
1210
  throw "Usage request failed. Check your connection."
1177
1211
  }
1178
1212
 
1213
+ state.accessToken = accessToken
1179
1214
  if (ctx.util.isAuthStatus(usageResp.status)) {
1180
1215
  ctx.host.log.error("usage returned auth error after all retries: status=" + usageResp.status)
1181
1216
  throw "Token expired. " + LOGIN_HINT
@@ -1368,7 +1403,9 @@ globalThis.__OPENUSAGE_PLUGIN_REGISTRATION_ID__ = "cursor-nightly";
1368
1403
  }
1369
1404
 
1370
1405
  function probe(ctx) {
1371
- var result = probeImpl(ctx)
1406
+ var state = {}
1407
+ var result = probeImpl(ctx, state)
1408
+ result = attachGrokBotUsage(ctx, result, state.accessToken)
1372
1409
  result = attachCursorTranscriptActivity(ctx, result)
1373
1410
  result = attachCursorBillingDaily(ctx, result)
1374
1411
  return attachCursorMtdUsage(ctx, result)
@@ -16,8 +16,9 @@
16
16
  { "type": "progress", "label": "Credits", "scope": "overview", "primaryOrder": 2 },
17
17
  { "type": "progress", "label": "Total usage", "scope": "overview", "primaryOrder": 1 },
18
18
  { "type": "progress", "label": "Requests", "scope": "overview", "primaryOrder": 3 },
19
- { "type": "progress", "label": "Auto usage", "scope": "detail" },
20
- { "type": "progress", "label": "API usage", "scope": "detail" },
19
+ { "type": "progress", "label": "Cursor Models", "scope": "detail" },
20
+ { "type": "progress", "label": "Other Models", "scope": "detail" },
21
+ { "type": "progress", "label": "Grok Bot usage", "scope": "detail" },
21
22
  { "type": "progress", "label": "On-demand", "scope": "detail" }
22
23
  ]
23
24
  }
File without changes
File without changes
File without changes