@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1 → 2.0.0-alpha.3
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 +0 -0
- package/native-manifest.json +365 -77
- package/package.json +49 -1
- package/plugins/UPSTREAM-LICENSES.md +109 -0
- package/plugins/abacus-ai/icon.svg +0 -0
- package/plugins/abacus-ai/plugin.js +0 -0
- package/plugins/abacus-ai/plugin.json +0 -0
- package/plugins/aiand/icon.svg +6 -0
- package/plugins/aiand/plugin.js +108 -0
- package/plugins/aiand/plugin.json +22 -0
- package/plugins/alibaba/icon-color.svg +0 -0
- package/plugins/alibaba/icon.svg +0 -0
- package/plugins/alibaba/plugin.js +0 -0
- package/plugins/alibaba/plugin.json +0 -0
- package/plugins/alibaba-token-plan/icon-color.svg +0 -0
- package/plugins/alibaba-token-plan/icon.svg +0 -0
- package/plugins/alibaba-token-plan/plugin.js +0 -0
- package/plugins/alibaba-token-plan/plugin.json +0 -0
- package/plugins/amp/icon-color.svg +0 -0
- package/plugins/amp/icon-conflict.svg +0 -0
- package/plugins/amp/icon.svg +0 -0
- package/plugins/amp/plugin.js +0 -0
- package/plugins/amp/plugin.json +0 -0
- package/plugins/antigravity/icon-color.svg +0 -0
- package/plugins/antigravity/icon-conflict.svg +0 -0
- package/plugins/antigravity/icon.svg +0 -0
- package/plugins/antigravity/plugin.js +0 -0
- package/plugins/antigravity/plugin.json +0 -0
- package/plugins/antigravity-cli/icon.svg +0 -0
- package/plugins/antigravity-cli/plugin.js +0 -0
- package/plugins/antigravity-cli/plugin.json +0 -0
- package/plugins/antigravity-ide/icon.svg +0 -0
- package/plugins/antigravity-ide/plugin.js +0 -0
- package/plugins/antigravity-ide/plugin.json +0 -0
- package/plugins/augment/icon.svg +0 -0
- package/plugins/augment/plugin.js +0 -0
- package/plugins/augment/plugin.json +0 -0
- package/plugins/aws-bedrock/icon-color.svg +0 -0
- package/plugins/aws-bedrock/icon.svg +0 -0
- package/plugins/aws-bedrock/plugin.js +0 -0
- package/plugins/aws-bedrock/plugin.json +0 -0
- package/plugins/azure-openai/icon-color.svg +0 -0
- package/plugins/azure-openai/icon.svg +0 -0
- package/plugins/azure-openai/plugin.js +0 -0
- package/plugins/azure-openai/plugin.json +0 -0
- package/plugins/chutes/icon.svg +0 -0
- package/plugins/chutes/plugin.js +0 -0
- package/plugins/chutes/plugin.json +0 -0
- package/plugins/claude/icon-color.svg +0 -0
- package/plugins/claude/icon.svg +0 -0
- package/plugins/claude/plugin.js +70 -23
- package/plugins/claude/plugin.json +0 -0
- package/plugins/clawrouter/icon.svg +7 -0
- package/plugins/clawrouter/plugin.js +45 -0
- package/plugins/clawrouter/plugin.json +22 -0
- package/plugins/clinepass/icon.svg +4 -0
- package/plugins/clinepass/plugin.js +71 -0
- package/plugins/clinepass/plugin.json +23 -0
- package/plugins/codebuddy/plugin.js +331 -0
- package/plugins/codebuddy/plugin.json +30 -0
- package/plugins/codebuff/icon.svg +0 -0
- package/plugins/codebuff/plugin.js +0 -0
- package/plugins/codebuff/plugin.json +0 -0
- package/plugins/codex/icon-color.svg +0 -0
- package/plugins/codex/icon.svg +0 -0
- package/plugins/codex/plugin.js +7 -2
- package/plugins/codex/plugin.json +0 -0
- package/plugins/command-code/icon.svg +0 -0
- package/plugins/command-code/plugin.js +7 -0
- package/plugins/command-code/plugin.json +0 -0
- package/plugins/copilot/icon-color.svg +0 -0
- package/plugins/copilot/icon.svg +0 -0
- package/plugins/copilot/plugin.js +61 -9
- package/plugins/copilot/plugin.json +4 -1
- package/plugins/crof/icon.svg +0 -0
- package/plugins/crof/plugin.js +0 -0
- package/plugins/crof/plugin.json +0 -0
- package/plugins/crofai/icon.svg +0 -0
- package/plugins/crofai/plugin.js +0 -0
- package/plugins/crofai/plugin.json +0 -0
- package/plugins/cursor/icon-conflict.svg +0 -0
- package/plugins/cursor/icon.svg +0 -0
- package/plugins/cursor/plugin.js +46 -9
- package/plugins/cursor/plugin.json +3 -2
- package/plugins/cursor-nightly/icon.png +0 -0
- package/plugins/cursor-nightly/plugin.js +45 -8
- package/plugins/cursor-nightly/plugin.json +3 -2
- package/plugins/deepgram/icon.svg +0 -0
- package/plugins/deepgram/plugin.js +0 -0
- package/plugins/deepgram/plugin.json +0 -0
- package/plugins/deepinfra/icon.svg +4 -0
- package/plugins/deepinfra/plugin.js +97 -0
- package/plugins/deepinfra/plugin.json +28 -0
- package/plugins/deepseek/icon-color.svg +0 -0
- package/plugins/deepseek/icon.svg +0 -0
- package/plugins/deepseek/plugin.js +0 -0
- package/plugins/deepseek/plugin.json +0 -0
- package/plugins/devin/icon.svg +0 -0
- package/plugins/devin/plugin.js +111 -0
- package/plugins/devin/plugin.json +2 -1
- package/plugins/doubao/icon-color.svg +0 -0
- package/plugins/doubao/icon.svg +0 -0
- package/plugins/doubao/plugin.js +0 -0
- package/plugins/doubao/plugin.json +0 -0
- package/plugins/droid/icon.svg +0 -0
- package/plugins/droid/plugin.json +2 -1
- package/plugins/elevenlabs/icon.svg +0 -0
- package/plugins/elevenlabs/plugin.js +17 -2
- package/plugins/elevenlabs/plugin.json +0 -0
- package/plugins/factory/icon-conflict.svg +0 -0
- package/plugins/factory/icon.svg +0 -0
- package/plugins/factory/plugin.js +38 -14
- package/plugins/factory/plugin.json +2 -1
- package/plugins/fireworks-ai/icon.svg +0 -0
- package/plugins/fireworks-ai/plugin.js +0 -0
- package/plugins/fireworks-ai/plugin.json +0 -0
- package/plugins/gemini/icon-color.svg +0 -0
- package/plugins/gemini/icon.svg +0 -0
- package/plugins/gemini/plugin.js +0 -0
- package/plugins/gemini/plugin.json +0 -0
- package/plugins/grok/icon.svg +0 -0
- package/plugins/grok/plugin.js +30 -5
- package/plugins/grok/plugin.json +3 -1
- package/plugins/groqcloud/icon.svg +0 -0
- package/plugins/groqcloud/plugin.js +0 -0
- package/plugins/groqcloud/plugin.json +0 -0
- package/plugins/ibmbob/icon.svg +23 -0
- package/plugins/ibmbob/plugin.js +61 -0
- package/plugins/ibmbob/plugin.json +22 -0
- package/plugins/jetbrains-ai-assistant/icon-color.svg +0 -0
- package/plugins/jetbrains-ai-assistant/icon-conflict.svg +0 -0
- package/plugins/jetbrains-ai-assistant/icon.svg +0 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +0 -0
- package/plugins/jetbrains-ai-assistant/plugin.json +0 -0
- package/plugins/kilo/icon.svg +0 -0
- package/plugins/kilo/plugin.js +0 -0
- package/plugins/kilo/plugin.json +0 -0
- package/plugins/kimi/icon-color.svg +0 -0
- package/plugins/kimi/icon-conflict.svg +0 -0
- package/plugins/kimi/icon.svg +0 -0
- package/plugins/kimi/plugin.js +122 -141
- package/plugins/kimi/plugin.json +5 -2
- package/plugins/kimi-k2/icon-color.svg +0 -0
- package/plugins/kimi-k2/icon.svg +0 -0
- package/plugins/kimi-k2/plugin.js +0 -0
- package/plugins/kimi-k2/plugin.json +0 -0
- package/plugins/kiro/icon-color.svg +0 -0
- package/plugins/kiro/icon-conflict.svg +0 -0
- package/plugins/kiro/icon.svg +0 -0
- package/plugins/kiro/plugin.js +49 -10
- package/plugins/kiro/plugin.json +3 -1
- package/plugins/litellm/icon.svg +0 -0
- package/plugins/litellm/plugin.js +0 -0
- package/plugins/litellm/plugin.json +0 -0
- package/plugins/llm-proxy/icon.svg +0 -0
- package/plugins/llm-proxy/plugin.js +0 -0
- package/plugins/llm-proxy/plugin.json +0 -0
- package/plugins/longcat/icon.svg +4 -0
- package/plugins/longcat/plugin.js +182 -0
- package/plugins/longcat/plugin.json +23 -0
- package/plugins/manus/icon.svg +0 -0
- package/plugins/manus/plugin.js +0 -0
- package/plugins/manus/plugin.json +0 -0
- package/plugins/mimo/icon.svg +0 -0
- package/plugins/mimo/plugin.js +0 -0
- package/plugins/mimo/plugin.json +0 -0
- package/plugins/minimax/icon-color.svg +0 -0
- package/plugins/minimax/icon-conflict.svg +0 -0
- package/plugins/minimax/icon.svg +0 -0
- package/plugins/minimax/plugin.js +25 -31
- package/plugins/minimax/plugin.json +0 -0
- package/plugins/mistral/icon-color.svg +0 -0
- package/plugins/mistral/icon.svg +0 -0
- package/plugins/mistral/plugin.js +0 -0
- package/plugins/mistral/plugin.json +0 -0
- package/plugins/moonshot/icon.svg +0 -0
- package/plugins/moonshot/plugin.js +8 -6
- package/plugins/moonshot/plugin.json +0 -0
- package/plugins/nanogpt/icon-color.svg +0 -0
- package/plugins/nanogpt/icon.svg +0 -0
- package/plugins/nanogpt/plugin.js +0 -0
- package/plugins/nanogpt/plugin.json +0 -0
- package/plugins/neuralwatt/icon.svg +0 -0
- package/plugins/neuralwatt/plugin.js +0 -0
- package/plugins/neuralwatt/plugin.json +0 -0
- package/plugins/notion/icon.svg +1 -0
- package/plugins/notion/plugin.js +282 -0
- package/plugins/notion/plugin.json +29 -0
- package/plugins/ollama/icon.svg +0 -0
- package/plugins/ollama/plugin.js +257 -56
- package/plugins/ollama/plugin.json +6 -3
- package/plugins/openai-api/icon.svg +0 -0
- package/plugins/openai-api/plugin.js +0 -0
- package/plugins/openai-api/plugin.json +0 -0
- package/plugins/opencode/icon.svg +0 -0
- package/plugins/opencode/plugin.js +0 -0
- package/plugins/opencode/plugin.json +0 -0
- package/plugins/opencode-go/icon-conflict.svg +0 -0
- package/plugins/opencode-go/icon.svg +0 -0
- package/plugins/opencode-go/plugin.js +78 -10
- package/plugins/opencode-go/plugin.json +5 -2
- package/plugins/openrouter/icon.svg +0 -0
- package/plugins/openrouter/plugin.js +371 -114
- package/plugins/openrouter/plugin.json +6 -0
- package/plugins/perplexity/icon-color.svg +0 -0
- package/plugins/perplexity/icon-conflict.svg +0 -0
- package/plugins/perplexity/icon.svg +0 -0
- package/plugins/perplexity/plugin.js +0 -0
- package/plugins/perplexity/plugin.json +0 -0
- package/plugins/poe/icon.svg +0 -0
- package/plugins/poe/plugin.js +24 -18
- package/plugins/poe/plugin.json +2 -0
- package/plugins/qoder/icon.svg +3 -0
- package/plugins/qoder/plugin.js +227 -0
- package/plugins/qoder/plugin.json +23 -0
- package/plugins/qwencloud/icon.svg +4 -0
- package/plugins/qwencloud/plugin.js +677 -0
- package/plugins/qwencloud/plugin.json +29 -0
- package/plugins/sakana/icon.svg +5 -0
- package/plugins/sakana/plugin.js +156 -0
- package/plugins/sakana/plugin.json +23 -0
- package/plugins/stepfun/icon-color.svg +0 -0
- package/plugins/stepfun/icon.svg +0 -0
- package/plugins/stepfun/plugin.js +0 -0
- package/plugins/stepfun/plugin.json +0 -0
- package/plugins/sub2api/icon.svg +4 -0
- package/plugins/sub2api/plugin.js +191 -0
- package/plugins/sub2api/plugin.json +16 -0
- package/plugins/synthetic/icon-conflict.svg +0 -0
- package/plugins/synthetic/icon.svg +0 -0
- package/plugins/synthetic/plugin.js +0 -0
- package/plugins/synthetic/plugin.json +0 -0
- package/plugins/t3chat/icon-color.svg +0 -0
- package/plugins/t3chat/icon.svg +0 -0
- package/plugins/t3chat/plugin.js +0 -0
- package/plugins/t3chat/plugin.json +0 -0
- package/plugins/venice/icon-color.svg +0 -0
- package/plugins/venice/icon.svg +0 -0
- package/plugins/venice/plugin.js +0 -0
- package/plugins/venice/plugin.json +0 -0
- package/plugins/vertex-ai/icon-color.svg +0 -0
- package/plugins/vertex-ai/icon.svg +0 -0
- package/plugins/vertex-ai/plugin.js +0 -0
- package/plugins/vertex-ai/plugin.json +0 -0
- package/plugins/warp/icon-color.svg +0 -0
- package/plugins/warp/icon.svg +0 -0
- package/plugins/warp/plugin.js +0 -0
- package/plugins/warp/plugin.json +0 -0
- package/plugins/wayfinder/icon.svg +5 -0
- package/plugins/wayfinder/plugin.js +47 -0
- package/plugins/wayfinder/plugin.json +16 -0
- package/plugins/windsurf/icon-conflict.svg +0 -0
- package/plugins/windsurf/icon.svg +0 -0
- package/plugins/windsurf/plugin.js +0 -0
- package/plugins/windsurf/plugin.json +0 -0
- package/plugins/xai/icon.svg +7 -0
- package/plugins/xai/plugin.js +162 -0
- package/plugins/xai/plugin.json +28 -0
- package/plugins/zai/icon-conflict.svg +0 -0
- package/plugins/zai/icon.svg +0 -0
- package/plugins/zai/plugin.js +111 -161
- package/plugins/zai/plugin.json +4 -1
- package/plugins/zed/icon.svg +0 -0
- package/plugins/zed/plugin.js +0 -0
- package/plugins/zed/plugin.json +0 -0
- package/plugins/zenmux/icon.svg +3 -0
- package/plugins/zenmux/plugin.js +102 -0
- package/plugins/zenmux/plugin.json +23 -0
- package/plugins/zoommate/icon.svg +1 -0
- package/plugins/zoommate/plugin.js +244 -0
- package/plugins/zoommate/plugin.json +29 -0
- package/usagestat +0 -0
- package/usagestatd +0 -0
package/plugins/kimi/plugin.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
(function () {
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098"
|
|
6
|
-
const REFRESH_BUFFER_SEC = 5 * 60
|
|
2
|
+
const WEB_USAGE_URL = "https://www.kimi.com/apiv2/kimi.gateway.billing.v1.BillingService/GetUsages"
|
|
3
|
+
const MEMBERSHIP_URL = "https://www.kimi.com/apiv2/kimi.gateway.membership.v2.MembershipService/"
|
|
4
|
+
const WEEK_MS = 7 * 86400000
|
|
7
5
|
|
|
8
6
|
function readNumber(value) {
|
|
7
|
+
if (typeof value !== "number" && typeof value !== "string") return null
|
|
8
|
+
if (typeof value === "string" && !value.trim()) return null
|
|
9
9
|
const n = Number(value)
|
|
10
10
|
return Number.isFinite(n) ? n : null
|
|
11
11
|
}
|
|
@@ -29,119 +29,109 @@
|
|
|
29
29
|
: null
|
|
30
30
|
if (!level) return null
|
|
31
31
|
|
|
32
|
+
if (level === "LEVEL_UNSPECIFIED") return null
|
|
33
|
+
const names = { LEVEL_FREE: "Adagio", LEVEL_TRIAL: "Andante", LEVEL_BASIC: "Moderato", LEVEL_INTERMEDIATE: "Allegretto", LEVEL_ADVANCED: "Allegro" }
|
|
34
|
+
if (data.version != null && data.version !== "GOODS_VERSION_V1") return level
|
|
35
|
+
if (names[level]) return names[level]
|
|
32
36
|
const cleaned = level.replace(/^LEVEL_/, "").replace(/_/g, " ")
|
|
33
37
|
const label = titleCaseWords(cleaned)
|
|
34
38
|
return label || null
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
function
|
|
38
|
-
|
|
39
|
-
ctx.host.log.warn("credentials file not found: " + CRED_PATH)
|
|
40
|
-
return null
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const text = ctx.host.fs.readText(CRED_PATH)
|
|
45
|
-
const parsed = ctx.util.tryParseJson(text)
|
|
46
|
-
if (!parsed || typeof parsed !== "object") {
|
|
47
|
-
ctx.host.log.warn("credentials file is not valid json")
|
|
48
|
-
return null
|
|
49
|
-
}
|
|
50
|
-
if (!parsed.access_token && !parsed.refresh_token) {
|
|
51
|
-
ctx.host.log.warn("credentials missing access_token and refresh_token")
|
|
52
|
-
return null
|
|
53
|
-
}
|
|
54
|
-
return parsed
|
|
55
|
-
} catch (e) {
|
|
56
|
-
ctx.host.log.warn("credentials read failed: " + String(e))
|
|
57
|
-
return null
|
|
58
|
-
}
|
|
41
|
+
function clean(value) {
|
|
42
|
+
return typeof value === "string" && value.trim() ? value.trim() : null
|
|
59
43
|
}
|
|
60
44
|
|
|
61
|
-
function
|
|
62
|
-
try {
|
|
63
|
-
ctx.host.fs.writeText(CRED_PATH, JSON.stringify(creds))
|
|
64
|
-
} catch (e) {
|
|
65
|
-
ctx.host.log.warn("failed to persist credentials: " + String(e))
|
|
66
|
-
}
|
|
45
|
+
function env(ctx, name) {
|
|
46
|
+
try { return clean(ctx.host.env.get(name)) } catch (_) { return null }
|
|
67
47
|
}
|
|
68
48
|
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
const expiresAt = readNumber(creds.expires_at)
|
|
72
|
-
if (expiresAt === null) return true
|
|
73
|
-
return nowSec + REFRESH_BUFFER_SEC >= expiresAt
|
|
49
|
+
function readText(ctx, path) {
|
|
50
|
+
try { return clean(ctx.host.fs.readText(path)) } catch (_) { return null }
|
|
74
51
|
}
|
|
75
52
|
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
})
|
|
100
|
-
} catch (e) {
|
|
101
|
-
ctx.host.log.error("refresh exception: " + String(e))
|
|
102
|
-
return null
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (ctx.util.isAuthStatus(resp.status)) {
|
|
106
|
-
throw "Session expired. Run `kimi login` to authenticate."
|
|
53
|
+
function cliSession(ctx) {
|
|
54
|
+
const override = env(ctx, "KIMI_CODE_HOME")
|
|
55
|
+
const homes = override ? [override] : ["~/.kimi-code", "~/.kimi"]
|
|
56
|
+
for (const home of homes) {
|
|
57
|
+
const raw = readText(ctx, home + "/credentials/kimi-code.json")
|
|
58
|
+
if (!raw) continue
|
|
59
|
+
const credential = ctx.util.tryParseJson(raw)
|
|
60
|
+
const expires = credential && readNumber(credential.expires_at)
|
|
61
|
+
if (!credential || !clean(credential.access_token) || expires === null || expires <= Date.parse(ctx.nowIso) / 1000 + 60) continue
|
|
62
|
+
let deviceId = readText(ctx, home + "/device_id")
|
|
63
|
+
if (!deviceId) {
|
|
64
|
+
// This is a client identity, not an authentication secret.
|
|
65
|
+
deviceId = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
66
|
+
const n = Math.floor(Math.random() * 16)
|
|
67
|
+
return (c === "x" ? n : (n & 3) | 8).toString(16)
|
|
68
|
+
})
|
|
69
|
+
try { ctx.host.fs.writeText(home + "/device_id", deviceId) } catch (_) {}
|
|
70
|
+
}
|
|
71
|
+
return { token: credential.access_token, headers: {
|
|
72
|
+
"X-Msh-Platform": "kimi_code_cli", "X-Msh-Version": ctx.app.version,
|
|
73
|
+
"X-Msh-Device-Model": ctx.app.platform,
|
|
74
|
+
"X-Msh-Device-Id": deviceId.replace(/[^\x20-\x7e]/g, ""),
|
|
75
|
+
} }
|
|
107
76
|
}
|
|
77
|
+
return null
|
|
78
|
+
}
|
|
108
79
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
80
|
+
function webToken(ctx) {
|
|
81
|
+
const raw = clean(ctx.provider.cookieHeader) || env(ctx, "KIMI_AUTH_TOKEN")
|
|
82
|
+
if (!raw) return null
|
|
83
|
+
const cookie = raw.replace(/^Cookie:\s*/i, "")
|
|
84
|
+
const match = /(?:^|;)\s*kimi-auth=([^;]+)/.exec(cookie)
|
|
85
|
+
if (match) return clean(match[1])
|
|
86
|
+
return cookie.includes("=") ? null : clean(cookie.replace(/^Bearer\s+/i, ""))
|
|
87
|
+
}
|
|
113
88
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
89
|
+
function webRequest(ctx, token, url, body, timeoutMs) {
|
|
90
|
+
const payload = ctx.jwt.decodePayload(token) || {}
|
|
91
|
+
const headers = {
|
|
92
|
+
Authorization: "Bearer " + token, Cookie: "kimi-auth=" + token,
|
|
93
|
+
"Content-Type": "application/json", Accept: "application/json",
|
|
94
|
+
Origin: "https://www.kimi.com", Referer: "https://www.kimi.com/code/console",
|
|
95
|
+
"connect-protocol-version": "1", "x-msh-platform": "web", "x-language": "en-US", "r-timezone": "UTC",
|
|
118
96
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (body.refresh_token) creds.refresh_token = body.refresh_token
|
|
122
|
-
if (typeof body.expires_in === "number") {
|
|
123
|
-
creds.expires_at = Date.now() / 1000 + body.expires_in
|
|
97
|
+
for (const pair of [["device_id", "x-msh-device-id"], ["ssid", "x-msh-session-id"], ["sub", "x-traffic-id"]]) {
|
|
98
|
+
if (clean(payload[pair[0]])) headers[pair[1]] = payload[pair[0]].replace(/[^\x20-\x7e]/g, "")
|
|
124
99
|
}
|
|
125
|
-
if (typeof body.scope === "string") creds.scope = body.scope
|
|
126
|
-
if (typeof body.token_type === "string") creds.token_type = body.token_type
|
|
127
|
-
|
|
128
|
-
saveCredentials(ctx, creds)
|
|
129
|
-
return creds.access_token
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function fetchUsage(ctx, accessToken) {
|
|
133
100
|
return ctx.util.request({
|
|
134
|
-
method: "
|
|
135
|
-
url: USAGE_URL,
|
|
136
|
-
headers: {
|
|
137
|
-
Authorization: "Bearer " + accessToken,
|
|
138
|
-
Accept: "application/json",
|
|
139
|
-
"User-Agent": "OpenUsage",
|
|
140
|
-
},
|
|
141
|
-
timeoutMs: 10000,
|
|
101
|
+
method: "POST", url, headers, bodyText: JSON.stringify(body), timeoutMs,
|
|
142
102
|
})
|
|
143
103
|
}
|
|
144
104
|
|
|
105
|
+
function enrichMembership(ctx, result, token) {
|
|
106
|
+
if (!token || ctx.provider.settings && ctx.provider.settings.cookieSource === "off") return result
|
|
107
|
+
try {
|
|
108
|
+
const response = webRequest(ctx, token, MEMBERSHIP_URL + "GetSubscriptionStats", {}, 2000)
|
|
109
|
+
const data = response.status === 200 && ctx.util.tryParseJson(response.bodyText)
|
|
110
|
+
if (!data) return result
|
|
111
|
+
const pool = data.subscriptionBalance
|
|
112
|
+
const ratio = pool && readNumber(pool.amountUsedRatio)
|
|
113
|
+
if (Number.isFinite(ratio) && pool && (!pool.feature || pool.feature === "FEATURE_OMNI") && (!pool.type || pool.type === "SUBSCRIPTION")) {
|
|
114
|
+
const reset = ctx.util.toIso(pool.expireTime)
|
|
115
|
+
const monthly = ctx.line.progress({ label: "Monthly", used: Math.max(0, Math.min(100, ratio * 100)), limit: 100,
|
|
116
|
+
format: { kind: "percent" }, resetsAt: reset, periodDurationMs: ctx.util.calendarMonthDuration(reset) })
|
|
117
|
+
// Automatic summaries use the first quota. Reset Code windows cannot
|
|
118
|
+
// make an exhausted membership pool available again.
|
|
119
|
+
if (ratio >= 1) result.lines.unshift(monthly)
|
|
120
|
+
else result.lines.push(monthly)
|
|
121
|
+
}
|
|
122
|
+
const weekly = data.ratelimitCode7d
|
|
123
|
+
const weeklyRatio = weekly && readNumber(weekly.ratio)
|
|
124
|
+
if (weekly && weekly.enabled !== false && Number.isFinite(weeklyRatio)) {
|
|
125
|
+
const reset = ctx.util.toIso(weekly.resetTime)
|
|
126
|
+
const used = Math.max(0, Math.min(100, weeklyRatio * 100))
|
|
127
|
+
if (!result.lines.some((line) => line.label === "Weekly" && Math.abs(line.used - used) < 0.01 && (line.resetsAt || null) === reset)) {
|
|
128
|
+
result.lines.push(ctx.line.progress({ label: "Code 7-day", used, limit: 100, format: { kind: "percent" }, resetsAt: reset, periodDurationMs: WEEK_MS }))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} catch (_) { ctx.host.log.warn("Kimi membership enrichment unavailable") }
|
|
132
|
+
return result
|
|
133
|
+
}
|
|
134
|
+
|
|
145
135
|
function parseWindowPeriodMs(window) {
|
|
146
136
|
if (!window || typeof window !== "object") return null
|
|
147
137
|
const duration = readNumber(window.duration)
|
|
@@ -164,11 +154,11 @@
|
|
|
164
154
|
let used = readNumber(row.used)
|
|
165
155
|
if (used === null) {
|
|
166
156
|
const remaining = readNumber(row.remaining)
|
|
167
|
-
if (remaining !== null) {
|
|
157
|
+
if (remaining !== null && remaining >= 0 && remaining <= limit) {
|
|
168
158
|
used = limit - remaining
|
|
169
159
|
}
|
|
170
160
|
}
|
|
171
|
-
if (used === null) return null
|
|
161
|
+
if (used === null || used < 0) return null
|
|
172
162
|
|
|
173
163
|
return {
|
|
174
164
|
used,
|
|
@@ -240,43 +230,29 @@
|
|
|
240
230
|
}
|
|
241
231
|
|
|
242
232
|
function probe(ctx) {
|
|
243
|
-
const
|
|
244
|
-
if (
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
let
|
|
250
|
-
|
|
251
|
-
if (needsRefresh(creds, nowSec)) {
|
|
252
|
-
const refreshed = refreshToken(ctx, creds)
|
|
253
|
-
if (refreshed) {
|
|
254
|
-
accessToken = refreshed
|
|
255
|
-
} else if (!accessToken) {
|
|
256
|
-
throw "Not logged in. Run `kimi login` to authenticate."
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
let didRefresh = false
|
|
233
|
+
const mode = ctx.sourceMode || "auto"
|
|
234
|
+
if (mode === "local") throw "Kimi quotas require a live source. Select api, oauth, cli, or web."
|
|
235
|
+
const key = clean(ctx.provider.apiKey) || env(ctx, "KIMI_CODE_API_KEY")
|
|
236
|
+
const baseOverride = clean(ctx.provider.settings && ctx.provider.settings.baseUrl) || env(ctx, "KIMI_CODE_BASE_URL")
|
|
237
|
+
const hasOverride = baseOverride || env(ctx, "KIMI_CODE_OAUTH_HOST") || env(ctx, "KIMI_OAUTH_HOST")
|
|
238
|
+
const token = webToken(ctx)
|
|
239
|
+
let source
|
|
261
240
|
let resp
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
throw "Usage request failed after refresh. Try again."
|
|
278
|
-
}
|
|
279
|
-
throw "Usage request failed. Check your connection."
|
|
241
|
+
if (mode === "api" && !key) throw "Set KIMI_CODE_API_KEY to a Kimi Code key, not an Open Platform key."
|
|
242
|
+
const useKey = key && (mode === "auto" || mode === "api")
|
|
243
|
+
const session = mode !== "web" && !useKey && !hasOverride ? cliSession(ctx) : null
|
|
244
|
+
if (useKey || session) {
|
|
245
|
+
const base = ctx.host.http.validateBaseUrl(baseOverride || "https://api.kimi.com", false)
|
|
246
|
+
const url = base + (/\/coding\/v1$/.test(base) ? "/usages" : /\/coding$/.test(base) ? "/v1/usages" : "/coding/v1/usages")
|
|
247
|
+
resp = ctx.util.request({ method: "GET", url, headers: Object.assign({}, session && session.headers,
|
|
248
|
+
{ Authorization: "Bearer " + (useKey ? key : session.token), Accept: "application/json", "User-Agent": "usagestat/" + ctx.app.version }), timeoutMs: 10000 })
|
|
249
|
+
source = useKey ? "api" : "oauth"
|
|
250
|
+
} else if (token && (mode === "web" || mode === "auto")) {
|
|
251
|
+
resp = webRequest(ctx, token, WEB_USAGE_URL, { scope: ["FEATURE_CODING"] }, 10000)
|
|
252
|
+
source = "web"
|
|
253
|
+
} else {
|
|
254
|
+
if (hasOverride) throw "Kimi endpoint overrides require an explicit API key; CLI credentials are never forwarded."
|
|
255
|
+
throw "No fresh Kimi Code credentials. Run `kimi login`, set KIMI_CODE_API_KEY, or configure a web session."
|
|
280
256
|
}
|
|
281
257
|
|
|
282
258
|
if (ctx.util.isAuthStatus(resp.status)) {
|
|
@@ -286,7 +262,11 @@
|
|
|
286
262
|
throw "Usage request failed (HTTP " + String(resp.status) + "). Try again later."
|
|
287
263
|
}
|
|
288
264
|
|
|
289
|
-
|
|
265
|
+
let data = ctx.util.tryParseJson(resp.bodyText)
|
|
266
|
+
if (source === "web") {
|
|
267
|
+
const coding = data && Array.isArray(data.usages) && data.usages.find((item) => item.scope === "FEATURE_CODING")
|
|
268
|
+
data = coding ? { usage: coding.detail, limits: coding.limits } : null
|
|
269
|
+
}
|
|
290
270
|
if (!data || typeof data !== "object") {
|
|
291
271
|
throw "Usage response invalid. Try again later."
|
|
292
272
|
}
|
|
@@ -298,7 +278,7 @@
|
|
|
298
278
|
let weeklyCandidate = null
|
|
299
279
|
const usageQuota = parseQuota(data.usage, ctx)
|
|
300
280
|
if (usageQuota) {
|
|
301
|
-
weeklyCandidate = { quota: usageQuota, periodMs:
|
|
281
|
+
weeklyCandidate = { quota: usageQuota, periodMs: WEEK_MS }
|
|
302
282
|
} else {
|
|
303
283
|
const withoutSession = candidates.filter(function (candidate) {
|
|
304
284
|
return candidate !== sessionCandidate
|
|
@@ -345,13 +325,14 @@
|
|
|
345
325
|
}
|
|
346
326
|
|
|
347
327
|
if (lines.length === 0) {
|
|
348
|
-
|
|
328
|
+
throw "Kimi usage response did not contain measurable quota counters."
|
|
349
329
|
}
|
|
350
330
|
|
|
351
|
-
return {
|
|
331
|
+
return enrichMembership(ctx, {
|
|
332
|
+
source,
|
|
352
333
|
plan: parsePlanLabel(data),
|
|
353
334
|
lines,
|
|
354
|
-
}
|
|
335
|
+
}, token)
|
|
355
336
|
}
|
|
356
337
|
|
|
357
338
|
globalThis.__openusage_plugin = { id: "kimi", probe }
|
package/plugins/kimi/plugin.json
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
"entry": "plugin.js",
|
|
7
7
|
"icon": "icon.svg",
|
|
8
8
|
"brandColor": "#000000",
|
|
9
|
-
"supportedModes": ["oauth", "
|
|
9
|
+
"supportedModes": ["api", "oauth", "cli", "web"],
|
|
10
10
|
"autoMode": "oauth",
|
|
11
|
+
"envVars": ["KIMI_CODE_API_KEY", "KIMI_CODE_HOME", "KIMI_CODE_BASE_URL", "KIMI_CODE_OAUTH_HOST", "KIMI_OAUTH_HOST", "KIMI_AUTH_TOKEN"],
|
|
11
12
|
"lines": [
|
|
12
13
|
{ "type": "progress", "label": "Session", "scope": "overview", "primaryOrder": 1 },
|
|
13
|
-
{ "type": "progress", "label": "Weekly", "scope": "overview", "primaryOrder": 2 }
|
|
14
|
+
{ "type": "progress", "label": "Weekly", "scope": "overview", "primaryOrder": 2 },
|
|
15
|
+
{ "type": "progress", "label": "Monthly", "scope": "overview" },
|
|
16
|
+
{ "type": "progress", "label": "Code 7-day", "scope": "detail" }
|
|
14
17
|
]
|
|
15
18
|
}
|
|
File without changes
|
package/plugins/kimi-k2/icon.svg
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/plugins/kiro/icon.svg
CHANGED
|
File without changes
|
package/plugins/kiro/plugin.js
CHANGED
|
@@ -88,7 +88,13 @@
|
|
|
88
88
|
}
|
|
89
89
|
function regionFromArn(profileArn) {
|
|
90
90
|
const parts = String(profileArn || "").split(":")
|
|
91
|
-
|
|
91
|
+
if (parts.length !== 6 || parts[0] !== "arn" || parts[1] !== "aws" ||
|
|
92
|
+
parts[2] !== "codewhisperer" || !/^profile\/.+/.test(parts[5]) ||
|
|
93
|
+
/[\s\x00-\x1f\x7f]/.test(profileArn) ||
|
|
94
|
+
["us-east-1", "eu-central-1"].indexOf(parts[3]) === -1) {
|
|
95
|
+
throw "Kiro profile ARN is invalid or uses an unsupported region. Sign in again with Kiro."
|
|
96
|
+
}
|
|
97
|
+
return parts[3]
|
|
92
98
|
}
|
|
93
99
|
function readStateValue(ctx, key) {
|
|
94
100
|
try {
|
|
@@ -118,9 +124,12 @@
|
|
|
118
124
|
}
|
|
119
125
|
function normalizeBreakdown(ctx, raw) {
|
|
120
126
|
if (!raw || typeof raw !== "object") return null
|
|
121
|
-
const
|
|
127
|
+
const totalUsage = first(raw.currentUsageWithPrecision, raw.currentUsage)
|
|
122
128
|
const usageLimit = first(raw.usageLimitWithPrecision, raw.usageLimit)
|
|
123
|
-
|
|
129
|
+
const overageUsed = first(raw.currentOveragesWithPrecision, raw.currentOverages)
|
|
130
|
+
if (totalUsage === null || totalUsage < 0 || usageLimit === null || usageLimit < 0) return null
|
|
131
|
+
if (overageUsed !== null && (overageUsed < 0 || overageUsed > totalUsage)) return null
|
|
132
|
+
const currentUsage = totalUsage - (overageUsed || 0)
|
|
124
133
|
const bonuses = Array.isArray(raw.bonuses)
|
|
125
134
|
? raw.bonuses
|
|
126
135
|
.map((item) =>
|
|
@@ -143,6 +152,11 @@
|
|
|
143
152
|
currentUsage,
|
|
144
153
|
usageLimit,
|
|
145
154
|
resetDate: iso(ctx, raw.nextDateReset || raw.resetDate),
|
|
155
|
+
overageUsed,
|
|
156
|
+
overageCap: first(raw.overageCapWithPrecision, raw.overageCap),
|
|
157
|
+
overageCharges: num(raw.overageCharges),
|
|
158
|
+
overageRate: num(raw.overageRate),
|
|
159
|
+
currency: typeof raw.currency === "string" ? raw.currency : "USD",
|
|
146
160
|
freeTrialUsage: normalizePool(ctx, raw.freeTrialInfo || raw.freeTrialUsage, {
|
|
147
161
|
current: "currentUsage",
|
|
148
162
|
preciseCurrent: "currentUsageWithPrecision",
|
|
@@ -169,11 +183,14 @@
|
|
|
169
183
|
if (!raw || typeof raw !== "object") return null
|
|
170
184
|
return {
|
|
171
185
|
usageBreakdowns: Array.isArray(raw.usageBreakdownList)
|
|
172
|
-
? raw.usageBreakdownList.map((item) => normalizeBreakdown(ctx,
|
|
186
|
+
? raw.usageBreakdownList.map((item) => normalizeBreakdown(ctx, {
|
|
187
|
+
...item, nextDateReset: item.nextDateReset || raw.nextDateReset,
|
|
188
|
+
})).filter(Boolean)
|
|
173
189
|
: [],
|
|
174
190
|
timestampMs: timestampMs !== null ? timestampMs : null,
|
|
175
191
|
plan: title(raw.subscriptionInfo && raw.subscriptionInfo.subscriptionTitle),
|
|
176
|
-
overageEnabled: raw.overageConfiguration
|
|
192
|
+
overageEnabled: raw.overageConfiguration && raw.overageConfiguration.overageStatus === "ENABLED"
|
|
193
|
+
? true : raw.overageConfiguration && raw.overageConfiguration.overageStatus === "DISABLED" ? false : null,
|
|
177
194
|
}
|
|
178
195
|
}
|
|
179
196
|
function parseUsageLogText(ctx, text) {
|
|
@@ -274,7 +291,7 @@
|
|
|
274
291
|
encodeURIComponent("AGENTIC_REQUEST")
|
|
275
292
|
|
|
276
293
|
let accessToken = authState.token && authState.token.accessToken
|
|
277
|
-
if (!accessToken || needsRefresh(ctx, authState, nowMs)) {
|
|
294
|
+
if (!accessToken || authState.token.refreshToken && needsRefresh(ctx, authState, nowMs)) {
|
|
278
295
|
const refreshed = refreshAccessToken(ctx, authState, nowMs)
|
|
279
296
|
if (refreshed) accessToken = refreshed
|
|
280
297
|
}
|
|
@@ -326,6 +343,7 @@
|
|
|
326
343
|
: null,
|
|
327
344
|
usageBreakdowns: usageSource.usageBreakdowns,
|
|
328
345
|
timestampMs: usageSource.timestampMs !== null ? usageSource.timestampMs : nowMs,
|
|
346
|
+
source: usageSource === liveState ? "api" : "local",
|
|
329
347
|
}
|
|
330
348
|
}
|
|
331
349
|
function pickPrimaryBreakdown(usageBreakdowns) {
|
|
@@ -347,7 +365,9 @@
|
|
|
347
365
|
function buildOutput(ctx, snapshot, nowMs) {
|
|
348
366
|
const primary = pickPrimaryBreakdown(snapshot.usageBreakdowns)
|
|
349
367
|
if (!primary) throw DATA_HINT
|
|
350
|
-
const lines = [
|
|
368
|
+
const lines = [primary.usageLimit > 0
|
|
369
|
+
? ctx.line.progress({ label: "Credits", used: primary.currentUsage, limit: primary.usageLimit, format: COUNT_FORMAT, resetsAt: primary.resetDate || undefined })
|
|
370
|
+
: ctx.line.text({ label: "Credits", value: String(primary.currentUsage) + " used; no included credits" })]
|
|
351
371
|
const bonusUsage = pickBonusUsage(primary)
|
|
352
372
|
if (bonusUsage) {
|
|
353
373
|
lines.push(
|
|
@@ -361,17 +381,36 @@
|
|
|
361
381
|
)
|
|
362
382
|
}
|
|
363
383
|
if (snapshot.overageEnabled !== null) lines.push(ctx.line.badge({ label: "Overages", text: snapshot.overageEnabled ? "Enabled" : "Disabled" }))
|
|
364
|
-
|
|
384
|
+
if (primary.overageUsed !== null && primary.overageUsed !== undefined) {
|
|
385
|
+
if (snapshot.overageEnabled === true && primary.overageCap > 0) {
|
|
386
|
+
lines.push(ctx.line.progress({ label: "Overage Credits", used: primary.overageUsed,
|
|
387
|
+
limit: primary.overageCap, format: COUNT_FORMAT, resetsAt: primary.resetDate || undefined }))
|
|
388
|
+
} else if (primary.overageUsed > 0) {
|
|
389
|
+
lines.push(ctx.line.text({ label: "Overage Credits", value: String(primary.overageUsed) + " credits" }))
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (primary.overageCharges !== null && primary.overageCharges >= 0) {
|
|
393
|
+
const cap = snapshot.overageEnabled === true && primary.overageCap > 0 && primary.overageRate > 0
|
|
394
|
+
? primary.overageCap * primary.overageRate : null
|
|
395
|
+
if (primary.currency === "USD" && cap > 0) {
|
|
396
|
+
lines.push(ctx.line.progress({ label: "Overage Charges", used: primary.overageCharges,
|
|
397
|
+
limit: cap, format: { kind: "dollars" }, resetsAt: primary.resetDate || undefined }))
|
|
398
|
+
} else {
|
|
399
|
+
lines.push(ctx.line.text({ label: "Overage Charges",
|
|
400
|
+
value: primary.currency + " " + primary.overageCharges.toFixed(2) }))
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return { plan: snapshot.plan || undefined, lines, source: snapshot.source, fetchedAt: ctx.util.toIso(snapshot.timestampMs) }
|
|
365
404
|
}
|
|
366
405
|
function probe(ctx) {
|
|
367
406
|
const nowMs = ctx.util.parseDateMs(ctx.nowIso) || Date.now()
|
|
368
407
|
const authState = loadAuthState(ctx)
|
|
369
|
-
if (
|
|
408
|
+
if (ctx.sourceMode !== "local" && (!authState || !authState.token)) throw LOGIN_HINT
|
|
370
409
|
const localState = normalizeCachedState(ctx)
|
|
371
410
|
const loggedState = loadLoggedState(ctx)
|
|
372
411
|
let liveState = null
|
|
373
412
|
let liveError = null
|
|
374
|
-
if (shouldTryLive(localState, loggedState, nowMs)) {
|
|
413
|
+
if (ctx.sourceMode !== "local" && shouldTryLive(localState, loggedState, nowMs)) {
|
|
375
414
|
try {
|
|
376
415
|
liveState = fetchLiveState(ctx, authState, nowMs)
|
|
377
416
|
} catch (e) {
|
package/plugins/kiro/plugin.json
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
"lines": [
|
|
12
12
|
{ "type": "progress", "label": "Credits", "scope": "overview", "primaryOrder": 1 },
|
|
13
13
|
{ "type": "progress", "label": "Bonus Credits", "scope": "overview" },
|
|
14
|
-
{ "type": "badge", "label": "Overages", "scope": "detail" }
|
|
14
|
+
{ "type": "badge", "label": "Overages", "scope": "detail" },
|
|
15
|
+
{ "type": "progress", "label": "Overage Credits", "scope": "detail" },
|
|
16
|
+
{ "type": "progress", "label": "Overage Charges", "scope": "detail" }
|
|
15
17
|
]
|
|
16
18
|
}
|
package/plugins/litellm/icon.svg
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.4 3.2c-.34-.26-.83.02-.78.45l.62 5.05A8.2 8.2 0 0 0 2.7 13.6c0 4.3 4.16 7.2 9.3 7.2s9.3-2.9 9.3-7.2c0-1.79-.5-3.36-1.54-4.9l.62-5.05c.05-.43-.44-.71-.78-.45l-3.4 2.62a11.6 11.6 0 0 0-8.4 0L4.4 3.2zm5.05 9.0c.7 0 1.27-.66 1.27-1.48 0-.81-.57-1.47-1.27-1.47s-1.27.66-1.27 1.47c0 .82.57 1.48 1.27 1.48zm5.1 0c.7 0 1.27-.66 1.27-1.48 0-.81-.57-1.47-1.27-1.47s-1.27.66-1.27 1.47c0 .82.57 1.48 1.27 1.48z"/>
|
|
3
|
+
<path d="M12 14.1c.86 0 1.6.3 1.6.76 0 .3-.32.5-.32.5l3.3.86c.3.08.26.5-.05.52l-2.93.2.97 1.2c.2.24-.07.57-.36.43L12 18.2l-2.21 1.07c-.3.14-.56-.19-.36-.43l.97-1.2-2.93-.2c-.31-.02-.35-.44-.05-.52l3.3-.86s-.32-.2-.32-.5c0-.46.74-.76 1.6-.76z"/>
|
|
4
|
+
</svg>
|