@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.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 (225) hide show
  1. package/LICENSE +57744 -0
  2. package/native-manifest.json +1414 -0
  3. package/package.json +254 -0
  4. package/plugins/abacus-ai/icon.svg +18 -0
  5. package/plugins/abacus-ai/plugin.js +121 -0
  6. package/plugins/abacus-ai/plugin.json +17 -0
  7. package/plugins/alibaba/icon-color.svg +1 -0
  8. package/plugins/alibaba/icon.svg +1 -0
  9. package/plugins/alibaba/plugin.js +322 -0
  10. package/plugins/alibaba/plugin.json +20 -0
  11. package/plugins/alibaba-token-plan/icon-color.svg +1 -0
  12. package/plugins/alibaba-token-plan/icon.svg +1 -0
  13. package/plugins/alibaba-token-plan/plugin.js +544 -0
  14. package/plugins/alibaba-token-plan/plugin.json +19 -0
  15. package/plugins/amp/icon-color.svg +1 -0
  16. package/plugins/amp/icon-conflict.svg +6 -0
  17. package/plugins/amp/icon.svg +1 -0
  18. package/plugins/amp/plugin.js +175 -0
  19. package/plugins/amp/plugin.json +16 -0
  20. package/plugins/antigravity/icon-color.svg +1 -0
  21. package/plugins/antigravity/icon-conflict.svg +3 -0
  22. package/plugins/antigravity/icon.svg +1 -0
  23. package/plugins/antigravity/plugin.js +739 -0
  24. package/plugins/antigravity/plugin.json +31 -0
  25. package/plugins/antigravity-cli/icon.svg +3 -0
  26. package/plugins/antigravity-cli/plugin.js +570 -0
  27. package/plugins/antigravity-cli/plugin.json +16 -0
  28. package/plugins/antigravity-ide/icon.svg +3 -0
  29. package/plugins/antigravity-ide/plugin.js +257 -0
  30. package/plugins/antigravity-ide/plugin.json +29 -0
  31. package/plugins/augment/icon.svg +14 -0
  32. package/plugins/augment/plugin.js +59 -0
  33. package/plugins/augment/plugin.json +18 -0
  34. package/plugins/aws-bedrock/icon-color.svg +1 -0
  35. package/plugins/aws-bedrock/icon.svg +1 -0
  36. package/plugins/aws-bedrock/plugin.js +206 -0
  37. package/plugins/aws-bedrock/plugin.json +18 -0
  38. package/plugins/azure-openai/icon-color.svg +1 -0
  39. package/plugins/azure-openai/icon.svg +1 -0
  40. package/plugins/azure-openai/plugin.js +145 -0
  41. package/plugins/azure-openai/plugin.json +17 -0
  42. package/plugins/chutes/icon.svg +7 -0
  43. package/plugins/chutes/plugin.js +236 -0
  44. package/plugins/chutes/plugin.json +19 -0
  45. package/plugins/claude/icon-color.svg +1 -0
  46. package/plugins/claude/icon.svg +1 -0
  47. package/plugins/claude/plugin.js +1723 -0
  48. package/plugins/claude/plugin.json +30 -0
  49. package/plugins/codebuff/icon.svg +92 -0
  50. package/plugins/codebuff/plugin.js +113 -0
  51. package/plugins/codebuff/plugin.json +17 -0
  52. package/plugins/codex/icon-color.svg +5 -0
  53. package/plugins/codex/icon.svg +1 -0
  54. package/plugins/codex/plugin.js +1009 -0
  55. package/plugins/codex/plugin.json +82 -0
  56. package/plugins/command-code/icon.svg +3 -0
  57. package/plugins/command-code/plugin.js +184 -0
  58. package/plugins/command-code/plugin.json +20 -0
  59. package/plugins/copilot/icon-color.svg +1 -0
  60. package/plugins/copilot/icon.svg +1 -0
  61. package/plugins/copilot/plugin.js +684 -0
  62. package/plugins/copilot/plugin.json +21 -0
  63. package/plugins/crof/icon.svg +3 -0
  64. package/plugins/crof/plugin.js +53 -0
  65. package/plugins/crof/plugin.json +17 -0
  66. package/plugins/crofai/icon.svg +16 -0
  67. package/plugins/crofai/plugin.js +81 -0
  68. package/plugins/crofai/plugin.json +18 -0
  69. package/plugins/cursor/icon-conflict.svg +3 -0
  70. package/plugins/cursor/icon.svg +1 -0
  71. package/plugins/cursor/plugin.js +1379 -0
  72. package/plugins/cursor/plugin.json +23 -0
  73. package/plugins/cursor-nightly/icon.png +0 -0
  74. package/plugins/cursor-nightly/plugin.js +1379 -0
  75. package/plugins/cursor-nightly/plugin.json +23 -0
  76. package/plugins/deepgram/icon.svg +1 -0
  77. package/plugins/deepgram/plugin.js +20 -0
  78. package/plugins/deepgram/plugin.json +17 -0
  79. package/plugins/deepseek/icon-color.svg +1 -0
  80. package/plugins/deepseek/icon.svg +1 -0
  81. package/plugins/deepseek/plugin.js +71 -0
  82. package/plugins/deepseek/plugin.json +17 -0
  83. package/plugins/devin/icon.svg +5 -0
  84. package/plugins/devin/plugin.js +341 -0
  85. package/plugins/devin/plugin.json +16 -0
  86. package/plugins/doubao/icon-color.svg +1 -0
  87. package/plugins/doubao/icon.svg +1 -0
  88. package/plugins/doubao/plugin.js +92 -0
  89. package/plugins/doubao/plugin.json +17 -0
  90. package/plugins/droid/icon.svg +1 -0
  91. package/plugins/droid/plugin.json +20 -0
  92. package/plugins/elevenlabs/icon.svg +4 -0
  93. package/plugins/elevenlabs/plugin.js +48 -0
  94. package/plugins/elevenlabs/plugin.json +18 -0
  95. package/plugins/factory/icon-conflict.svg +1 -0
  96. package/plugins/factory/icon.svg +1 -0
  97. package/plugins/factory/plugin.js +487 -0
  98. package/plugins/factory/plugin.json +15 -0
  99. package/plugins/fireworks-ai/icon.svg +6 -0
  100. package/plugins/fireworks-ai/plugin.js +370 -0
  101. package/plugins/fireworks-ai/plugin.json +19 -0
  102. package/plugins/gemini/icon-color.svg +1 -0
  103. package/plugins/gemini/icon.svg +1 -0
  104. package/plugins/gemini/plugin.js +460 -0
  105. package/plugins/gemini/plugin.json +16 -0
  106. package/plugins/grok/icon.svg +1 -0
  107. package/plugins/grok/plugin.js +297 -0
  108. package/plugins/grok/plugin.json +19 -0
  109. package/plugins/groqcloud/icon.svg +1 -0
  110. package/plugins/groqcloud/plugin.js +117 -0
  111. package/plugins/groqcloud/plugin.json +19 -0
  112. package/plugins/jetbrains-ai-assistant/icon-color.svg +14 -0
  113. package/plugins/jetbrains-ai-assistant/icon-conflict.svg +3 -0
  114. package/plugins/jetbrains-ai-assistant/icon.svg +14 -0
  115. package/plugins/jetbrains-ai-assistant/plugin.js +313 -0
  116. package/plugins/jetbrains-ai-assistant/plugin.json +16 -0
  117. package/plugins/kilo/icon.svg +1 -0
  118. package/plugins/kilo/plugin.js +111 -0
  119. package/plugins/kilo/plugin.json +19 -0
  120. package/plugins/kimi/icon-color.svg +1 -0
  121. package/plugins/kimi/icon-conflict.svg +3 -0
  122. package/plugins/kimi/icon.svg +1 -0
  123. package/plugins/kimi/plugin.js +358 -0
  124. package/plugins/kimi/plugin.json +15 -0
  125. package/plugins/kimi-k2/icon-color.svg +1 -0
  126. package/plugins/kimi-k2/icon.svg +1 -0
  127. package/plugins/kimi-k2/plugin.js +58 -0
  128. package/plugins/kimi-k2/plugin.json +18 -0
  129. package/plugins/kiro/icon-color.svg +5 -0
  130. package/plugins/kiro/icon-conflict.svg +1 -0
  131. package/plugins/kiro/icon.svg +4 -0
  132. package/plugins/kiro/plugin.js +390 -0
  133. package/plugins/kiro/plugin.json +16 -0
  134. package/plugins/litellm/icon.svg +16 -0
  135. package/plugins/litellm/plugin.js +199 -0
  136. package/plugins/litellm/plugin.json +16 -0
  137. package/plugins/llm-proxy/icon.svg +1 -0
  138. package/plugins/llm-proxy/plugin.js +40 -0
  139. package/plugins/llm-proxy/plugin.json +17 -0
  140. package/plugins/manus/icon.svg +6 -0
  141. package/plugins/manus/plugin.js +50 -0
  142. package/plugins/manus/plugin.json +17 -0
  143. package/plugins/mimo/icon.svg +1 -0
  144. package/plugins/mimo/plugin.js +177 -0
  145. package/plugins/mimo/plugin.json +19 -0
  146. package/plugins/minimax/icon-color.svg +1 -0
  147. package/plugins/minimax/icon-conflict.svg +4 -0
  148. package/plugins/minimax/icon.svg +1 -0
  149. package/plugins/minimax/plugin.js +453 -0
  150. package/plugins/minimax/plugin.json +14 -0
  151. package/plugins/mistral/icon-color.svg +1 -0
  152. package/plugins/mistral/icon.svg +1 -0
  153. package/plugins/mistral/plugin.js +152 -0
  154. package/plugins/mistral/plugin.json +18 -0
  155. package/plugins/moonshot/icon.svg +1 -0
  156. package/plugins/moonshot/plugin.js +43 -0
  157. package/plugins/moonshot/plugin.json +16 -0
  158. package/plugins/nanogpt/icon-color.svg +17 -0
  159. package/plugins/nanogpt/icon.svg +10 -0
  160. package/plugins/nanogpt/plugin.js +80 -0
  161. package/plugins/nanogpt/plugin.json +17 -0
  162. package/plugins/neuralwatt/icon.svg +3 -0
  163. package/plugins/neuralwatt/plugin.js +152 -0
  164. package/plugins/neuralwatt/plugin.json +17 -0
  165. package/plugins/ollama/icon.svg +1 -0
  166. package/plugins/ollama/plugin.js +92 -0
  167. package/plugins/ollama/plugin.json +20 -0
  168. package/plugins/openai-api/icon.svg +1 -0
  169. package/plugins/openai-api/plugin.js +533 -0
  170. package/plugins/openai-api/plugin.json +26 -0
  171. package/plugins/opencode/icon.svg +1 -0
  172. package/plugins/opencode/plugin.js +342 -0
  173. package/plugins/opencode/plugin.json +19 -0
  174. package/plugins/opencode-go/icon-conflict.svg +1 -0
  175. package/plugins/opencode-go/icon.svg +1 -0
  176. package/plugins/opencode-go/plugin.js +617 -0
  177. package/plugins/opencode-go/plugin.json +50 -0
  178. package/plugins/openrouter/icon.svg +1 -0
  179. package/plugins/openrouter/plugin.js +156 -0
  180. package/plugins/openrouter/plugin.json +8 -0
  181. package/plugins/perplexity/icon-color.svg +1 -0
  182. package/plugins/perplexity/icon-conflict.svg +1 -0
  183. package/plugins/perplexity/icon.svg +1 -0
  184. package/plugins/perplexity/plugin.js +425 -0
  185. package/plugins/perplexity/plugin.json +19 -0
  186. package/plugins/poe/icon.svg +1 -0
  187. package/plugins/poe/plugin.js +190 -0
  188. package/plugins/poe/plugin.json +19 -0
  189. package/plugins/stepfun/icon-color.svg +1 -0
  190. package/plugins/stepfun/icon.svg +1 -0
  191. package/plugins/stepfun/plugin.js +155 -0
  192. package/plugins/stepfun/plugin.json +18 -0
  193. package/plugins/synthetic/icon-conflict.svg +12 -0
  194. package/plugins/synthetic/icon.svg +14 -0
  195. package/plugins/synthetic/plugin.js +331 -0
  196. package/plugins/synthetic/plugin.json +23 -0
  197. package/plugins/t3chat/icon-color.svg +28 -0
  198. package/plugins/t3chat/icon.svg +4 -0
  199. package/plugins/t3chat/plugin.js +243 -0
  200. package/plugins/t3chat/plugin.json +20 -0
  201. package/plugins/venice/icon-color.svg +1 -0
  202. package/plugins/venice/icon.svg +1 -0
  203. package/plugins/venice/plugin.js +69 -0
  204. package/plugins/venice/plugin.json +16 -0
  205. package/plugins/vertex-ai/icon-color.svg +1 -0
  206. package/plugins/vertex-ai/icon.svg +1 -0
  207. package/plugins/vertex-ai/plugin.js +172 -0
  208. package/plugins/vertex-ai/plugin.json +18 -0
  209. package/plugins/warp/icon-color.svg +10 -0
  210. package/plugins/warp/icon.svg +6 -0
  211. package/plugins/warp/plugin.js +108 -0
  212. package/plugins/warp/plugin.json +18 -0
  213. package/plugins/windsurf/icon-conflict.svg +3 -0
  214. package/plugins/windsurf/icon.svg +1 -0
  215. package/plugins/windsurf/plugin.js +208 -0
  216. package/plugins/windsurf/plugin.json +16 -0
  217. package/plugins/zai/icon-conflict.svg +5 -0
  218. package/plugins/zai/icon.svg +1 -0
  219. package/plugins/zai/plugin.js +188 -0
  220. package/plugins/zai/plugin.json +16 -0
  221. package/plugins/zed/icon.svg +4 -0
  222. package/plugins/zed/plugin.js +270 -0
  223. package/plugins/zed/plugin.json +19 -0
  224. package/usagestat +0 -0
  225. package/usagestatd +0 -0
