@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,145 @@
1
+ (function () {
2
+ var DEFAULT_API_VERSION = "2024-10-21";
3
+
4
+ function trim(value) {
5
+ return typeof value === "string" && value.trim() ? value.trim() : null;
6
+ }
7
+
8
+ function env(ctx, name) {
9
+ try {
10
+ return trim(ctx.host.env.get(name));
11
+ } catch (_) {
12
+ return null;
13
+ }
14
+ }
15
+
16
+ function settings(ctx) {
17
+ return ctx.provider && ctx.provider.settings ? ctx.provider.settings : {};
18
+ }
19
+
20
+ function parseSavedConfig(ctx, raw) {
21
+ var text = trim(raw);
22
+ if (!text) return null;
23
+ var parsed = ctx.util.tryParseJson(text);
24
+ if (parsed && typeof parsed === "object") {
25
+ return {
26
+ apiKey: trim(parsed.apiKey || parsed.api_key),
27
+ endpoint: trim(parsed.endpoint),
28
+ deployment: trim(parsed.deployment || parsed.deploymentName || parsed.deployment_name),
29
+ apiVersion: trim(parsed.apiVersion || parsed.api_version),
30
+ };
31
+ }
32
+ var parts = text.split("|").map(function (part) { return part.trim(); });
33
+ if (parts.length >= 3) {
34
+ return {
35
+ apiKey: trim(parts[0]),
36
+ endpoint: trim(parts[1]),
37
+ deployment: trim(parts[2]),
38
+ apiVersion: trim(parts[3]),
39
+ };
40
+ }
41
+ return { apiKey: text };
42
+ }
43
+
44
+ function resolveConfig(ctx) {
45
+ var s = settings(ctx);
46
+ var saved = parseSavedConfig(ctx, ctx.provider && ctx.provider.apiKey);
47
+ var config = {
48
+ apiKey: trim(s.apiKey) || (saved && saved.apiKey) || env(ctx, "AZURE_OPENAI_API_KEY"),
49
+ endpoint: trim(s.endpoint) || (saved && saved.endpoint) || env(ctx, "AZURE_OPENAI_ENDPOINT"),
50
+ deployment: trim(s.deployment) || trim(s.deploymentName) || (saved && saved.deployment) ||
51
+ env(ctx, "AZURE_OPENAI_DEPLOYMENT") || env(ctx, "AZURE_OPENAI_DEPLOYMENT_NAME"),
52
+ apiVersion: trim(s.apiVersion) || trim(s.api_version) || (saved && saved.apiVersion) ||
53
+ env(ctx, "AZURE_OPENAI_API_VERSION") || DEFAULT_API_VERSION,
54
+ };
55
+ if (!config.apiKey) throw "Azure OpenAI API key not configured. Set AZURE_OPENAI_API_KEY.";
56
+ if (!config.endpoint) throw "Azure OpenAI endpoint not configured. Set AZURE_OPENAI_ENDPOINT.";
57
+ if (!config.deployment) throw "Azure OpenAI deployment not configured. Set AZURE_OPENAI_DEPLOYMENT.";
58
+ return config;
59
+ }
60
+
61
+ function endpointBase(raw) {
62
+ var value = String(raw || "").trim().replace(/\/+$/, "");
63
+ if (!/^https?:\/\//i.test(value)) value = "https://" + value;
64
+ return value;
65
+ }
66
+
67
+ function stripSuffix(value, suffix) {
68
+ var lower = value.toLowerCase();
69
+ return lower.endsWith(suffix) ? value.slice(0, value.length - suffix.length) : value;
70
+ }
71
+
72
+ function chatUrl(config) {
73
+ var base = endpointBase(config.endpoint);
74
+ if (String(config.apiVersion).trim().toLowerCase() === "v1") {
75
+ base = stripSuffix(stripSuffix(base, "/openai/v1"), "/openai");
76
+ return base + "/openai/v1/chat/completions";
77
+ }
78
+ base = stripSuffix(base, "/openai");
79
+ return base + "/openai/deployments/" + encodeURIComponent(config.deployment) +
80
+ "/chat/completions?api-version=" + encodeURIComponent(config.apiVersion);
81
+ }
82
+
83
+ function validationBody(config) {
84
+ if (String(config.apiVersion).trim().toLowerCase() === "v1") {
85
+ return JSON.stringify({
86
+ model: config.deployment,
87
+ messages: [{ role: "user", content: "ping" }],
88
+ max_completion_tokens: 1,
89
+ });
90
+ }
91
+ return JSON.stringify({
92
+ messages: [{ role: "user", content: "ping" }],
93
+ max_tokens: 1,
94
+ });
95
+ }
96
+
97
+ function responseSummary(bodyText) {
98
+ var collapsed = String(bodyText || "").split(/\s+/).filter(Boolean).join(" ");
99
+ return collapsed.length > 240 ? collapsed.slice(0, 240) + "... [truncated]" : collapsed;
100
+ }
101
+
102
+ function probe(ctx) {
103
+ var config = resolveConfig(ctx);
104
+ var resp;
105
+ try {
106
+ resp = ctx.util.request({
107
+ method: "POST",
108
+ url: chatUrl(config),
109
+ headers: {
110
+ "api-key": config.apiKey,
111
+ Accept: "application/json",
112
+ "Content-Type": "application/json",
113
+ },
114
+ bodyText: validationBody(config),
115
+ timeoutMs: 15000,
116
+ });
117
+ } catch (_) {
118
+ throw "Azure OpenAI validation request failed. Check your connection.";
119
+ }
120
+
121
+ if (ctx.util.isAuthStatus(resp.status)) {
122
+ throw "Azure OpenAI API key is invalid or unauthorized.";
123
+ }
124
+ if (resp.status < 200 || resp.status >= 300) {
125
+ throw "Azure OpenAI API error: HTTP " + resp.status + ": " + responseSummary(resp.bodyText);
126
+ }
127
+
128
+ var parsed = ctx.util.tryParseJson(resp.bodyText);
129
+ if (!parsed || typeof parsed !== "object") {
130
+ throw "Azure OpenAI response was not valid JSON.";
131
+ }
132
+ var model = trim(parsed.model);
133
+ var subtitle = model ? "Deployment: " + config.deployment + " / Model: " + model : "Deployment: " + config.deployment;
134
+ return {
135
+ displayName: "Azure OpenAI",
136
+ source: "api",
137
+ plan: config.deployment,
138
+ lines: [
139
+ ctx.line.badge({ label: "Deployment", text: "Validated", color: "#22c55e", subtitle: subtitle }),
140
+ ],
141
+ };
142
+ }
143
+
144
+ globalThis.__openusage_plugin = { id: "azure-openai", probe: probe };
145
+ })();
@@ -0,0 +1,17 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "azure-openai",
4
+ "name": "Azure OpenAI",
5
+ "version": "0.0.1",
6
+ "entry": "plugin.js",
7
+ "brandColor": "#0078D4",
8
+ "links": [
9
+ { "label": "AI Foundry", "url": "https://ai.azure.com" },
10
+ { "label": "Azure Status", "url": "https://azure.status.microsoft/en-us/status" }
11
+ ],
12
+ "supportedModes": ["api"],
13
+ "autoMode": "api",
14
+ "lines": [
15
+ { "type": "badge", "label": "Deployment", "scope": "overview", "primaryOrder": 1 }
16
+ ]
17
+ }
@@ -0,0 +1,7 @@
1
+ <svg viewBox="0 0 32 32" fill="#3184FF" xmlns="http://www.w3.org/2000/svg">
2
+ <title>Chutes</title>
3
+ <path d="M16 3c-6.1 0-11 4.9-11 11h5c0-3.3 2.7-6 6-6s6 2.7 6 6h5c0-6.1-4.9-11-11-11Z"/>
4
+ <path d="M11 14h10l-5 8-5-8Z"/>
5
+ <path d="M15 21h2v5h-2v-5Z"/>
6
+ <path d="M11 26h10v3H11v-3Z"/>
7
+ </svg>
@@ -0,0 +1,236 @@
1
+ (function () {
2
+ var DEFAULT_BASE = "https://api.chutes.ai";
3
+
4
+ function env(ctx, name) {
5
+ try {
6
+ var value = ctx.host.env.get(name);
7
+ return typeof value === "string" && value.trim() ? value.trim() : null;
8
+ } catch (_) {
9
+ return null;
10
+ }
11
+ }
12
+
13
+ function apiKey(ctx) {
14
+ var configured = ctx.provider && typeof ctx.provider.apiKey === "string" ? ctx.provider.apiKey.trim() : "";
15
+ return configured || env(ctx, "CHUTES_API_KEY");
16
+ }
17
+
18
+ function apiBase(ctx) {
19
+ var configured = ctx.provider && ctx.provider.settings && typeof ctx.provider.settings.apiUrl === "string"
20
+ ? ctx.provider.settings.apiUrl.trim()
21
+ : "";
22
+ var base = configured || env(ctx, "CHUTES_API_URL") || DEFAULT_BASE;
23
+ base = base.replace(/\/+$/, "");
24
+ if (!/^https:\/\//i.test(base)) throw "Chutes API URL must be HTTPS.";
25
+ return base;
26
+ }
27
+
28
+ function numberValue(value) {
29
+ if (typeof value === "number" && Number.isFinite(value)) return value;
30
+ if (typeof value === "string" && value.trim()) {
31
+ var parsed = Number(value.replace(/,/g, ""));
32
+ if (Number.isFinite(parsed)) return parsed;
33
+ }
34
+ return null;
35
+ }
36
+
37
+ function boolValue(value) {
38
+ if (typeof value === "boolean") return value;
39
+ if (typeof value === "string") {
40
+ var lower = value.trim().toLowerCase();
41
+ if (lower === "true" || lower === "active") return true;
42
+ if (lower === "false" || lower === "inactive") return false;
43
+ }
44
+ return null;
45
+ }
46
+
47
+ function first(obj, keys) {
48
+ if (!obj || typeof obj !== "object") return undefined;
49
+ for (var i = 0; i < keys.length; i++) {
50
+ if (obj[keys[i]] !== undefined && obj[keys[i]] !== null) return obj[keys[i]];
51
+ }
52
+ return undefined;
53
+ }
54
+
55
+ function requestJson(ctx, base, path, key) {
56
+ var resp = ctx.util.request({
57
+ method: "GET",
58
+ url: base + path,
59
+ headers: { Authorization: "Bearer " + key, Accept: "application/json" },
60
+ timeoutMs: 15000,
61
+ });
62
+ if (ctx.util.isAuthStatus(resp.status)) throw "Chutes API key was rejected.";
63
+ if (resp.status < 200 || resp.status >= 300) {
64
+ throw "Chutes API request failed (HTTP " + resp.status + ").";
65
+ }
66
+ var json = ctx.util.tryParseJson(resp.bodyText);
67
+ if (!json) throw "Chutes response was not valid JSON.";
68
+ return json;
69
+ }
70
+
71
+ function dataRoot(root) {
72
+ if (root && root.data && typeof root.data === "object" && !Array.isArray(root.data)) return root.data;
73
+ if (root && root.result && typeof root.result === "object" && !Array.isArray(root.result)) return root.result;
74
+ return root && typeof root === "object" ? root : {};
75
+ }
76
+
77
+ function parseDate(value) {
78
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value > 10000000000 ? value : value * 1000);
79
+ if (typeof value === "string" && value.trim()) {
80
+ var numeric = Number(value);
81
+ if (Number.isFinite(numeric)) return parseDate(numeric);
82
+ var ms = Date.parse(value);
83
+ if (Number.isFinite(ms)) return new Date(ms);
84
+ }
85
+ return null;
86
+ }
87
+
88
+ function normalizePercent(value) {
89
+ var n = numberValue(value);
90
+ if (n == null) return null;
91
+ if (n <= 1 && n >= 0) n = n * 100;
92
+ return Math.max(0, Math.min(100, n));
93
+ }
94
+
95
+ function windowMinutes(payload) {
96
+ var minutes = numberValue(first(payload, ["window_minutes", "windowMinutes", "period_minutes", "periodMinutes"]));
97
+ if (minutes != null) return Math.round(minutes);
98
+ var hours = numberValue(first(payload, ["window_hours", "windowHours", "period_hours", "periodHours"]));
99
+ if (hours != null) return Math.round(hours * 60);
100
+ var days = numberValue(first(payload, ["window_days", "windowDays", "period_days", "periodDays"]));
101
+ if (days != null) return Math.round(days * 24 * 60);
102
+ var seconds = numberValue(first(payload, ["window_seconds", "windowSeconds", "period_seconds", "periodSeconds"]));
103
+ if (seconds != null) return Math.round(seconds / 60);
104
+ var text = first(payload, ["window", "period", "duration"]);
105
+ if (typeof text === "string") {
106
+ var match = text.trim().toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(m|min|minute|minutes|h|hr|hour|hours|d|day|days|mo|month|months)/);
107
+ if (match) {
108
+ var value = Number(match[1]);
109
+ var unit = match[2];
110
+ if (unit[0] === "m" && unit !== "mo" && unit.indexOf("month") !== 0) return Math.round(value);
111
+ if (unit[0] === "h") return Math.round(value * 60);
112
+ if (unit[0] === "d") return Math.round(value * 24 * 60);
113
+ return Math.round(value * 30 * 24 * 60);
114
+ }
115
+ }
116
+ return null;
117
+ }
118
+
119
+ function parseQuota(payload, fallbackLabel, fallbackWindow) {
120
+ if (!payload || typeof payload !== "object") return null;
121
+ var limit = numberValue(first(payload, ["limit", "quota", "max", "monthly_limit", "monthlyLimit"]));
122
+ var used = numberValue(first(payload, ["used", "usage", "consumed", "current_usage", "currentUsage"]));
123
+ var remaining = numberValue(first(payload, ["remaining", "available", "left"]));
124
+ var percent = normalizePercent(first(payload, ["used_percent", "usedPercent", "usage_percent", "usagePercent", "percent_used", "percentUsed"]));
125
+ var remainingPercent = normalizePercent(first(payload, ["remaining_percent", "remainingPercent", "percent_remaining", "percentRemaining"]));
126
+ if (percent == null && remainingPercent != null) percent = 100 - remainingPercent;
127
+ if (limit == null && used != null && remaining != null) limit = used + remaining;
128
+ if (used == null && limit != null && remaining != null) used = Math.max(0, limit - remaining);
129
+ if (percent == null && used != null && limit > 0) percent = (used / limit) * 100;
130
+ if (percent == null) return null;
131
+
132
+ return {
133
+ label: String(first(payload, ["label", "name", "quota_name", "quotaName", "chute_id", "chuteId"]) || fallbackLabel || "Quota"),
134
+ used: used,
135
+ limit: limit,
136
+ percent: Math.max(0, Math.min(100, percent)),
137
+ windowMinutes: windowMinutes(payload) || fallbackWindow || null,
138
+ resetsAt: parseDate(first(payload, ["resets_at", "resetsAt", "reset_at", "resetAt", "renews_at", "renewsAt", "expires_at", "expiresAt"])),
139
+ unit: String(first(payload, ["unit", "units"]) || "credits"),
140
+ };
141
+ }
142
+
143
+ function collectQuotaObjects(value, out) {
144
+ if (!value || typeof value !== "object") return;
145
+ if (Array.isArray(value)) {
146
+ for (var i = 0; i < value.length; i++) collectQuotaObjects(value[i], out);
147
+ return;
148
+ }
149
+ if (
150
+ first(value, ["limit", "quota", "used", "usage", "remaining", "used_percent", "usedPercent", "usage_percent", "usagePercent"]) !== undefined
151
+ ) {
152
+ out.push(value);
153
+ }
154
+ var keys = Object.keys(value);
155
+ for (var j = 0; j < keys.length; j++) collectQuotaObjects(value[keys[j]], out);
156
+ }
157
+
158
+ function kindFor(window) {
159
+ var label = (window.label + " " + (window.unit || "")).toLowerCase();
160
+ if (label.indexOf("rolling") >= 0 || label.indexOf("4-hour") >= 0 || label.indexOf("4h") >= 0 || window.windowMinutes === 240) return "rolling";
161
+ if (label.indexOf("month") >= 0 || label.indexOf("billing") >= 0 || label.indexOf("subscription") >= 0 || (window.windowMinutes || 0) >= 28 * 24 * 60) return "monthly";
162
+ return null;
163
+ }
164
+
165
+ function appendQuotaLine(lines, quota, label) {
166
+ if (!quota) return;
167
+ var text = "";
168
+ if (quota.used != null && quota.limit != null) text = fmtAmount(quota.used) + " / " + fmtAmount(quota.limit) + " " + quota.unit;
169
+ lines.push(ctxLineProgress(label || quota.label, quota.percent, quota.resetsAt, quota.windowMinutes));
170
+ if (text) lines.push({ type: "text", label: (label || quota.label) + " Used", value: text });
171
+ }
172
+
173
+ function ctxLineProgress(label, percent, resetsAt, windowMinutes) {
174
+ var line = {
175
+ type: "progress",
176
+ label: label,
177
+ used: Math.max(0, Math.min(100, percent)),
178
+ limit: 100,
179
+ format: { kind: "percent" },
180
+ };
181
+ if (resetsAt) line.resetsAt = resetsAt.toISOString();
182
+ if (windowMinutes) line.periodDurationMs = windowMinutes * 60 * 1000;
183
+ return line;
184
+ }
185
+
186
+ function fmtAmount(value) {
187
+ var n = Number(value) || 0;
188
+ if (Math.abs(n - Math.round(n)) < 0.0001) return String(Math.round(n));
189
+ return n.toFixed(2).replace(/\.?0+$/, "");
190
+ }
191
+
192
+ function parseSnapshot(root) {
193
+ var data = dataRoot(root);
194
+ var all = [];
195
+ collectQuotaObjects(root, all);
196
+ var windows = all.map(function (payload) { return parseQuota(payload, null, null); }).filter(Boolean);
197
+ var rolling = parseQuota(first(data, ["rolling", "rolling_window", "rollingWindow", "four_hour", "fourHour"]), "4-hour quota", 240) ||
198
+ windows.find(function (w) { return kindFor(w) === "rolling"; });
199
+ var monthly = parseQuota(first(data, ["monthly", "monthly_window", "monthlyWindow", "subscription", "subscription_usage", "subscriptionUsage"]), "Monthly quota", 30 * 24 * 60) ||
200
+ windows.find(function (w) { return kindFor(w) === "monthly"; });
201
+ var active = boolValue(first(data, ["active", "is_active", "isActive"]));
202
+ var status = String(first(data, ["status", "subscription_state", "subscriptionState"]) || "").trim();
203
+ var plan = String(first(data, ["plan", "plan_name", "planName", "tier", "subscription_tier", "subscriptionTier"]) || "").trim();
204
+ return { rolling: rolling, monthly: monthly, windows: windows, active: active, status: status, plan: plan };
205
+ }
206
+
207
+ function probe(ctx) {
208
+ var key = apiKey(ctx);
209
+ if (!key) throw "Missing Chutes API key. Set CHUTES_API_KEY or provider apiKey.";
210
+ var base = apiBase(ctx);
211
+ var snapshot = parseSnapshot(requestJson(ctx, base, "/users/me/subscription_usage", key));
212
+ if (!snapshot.rolling || !snapshot.monthly) {
213
+ try {
214
+ var fallback = parseSnapshot(requestJson(ctx, base, "/users/me/quotas", key));
215
+ snapshot.rolling = snapshot.rolling || fallback.rolling;
216
+ snapshot.monthly = snapshot.monthly || fallback.monthly;
217
+ snapshot.windows = snapshot.windows.concat(fallback.windows || []);
218
+ } catch (e) {
219
+ ctx.host.log.warn("chutes quota fallback failed: " + String(e));
220
+ }
221
+ }
222
+
223
+ var lines = [];
224
+ appendQuotaLine(lines, snapshot.rolling, "4-hour quota");
225
+ appendQuotaLine(lines, snapshot.monthly, "Monthly quota");
226
+ for (var i = 0; i < snapshot.windows.length && lines.length < 8; i++) {
227
+ var w = snapshot.windows[i];
228
+ if (w === snapshot.rolling || w === snapshot.monthly) continue;
229
+ appendQuotaLine(lines, w, w.label);
230
+ }
231
+ if (!lines.length) lines.push({ type: "badge", label: "Status", text: snapshot.active === false ? "No active subscription" : "No usage data", color: "yellow" });
232
+ return { displayName: "Chutes", source: "api", plan: snapshot.plan || snapshot.status || null, lines: lines };
233
+ }
234
+
235
+ globalThis.__openusage_plugin = { id: "chutes", probe: probe };
236
+ })();
@@ -0,0 +1,19 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "chutes",
4
+ "name": "Chutes",
5
+ "version": "0.0.1",
6
+ "entry": "plugin.js",
7
+ "icon": "icon.svg",
8
+ "brandColor": "#67E8F9",
9
+ "links": [
10
+ { "label": "Dashboard", "url": "https://chutes.ai" },
11
+ { "label": "Docs", "url": "https://chutes.ai/docs/getting-started/authentication" }
12
+ ],
13
+ "supportedModes": ["api"],
14
+ "autoMode": "api",
15
+ "lines": [
16
+ { "type": "progress", "label": "4-hour quota", "scope": "overview", "primaryOrder": 1 },
17
+ { "type": "progress", "label": "Monthly quota", "scope": "overview", "primaryOrder": 2 }
18
+ ]
19
+ }
@@ -0,0 +1 @@
1
+ <svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>
@@ -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>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"></path></svg>