@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.
- package/LICENSE +57744 -0
- package/native-manifest.json +1414 -0
- package/package.json +254 -0
- package/plugins/abacus-ai/icon.svg +18 -0
- package/plugins/abacus-ai/plugin.js +121 -0
- package/plugins/abacus-ai/plugin.json +17 -0
- package/plugins/alibaba/icon-color.svg +1 -0
- package/plugins/alibaba/icon.svg +1 -0
- package/plugins/alibaba/plugin.js +322 -0
- package/plugins/alibaba/plugin.json +20 -0
- package/plugins/alibaba-token-plan/icon-color.svg +1 -0
- package/plugins/alibaba-token-plan/icon.svg +1 -0
- package/plugins/alibaba-token-plan/plugin.js +544 -0
- package/plugins/alibaba-token-plan/plugin.json +19 -0
- package/plugins/amp/icon-color.svg +1 -0
- package/plugins/amp/icon-conflict.svg +6 -0
- package/plugins/amp/icon.svg +1 -0
- package/plugins/amp/plugin.js +175 -0
- package/plugins/amp/plugin.json +16 -0
- package/plugins/antigravity/icon-color.svg +1 -0
- package/plugins/antigravity/icon-conflict.svg +3 -0
- package/plugins/antigravity/icon.svg +1 -0
- package/plugins/antigravity/plugin.js +739 -0
- package/plugins/antigravity/plugin.json +31 -0
- package/plugins/antigravity-cli/icon.svg +3 -0
- package/plugins/antigravity-cli/plugin.js +570 -0
- package/plugins/antigravity-cli/plugin.json +16 -0
- package/plugins/antigravity-ide/icon.svg +3 -0
- package/plugins/antigravity-ide/plugin.js +257 -0
- package/plugins/antigravity-ide/plugin.json +29 -0
- package/plugins/augment/icon.svg +14 -0
- package/plugins/augment/plugin.js +59 -0
- package/plugins/augment/plugin.json +18 -0
- package/plugins/aws-bedrock/icon-color.svg +1 -0
- package/plugins/aws-bedrock/icon.svg +1 -0
- package/plugins/aws-bedrock/plugin.js +206 -0
- package/plugins/aws-bedrock/plugin.json +18 -0
- package/plugins/azure-openai/icon-color.svg +1 -0
- package/plugins/azure-openai/icon.svg +1 -0
- package/plugins/azure-openai/plugin.js +145 -0
- package/plugins/azure-openai/plugin.json +17 -0
- package/plugins/chutes/icon.svg +7 -0
- package/plugins/chutes/plugin.js +236 -0
- package/plugins/chutes/plugin.json +19 -0
- package/plugins/claude/icon-color.svg +1 -0
- package/plugins/claude/icon.svg +1 -0
- package/plugins/claude/plugin.js +1723 -0
- package/plugins/claude/plugin.json +30 -0
- package/plugins/codebuff/icon.svg +92 -0
- package/plugins/codebuff/plugin.js +113 -0
- package/plugins/codebuff/plugin.json +17 -0
- package/plugins/codex/icon-color.svg +5 -0
- package/plugins/codex/icon.svg +1 -0
- package/plugins/codex/plugin.js +1009 -0
- package/plugins/codex/plugin.json +82 -0
- package/plugins/command-code/icon.svg +3 -0
- package/plugins/command-code/plugin.js +184 -0
- package/plugins/command-code/plugin.json +20 -0
- package/plugins/copilot/icon-color.svg +1 -0
- package/plugins/copilot/icon.svg +1 -0
- package/plugins/copilot/plugin.js +684 -0
- package/plugins/copilot/plugin.json +21 -0
- package/plugins/crof/icon.svg +3 -0
- package/plugins/crof/plugin.js +53 -0
- package/plugins/crof/plugin.json +17 -0
- package/plugins/crofai/icon.svg +16 -0
- package/plugins/crofai/plugin.js +81 -0
- package/plugins/crofai/plugin.json +18 -0
- package/plugins/cursor/icon-conflict.svg +3 -0
- package/plugins/cursor/icon.svg +1 -0
- package/plugins/cursor/plugin.js +1379 -0
- package/plugins/cursor/plugin.json +23 -0
- package/plugins/cursor-nightly/icon.png +0 -0
- package/plugins/cursor-nightly/plugin.js +1379 -0
- package/plugins/cursor-nightly/plugin.json +23 -0
- package/plugins/deepgram/icon.svg +1 -0
- package/plugins/deepgram/plugin.js +20 -0
- package/plugins/deepgram/plugin.json +17 -0
- package/plugins/deepseek/icon-color.svg +1 -0
- package/plugins/deepseek/icon.svg +1 -0
- package/plugins/deepseek/plugin.js +71 -0
- package/plugins/deepseek/plugin.json +17 -0
- package/plugins/devin/icon.svg +5 -0
- package/plugins/devin/plugin.js +341 -0
- package/plugins/devin/plugin.json +16 -0
- package/plugins/doubao/icon-color.svg +1 -0
- package/plugins/doubao/icon.svg +1 -0
- package/plugins/doubao/plugin.js +92 -0
- package/plugins/doubao/plugin.json +17 -0
- package/plugins/droid/icon.svg +1 -0
- package/plugins/droid/plugin.json +20 -0
- package/plugins/elevenlabs/icon.svg +4 -0
- package/plugins/elevenlabs/plugin.js +48 -0
- package/plugins/elevenlabs/plugin.json +18 -0
- package/plugins/factory/icon-conflict.svg +1 -0
- package/plugins/factory/icon.svg +1 -0
- package/plugins/factory/plugin.js +487 -0
- package/plugins/factory/plugin.json +15 -0
- package/plugins/fireworks-ai/icon.svg +6 -0
- package/plugins/fireworks-ai/plugin.js +370 -0
- package/plugins/fireworks-ai/plugin.json +19 -0
- package/plugins/gemini/icon-color.svg +1 -0
- package/plugins/gemini/icon.svg +1 -0
- package/plugins/gemini/plugin.js +460 -0
- package/plugins/gemini/plugin.json +16 -0
- package/plugins/grok/icon.svg +1 -0
- package/plugins/grok/plugin.js +297 -0
- package/plugins/grok/plugin.json +19 -0
- package/plugins/groqcloud/icon.svg +1 -0
- package/plugins/groqcloud/plugin.js +117 -0
- package/plugins/groqcloud/plugin.json +19 -0
- package/plugins/jetbrains-ai-assistant/icon-color.svg +14 -0
- package/plugins/jetbrains-ai-assistant/icon-conflict.svg +3 -0
- package/plugins/jetbrains-ai-assistant/icon.svg +14 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +313 -0
- package/plugins/jetbrains-ai-assistant/plugin.json +16 -0
- package/plugins/kilo/icon.svg +1 -0
- package/plugins/kilo/plugin.js +111 -0
- package/plugins/kilo/plugin.json +19 -0
- package/plugins/kimi/icon-color.svg +1 -0
- package/plugins/kimi/icon-conflict.svg +3 -0
- package/plugins/kimi/icon.svg +1 -0
- package/plugins/kimi/plugin.js +358 -0
- package/plugins/kimi/plugin.json +15 -0
- package/plugins/kimi-k2/icon-color.svg +1 -0
- package/plugins/kimi-k2/icon.svg +1 -0
- package/plugins/kimi-k2/plugin.js +58 -0
- package/plugins/kimi-k2/plugin.json +18 -0
- package/plugins/kiro/icon-color.svg +5 -0
- package/plugins/kiro/icon-conflict.svg +1 -0
- package/plugins/kiro/icon.svg +4 -0
- package/plugins/kiro/plugin.js +390 -0
- package/plugins/kiro/plugin.json +16 -0
- package/plugins/litellm/icon.svg +16 -0
- package/plugins/litellm/plugin.js +199 -0
- package/plugins/litellm/plugin.json +16 -0
- package/plugins/llm-proxy/icon.svg +1 -0
- package/plugins/llm-proxy/plugin.js +40 -0
- package/plugins/llm-proxy/plugin.json +17 -0
- package/plugins/manus/icon.svg +6 -0
- package/plugins/manus/plugin.js +50 -0
- package/plugins/manus/plugin.json +17 -0
- package/plugins/mimo/icon.svg +1 -0
- package/plugins/mimo/plugin.js +177 -0
- package/plugins/mimo/plugin.json +19 -0
- package/plugins/minimax/icon-color.svg +1 -0
- package/plugins/minimax/icon-conflict.svg +4 -0
- package/plugins/minimax/icon.svg +1 -0
- package/plugins/minimax/plugin.js +453 -0
- package/plugins/minimax/plugin.json +14 -0
- package/plugins/mistral/icon-color.svg +1 -0
- package/plugins/mistral/icon.svg +1 -0
- package/plugins/mistral/plugin.js +152 -0
- package/plugins/mistral/plugin.json +18 -0
- package/plugins/moonshot/icon.svg +1 -0
- package/plugins/moonshot/plugin.js +43 -0
- package/plugins/moonshot/plugin.json +16 -0
- package/plugins/nanogpt/icon-color.svg +17 -0
- package/plugins/nanogpt/icon.svg +10 -0
- package/plugins/nanogpt/plugin.js +80 -0
- package/plugins/nanogpt/plugin.json +17 -0
- package/plugins/neuralwatt/icon.svg +3 -0
- package/plugins/neuralwatt/plugin.js +152 -0
- package/plugins/neuralwatt/plugin.json +17 -0
- package/plugins/ollama/icon.svg +1 -0
- package/plugins/ollama/plugin.js +92 -0
- package/plugins/ollama/plugin.json +20 -0
- package/plugins/openai-api/icon.svg +1 -0
- package/plugins/openai-api/plugin.js +533 -0
- package/plugins/openai-api/plugin.json +26 -0
- package/plugins/opencode/icon.svg +1 -0
- package/plugins/opencode/plugin.js +342 -0
- package/plugins/opencode/plugin.json +19 -0
- package/plugins/opencode-go/icon-conflict.svg +1 -0
- package/plugins/opencode-go/icon.svg +1 -0
- package/plugins/opencode-go/plugin.js +617 -0
- package/plugins/opencode-go/plugin.json +50 -0
- package/plugins/openrouter/icon.svg +1 -0
- package/plugins/openrouter/plugin.js +156 -0
- package/plugins/openrouter/plugin.json +8 -0
- package/plugins/perplexity/icon-color.svg +1 -0
- package/plugins/perplexity/icon-conflict.svg +1 -0
- package/plugins/perplexity/icon.svg +1 -0
- package/plugins/perplexity/plugin.js +425 -0
- package/plugins/perplexity/plugin.json +19 -0
- package/plugins/poe/icon.svg +1 -0
- package/plugins/poe/plugin.js +190 -0
- package/plugins/poe/plugin.json +19 -0
- package/plugins/stepfun/icon-color.svg +1 -0
- package/plugins/stepfun/icon.svg +1 -0
- package/plugins/stepfun/plugin.js +155 -0
- package/plugins/stepfun/plugin.json +18 -0
- package/plugins/synthetic/icon-conflict.svg +12 -0
- package/plugins/synthetic/icon.svg +14 -0
- package/plugins/synthetic/plugin.js +331 -0
- package/plugins/synthetic/plugin.json +23 -0
- package/plugins/t3chat/icon-color.svg +28 -0
- package/plugins/t3chat/icon.svg +4 -0
- package/plugins/t3chat/plugin.js +243 -0
- package/plugins/t3chat/plugin.json +20 -0
- package/plugins/venice/icon-color.svg +1 -0
- package/plugins/venice/icon.svg +1 -0
- package/plugins/venice/plugin.js +69 -0
- package/plugins/venice/plugin.json +16 -0
- package/plugins/vertex-ai/icon-color.svg +1 -0
- package/plugins/vertex-ai/icon.svg +1 -0
- package/plugins/vertex-ai/plugin.js +172 -0
- package/plugins/vertex-ai/plugin.json +18 -0
- package/plugins/warp/icon-color.svg +10 -0
- package/plugins/warp/icon.svg +6 -0
- package/plugins/warp/plugin.js +108 -0
- package/plugins/warp/plugin.json +18 -0
- package/plugins/windsurf/icon-conflict.svg +3 -0
- package/plugins/windsurf/icon.svg +1 -0
- package/plugins/windsurf/plugin.js +208 -0
- package/plugins/windsurf/plugin.json +16 -0
- package/plugins/zai/icon-conflict.svg +5 -0
- package/plugins/zai/icon.svg +1 -0
- package/plugins/zai/plugin.js +188 -0
- package/plugins/zai/plugin.json +16 -0
- package/plugins/zed/icon.svg +4 -0
- package/plugins/zed/plugin.js +270 -0
- package/plugins/zed/plugin.json +19 -0
- package/usagestat +0 -0
- 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,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>
|