@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1 → 2.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/native-manifest.json +1088 -134
- package/package.json +160 -1
- package/plugins/UPSTREAM-LICENSES.md +113 -0
- package/plugins/_provider-icons/LICENSE +21 -0
- package/plugins/_provider-icons/NOTICE +12 -0
- package/plugins/_provider-icons/licenses/CodexBar-MIT.txt +21 -0
- package/plugins/_provider-icons/licenses/LobeHub-MIT.txt +21 -0
- package/plugins/_provider-icons/licenses/UsageStat-Bar-MIT.txt +21 -0
- package/plugins/_provider-icons/manifest.json +1219 -0
- package/plugins/_provider-icons/provenance.json +269 -0
- package/plugins/_provider-icons/source.json +4 -0
- package/plugins/abacus-ai/icon-color.svg +18 -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/aixy/LICENSE +21 -0
- package/plugins/aixy/plugin.js +261 -0
- package/plugins/aixy/plugin.json +24 -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 +136 -46
- package/plugins/antigravity/plugin.json +0 -0
- package/plugins/antigravity-cli/icon-color.svg +1 -0
- package/plugins/antigravity-cli/icon.svg +1 -3
- package/plugins/antigravity-cli/plugin.js +11 -15
- package/plugins/antigravity-cli/plugin.json +0 -0
- package/plugins/antigravity-ide/icon-color.svg +1 -0
- package/plugins/antigravity-ide/icon.svg +1 -3
- package/plugins/antigravity-ide/plugin.js +0 -0
- package/plugins/antigravity-ide/plugin.json +0 -0
- package/plugins/atlascloud/LICENSE +21 -0
- package/plugins/atlascloud/icon-color.svg +1 -0
- package/plugins/atlascloud/icon.svg +1 -0
- package/plugins/atlascloud/plugin.js +49 -0
- package/plugins/atlascloud/plugin.json +23 -0
- package/plugins/augment/icon-color.svg +14 -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/bifrost/LICENSE +21 -0
- package/plugins/bifrost/plugin.js +361 -0
- package/plugins/bifrost/plugin.json +23 -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 +358 -161
- package/plugins/claude/plugin.json +1 -1
- 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 +87 -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-color.svg +92 -0
- package/plugins/codebuff/icon.svg +0 -0
- package/plugins/codebuff/plugin.js +0 -0
- package/plugins/codebuff/plugin.json +0 -0
- package/plugins/coderabbit/plugin.js +25 -0
- package/plugins/coderabbit/plugin.json +12 -0
- package/plugins/codex/icon-color.svg +0 -0
- package/plugins/codex/icon.svg +0 -0
- package/plugins/codex/plugin.js +8 -2
- package/plugins/codex/plugin.json +0 -0
- package/plugins/command-code/icon-color.svg +3 -0
- package/plugins/command-code/icon.svg +0 -0
- package/plugins/command-code/plugin.js +14 -3
- package/plugins/command-code/plugin.json +0 -0
- package/plugins/copilot/icon-color.svg +0 -0
- package/plugins/copilot/icon.svg +1 -1
- package/plugins/copilot/plugin.js +61 -9
- package/plugins/copilot/plugin.json +4 -1
- package/plugins/crof/icon-color.svg +3 -0
- 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-color.svg +3 -0
- package/plugins/crofai/icon.svg +2 -15
- package/plugins/crofai/plugin.js +0 -0
- package/plugins/crofai/plugin.json +0 -0
- package/plugins/cursor/icon-color.svg +1 -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-color.svg +1 -0
- package/plugins/deepinfra/icon.svg +1 -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 +150 -59
- package/plugins/deepseek/plugin.json +3 -1
- package/plugins/devin/icon.svg +0 -0
- package/plugins/devin/plugin.js +114 -0
- package/plugins/devin/plugin.json +2 -1
- package/plugins/devpass/LICENSE +21 -0
- package/plugins/devpass/plugin.js +115 -0
- package/plugins/devpass/plugin.json +23 -0
- 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-color.svg +4 -0
- 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-color.svg +1 -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-color.svg +1 -0
- package/plugins/fireworks-ai/icon.svg +1 -6
- 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/gemini-apps/LICENSE +22 -0
- package/plugins/gemini-apps/icon-color.svg +1 -0
- package/plugins/gemini-apps/icon.svg +1 -0
- package/plugins/gemini-apps/plugin.js +470 -0
- package/plugins/gemini-apps/plugin.json +19 -0
- package/plugins/gitkraken/LICENSE +21 -0
- package/plugins/gitkraken/plugin.js +153 -0
- package/plugins/gitkraken/plugin.json +24 -0
- package/plugins/grok/icon-color.svg +1 -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-color.svg +1 -0
- package/plugins/groqcloud/icon.svg +0 -0
- package/plugins/groqcloud/plugin.js +0 -0
- package/plugins/groqcloud/plugin.json +0 -0
- package/plugins/helmcode/LICENSE +21 -0
- package/plugins/helmcode/plugin.js +188 -0
- package/plugins/helmcode/plugin.json +24 -0
- package/plugins/huggingface/LICENSE +21 -0
- package/plugins/huggingface/icon-color.svg +1 -0
- package/plugins/huggingface/icon.svg +1 -0
- package/plugins/huggingface/plugin.js +293 -0
- package/plugins/huggingface/plugin.json +25 -0
- package/plugins/hyper/LICENSE +21 -0
- package/plugins/hyper/plugin.js +131 -0
- package/plugins/hyper/plugin.json +26 -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-color.svg +1 -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 +54 -3
- 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/llmman/LICENSE +21 -0
- package/plugins/llmman/plugin.js +133 -0
- package/plugins/llmman/plugin.json +23 -0
- package/plugins/longcat/icon-color.svg +1 -0
- package/plugins/longcat/icon.svg +1 -0
- package/plugins/longcat/plugin.js +182 -0
- package/plugins/longcat/plugin.json +23 -0
- package/plugins/manus/icon-color.svg +6 -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-color.svg +4 -0
- package/plugins/mimo/icon.svg +4 -1
- 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 +110 -5
- package/plugins/mistral/plugin.json +0 -0
- package/plugins/moonshot/icon-color.svg +1 -0
- package/plugins/moonshot/icon.svg +0 -0
- package/plugins/moonshot/plugin.js +8 -6
- package/plugins/moonshot/plugin.json +0 -0
- package/plugins/muse/LICENSE +21 -0
- package/plugins/muse/plugin.js +319 -0
- package/plugins/muse/plugin.json +26 -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/nous/LICENSE +21 -0
- package/plugins/nous/icon-color.svg +1 -0
- package/plugins/nous/icon.svg +1 -0
- package/plugins/nous/plugin.js +124 -0
- package/plugins/nous/plugin.json +24 -0
- package/plugins/ollama/icon-color.svg +1 -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-color.svg +1 -0
- 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-color.svg +1 -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-color.svg +1 -0
- package/plugins/opencode-go/icon-conflict.svg +0 -0
- package/plugins/opencode-go/icon.svg +0 -0
- package/plugins/opencode-go/plugin.js +103 -17
- package/plugins/opencode-go/plugin.json +5 -2
- package/plugins/openrouter/icon-color.svg +1 -0
- 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/pi/plugin.js +113 -0
- package/plugins/pi/plugin.json +11 -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-color.svg +1 -0
- package/plugins/qwencloud/icon.svg +1 -0
- package/plugins/qwencloud/plugin.js +677 -0
- package/plugins/qwencloud/plugin.json +29 -0
- package/plugins/raycast/LICENSE +21 -0
- package/plugins/raycast/plugin.js +174 -0
- package/plugins/raycast/plugin.json +24 -0
- package/plugins/replicate/LICENSE +21 -0
- package/plugins/replicate/icon-color.svg +1 -0
- package/plugins/replicate/icon.svg +1 -0
- package/plugins/replicate/plugin.js +165 -0
- package/plugins/replicate/plugin.json +24 -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-color.svg +14 -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/typesafe/LICENSE +21 -0
- package/plugins/typesafe/plugin.js +225 -0
- package/plugins/typesafe/plugin.json +24 -0
- package/plugins/v0/LICENSE +21 -0
- package/plugins/v0/icon-color.svg +1 -0
- package/plugins/v0/icon.svg +1 -0
- package/plugins/v0/plugin.js +214 -0
- package/plugins/v0/plugin.json +24 -0
- package/plugins/venice/icon-color.svg +0 -0
- package/plugins/venice/icon.svg +0 -0
- package/plugins/venice/plugin.js +50 -1
- package/plugins/venice/plugin.json +2 -1
- package/plugins/vercel/LICENSE +21 -0
- package/plugins/vercel/icon-color.svg +1 -0
- package/plugins/vercel/icon.svg +1 -0
- package/plugins/vercel/plugin.js +55 -0
- package/plugins/vercel/plugin.json +23 -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-color.svg +1 -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-color.svg +1 -0
- package/plugins/xai/icon.svg +1 -0
- package/plugins/xai/plugin.js +162 -0
- package/plugins/xai/plugin.json +28 -0
- package/plugins/xkiro/LICENSE +21 -0
- package/plugins/xkiro/plugin.js +99 -0
- package/plugins/xkiro/plugin.json +23 -0
- package/plugins/zai/icon-color.svg +1 -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-color.svg +1 -0
- package/plugins/zenmux/icon.svg +1 -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
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
var USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36"
|
|
4
4
|
|
|
5
5
|
function getCookieHeader(ctx) {
|
|
6
|
-
var
|
|
6
|
+
var provider = ctx.provider || {}
|
|
7
|
+
var raw = Object.prototype.hasOwnProperty.call(provider, 'cookieHeader') ? provider.cookieHeader :
|
|
8
|
+
provider.instanceId && provider.instanceId !== 'mistral' ? null : ctx.host.env.get("MISTRAL_COOKIE")
|
|
7
9
|
if (!raw || !raw.trim()) {
|
|
8
10
|
throw "Set MISTRAL_COOKIE to your cookie header from admin.mistral.ai. Include csrftoken if present."
|
|
9
11
|
}
|
|
@@ -62,8 +64,9 @@
|
|
|
62
64
|
var total = 0
|
|
63
65
|
for (var i = 0; i < entries.length; i++) {
|
|
64
66
|
var e = entries[i]
|
|
65
|
-
total += e.
|
|
67
|
+
total += Number(e.value != null ? e.value : (e.value_paid || 0))
|
|
66
68
|
}
|
|
69
|
+
if (!Number.isSafeInteger(total) || total < 0) throw new Error('Invalid Mistral token total.')
|
|
67
70
|
return total
|
|
68
71
|
}
|
|
69
72
|
|
|
@@ -80,6 +83,104 @@
|
|
|
80
83
|
return index
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
function subscriptionBudgets(html) {
|
|
87
|
+
if (typeof html !== 'string' || html.length > 2 * 1024 * 1024) throw new Error('Invalid subscription page.')
|
|
88
|
+
var chunks = [], marker = 'self.__next_f.push(', cursor = 0
|
|
89
|
+
while ((cursor = html.indexOf(marker, cursor)) >= 0) {
|
|
90
|
+
cursor += marker.length
|
|
91
|
+
var start = cursor, stack = [], quoted = false, escaped = false
|
|
92
|
+
while (/\s/.test(html[start] || '') && start < html.length) start++
|
|
93
|
+
if (html[start] !== '[') continue
|
|
94
|
+
for (var end = start; end < html.length; end++) {
|
|
95
|
+
var ch = html[end]
|
|
96
|
+
if (quoted) { if (escaped) escaped = false; else if (ch === '\\') escaped = true; else if (ch === '"') quoted = false }
|
|
97
|
+
else if (ch === '"') quoted = true
|
|
98
|
+
else if (ch === '[' || ch === '{') stack.push(ch === '[' ? ']' : '}')
|
|
99
|
+
else if (ch === ']' || ch === '}') {
|
|
100
|
+
if (stack.pop() !== ch) throw new Error('Invalid subscription record.')
|
|
101
|
+
if (!stack.length) {
|
|
102
|
+
var value = JSON.parse(html.slice(start,end+1))
|
|
103
|
+
if (value[0] === 1 && typeof value[1] === 'string') chunks.push(value[1])
|
|
104
|
+
cursor = end+1; break
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Flight's text/binary records are byte-counted and may contain fake JSON rows.
|
|
110
|
+
var stream = encodeURIComponent(chunks.join('')).replace(/%([0-9A-F]{2})/g, function(_,hex){return String.fromCharCode(parseInt(hex,16))})
|
|
111
|
+
var found = new Map()
|
|
112
|
+
function budget(raw) {
|
|
113
|
+
if (!raw || typeof raw.usage_percentage !== 'number' || !Number.isFinite(raw.usage_percentage) || raw.usage_percentage < 0 ||
|
|
114
|
+
typeof raw.initial_budget !== 'number' || !Number.isFinite(raw.initial_budget) || raw.initial_budget <= 0 ||
|
|
115
|
+
!/^[A-Za-z]{3}$/.test(raw.currency || '')) return null
|
|
116
|
+
return {percent:raw.usage_percentage,limit:raw.initial_budget,currency:raw.currency.toUpperCase(),reset:raw.reset_at || null}
|
|
117
|
+
}
|
|
118
|
+
function collect(value, depth) {
|
|
119
|
+
if (depth > 64) throw new Error('Subscription record too deep.')
|
|
120
|
+
if (!value || typeof value !== 'object') return
|
|
121
|
+
if (value.budget) {
|
|
122
|
+
var pair = [budget(value.budget.api_budget),budget(value.budget.vibe_budget)]
|
|
123
|
+
if (pair.some(Boolean)) found.set(JSON.stringify(pair),pair)
|
|
124
|
+
}
|
|
125
|
+
for (var child of Object.values(value)) collect(child,depth+1)
|
|
126
|
+
}
|
|
127
|
+
cursor = 0
|
|
128
|
+
while (cursor < stream.length) {
|
|
129
|
+
var newline = stream.indexOf('\n',cursor); if (newline < 0) newline = stream.length
|
|
130
|
+
var row = stream.slice(cursor,newline), match = /^[0-9a-f]+:/i.exec(row)
|
|
131
|
+
if (!match) { cursor = newline+1; continue }
|
|
132
|
+
var body = row.slice(match[0].length)
|
|
133
|
+
if (/^[TAOoUSsLlGgMmV]/.test(body)) {
|
|
134
|
+
var length = /^[TAOoUSsLlGgMmV]([0-9a-f]+),/i.exec(body)
|
|
135
|
+
if (!length) throw new Error('Invalid Flight length.')
|
|
136
|
+
cursor += match[0].length+length[0].length+parseInt(length[1],16)
|
|
137
|
+
if (cursor > stream.length) throw new Error('Incomplete Flight record.')
|
|
138
|
+
continue
|
|
139
|
+
}
|
|
140
|
+
if (/^[\[{]/.test(body)) {
|
|
141
|
+
var text = decodeURIComponent(Array.from(body,function(c){return '%'+c.charCodeAt(0).toString(16).padStart(2,'0')}).join(''))
|
|
142
|
+
collect(JSON.parse(text),0)
|
|
143
|
+
}
|
|
144
|
+
cursor = newline+1
|
|
145
|
+
}
|
|
146
|
+
if (found.size !== 1) throw new Error('Subscription budgets absent or ambiguous.')
|
|
147
|
+
return found.values().next().value
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function optionalAllowances(ctx, headers, cookie, csrf, lines) {
|
|
151
|
+
var hasVibe = false
|
|
152
|
+
try {
|
|
153
|
+
var page = ctx.host.http.request({method:'GET',url:BASE_URL+'/subscription',headers:headers,timeoutMs:3000})
|
|
154
|
+
if (page.status === 200) subscriptionBudgets(page.bodyText).forEach(function(b,index){
|
|
155
|
+
if (!b) return
|
|
156
|
+
var used = b.limit*b.percent/100
|
|
157
|
+
if (!Number.isFinite(used)) return
|
|
158
|
+
var reset = ctx.util.toIso(b.reset)
|
|
159
|
+
lines.push(ctx.line.progress({label:index?'Monthly Plan':'Included API',used:b.percent,limit:100,
|
|
160
|
+
format:{kind:'percent'},resetsAt:reset || undefined,
|
|
161
|
+
detail:b.currency+' '+used.toFixed(2)+' / '+b.limit.toFixed(2)}))
|
|
162
|
+
if (index) hasVibe = true
|
|
163
|
+
})
|
|
164
|
+
} catch (_) {}
|
|
165
|
+
if (!hasVibe && csrf) try {
|
|
166
|
+
var minimal = cookie.split(';').map(function(p){return p.trim()}).filter(function(p){return /^(csrftoken|ory_session_[^=]+)=/.test(p)}).join('; ')
|
|
167
|
+
var url = 'https://console.mistral.ai/api-ui/trpc/billing.vibeUsage?batch=1&input='+encodeURIComponent(JSON.stringify({'0':{json:null,meta:{values:['undefined'],v:1}}}))
|
|
168
|
+
var resp = ctx.host.http.request({method:'GET',url:url,headers:{Cookie:minimal,'X-CSRFTOKEN':csrf,Accept:'application/json'},timeoutMs:2000})
|
|
169
|
+
var vibe = resp.status===200 ? ctx.util.tryParseJson(resp.bodyText)?.[0]?.result?.data?.json : null
|
|
170
|
+
if (typeof vibe?.usage_percentage==='number' && vibe.usage_percentage>=0 && vibe.usage_percentage<=100)
|
|
171
|
+
lines.push(ctx.line.progress({label:'Monthly Plan',used:vibe.usage_percentage,limit:100,format:{kind:'percent'},resetsAt:ctx.util.toIso(vibe.reset_at) || undefined}))
|
|
172
|
+
} catch (_) {}
|
|
173
|
+
try {
|
|
174
|
+
var credits = ctx.util.requestJson({method:'GET',url:BASE_URL+'/api/billing/credits',headers:headers,timeoutMs:2000})
|
|
175
|
+
var data = credits.json
|
|
176
|
+
if (credits.resp.status!==200 || typeof data?.wallet_amount!=='number' || !/^[A-Za-z]{3}$/.test(data.currency || '')) return
|
|
177
|
+
var values = [data.wallet_amount,data.credit_notes_amount ?? 0,data.ongoing_usage_balance ?? 0]
|
|
178
|
+
if (!values.every(function(n){return typeof n==='number'&&Number.isFinite(n)})) return
|
|
179
|
+
var amount = values[0]+values[1]-values[2]
|
|
180
|
+
if (Number.isFinite(amount)) lines.push(ctx.line.text({label:'Credit balance',value:data.currency.toUpperCase()+' '+amount.toFixed(2)}))
|
|
181
|
+
} catch (_) {}
|
|
182
|
+
}
|
|
183
|
+
|
|
83
184
|
function probe(ctx) {
|
|
84
185
|
var cookieHeader = getCookieHeader(ctx)
|
|
85
186
|
var csrf = extractCsrf(cookieHeader)
|
|
@@ -119,8 +220,10 @@
|
|
|
119
220
|
var totalInput = 0
|
|
120
221
|
var totalOutput = 0
|
|
121
222
|
|
|
122
|
-
|
|
123
|
-
|
|
223
|
+
var completions = [billing.completion, billing.chat, billing.vibe_code && billing.vibe_code.completion]
|
|
224
|
+
for (var c = 0; c < completions.length; c++) {
|
|
225
|
+
if (!completions[c] || !completions[c].models) continue
|
|
226
|
+
var r = aggregateModels(completions[c].models, prices)
|
|
124
227
|
totalCost += r.cost; totalInput += r.inputTokens; totalOutput += r.outputTokens
|
|
125
228
|
}
|
|
126
229
|
|
|
@@ -145,7 +248,9 @@
|
|
|
145
248
|
ctx.line.text({ label: "Tokens", value: tokenDetail }),
|
|
146
249
|
]
|
|
147
250
|
|
|
148
|
-
|
|
251
|
+
optionalAllowances(ctx,headers,cookieHeader,csrf,lines)
|
|
252
|
+
|
|
253
|
+
return { source:'web', lines: lines }
|
|
149
254
|
}
|
|
150
255
|
|
|
151
256
|
globalThis.__openusage_plugin = { id: "mistral", probe: probe }
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>MoonshotAI</title><path d="M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z"></path></svg>
|
|
File without changes
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
function apiKey(ctx) {
|
|
3
|
-
return ctx.host.env.get("MOONSHOT_API_KEY") || ctx.host.env.get("MOONSHOT_KEY");
|
|
3
|
+
return (ctx.provider && ctx.provider.apiKey) || ctx.host.env.get("MOONSHOT_API_KEY") || ctx.host.env.get("MOONSHOT_KEY");
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
function baseUrl(ctx) {
|
|
7
|
-
var region = String(ctx.host.env.get("MOONSHOT_REGION") || "").toLowerCase();
|
|
7
|
+
var region = String((ctx.provider && ctx.provider.region) || ctx.host.env.get("MOONSHOT_REGION") || "").toLowerCase();
|
|
8
8
|
var explicit = ctx.host.env.get("MOONSHOT_API_URL");
|
|
9
9
|
if (explicit) return explicit.replace(/\/$/, "");
|
|
10
10
|
return region === "cn" || region === "china" ? "https://api.moonshot.cn" : "https://api.moonshot.ai";
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
function pick(obj, names) {
|
|
14
14
|
for (var i = 0; i < names.length; i++) {
|
|
15
15
|
var v = obj && obj[names[i]];
|
|
16
|
-
if (typeof v === "number") return v;
|
|
17
|
-
if (typeof v === "string" && v.trim() !== "" &&
|
|
16
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
17
|
+
if (typeof v === "string" && v.trim() !== "" && Number.isFinite(Number(v))) return Number(v);
|
|
18
18
|
}
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
@@ -23,9 +23,10 @@
|
|
|
23
23
|
var key = apiKey(ctx);
|
|
24
24
|
if (!key) throw "Moonshot API key not found. Set MOONSHOT_API_KEY or MOONSHOT_KEY.";
|
|
25
25
|
|
|
26
|
+
var base = baseUrl(ctx);
|
|
26
27
|
var result = ctx.util.requestJson({
|
|
27
28
|
method: "GET",
|
|
28
|
-
url:
|
|
29
|
+
url: base + "/v1/users/me/balance",
|
|
29
30
|
headers: { Authorization: "Bearer " + key, Accept: "application/json" },
|
|
30
31
|
timeoutMs: 15000,
|
|
31
32
|
});
|
|
@@ -36,7 +37,8 @@
|
|
|
36
37
|
var data = json.data || json;
|
|
37
38
|
var available = pick(data, ["available_balance", "availableBalance", "balance", "cash_balance"]);
|
|
38
39
|
if (available === null) throw "Moonshot response did not include a recognizable balance.";
|
|
39
|
-
|
|
40
|
+
var currency = /^https:\/\/api\.moonshot\.cn(?::443)?(?:\/|$)/i.test(base) ? "CNY" : "USD";
|
|
41
|
+
return { source: "api", lines: [ctx.line.text({ label: "Balance", value: currency + " " + available.toFixed(2) })] };
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
globalThis.__openusage_plugin = { id: "moonshot", probe: probe };
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peter Steinberger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
|
|
2
|
+
globalThis.__usagestat_bundled_options = {"labels":["Session","Weekly","Additional"],"defaults":{},"autoMode":"api"};
|
|
3
|
+
function _nullishCoalesce(lhs, rhsFn) {
|
|
4
|
+
if (lhs != null) {
|
|
5
|
+
return lhs;
|
|
6
|
+
} else {
|
|
7
|
+
return rhsFn();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function _optionalChain(ops) {
|
|
11
|
+
let lastAccessLHS = undefined;
|
|
12
|
+
let value = ops[0];
|
|
13
|
+
let i = 1;
|
|
14
|
+
while (i < ops.length) {
|
|
15
|
+
const op = ops[i];
|
|
16
|
+
const fn = ops[i + 1];
|
|
17
|
+
i += 2;
|
|
18
|
+
if ((op === "optionalAccess" || op === "optionalCall") && value == null) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
if (op === "access" || op === "optionalAccess") {
|
|
22
|
+
lastAccessLHS = value;
|
|
23
|
+
value = fn(value);
|
|
24
|
+
} else if (op === "call" || op === "optionalCall") {
|
|
25
|
+
value = fn((...args) => value.call(lastAccessLHS, ...args));
|
|
26
|
+
lastAccessLHS = undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
async function _asyncOptionalChain(ops) {
|
|
32
|
+
let lastAccessLHS = undefined;
|
|
33
|
+
let value = ops[0];
|
|
34
|
+
let i = 1;
|
|
35
|
+
while (i < ops.length) {
|
|
36
|
+
const op = ops[i];
|
|
37
|
+
const fn = ops[i + 1];
|
|
38
|
+
i += 2;
|
|
39
|
+
if ((op === "optionalAccess" || op === "optionalCall") && value == null) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
if (op === "access" || op === "optionalAccess") {
|
|
43
|
+
lastAccessLHS = value;
|
|
44
|
+
value = await fn(value);
|
|
45
|
+
} else if (op === "call" || op === "optionalCall") {
|
|
46
|
+
value = await fn((...args) => value.call(lastAccessLHS, ...args));
|
|
47
|
+
lastAccessLHS = undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
defineProvider({
|
|
53
|
+
id: "muse",
|
|
54
|
+
name: "Muse Code",
|
|
55
|
+
endpoints: ["https://api.meta.ai", "https://dev.meta.ai"],
|
|
56
|
+
settings: [
|
|
57
|
+
{ key: "MUSE_DEVICE_TOKEN", title: "Muse login", type: "secure" },
|
|
58
|
+
{ key: "MUSE_WEB_TEAM_ID", title: "Browser team ID", type: "plain" },
|
|
59
|
+
],
|
|
60
|
+
capabilities: ["browser-cookies", "http-status"],
|
|
61
|
+
cookieDomains: ["dev.meta.ai"],
|
|
62
|
+
async fetchUsage(ctx) {
|
|
63
|
+
const token = ctx.settings.getSecret("MUSE_DEVICE_TOKEN");
|
|
64
|
+
if (!_optionalChain([token, "optionalAccess", (_) => _.startsWith, "call", (_2) => _2("dca:")])) {
|
|
65
|
+
throw ctx.fail.authenticationExpired("Muse Code requires a device-code login. Run `muse login` again.");
|
|
66
|
+
}
|
|
67
|
+
// Keep the device credential off dev.meta.ai requests, which authenticate with the browser session.
|
|
68
|
+
const response = await ctx.http.post("https://api.meta.ai/muse-code/key", {
|
|
69
|
+
body: {},
|
|
70
|
+
headers: { Authorization: `Bearer ${token}`, "x-api-version": "1.0.0", "User-Agent": "CodexBar" },
|
|
71
|
+
timeoutSeconds: 15,
|
|
72
|
+
});
|
|
73
|
+
if (response.status === 401 || response.status === 403) {
|
|
74
|
+
throw ctx.fail.authenticationExpired("Muse Code login was rejected. Run `muse login` again.");
|
|
75
|
+
}
|
|
76
|
+
if (response.status === 429) throw ctx.fail.rateLimited("Muse Code usage requests are rate limited.");
|
|
77
|
+
if (response.status >= 500) throw ctx.fail.providerUnavailable(`Muse Code API returned HTTP ${response.status}.`);
|
|
78
|
+
if (response.status !== 200) throw ctx.fail.apiFailure(`Muse Code API returned HTTP ${response.status}.`);
|
|
79
|
+
const fail = (field) => {
|
|
80
|
+
throw ctx.fail.parseFailure(`Could not parse Muse Code subscription usage: ${field}`);
|
|
81
|
+
};
|
|
82
|
+
const object = (value, field) => {
|
|
83
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return fail(field);
|
|
84
|
+
return value;
|
|
85
|
+
};
|
|
86
|
+
const number = (value, field) => {
|
|
87
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return fail(field);
|
|
88
|
+
return value;
|
|
89
|
+
};
|
|
90
|
+
const text = (value, field) => {
|
|
91
|
+
if (value === undefined || value === null) return undefined;
|
|
92
|
+
if (typeof value !== "string") return fail(field);
|
|
93
|
+
return value.trim() || undefined;
|
|
94
|
+
};
|
|
95
|
+
const reset = (value) => {
|
|
96
|
+
if (value === undefined || value === null) return undefined;
|
|
97
|
+
const seconds = number(value, "resets_at");
|
|
98
|
+
// Match the native countdown boundary; oversized dates must not discard useful quota data.
|
|
99
|
+
if (seconds <= 0 || seconds > 64092211200) return undefined;
|
|
100
|
+
return ctx.date.unixSeconds(seconds);
|
|
101
|
+
};
|
|
102
|
+
let decoded;
|
|
103
|
+
try {
|
|
104
|
+
decoded = JSON.parse(response.bodyText);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
void error;
|
|
107
|
+
return fail("expected JSON");
|
|
108
|
+
}
|
|
109
|
+
const root = object(decoded, "expected a response object");
|
|
110
|
+
for (const key of ["require_payment", "is_subs_active"]) {
|
|
111
|
+
if (root[key] !== undefined && root[key] !== null && typeof root[key] !== "boolean") return fail(key);
|
|
112
|
+
}
|
|
113
|
+
if (root.require_payment === true) {
|
|
114
|
+
throw ctx.fail.permissionDenied("Muse Code requires a payment method. Finish billing at https://dev.meta.ai");
|
|
115
|
+
}
|
|
116
|
+
if (root.is_subs_active !== true) {
|
|
117
|
+
throw ctx.fail.permissionDenied("No Muse Code subscription is active on this login.");
|
|
118
|
+
}
|
|
119
|
+
const plan = text(root.subs_tier_name, "subs_tier_name");
|
|
120
|
+
const rows = [];
|
|
121
|
+
if (plan) rows.push({ label: "Plan", value: plan });
|
|
122
|
+
const snapshot = {
|
|
123
|
+
details: [{ title: "Muse Code subscription", rows }],
|
|
124
|
+
identity: { email: text(root.user_email, "user_email"), loginMethod: _nullishCoalesce(plan, () => "Muse login") },
|
|
125
|
+
dataConfidence: "unknown",
|
|
126
|
+
};
|
|
127
|
+
const percentLabel = (value) => `${ctx.format.number(value, { maximumFractionDigits: 0 })}%`;
|
|
128
|
+
|
|
129
|
+
// The browser quota belongs to one dev.meta.ai team, which the user must choose explicitly: a session can
|
|
130
|
+
// see several teams, and list order says nothing about which one holds the CLI login's subscription.
|
|
131
|
+
async function webQuota() {
|
|
132
|
+
if (ctx.browser.availability("dev.meta.ai") === "off") return undefined;
|
|
133
|
+
try {
|
|
134
|
+
let requestsLeft = 5;
|
|
135
|
+
for await (const session of ctx.browser.sessions("dev.meta.ai")) {
|
|
136
|
+
if (requestsLeft <= 0) break;
|
|
137
|
+
let rejected = false;
|
|
138
|
+
const headers = { Cookie: session.header, "User-Agent": "CodexBar" };
|
|
139
|
+
const get = async (path) => {
|
|
140
|
+
if (requestsLeft-- <= 0) throw new Error("Muse browser request budget exhausted");
|
|
141
|
+
const response = await ctx.http.get(`https://dev.meta.ai${path}`, { headers, timeoutSeconds: 8 });
|
|
142
|
+
if (response.status === 401 || response.status === 403) {
|
|
143
|
+
rejected = true;
|
|
144
|
+
ctx.browser.rejectCookie("dev.meta.ai", session);
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
if (response.status !== 200) return undefined;
|
|
148
|
+
const value = JSON.parse(response.bodyText);
|
|
149
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
150
|
+
};
|
|
151
|
+
// The browser session must belong to the same Meta account as the CLI login.
|
|
152
|
+
const loginEmail = _optionalChain([
|
|
153
|
+
text,
|
|
154
|
+
"call",
|
|
155
|
+
(_3) => _3(root.user_email, "user_email"),
|
|
156
|
+
"optionalAccess",
|
|
157
|
+
(_4) => _4.toLowerCase,
|
|
158
|
+
"call",
|
|
159
|
+
(_5) => _5(),
|
|
160
|
+
]);
|
|
161
|
+
const me = await get("/api/auth/me");
|
|
162
|
+
const webEmail =
|
|
163
|
+
typeof _optionalChain([me, "optionalAccess", (_6) => _6.email]) === "string"
|
|
164
|
+
? me.email.trim().toLowerCase()
|
|
165
|
+
: undefined;
|
|
166
|
+
if (!loginEmail || !webEmail || loginEmail !== webEmail) continue;
|
|
167
|
+
const listed = await _asyncOptionalChain([
|
|
168
|
+
await get("/api/portal/teams"),
|
|
169
|
+
"optionalAccess",
|
|
170
|
+
async (_7) => _7.teams,
|
|
171
|
+
]);
|
|
172
|
+
if (rejected) continue;
|
|
173
|
+
if (!Array.isArray(listed)) return undefined;
|
|
174
|
+
const teams = [];
|
|
175
|
+
for (const entry of listed) {
|
|
176
|
+
const item = entry && typeof entry === "object" ? entry : {};
|
|
177
|
+
const id =
|
|
178
|
+
typeof item.team_id === "string"
|
|
179
|
+
? item.team_id
|
|
180
|
+
: Number.isSafeInteger(item.team_id)
|
|
181
|
+
? String(item.team_id)
|
|
182
|
+
: "";
|
|
183
|
+
if (!/^[0-9]+$/.test(id)) continue;
|
|
184
|
+
const name = typeof item.team_name === "string" && item.team_name.trim() ? item.team_name.trim() : id;
|
|
185
|
+
teams.push({ id, name });
|
|
186
|
+
}
|
|
187
|
+
const selected = _nullishCoalesce(
|
|
188
|
+
_optionalChain([
|
|
189
|
+
ctx,
|
|
190
|
+
"access",
|
|
191
|
+
(_8) => _8.settings,
|
|
192
|
+
"access",
|
|
193
|
+
(_9) => _9.get,
|
|
194
|
+
"call",
|
|
195
|
+
(_10) => _10("MUSE_WEB_TEAM_ID"),
|
|
196
|
+
"optionalAccess",
|
|
197
|
+
(_11) => _11.trim,
|
|
198
|
+
"call",
|
|
199
|
+
(_12) => _12(),
|
|
200
|
+
]),
|
|
201
|
+
() => "",
|
|
202
|
+
);
|
|
203
|
+
const team = teams.find((candidate) => candidate.id === selected);
|
|
204
|
+
if (!selected) return { teams, note: "Choose a browser team in Muse Code settings" };
|
|
205
|
+
if (!team) return { teams, note: "The selected browser team is not visible to this session" };
|
|
206
|
+
const quota = await _asyncOptionalChain([
|
|
207
|
+
await get(`/api/portal/teams/${team.id}/subscription-quota`),
|
|
208
|
+
"optionalAccess",
|
|
209
|
+
async (_13) => _13.subscription_quota,
|
|
210
|
+
]);
|
|
211
|
+
if (rejected) continue;
|
|
212
|
+
if (!quota || typeof quota !== "object")
|
|
213
|
+
return { teams, note: "No subscription quota for the selected team" };
|
|
214
|
+
const record = quota;
|
|
215
|
+
// The team's quota must be for the same plan the CLI login reports.
|
|
216
|
+
if (!plan || typeof record.tier !== "string" || record.tier.trim() !== plan) {
|
|
217
|
+
return { teams, note: "The selected team's plan differs from the Muse login" };
|
|
218
|
+
}
|
|
219
|
+
const parsed = parseWebQuota(record);
|
|
220
|
+
return parsed ? { teams, quota: { team, ...parsed } } : { teams };
|
|
221
|
+
}
|
|
222
|
+
} catch (error) {
|
|
223
|
+
void error;
|
|
224
|
+
}
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
function parseWebQuota(quota) {
|
|
228
|
+
// Limits and usage are weighted token counts encoded as decimal strings.
|
|
229
|
+
const amount = (value) => {
|
|
230
|
+
const parsed = typeof value === "string" && /^[0-9]+$/.test(value) ? Number(value) : value;
|
|
231
|
+
return typeof parsed === "number" && Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
|
|
232
|
+
};
|
|
233
|
+
const percent = (used, limit) => {
|
|
234
|
+
const u = amount(used);
|
|
235
|
+
const l = amount(limit);
|
|
236
|
+
return u === null || l === null || l <= 0 ? null : Math.min(100, (u / l) * 100);
|
|
237
|
+
};
|
|
238
|
+
const resetAt = (value) => {
|
|
239
|
+
const parsed = amount(value);
|
|
240
|
+
return parsed === null || parsed <= 0 || parsed > 64092211200 ? undefined : ctx.date.unixSeconds(parsed);
|
|
241
|
+
};
|
|
242
|
+
const now = ctx.date.now().getTime();
|
|
243
|
+
const weeklyReset = resetAt(quota.weekly_resets_at);
|
|
244
|
+
const weeklyPercent = percent(quota.weekly_weighted_used, quota.weekly_weighted_limit);
|
|
245
|
+
const seconds = amount(quota.window_duration_secs);
|
|
246
|
+
// A weekly quota without a future reset is stale; show nothing rather than an old reading.
|
|
247
|
+
if (weeklyPercent === null || !weeklyReset || weeklyReset.getTime() <= now) return null;
|
|
248
|
+
if (seconds === null || !Number.isSafeInteger(seconds) || seconds < 60) return null;
|
|
249
|
+
const windowReset = resetAt(quota.window_resets_at);
|
|
250
|
+
let primaryPercent = percent(quota.window_weighted_used, quota.window_weighted_limit);
|
|
251
|
+
if (primaryPercent === null) return null;
|
|
252
|
+
const noWindowReset = quota.window_resets_at === undefined || quota.window_resets_at === null;
|
|
253
|
+
if ((!noWindowReset && !windowReset) || (noWindowReset && primaryPercent !== 0)) return null;
|
|
254
|
+
// An idle 5-hour window has no reset time; one whose reset has passed carries no usage into the next window.
|
|
255
|
+
const windowActive = windowReset !== undefined && windowReset.getTime() > now;
|
|
256
|
+
if (!windowActive) primaryPercent = 0;
|
|
257
|
+
return {
|
|
258
|
+
primary: {
|
|
259
|
+
usedPercent: primaryPercent,
|
|
260
|
+
windowMinutes: Math.round(seconds / 60),
|
|
261
|
+
resetsAt: windowActive ? windowReset : undefined,
|
|
262
|
+
},
|
|
263
|
+
secondary: { usedPercent: weeklyPercent, windowMinutes: 10080, resetsAt: weeklyReset },
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
if (root.subs_usage === undefined || root.subs_usage === null) {
|
|
267
|
+
// The login response omits quotas while the 5-hour window is idle, even when the weekly limit has usage.
|
|
268
|
+
// The dev.meta.ai usage page reads the same subscription quota with the browser session.
|
|
269
|
+
const web = await webQuota();
|
|
270
|
+
if (!_optionalChain([web, "optionalAccess", (_14) => _14.quota]))
|
|
271
|
+
rows.push({ label: "Quota", value: "Not included in this login response" });
|
|
272
|
+
if (!web) return snapshot;
|
|
273
|
+
const teamRows = _nullishCoalesce(web.teams, () => []).map((team) => ({ label: team.name, value: team.id }));
|
|
274
|
+
if (web.note) teamRows.unshift({ label: "Status", value: web.note });
|
|
275
|
+
_optionalChain([
|
|
276
|
+
snapshot,
|
|
277
|
+
"access",
|
|
278
|
+
(_15) => _15.details,
|
|
279
|
+
"optionalAccess",
|
|
280
|
+
(_16) => _16.push,
|
|
281
|
+
"call",
|
|
282
|
+
(_17) => _17({ title: "Browser teams", rows: teamRows }),
|
|
283
|
+
]);
|
|
284
|
+
if (!web.quota) return snapshot;
|
|
285
|
+
const { team, primary, secondary } = web.quota;
|
|
286
|
+
const webRows = [
|
|
287
|
+
{ label: "Team", value: team.name },
|
|
288
|
+
{ label: "5 hours", value: percentLabel(primary.usedPercent) },
|
|
289
|
+
{ label: "Weekly", value: percentLabel(secondary.usedPercent) },
|
|
290
|
+
];
|
|
291
|
+
_optionalChain([
|
|
292
|
+
snapshot,
|
|
293
|
+
"access",
|
|
294
|
+
(_18) => _18.details,
|
|
295
|
+
"optionalAccess",
|
|
296
|
+
(_19) => _19.push,
|
|
297
|
+
"call",
|
|
298
|
+
(_20) => _20({ title: "Browser team quota (dev.meta.ai)", rows: webRows }),
|
|
299
|
+
]);
|
|
300
|
+
// Weighted usage reported for a user-selected team, not by the CLI login itself.
|
|
301
|
+
return { usage: { ...snapshot, primary, secondary, dataConfidence: "estimated" }, sourceLabel: "oauth+web" };
|
|
302
|
+
}
|
|
303
|
+
const usage = object(root.subs_usage, "subs_usage");
|
|
304
|
+
const window = object(usage.window, "missing subscription window");
|
|
305
|
+
const weekly = object(usage.weekly, "missing weekly window");
|
|
306
|
+
const minutes = Math.round(number(window.window_duration_mins, "window_duration_mins"));
|
|
307
|
+
if (!Number.isSafeInteger(minutes) || minutes <= 0) return fail("window_duration_mins");
|
|
308
|
+
const primaryPercent = Math.min(100, Math.max(0, number(window.used_percent, "window.used_percent")));
|
|
309
|
+
const weeklyPercent = Math.min(100, Math.max(0, number(weekly.used_percent, "weekly.used_percent")));
|
|
310
|
+
rows.push({ label: "5 hours", value: percentLabel(primaryPercent) });
|
|
311
|
+
rows.push({ label: "Weekly", value: percentLabel(weeklyPercent) });
|
|
312
|
+
return {
|
|
313
|
+
...snapshot,
|
|
314
|
+
primary: { usedPercent: primaryPercent, windowMinutes: minutes, resetsAt: reset(window.resets_at) },
|
|
315
|
+
secondary: { usedPercent: weeklyPercent, windowMinutes: 10080, resetsAt: reset(weekly.resets_at) },
|
|
316
|
+
dataConfidence: "exact",
|
|
317
|
+
};
|
|
318
|
+
},
|
|
319
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "muse",
|
|
4
|
+
"name": "Muse Code",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"enabledByDefault": false,
|
|
8
|
+
"supportedModes": [
|
|
9
|
+
"api"
|
|
10
|
+
],
|
|
11
|
+
"autoMode": "api",
|
|
12
|
+
"usageDashboardUrl": "https://dev.meta.ai",
|
|
13
|
+
"webUrl": "https://dev.meta.ai",
|
|
14
|
+
"envVars": [
|
|
15
|
+
"MUSE_DEVICE_TOKEN",
|
|
16
|
+
"MUSE_WEB_TEAM_ID",
|
|
17
|
+
"MUSE_COOKIE"
|
|
18
|
+
],
|
|
19
|
+
"upstream": {
|
|
20
|
+
"repository": "https://github.com/steipete/CodexBar",
|
|
21
|
+
"revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
|
|
22
|
+
"path": "Sources/CodexBarCore/Resources/Plugins/muse.js",
|
|
23
|
+
"sha256": "80ddeae2d6f2fb90b22b3a978dfdd5f8904a1766687a19bc93c8108fd5a7dc41",
|
|
24
|
+
"license": "MIT"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
File without changes
|
package/plugins/nanogpt/icon.svg
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="512" style="flex:none;line-height:1" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><title>Notion</title><path clip-rule="evenodd" d="M15.257.055l-13.31.98C.874 1.128.5 1.83.5 2.667v14.559c0 .654.233 1.213.794 1.96l3.129 4.06c.513.653.98.794 1.962.745l15.457-.932c1.307-.093 1.681-.7 1.681-1.727V4.954c0-.53-.21-.684-.829-1.135l-.106-.078L18.34.755c-1.027-.746-1.45-.84-3.083-.7zm-8.521 4.63c-1.263.086-1.549.105-2.266-.477L2.647 2.76c-.186-.187-.092-.42.375-.466l12.796-.933c1.074-.094 1.634.28 2.054.606l2.195 1.587c.093.047.326.326.047.326l-13.216.794-.162.01zM5.263 21.193V7.287c0-.606.187-.886.748-.933l15.176-.886c.515-.047.748.28.748.886v13.81c0 .609-.093 1.122-.934 1.168l-14.523.84c-.842.047-1.215-.232-1.215-.98zm14.338-13.16c.093.422 0 .842-.422.89l-.699.139v10.264c-.608.327-1.168.513-1.635.513-.747 0-.934-.232-1.495-.932l-4.576-7.185v6.952l1.448.327s0 .84-1.169.84l-3.221.186c-.094-.187 0-.654.327-.747l.84-.232V9.853L7.832 9.76c-.093-.42.14-1.026.794-1.073l3.456-.232 4.763 7.279v-6.44l-1.214-.14c-.094-.513.28-.887.747-.933l3.223-.187z"></path></svg>
|