@@ -0,0 +1,43 @@
1
+ (function () {
2
+ function apiKey(ctx) {
3
+ return ctx.host.env.get("MOONSHOT_API_KEY") || ctx.host.env.get("MOONSHOT_KEY");
4
+ }
5
+
6
+ function baseUrl(ctx) {
7
+ var region = String(ctx.host.env.get("MOONSHOT_REGION") || "").toLowerCase();
8
+ var explicit = ctx.host.env.get("MOONSHOT_API_URL");
9
+ if (explicit) return explicit.replace(/\/$/, "");
10
+ return region === "cn" || region === "china" ? "https://api.moonshot.cn" : "https://api.moonshot.ai";
11
+ }
12
+
13
+ function pick(obj, names) {
14
+ for (var i = 0; i < names.length; i++) {
15
+ var v = obj && obj[names[i]];
16
+ if (typeof v === "number") return v;
17
+ if (typeof v === "string" && v.trim() !== "" && !isNaN(Number(v))) return Number(v);
18
+ }
19
+ return null;
20
+ }
21
+
22
+ function probe(ctx) {
23
+ var key = apiKey(ctx);
24
+ if (!key) throw "Moonshot API key not found. Set MOONSHOT_API_KEY or MOONSHOT_KEY.";
25
+
26
+ var result = ctx.util.requestJson({
27
+ method: "GET",
28
+ url: baseUrl(ctx) + "/v1/users/me/balance",
29
+ headers: { Authorization: "Bearer " + key, Accept: "application/json" },
30
+ timeoutMs: 15000,
31
+ });
32
+ if (ctx.util.isAuthStatus(result.resp.status)) throw "Moonshot API key invalid or expired.";
33
+ if (result.resp.status < 200 || result.resp.status >= 300) throw "Moonshot API error (HTTP " + result.resp.status + ").";
34
+
35
+ var json = result.json || {};
36
+ var data = json.data || json;
37
+ var available = pick(data, ["available_balance", "availableBalance", "balance", "cash_balance"]);
38
+ if (available === null) throw "Moonshot response did not include a recognizable balance.";
39
+ return { lines: [ctx.line.text({ label: "Balance", value: String(available) })] };
40
+ }
41
+
42
+ globalThis.__openusage_plugin = { id: "moonshot", probe: probe };
43
+ })();
@@ -0,0 +1,16 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "moonshot",
4
+ "name": "Moonshot",
5
+ "version": "0.0.1",
6
+ "entry": "plugin.js",
7
+ "brandColor": "#111827",
8
+ "links": [
9
+ { "label": "Console", "url": "https://platform.moonshot.ai" }
10
+ ],
11
+ "supportedModes": ["api"],
12
+ "autoMode": "api",
13
+ "lines": [
14
+ { "type": "text", "label": "Balance", "scope": "overview", "primaryOrder": 1 }
15
+ ]
16
+ }
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 756 779" role="img" aria-label="NanoGPT logo">
2
+ <defs>
3
+ <linearGradient id="nanoGradient" x1="0" y1="0" x2="0" y2="1">
4
+ <stop offset="0%" stop-color="#11E9BB"/>
5
+ <stop offset="100%" stop-color="#015A9E"/>
6
+ </linearGradient>
7
+ </defs>
8
+
9
+ <g fill="url(#nanoGradient)">
10
+ <polygon points="442,11 295,116 184,401 609,268"/>
11
+ <polygon points="542,102 544,112 642,264 722,298 560,88"/>
12
+ <polygon points="604,301 183,432 388,766"/>
13
+ <polygon points="744,339 640,296 458,693"/>
14
+ <polygon points="125,178 11,327 151,403 222,218"/>
15
+ <polygon points="52,383 272,637 149,437"/>
16
+ </g>
17
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 756 779" role="img" aria-label="NanoGPT logo">
2
+ <g fill="currentColor">
3
+ <polygon points="442,11 295,116 184,401 609,268"/>
4
+ <polygon points="542,102 544,112 642,264 722,298 560,88"/>
5
+ <polygon points="604,301 183,432 388,766"/>
6
+ <polygon points="744,339 640,296 458,693"/>
7
+ <polygon points="125,178 11,327 151,403 222,218"/>
8
+ <polygon points="52,383 272,637 149,437"/>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,80 @@
1
+ (function () {
2
+ var API_URL = "https://nano-gpt.com/api/subscription/v1/usage";
3
+ var DAY_MS = 24 * 60 * 60 * 1000;
4
+ var MONTH_MS = 30 * DAY_MS;
5
+
6
+ function loadApiKey(ctx) {
7
+ var v = ctx.host.env.get("NANOGPT_API_KEY");
8
+ if (typeof v === "string" && v.trim()) return v.trim();
9
+ return null;
10
+ }
11
+
12
+ function probe(ctx) {
13
+ var apiKey = loadApiKey(ctx);
14
+ if (!apiKey) {
15
+ throw "NanoGPT API key not found. Set NANOGPT_API_KEY.";
16
+ }
17
+
18
+ var result = ctx.util.requestJson({
19
+ method: "GET",
20
+ url: API_URL,
21
+ headers: { Authorization: "Bearer " + apiKey, Accept: "application/json" },
22
+ timeoutMs: 15000,
23
+ });
24
+
25
+ if (ctx.util.isAuthStatus(result.resp.status)) {
26
+ throw "API key invalid or expired.";
27
+ }
28
+ if (result.resp.status < 200 || result.resp.status >= 300) {
29
+ throw "NanoGPT API error (HTTP " + result.resp.status + ").";
30
+ }
31
+ if (!result.json) throw "Could not parse NanoGPT usage response.";
32
+
33
+ var json = result.json;
34
+ if (!json.active) {
35
+ throw "NanoGPT subscription inactive. Check your subscription at nano-gpt.com.";
36
+ }
37
+
38
+ var limits = json.limits || {};
39
+ var daily = json.daily || {};
40
+ var monthly = json.monthly || {};
41
+
42
+ var dailyPct = typeof daily.percentUsed === "number" ? Math.min(100, daily.percentUsed * 100) : 0;
43
+ var dailyOpts = {
44
+ label: "Daily",
45
+ used: dailyPct,
46
+ limit: 100,
47
+ format: { kind: "percent" },
48
+ periodDurationMs: DAY_MS,
49
+ };
50
+ if (daily.resetAt) {
51
+ var dailyReset = ctx.util.toIso(daily.resetAt);
52
+ if (dailyReset) dailyOpts.resetsAt = dailyReset;
53
+ }
54
+
55
+ var monthlyPct = typeof monthly.percentUsed === "number" ? Math.min(100, monthly.percentUsed * 100) : 0;
56
+ var monthlyOpts = {
57
+ label: "Monthly",
58
+ used: monthlyPct,
59
+ limit: 100,
60
+ format: { kind: "percent" },
61
+ periodDurationMs: MONTH_MS,
62
+ };
63
+ if (monthly.resetAt) {
64
+ var monthlyReset = ctx.util.toIso(monthly.resetAt);
65
+ if (monthlyReset) monthlyOpts.resetsAt = monthlyReset;
66
+ }
67
+
68
+ var stateLabel = json.state || "active";
69
+ if (json.graceUntil) stateLabel += " (grace until " + json.graceUntil + ")";
70
+
71
+ var lines = [
72
+ ctx.line.progress(dailyOpts),
73
+ ctx.line.progress(monthlyOpts),
74
+ ];
75
+
76
+ return { plan: stateLabel, lines: lines };
77
+ }
78
+
79
+ globalThis.__openusage_plugin = { id: "nanogpt", probe: probe };
80
+ })();
@@ -0,0 +1,17 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "nanogpt",
4
+ "name": "NanoGPT",
5
+ "version": "0.0.1",
6
+ "entry": "plugin.js",
7
+ "brandColor": "#6366F1",
8
+ "links": [
9
+ { "label": "Usage", "url": "https://nano-gpt.com/usage" }
10
+ ],
11
+ "supportedModes": ["api"],
12
+ "autoMode": "api",
13
+ "lines": [
14
+ { "type": "progress", "label": "Daily", "scope": "overview", "primaryOrder": 1 },
15
+ { "type": "progress", "label": "Monthly", "scope": "overview", "primaryOrder": 2 }
16
+ ]
17
+ }
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M13 10V3L4 14h7v7l9-11h-7z"/>
3
+ </svg>
@@ -0,0 +1,152 @@
1
+ (function () {
2
+ var API_KEY_ENV_VARS = ["NEURALWATT_API_KEY"]
3
+ var QUOTA_URL = "https://api.neuralwatt.com/v1/quota"
4
+
5
+ function readNumber(value) {
6
+ if (typeof value === "number") return Number.isFinite(value) ? value : null
7
+ if (typeof value === "string") {
8
+ var parsed = Number(value)
9
+ return Number.isFinite(parsed) ? parsed : null
10
+ }
11
+ return null
12
+ }
13
+
14
+ function readString(value) {
15
+ if (typeof value !== "string") return null
16
+ var trimmed = value.trim()
17
+ return trimmed || null
18
+ }
19
+
20
+ function parseDateMs(value) {
21
+ if (typeof value === "number") return Number.isFinite(value) ? value : null
22
+ if (typeof value === "string") {
23
+ var parsed = Date.parse(value)
24
+ return Number.isFinite(parsed) ? parsed : null
25
+ }
26
+ return null
27
+ }
28
+
29
+ function parseSubscriptionPeriodMs(sub) {
30
+ if (!sub || !sub.current_period_start || !sub.current_period_end) return null
31
+ var startMs = parseDateMs(sub.current_period_start)
32
+ var endMs = parseDateMs(sub.current_period_end)
33
+ if (startMs !== null && endMs !== null && endMs > startMs) return endMs - startMs
34
+ return null
35
+ }
36
+
37
+ function loadApiKey(ctx) {
38
+ for (var i = 0; i < API_KEY_ENV_VARS.length; i += 1) {
39
+ var name = API_KEY_ENV_VARS[i]
40
+ var value = null
41
+ try {
42
+ value = ctx.host.env.get(name)
43
+ } catch (e) {
44
+ ctx.host.log.warn("env read failed for " + name + ": " + String(e))
45
+ }
46
+ if (value && typeof value === "string" && value.trim()) {
47
+ ctx.host.log.info("api key loaded from " + name)
48
+ return { value: value.trim(), source: name }
49
+ }
50
+ }
51
+ return null
52
+ }
53
+
54
+ function probe(ctx) {
55
+ var apiKeyInfo = loadApiKey(ctx)
56
+ if (!apiKeyInfo) {
57
+ throw "Neuralwatt API key missing. Set NEURALWATT_API_KEY."
58
+ }
59
+
60
+ var resp
61
+ try {
62
+ resp = ctx.util.request({
63
+ method: "GET",
64
+ url: QUOTA_URL,
65
+ headers: {
66
+ Authorization: "Bearer " + apiKeyInfo.value,
67
+ Accept: "application/json",
68
+ "User-Agent": "usagestat",
69
+ },
70
+ timeoutMs: 10000,
71
+ })
72
+ } catch (e) {
73
+ throw "Request failed. Check your connection."
74
+ }
75
+
76
+ if (ctx.util.isAuthStatus(resp.status)) {
77
+ throw "Invalid API key. Check NEURALWATT_API_KEY."
78
+ }
79
+ if (resp.status < 200 || resp.status >= 300) {
80
+ throw "Request failed (HTTP " + String(resp.status) + "). Try again later."
81
+ }
82
+
83
+ var data = ctx.util.tryParseJson(resp.bodyText)
84
+ if (!data || typeof data !== "object") {
85
+ throw "Response invalid. Try again later."
86
+ }
87
+
88
+ var sub = data.subscription && typeof data.subscription === "object" ? data.subscription : null
89
+ var balance = data.balance && typeof data.balance === "object" ? data.balance : null
90
+ var plan = null
91
+ var resetsAt = null
92
+ var periodDurationMs = null
93
+
94
+ if (sub) {
95
+ if (typeof sub.plan === "string" && sub.plan) {
96
+ plan = sub.plan.charAt(0).toUpperCase() + sub.plan.slice(1)
97
+ }
98
+ if (sub.current_period_end) {
99
+ var endMs = parseDateMs(sub.current_period_end)
100
+ resetsAt = endMs !== null ? ctx.util.toIso(endMs) : null
101
+ }
102
+ periodDurationMs = parseSubscriptionPeriodMs(sub)
103
+ }
104
+
105
+ var lines = []
106
+
107
+ // Subscription energy line (hidden if no subscription)
108
+ if (sub) {
109
+ var kwhIncluded = readNumber(sub.kwh_included)
110
+ var kwhUsed = readNumber(sub.kwh_used)
111
+ if (kwhIncluded !== null && kwhIncluded > 0 && kwhUsed !== null) {
112
+ var energyLine = {
113
+ label: "Subscription",
114
+ used: Math.round(kwhUsed * 10000) / 10000,
115
+ limit: Math.round(kwhIncluded * 10000) / 10000,
116
+ format: { kind: "count", suffix: "kWh" },
117
+ }
118
+ if (resetsAt) energyLine.resetsAt = resetsAt
119
+ if (periodDurationMs) energyLine.periodDurationMs = periodDurationMs
120
+ lines.push(ctx.line.progress(energyLine))
121
+ }
122
+ }
123
+
124
+ // Balance line (hidden if total credits is 0)
125
+ if (balance) {
126
+ var totalCredits = readNumber(balance.total_credits_usd)
127
+ var usedCredits = readNumber(balance.credits_used_usd)
128
+ if (totalCredits !== null && totalCredits > 0 && usedCredits !== null) {
129
+ lines.push(ctx.line.progress({
130
+ label: "Balance",
131
+ used: Math.round(usedCredits * 100) / 100,
132
+ limit: Math.round(totalCredits * 100) / 100,
133
+ format: { kind: "dollars" },
134
+ }))
135
+ }
136
+
137
+ // Accounting method badge
138
+ var method = readString(balance.accounting_method)
139
+ if (method) {
140
+ lines.push(ctx.line.badge({ label: "Method", text: method.charAt(0).toUpperCase() + method.slice(1) }))
141
+ }
142
+ }
143
+
144
+ if (lines.length === 0) {
145
+ lines.push(ctx.line.badge({ label: "Status", text: "No usage data", color: "#a3a3a3" }))
146
+ }
147
+
148
+ return { plan: plan, lines: lines }
149
+ }
150
+
151
+ globalThis.__openusage_plugin = { id: "neuralwatt", probe: probe }
152
+ })()
@@ -0,0 +1,17 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "neuralwatt",
4
+ "name": "Neuralwatt",
5
+ "version": "0.0.1",
6
+ "entry": "plugin.js",
7
+ "icon": "icon.svg",
8
+ "brandColor": "#D55934",
9
+ "supportedModes": ["api"],
10
+ "autoMode": "api",
11
+ "lines": [
12
+ { "type": "progress", "label": "Subscription", "scope": "overview", "primaryOrder": 1 },
13
+ { "type": "progress", "label": "Balance", "scope": "overview" },
14
+ { "type": "badge", "label": "Method", "scope": "detail" },
15
+ { "type": "badge", "label": "Status", "scope": "overview" }
16
+ ]
17
+ }
@@ -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>Ollama</title><path d="M7.905 1.09c.216.085.411.225.588.41.295.306.544.744.734 1.263.191.522.315 1.1.362 1.68a5.054 5.054 0 012.049-.636l.051-.004c.87-.07 1.73.087 2.48.474.101.053.2.11.297.17.05-.569.172-1.134.36-1.644.19-.52.439-.957.733-1.264a1.67 1.67 0 01.589-.41c.257-.1.53-.118.796-.042.401.114.745.368 1.016.737.248.337.434.769.561 1.287.23.934.27 2.163.115 3.645l.053.04.026.019c.757.576 1.284 1.397 1.563 2.35.435 1.487.216 3.155-.534 4.088l-.018.021.002.003c.417.762.67 1.567.724 2.4l.002.03c.064 1.065-.2 2.137-.814 3.19l-.007.01.01.024c.472 1.157.62 2.322.438 3.486l-.006.039a.651.651 0 01-.747.536.648.648 0 01-.54-.742c.167-1.033.01-2.069-.48-3.123a.643.643 0 01.04-.617l.004-.006c.604-.924.854-1.83.8-2.72-.046-.779-.325-1.544-.8-2.273a.644.644 0 01.18-.886l.009-.006c.243-.159.467-.565.58-1.12a4.229 4.229 0 00-.095-1.974c-.205-.7-.58-1.284-1.105-1.683-.595-.454-1.383-.673-2.38-.61a.653.653 0 01-.632-.371c-.314-.665-.772-1.141-1.343-1.436a3.288 3.288 0 00-1.772-.332c-1.245.099-2.343.801-2.67 1.686a.652.652 0 01-.61.425c-1.067.002-1.893.252-2.497.703-.522.39-.878.935-1.066 1.588a4.07 4.07 0 00-.068 1.886c.112.558.331 1.02.582 1.269l.008.007c.212.207.257.53.109.785-.36.622-.629 1.549-.673 2.44-.05 1.018.186 1.902.719 2.536l.016.019a.643.643 0 01.095.69c-.576 1.236-.753 2.252-.562 3.052a.652.652 0 01-1.269.298c-.243-1.018-.078-2.184.473-3.498l.014-.035-.008-.012a4.339 4.339 0 01-.598-1.309l-.005-.019a5.764 5.764 0 01-.177-1.785c.044-.91.278-1.842.622-2.59l.012-.026-.002-.002c-.293-.418-.51-.953-.63-1.545l-.005-.024a5.352 5.352 0 01.093-2.49c.262-.915.777-1.701 1.536-2.269.06-.045.123-.09.186-.132-.159-1.493-.119-2.73.112-3.67.127-.518.314-.95.562-1.287.27-.368.614-.622 1.015-.737.266-.076.54-.059.797.042zm4.116 9.09c.936 0 1.8.313 2.446.855.63.527 1.005 1.235 1.005 1.94 0 .888-.406 1.58-1.133 2.022-.62.375-1.451.557-2.403.557-1.009 0-1.871-.259-2.493-.734-.617-.47-.963-1.13-.963-1.845 0-.707.398-1.417 1.056-1.946.668-.537 1.55-.849 2.485-.849zm0 .896a3.07 3.07 0 00-1.916.65c-.461.37-.722.835-.722 1.25 0 .428.21.829.61 1.134.455.347 1.124.548 1.943.548.799 0 1.473-.147 1.932-.426.463-.28.7-.686.7-1.257 0-.423-.246-.89-.683-1.256-.484-.405-1.14-.643-1.864-.643zm.662 1.21l.004.004c.12.151.095.37-.056.49l-.292.23v.446a.375.375 0 01-.376.373.375.375 0 01-.376-.373v-.46l-.271-.218a.347.347 0 01-.052-.49.353.353 0 01.494-.051l.215.172.22-.174a.353.353 0 01.49.051zm-5.04-1.919c.478 0 .867.39.867.871a.87.87 0 01-.868.871.87.87 0 01-.867-.87.87.87 0 01.867-.872zm8.706 0c.48 0 .868.39.868.871a.87.87 0 01-.868.871.87.87 0 01-.867-.87.87.87 0 01.867-.872zM7.44 2.3l-.003.002a.659.659 0 00-.285.238l-.005.006c-.138.189-.258.467-.348.832-.17.692-.216 1.631-.124 2.782.43-.128.899-.208 1.404-.237l.01-.001.019-.034c.046-.082.095-.161.148-.239.123-.771.022-1.692-.253-2.444-.134-.364-.297-.65-.453-.813a.628.628 0 00-.107-.09L7.44 2.3zm9.174.04l-.002.001a.628.628 0 00-.107.09c-.156.163-.32.45-.453.814-.29.794-.387 1.776-.23 2.572l.058.097.008.014h.03a5.184 5.184 0 011.466.212c.086-1.124.038-2.043-.128-2.722-.09-.365-.21-.643-.349-.832l-.004-.006a.659.659 0 00-.285-.239h-.004z"></path></svg>
@@ -0,0 +1,92 @@
1
+ (function () {
2
+ var SETTINGS_URL = "https://ollama.com/settings"
3
+ var SESSION_COOKIE = "__Secure-session"
4
+
5
+ function getCookieHeader(ctx) {
6
+ var raw = ctx.host.env.get("OLLAMA_COOKIE")
7
+ if (!raw || !raw.trim()) {
8
+ throw "Set OLLAMA_COOKIE to your " + SESSION_COOKIE + " cookie value from ollama.com/settings."
9
+ }
10
+ var val = raw.trim()
11
+ // Strip optional "cookie:" prefix
12
+ if (val.toLowerCase().slice(0, 7) === "cookie:") {
13
+ val = val.slice(7).trim()
14
+ }
15
+ // If just a bare token value with no key=value format, wrap it
16
+ if (val.indexOf("=") < 0) {
17
+ return SESSION_COOKIE + "=" + val
18
+ }
19
+ return val
20
+ }
21
+
22
+ function parsePercent(html, labels) {
23
+ for (var i = 0; i < labels.length; i++) {
24
+ var idx = html.indexOf(labels[i])
25
+ if (idx < 0) continue
26
+ var window = html.slice(idx, idx + 800)
27
+
28
+ var usedMatch = window.match(/(\d+(?:\.\d+)?)\s*%\s*used/)
29
+ if (usedMatch) return parseFloat(usedMatch[1])
30
+
31
+ var widthMatch = window.match(/width:\s*(\d+(?:\.\d+)?)%/)
32
+ if (widthMatch) return parseFloat(widthMatch[1])
33
+ }
34
+ return null
35
+ }
36
+
37
+ function probe(ctx) {
38
+ var cookieHeader = getCookieHeader(ctx)
39
+
40
+ var resp = ctx.host.http.request({
41
+ method: "GET",
42
+ url: SETTINGS_URL,
43
+ headers: {
44
+ "Cookie": cookieHeader,
45
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
46
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
47
+ },
48
+ timeoutMs: 20000,
49
+ })
50
+
51
+ if (resp.status === 401 || resp.status === 403) {
52
+ throw "Session expired. Update OLLAMA_COOKIE with a fresh session token."
53
+ }
54
+
55
+ var html = resp.bodyText || ""
56
+
57
+ if (!html.includes("Session usage") && !html.includes("Weekly usage") && !html.includes("Cloud Usage")) {
58
+ if (html.includes("Sign in") || resp.status !== 200) {
59
+ throw "Session expired. Update OLLAMA_COOKIE with a fresh session token."
60
+ }
61
+ }
62
+
63
+ var sessionPct = parsePercent(html, ["Session usage", "Hourly usage"])
64
+ var weeklyPct = parsePercent(html, ["Weekly usage"])
65
+
66
+ if (sessionPct === null && weeklyPct === null) {
67
+ throw "Could not find usage data on Ollama settings page."
68
+ }
69
+
70
+ var lines = []
71
+ if (sessionPct !== null) {
72
+ lines.push(ctx.line.progress({
73
+ label: "Session",
74
+ used: sessionPct,
75
+ limit: 100,
76
+ format: { kind: "percent" },
77
+ }))
78
+ }
79
+ if (weeklyPct !== null) {
80
+ lines.push(ctx.line.progress({
81
+ label: "Weekly",
82
+ used: weeklyPct,
83
+ limit: 100,
84
+ format: { kind: "percent" },
85
+ }))
86
+ }
87
+
88
+ return { lines: lines }
89
+ }
90
+
91
+ globalThis.__openusage_plugin = { id: "ollama", probe: probe }
92
+ })()
@@ -0,0 +1,20 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "ollama",
4
+ "name": "Ollama",
5
+ "version": "0.0.1",
6
+ "entry": "plugin.js",
7
+ "brandColor": "#FFFFFF",
8
+ "links": [
9
+ { "label": "Settings", "url": "https://ollama.com/settings" }
10
+ ],
11
+ "envVars": ["OLLAMA_COOKIE"],
12
+ "supportedModes": ["web"],
13
+ "autoMode": "web",
14
+ "webUrl": "https://ollama.com",
15
+ "usageDashboardUrl": "https://ollama.com/settings",
16
+ "lines": [
17
+ { "type": "progress", "label": "Session", "scope": "overview" },
18
+ { "type": "progress", "label": "Weekly", "scope": "detail" }
19
+ ]
20
+ }
@@ -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>OpenAI</title><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"></path></svg>