@hashimkarim/usagestat-linux-x64-gnu 2.1.0 → 2.2.0
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/native-manifest.json +197 -89
- package/package.json +19 -1
- package/plugins/abliteration/plugin.json +1 -1
- package/plugins/aerostack/plugin.json +1 -1
- package/plugins/aixy/plugin.json +1 -1
- package/plugins/atlascloud/plugin.json +1 -1
- package/plugins/bifrost/plugin.json +1 -1
- package/plugins/chatbox/plugin.json +1 -1
- package/plugins/claudeplatform/plugin.json +1 -1
- package/plugins/codex/plugin.js +11 -6
- package/plugins/codex/plugin.json +10 -1
- package/plugins/cosmic/plugin.json +1 -1
- package/plugins/cursor/plugin.js +18 -6
- package/plugins/devpass/plugin.json +1 -1
- package/plugins/exa/plugin.json +1 -1
- package/plugins/fal/plugin.json +1 -1
- package/plugins/flora/plugin.json +1 -1
- package/plugins/futureagi/plugin.json +1 -1
- package/plugins/gemini-apps/plugin.json +1 -1
- package/plugins/gitkraken/plugin.json +1 -1
- package/plugins/googledeveloper/LICENSE +21 -0
- package/plugins/googledeveloper/icon.svg +3 -0
- package/plugins/googledeveloper/plugin.js +204 -0
- package/plugins/googledeveloper/plugin.json +25 -0
- package/plugins/helmcode/plugin.js +80 -23
- package/plugins/helmcode/plugin.json +2 -2
- package/plugins/huggingface/plugin.json +1 -1
- package/plugins/hyper/plugin.json +1 -1
- package/plugins/jetbrains-ai-assistant/LICENSE +22 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +502 -16
- package/plugins/jetbrains-ai-assistant/plugin.json +27 -4
- package/plugins/kimi/plugin.js +16 -1
- package/plugins/kimi/plugin.json +46 -6
- package/plugins/langdock/plugin.json +1 -1
- package/plugins/linkup/plugin.json +1 -1
- package/plugins/lithosai/plugin.json +1 -1
- package/plugins/llmman/plugin.json +1 -1
- package/plugins/munito/plugin.json +1 -1
- package/plugins/muse/plugin.json +1 -1
- package/plugins/museai/plugin.js +5 -3
- package/plugins/museai/plugin.json +2 -2
- package/plugins/nous/plugin.json +1 -1
- package/plugins/opencode-go/plugin.js +4 -3
- package/plugins/opendesign/LICENSE +21 -0
- package/plugins/opendesign/icon.svg +4 -0
- package/plugins/opendesign/plugin.js +108 -0
- package/plugins/opendesign/plugin.json +25 -0
- package/plugins/parallel/plugin.json +1 -1
- package/plugins/perplexity/LICENSE +22 -0
- package/plugins/perplexity/plugin.js +122 -0
- package/plugins/perplexity/plugin.json +36 -7
- package/plugins/qwencloud/plugin.json +1 -1
- package/plugins/raycast/plugin.json +1 -1
- package/plugins/replicate/plugin.json +1 -1
- package/plugins/sailresearch/plugin.json +1 -1
- package/plugins/siliconflow/LICENSE +21 -0
- package/plugins/siliconflow/icon.svg +3 -0
- package/plugins/siliconflow/plugin.js +87 -0
- package/plugins/siliconflow/plugin.json +32 -0
- package/plugins/sofya/plugin.json +1 -1
- package/plugins/soniox/plugin.json +1 -1
- package/plugins/synthetic/plugin.js +12 -0
- package/plugins/synthetic/plugin.json +51 -9
- package/plugins/tavily/plugin.json +1 -1
- package/plugins/tinyapi/plugin.json +1 -1
- package/plugins/traecn/plugin.js +10 -11
- package/plugins/traecn/plugin.json +2 -2
- package/plugins/tripo/LICENSE +21 -0
- package/plugins/tripo/icon.svg +4 -0
- package/plugins/tripo/plugin.js +60 -0
- package/plugins/tripo/plugin.json +24 -0
- package/plugins/typesafe/plugin.js +63 -112
- package/plugins/typesafe/plugin.json +2 -2
- package/plugins/v0/plugin.json +1 -1
- package/plugins/vercel/plugin.json +2 -2
- package/plugins/workbuddy/plugin.js +103 -17
- package/plugins/workbuddy/plugin.json +14 -2
- package/plugins/xapi/plugin.json +1 -1
- package/plugins/xkiro/plugin.json +1 -1
- package/usagestat +0 -0
- package/usagestatd +0 -0
package/plugins/kimi/plugin.js
CHANGED
|
@@ -104,6 +104,14 @@
|
|
|
104
104
|
})
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
function monthlyBreakdown(ctx, lines, total, code) {
|
|
108
|
+
for (let i=lines.length-1;i>=0;i--) if (["Monthly Kimi Code","Monthly other features"].includes(lines[i].label)) lines.splice(i,1)
|
|
109
|
+
if (!Number.isFinite(total) || total < 0 || !Number.isFinite(code) || code < 0) return
|
|
110
|
+
const percent = value => value > 0 && value < .01 ? "<1% used" : Math.round(Math.min(1,value)*100)+"% used"
|
|
111
|
+
lines.push(ctx.line.text({label:"Monthly Kimi Code",value:percent(code)}),
|
|
112
|
+
ctx.line.text({label:"Monthly other features",value:percent(Math.max(0,total-code))}))
|
|
113
|
+
}
|
|
114
|
+
|
|
107
115
|
function enrichMembership(ctx, result, token) {
|
|
108
116
|
if (!token || ctx.provider.settings && ctx.provider.settings.cookieSource === "off") return result
|
|
109
117
|
try {
|
|
@@ -122,7 +130,11 @@
|
|
|
122
130
|
if (ratio >= 1) {
|
|
123
131
|
if (existing >= 0) result.lines.splice(existing,1)
|
|
124
132
|
result.lines.unshift(monthly)
|
|
125
|
-
|
|
133
|
+
monthlyBreakdown(ctx,result.lines,ratio,readNumber(pool.kimiCodeUsedRatio))
|
|
134
|
+
} else if (existing < 0) {
|
|
135
|
+
result.lines.push(monthly)
|
|
136
|
+
monthlyBreakdown(ctx,result.lines,ratio,readNumber(pool.kimiCodeUsedRatio))
|
|
137
|
+
}
|
|
126
138
|
}
|
|
127
139
|
const weekly = data.ratelimitCode7d
|
|
128
140
|
const weeklyRatio = weekly && readNumber(weekly.ratio)
|
|
@@ -355,6 +367,9 @@
|
|
|
355
367
|
} else if (previous >= 0) lines[previous] = line
|
|
356
368
|
else lines.push(line)
|
|
357
369
|
}
|
|
370
|
+
if (lines.some(line => line.label === "Monthly")) {
|
|
371
|
+
monthlyBreakdown(ctx,lines,readNumber(data.usages?.limit_month_total?.used_ratio),readNumber(data.usages?.limit_month_code?.used_ratio))
|
|
372
|
+
}
|
|
358
373
|
const result = enrichMembership(ctx, {source,plan:parsePlanLabel(data),lines}, token)
|
|
359
374
|
if (result.lines.length === 0) throw "Kimi usage response did not contain measurable quota counters."
|
|
360
375
|
return result
|
package/plugins/kimi/plugin.json
CHANGED
|
@@ -6,13 +6,53 @@
|
|
|
6
6
|
"entry": "plugin.js",
|
|
7
7
|
"icon": "icon.svg",
|
|
8
8
|
"brandColor": "#000000",
|
|
9
|
-
"supportedModes": [
|
|
9
|
+
"supportedModes": [
|
|
10
|
+
"api",
|
|
11
|
+
"oauth",
|
|
12
|
+
"cli",
|
|
13
|
+
"web"
|
|
14
|
+
],
|
|
10
15
|
"autoMode": "oauth",
|
|
11
|
-
"envVars": [
|
|
16
|
+
"envVars": [
|
|
17
|
+
"KIMI_CODE_API_KEY",
|
|
18
|
+
"KIMI_CODE_HOME",
|
|
19
|
+
"KIMI_CODE_BASE_URL",
|
|
20
|
+
"KIMI_CODE_OAUTH_HOST",
|
|
21
|
+
"KIMI_OAUTH_HOST",
|
|
22
|
+
"KIMI_AUTH_TOKEN"
|
|
23
|
+
],
|
|
12
24
|
"lines": [
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
25
|
+
{
|
|
26
|
+
"type": "progress",
|
|
27
|
+
"label": "Session",
|
|
28
|
+
"scope": "overview",
|
|
29
|
+
"primaryOrder": 1
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "progress",
|
|
33
|
+
"label": "Weekly",
|
|
34
|
+
"scope": "overview",
|
|
35
|
+
"primaryOrder": 2
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "progress",
|
|
39
|
+
"label": "Monthly",
|
|
40
|
+
"scope": "overview"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "progress",
|
|
44
|
+
"label": "Code 7-day",
|
|
45
|
+
"scope": "detail"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "text",
|
|
49
|
+
"label": "Monthly Kimi Code",
|
|
50
|
+
"scope": "detail"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "text",
|
|
54
|
+
"label": "Monthly other features",
|
|
55
|
+
"scope": "detail"
|
|
56
|
+
}
|
|
17
57
|
]
|
|
18
58
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"setupFields": [],
|
|
18
18
|
"upstream": {
|
|
19
19
|
"repository": "https://github.com/steipete/CodexBar",
|
|
20
|
-
"revision": "
|
|
20
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
21
21
|
"path": "Sources/CodexBarCore/Resources/Plugins/langdock.js",
|
|
22
22
|
"sha256": "c950eb7566aea322bba26fc97735a7ba688b6cfb7fa6a5e06a2e0cb6fff6f831",
|
|
23
23
|
"license": "MIT"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/linkup.js",
|
|
21
21
|
"sha256": "7857c63217818a2a9935397a8fe70621b42ab17115a43da2eab6b4a0ea27b775",
|
|
22
22
|
"license": "MIT"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"setupFields": [],
|
|
19
19
|
"upstream": {
|
|
20
20
|
"repository": "https://github.com/steipete/CodexBar",
|
|
21
|
-
"revision": "
|
|
21
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
22
22
|
"path": "Sources/CodexBarCore/Resources/Plugins/lithosai.js",
|
|
23
23
|
"sha256": "11f83683e93728e8d35ae6d9852b854d6f8db9dee2b0b293e5899089216b01ff",
|
|
24
24
|
"license": "MIT"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"upstream": {
|
|
25
25
|
"repository": "https://github.com/steipete/CodexBar",
|
|
26
|
-
"revision": "
|
|
26
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
27
27
|
"path": "Sources/CodexBarCore/Resources/Plugins/llmman.js",
|
|
28
28
|
"sha256": "eb48d35bb101fda0e3bf122eea358c6e16ea937ac72376e6e4ede52e7828d209",
|
|
29
29
|
"license": "MIT"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/munito.js",
|
|
21
21
|
"sha256": "6feee407bd3765acb723bca995e660ee9dc8d556e51bfdff158686e3ffaf0ffe",
|
|
22
22
|
"license": "MIT"
|
package/plugins/muse/plugin.json
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"upstream": {
|
|
28
28
|
"repository": "https://github.com/steipete/CodexBar",
|
|
29
|
-
"revision": "
|
|
29
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
30
30
|
"path": "Sources/CodexBarCore/Resources/Plugins/muse.js",
|
|
31
31
|
"sha256": "85b6f9489f4e004d027cca1fe2a0a87884792d0be7aa50ef7b8df3b17902c424",
|
|
32
32
|
"license": "MIT"
|
package/plugins/museai/plugin.js
CHANGED
|
@@ -17,7 +17,8 @@ defineProvider({
|
|
|
17
17
|
if (policy === "off") throw ctx.fail.missingCredential("muse.ai cookies are disabled.");
|
|
18
18
|
const signedOut = (r) =>
|
|
19
19
|
r.status === 401 || r.status === 403 || (r.headers["location"] ?? "").startsWith("https://auth.muse.ai/");
|
|
20
|
-
|
|
20
|
+
// A redeployed muse.ai answers a stale action with 400, 404 or 409 (#5051).
|
|
21
|
+
const actionNeedsRediscovery = (r) => !signedOut(r) && [400, 404, 409].includes(r.status);
|
|
21
22
|
const discoveryFailure = () =>
|
|
22
23
|
ctx.fail.parseFailure(
|
|
23
24
|
"Could not find a working muse.ai subscription action. muse.ai may have changed. Refresh to retry.",
|
|
@@ -34,6 +35,7 @@ defineProvider({
|
|
|
34
35
|
"Sec-Fetch-Site": "same-origin",
|
|
35
36
|
"Sec-Fetch-Mode": "cors",
|
|
36
37
|
"Sec-Fetch-Dest": "empty",
|
|
38
|
+
"Content-Type": "text/plain;charset=UTF-8",
|
|
37
39
|
"User-Agent": userAgent,
|
|
38
40
|
},
|
|
39
41
|
});
|
|
@@ -84,14 +86,14 @@ defineProvider({
|
|
|
84
86
|
let actionID = ctx.storage.get("actionID");
|
|
85
87
|
const subscription = async (cookie) => {
|
|
86
88
|
const response = actionID ? await post(cookie, actionID) : undefined;
|
|
87
|
-
if (response && !
|
|
89
|
+
if (response && !actionNeedsRediscovery(response)) {
|
|
88
90
|
return signedOut(response) ? undefined : response;
|
|
89
91
|
}
|
|
90
92
|
ctx.storage.remove("actionID");
|
|
91
93
|
actionID = await discover(cookie);
|
|
92
94
|
if (!actionID) return undefined;
|
|
93
95
|
const fresh = await post(cookie, actionID);
|
|
94
|
-
if (
|
|
96
|
+
if (actionNeedsRediscovery(fresh)) throw discoveryFailure();
|
|
95
97
|
return signedOut(fresh) ? undefined : fresh;
|
|
96
98
|
};
|
|
97
99
|
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"setupFields": [],
|
|
19
19
|
"upstream": {
|
|
20
20
|
"repository": "https://github.com/steipete/CodexBar",
|
|
21
|
-
"revision": "
|
|
21
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
22
22
|
"path": "Sources/CodexBarCore/Resources/Plugins/museai.js",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "fa82f1936a5b59e16aab91d42e3c3591d3f6b50d65017557a341924095234f1d",
|
|
24
24
|
"license": "MIT"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/plugins/nous/plugin.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/nous.js",
|
|
29
29
|
"sha256": "160f5329bf4895a061d3bed74d0476283d3abad47e071fb868d667c0c5cb485e",
|
|
30
30
|
"license": "MIT"
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
const TABLES_SQL = "SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('message','session_message','credential','migration')";
|
|
16
16
|
const CREDENTIALS_IMPORTED_SQL = "SELECT 1 AS imported FROM migration WHERE id = '20260805200742_import_legacy_credentials' LIMIT 1";
|
|
17
17
|
const CREDENTIAL_SQL = `SELECT value FROM credential
|
|
18
|
-
WHERE integration_id = 'opencode-go' AND (active IS NULL OR active = 1)
|
|
19
|
-
|
|
18
|
+
WHERE (integration_id = 'opencode-go' AND (active IS NULL OR active = 1))
|
|
19
|
+
OR (integration_id = 'opencode' AND active = 1)
|
|
20
|
+
ORDER BY CASE integration_id WHEN 'opencode-go' THEN 0 ELSE 1 END, active DESC, time_updated DESC, id DESC LIMIT 1`;
|
|
20
21
|
function historySQL(tables) {
|
|
21
22
|
const sources = [];
|
|
22
23
|
if (tables.includes('session_message')) sources.push(`SELECT id, time_created, data FROM session_message
|
|
@@ -367,7 +368,7 @@
|
|
|
367
368
|
if (inline) throw {code: "credential-malformed", message: "OPENCODE_AUTH_CONTENT must contain an auth JSON object."};
|
|
368
369
|
throw {code:'credential-malformed',message:'OpenCode auth file is not valid JSON.'};
|
|
369
370
|
}
|
|
370
|
-
const entry = parsed[PROVIDER_ID];
|
|
371
|
+
const entry = parsed[PROVIDER_ID] || parsed.opencode;
|
|
371
372
|
if (!entry || typeof entry !== "object") return null;
|
|
372
373
|
const key = typeof entry.key === "string" ? entry.key.trim() : "";
|
|
373
374
|
return key || null;
|
|
@@ -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,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="100 100 385 385" fill="currentColor">
|
|
2
|
+
<path fill-rule="evenodd" d="M292.716 112.374C392.751 112.374 473.845 193.468 473.845 293.503C473.845 393.538 392.751 474.632 292.716 474.632H135.685C122.347 474.632 111.587 463.874 111.587 450.536C111.587 410.139 111.587 329.633 111.587 293.503C111.587 193.468 192.681 112.374 292.716 112.374ZM292.716 148.6C212.689 148.6 147.813 213.476 147.813 293.504C147.813 373.532 212.689 438.407 292.716 438.407C372.744 438.407 437.619 373.532 437.619 293.504C437.619 213.476 372.744 148.6 292.716 148.6Z"/>
|
|
3
|
+
<path d="M281.618 378.232L226.395 232.908C224.608 228.205 229.201 223.594 233.873 225.402L379.265 281.651C385.249 283.966 383.6 292.898 377.189 292.898H292.803V376.155C292.803 382.61 283.91 384.262 281.618 378.232Z"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
|
|
2
|
+
globalThis.__usagestat_bundled_options = {"labels":["Session","Weekly","Additional"],"defaults":{},"autoMode":"web"};
|
|
3
|
+
(function(defineProvider) {
|
|
4
|
+
// BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/opendesign.js
|
|
5
|
+
defineProvider({
|
|
6
|
+
id: "opendesign",
|
|
7
|
+
name: "OpenDesign",
|
|
8
|
+
settings: [{ key: "MESSAGES", title: "OpenDesign", type: "plain" }],
|
|
9
|
+
endpoints: ["https://amr-api.open-design.ai"],
|
|
10
|
+
capabilities: ["browser-cookies", "http-status"],
|
|
11
|
+
cookieDomains: ["amr-api.open-design.ai"],
|
|
12
|
+
cookiePolicy: {
|
|
13
|
+
selection: "request-url",
|
|
14
|
+
cache: "nonpersistent",
|
|
15
|
+
imports: "access-gated",
|
|
16
|
+
// The host's optional name filter excludes dots; validate the opaque session at the endpoint.
|
|
17
|
+
},
|
|
18
|
+
async fetchUsage(ctx) {
|
|
19
|
+
const domain = "amr-api.open-design.ai";
|
|
20
|
+
const messages = JSON.parse(ctx.settings.get("MESSAGES") || "{}");
|
|
21
|
+
const message = (key) => messages[key] || key;
|
|
22
|
+
const signIn = message("Sign in to OpenDesign, then refresh CodexBar.");
|
|
23
|
+
const expired = ctx.fail.authenticationExpired(signIn);
|
|
24
|
+
const malformed = () => {
|
|
25
|
+
throw ctx.fail.parseFailure(message("OpenDesign usage response format changed."));
|
|
26
|
+
};
|
|
27
|
+
const text = (value) => (typeof value === "string" && value.trim() ? value.trim() : undefined);
|
|
28
|
+
const credits = (value) => {
|
|
29
|
+
if (typeof value === "string" && /^\d+(\.\d+)?$/.test(value)) value = Number(value);
|
|
30
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= Number.MAX_SAFE_INTEGER
|
|
31
|
+
? value
|
|
32
|
+
: malformed();
|
|
33
|
+
};
|
|
34
|
+
if (ctx.browser.availability(domain) === "off") throw ctx.fail.missingCredential(signIn);
|
|
35
|
+
let rejected = false;
|
|
36
|
+
for await (const session of ctx.browser.sessions(domain)) {
|
|
37
|
+
const get = async (path, workspace) => {
|
|
38
|
+
const response = await ctx.http.get(`https://${domain}/api/v1/workspaces/${path}`, {
|
|
39
|
+
cookieSession: session.id,
|
|
40
|
+
headers: { Accept: "application/json", ...(workspace ? { "X-Vela-Workspace-Id": workspace } : {}) },
|
|
41
|
+
});
|
|
42
|
+
if (response.status === 401) throw expired;
|
|
43
|
+
if (response.status === 403) throw ctx.fail.permissionDenied(message("OpenDesign billing access was denied."));
|
|
44
|
+
const failed = message("OpenDesign request failed. Try again later.");
|
|
45
|
+
if (response.status === 429) throw ctx.fail.rateLimited(failed);
|
|
46
|
+
if (response.status >= 500 || response.status === 408) throw ctx.fail.providerUnavailable(failed);
|
|
47
|
+
if (response.status !== 200) throw ctx.fail.apiFailure(failed);
|
|
48
|
+
try {
|
|
49
|
+
return JSON.parse(response.bodyText);
|
|
50
|
+
} catch {
|
|
51
|
+
return malformed();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
try {
|
|
55
|
+
const workspace = await get("current");
|
|
56
|
+
const id = text(workspace?.workspaceId);
|
|
57
|
+
if (!id || !/^[A-Za-z0-9_-]{1,128}$/.test(id)) return malformed();
|
|
58
|
+
const usage = await get(`${id}/billing/coding-plan-usage`, id);
|
|
59
|
+
if (usage?.workspaceId !== id || typeof usage.eligible !== "boolean" || !Array.isArray(usage.windows))
|
|
60
|
+
return malformed();
|
|
61
|
+
const unavailable = () => {
|
|
62
|
+
throw ctx.fail.providerUnavailable(
|
|
63
|
+
message("OpenDesign subscription usage is unavailable for this workspace."),
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
if (!usage.eligible) return unavailable();
|
|
67
|
+
const window = (seconds) => {
|
|
68
|
+
const matches = usage.windows.filter((item) => item?.durationSeconds === seconds);
|
|
69
|
+
if (matches.length === 0) return undefined;
|
|
70
|
+
if (matches.length !== 1) return malformed();
|
|
71
|
+
const item = matches[0];
|
|
72
|
+
const used = credits(item.usedCredits);
|
|
73
|
+
const limit = credits(item.limitCredits);
|
|
74
|
+
if (limit <= 0) return malformed();
|
|
75
|
+
const reset = text(item.resetsAt);
|
|
76
|
+
return {
|
|
77
|
+
usedPercent: ctx.pct(used, limit),
|
|
78
|
+
windowMinutes: seconds / 60,
|
|
79
|
+
quotaLimit: limit,
|
|
80
|
+
quotaUnit: "credits",
|
|
81
|
+
resetsAt:
|
|
82
|
+
reset && /^\d{4}-\d{2}-\d{2}T/.test(reset) && Number.isFinite(Date.parse(reset)) ? reset : undefined,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
const primary = window(18000);
|
|
86
|
+
const secondary = window(604800);
|
|
87
|
+
if (!primary && !secondary) return unavailable();
|
|
88
|
+
return {
|
|
89
|
+
primary,
|
|
90
|
+
secondary,
|
|
91
|
+
identity: {
|
|
92
|
+
accountID: id,
|
|
93
|
+
organization: text(workspace.workspaceName),
|
|
94
|
+
loginMethod: text(usage.tier) ?? text(workspace.personalMembershipTier),
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (error !== expired) throw error;
|
|
99
|
+
ctx.browser.rejectCookie(domain, session);
|
|
100
|
+
rejected = true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
throw rejected ? expired : ctx.fail.missingCredential(signIn);
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// END UPSTREAM
|
|
108
|
+
})(globalThis.defineProvider);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "opendesign",
|
|
4
|
+
"name": "OpenDesign",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"enabledByDefault": false,
|
|
8
|
+
"supportedModes": [
|
|
9
|
+
"web"
|
|
10
|
+
],
|
|
11
|
+
"autoMode": "web",
|
|
12
|
+
"usageDashboardUrl": "https://open-design.ai",
|
|
13
|
+
"webUrl": "https://amr-api.open-design.ai",
|
|
14
|
+
"envVars": [
|
|
15
|
+
"OPENDESIGN_COOKIE"
|
|
16
|
+
],
|
|
17
|
+
"setupFields": [],
|
|
18
|
+
"upstream": {
|
|
19
|
+
"repository": "https://github.com/steipete/CodexBar",
|
|
20
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
21
|
+
"path": "Sources/CodexBarCore/Resources/Plugins/opendesign.js",
|
|
22
|
+
"sha256": "9eb64161b779de122e6343eb166ee6ebca6d3e828dc7e40df7a1af695f6a79d4",
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"setupFields": [],
|
|
18
18
|
"upstream": {
|
|
19
19
|
"repository": "https://github.com/steipete/CodexBar",
|
|
20
|
-
"revision": "
|
|
20
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
21
21
|
"path": "Sources/CodexBarCore/Resources/Plugins/parallel.js",
|
|
22
22
|
"sha256": "854d5faa2b6c01b96cf009295fabe85cbdc28d07911d7c7e1da970c8cc77e5e8",
|
|
23
23
|
"license": "MIT"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Robin Ebers (original macOS creator)
|
|
4
|
+
Copyright (c) 2026 barramee kottanawadee
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// Adapted from barramee27/crossusage at 78b243b798abce1270d6fed775c79e65825b2c33; see LICENSE.
|
|
1
2
|
(function () {
|
|
2
3
|
const LOCAL_USER_ENDPOINT = "https://www.perplexity.ai/api/user"
|
|
3
4
|
const REST_API_BASE = "https://www.perplexity.ai/rest/pplx-api/v2"
|
|
@@ -380,7 +381,128 @@
|
|
|
380
381
|
return { groupId: groupId, group: group, usageAnalytics: usageAnalytics, rateLimits: rateLimits }
|
|
381
382
|
}
|
|
382
383
|
|
|
384
|
+
// --- Web-session (cookie) auth -------------------------------------------
|
|
385
|
+
// The Bearer flow above only exists on macOS: it scrapes the CFURL cache of
|
|
386
|
+
// the native app. On Windows/Linux there is no Bearer token anywhere — the
|
|
387
|
+
// Electron app and the website both authenticate with next-auth cookies.
|
|
388
|
+
// So accept a pasted session cookie and talk to the same REST API the web
|
|
389
|
+
// client uses.
|
|
390
|
+
const WEB_ORIGIN = "https://www.perplexity.ai"
|
|
391
|
+
const WEB_QS = "?version=2.18&source=default"
|
|
392
|
+
const WEB_UA =
|
|
393
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"
|
|
394
|
+
|
|
395
|
+
const WEB_MODE_CATEGORIES = [
|
|
396
|
+
{ key: "pro_search", label: "Queries" },
|
|
397
|
+
{ key: "research", label: "Deep Research" },
|
|
398
|
+
{ key: "labs", label: "Labs" },
|
|
399
|
+
{ key: "agentic_research", label: "Agentic Research" },
|
|
400
|
+
]
|
|
401
|
+
|
|
402
|
+
function fetchWebJson(ctx, path) {
|
|
403
|
+
let resp
|
|
404
|
+
try {
|
|
405
|
+
resp = ctx.host.http.requestCookieSession({
|
|
406
|
+
method: "GET",
|
|
407
|
+
url: WEB_ORIGIN + path + WEB_QS,
|
|
408
|
+
headers: {
|
|
409
|
+
Accept: "application/json",
|
|
410
|
+
"User-Agent": WEB_UA,
|
|
411
|
+
Origin: WEB_ORIGIN,
|
|
412
|
+
Referer: WEB_ORIGIN + "/account/usage",
|
|
413
|
+
},
|
|
414
|
+
timeoutMs: 10000,
|
|
415
|
+
cookieSession: "configured",
|
|
416
|
+
})
|
|
417
|
+
} catch (e) {
|
|
418
|
+
ctx.host.log.warn("web request failed (" + path + "): " + String(e))
|
|
419
|
+
return null
|
|
420
|
+
}
|
|
421
|
+
if (typeof resp.bodyText === "string" && resp.bodyText.indexOf("Just a moment") !== -1) {
|
|
422
|
+
ctx.host.log.warn("cloudflare challenge on " + path + " — paste the full cookie string incl. cf_clearance")
|
|
423
|
+
return null
|
|
424
|
+
}
|
|
425
|
+
if (ctx.util.isAuthStatus(resp.status)) {
|
|
426
|
+
ctx.host.log.warn("web request unauthorized (" + path + "): status=" + String(resp.status))
|
|
427
|
+
return null
|
|
428
|
+
}
|
|
429
|
+
if (resp.status < 200 || resp.status >= 300) {
|
|
430
|
+
ctx.host.log.warn("web request status " + String(resp.status) + " (" + path + ")")
|
|
431
|
+
return null
|
|
432
|
+
}
|
|
433
|
+
const parsed = ctx.util.tryParseJson(resp.bodyText)
|
|
434
|
+
if (!parsed || typeof parsed !== "object") {
|
|
435
|
+
ctx.host.log.warn("web request returned invalid JSON (" + path + ")")
|
|
436
|
+
return null
|
|
437
|
+
}
|
|
438
|
+
return parsed
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function describeModeAvailability(mode) {
|
|
442
|
+
if (!mode || typeof mode !== "object") return null
|
|
443
|
+
const detail = mode.remaining_detail || mode.remainingDetail
|
|
444
|
+
if (detail && detail.kind === "exact") {
|
|
445
|
+
const n = Number(detail.remaining)
|
|
446
|
+
if (Number.isFinite(n)) return String(Math.max(0, Math.floor(n))) + " remaining"
|
|
447
|
+
}
|
|
448
|
+
if (mode.available === true) return "available"
|
|
449
|
+
if (mode.available === false) return "not available"
|
|
450
|
+
return null
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function probeViaCookie(ctx) {
|
|
454
|
+
ctx.host.log.info("session loaded from provider account (web cookie)")
|
|
455
|
+
|
|
456
|
+
const status = fetchWebJson(ctx, "/rest/rate-limit/status")
|
|
457
|
+
const authSession = fetchWebJson(ctx, "/api/auth/session")
|
|
458
|
+
const credits =
|
|
459
|
+
fetchWebJson(ctx, "/rest/billing/credits") ||
|
|
460
|
+
fetchWebJson(ctx, "/rest/billing/credits/computer-submit-gate")
|
|
461
|
+
|
|
462
|
+
if (!status && !authSession && !credits) {
|
|
463
|
+
throw "Session cookie rejected. Re-copy it from a logged-in perplexity.ai tab."
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const lines = []
|
|
467
|
+
|
|
468
|
+
const balanceCents = credits ? readNumberField(credits, ["balance_cents", "balanceCents"]) : null
|
|
469
|
+
if (balanceCents !== null && Number.isFinite(balanceCents)) {
|
|
470
|
+
lines.push(ctx.line.text({
|
|
471
|
+
label: "API credits",
|
|
472
|
+
value: "$" + (balanceCents / 100).toFixed(2),
|
|
473
|
+
}))
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const modes = status && (status.modes || status.Modes)
|
|
477
|
+
if (modes && typeof modes === "object") {
|
|
478
|
+
for (let i = 0; i < WEB_MODE_CATEGORIES.length; i += 1) {
|
|
479
|
+
const cat = WEB_MODE_CATEGORIES[i]
|
|
480
|
+
const text = describeModeAvailability(modes[cat.key])
|
|
481
|
+
if (text) lines.push(ctx.line.text({ label: cat.label, value: text }))
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (lines.length === 0) throw "Usage data unavailable. Try again later."
|
|
486
|
+
|
|
487
|
+
const user = authSession && authSession.user
|
|
488
|
+
const tier = user && (user.subscription_tier || user.subscriptionTier)
|
|
489
|
+
const plan =
|
|
490
|
+
typeof tier === "string" && tier
|
|
491
|
+
? tier
|
|
492
|
+
.split("_")
|
|
493
|
+
.filter(Boolean)
|
|
494
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
495
|
+
.join(" ")
|
|
496
|
+
: null
|
|
497
|
+
|
|
498
|
+
return plan ? { plan: plan, lines: lines } : { lines: lines }
|
|
499
|
+
}
|
|
500
|
+
|
|
383
501
|
function probe(ctx) {
|
|
502
|
+
if (ctx.provider?.settings?.cookies !== "off" && ctx.host.http.cookieSessionAvailable === true) {
|
|
503
|
+
return probeViaCookie(ctx)
|
|
504
|
+
}
|
|
505
|
+
|
|
384
506
|
const session = loadLocalSession(ctx)
|
|
385
507
|
if (!session) throw "Not logged in. Sign in via Perplexity app."
|
|
386
508
|
if (session.sourcePath) ctx.host.log.info("using cache db: " + session.sourcePath)
|
|
@@ -6,14 +6,43 @@
|
|
|
6
6
|
"entry": "plugin.js",
|
|
7
7
|
"icon": "icon.svg",
|
|
8
8
|
"brandColor": "#20808D",
|
|
9
|
-
"supportedModes": [
|
|
9
|
+
"supportedModes": [
|
|
10
|
+
"oauth",
|
|
11
|
+
"local",
|
|
12
|
+
"web"
|
|
13
|
+
],
|
|
10
14
|
"autoMode": "web",
|
|
11
15
|
"webUrl": "https://www.perplexity.ai",
|
|
12
16
|
"lines": [
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
{
|
|
18
|
+
"type": "progress",
|
|
19
|
+
"label": "API credits",
|
|
20
|
+
"scope": "overview",
|
|
21
|
+
"primaryOrder": 1
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "text",
|
|
25
|
+
"label": "Queries",
|
|
26
|
+
"scope": "overview"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "text",
|
|
30
|
+
"label": "Deep Research",
|
|
31
|
+
"scope": "overview"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"type": "text",
|
|
35
|
+
"label": "Labs",
|
|
36
|
+
"scope": "detail"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "text",
|
|
40
|
+
"label": "Agentic Research",
|
|
41
|
+
"scope": "detail"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"envVars": [
|
|
45
|
+
"PERPLEXITY_COOKIE"
|
|
46
|
+
],
|
|
47
|
+
"setupHelp": "Paste a Cookie header from your own perplexity.ai session for web usage. The scoped cookie is sent only to approved Perplexity read routes."
|
|
19
48
|
}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"upstreamSources": [
|
|
30
30
|
{
|
|
31
31
|
"repository": "https://github.com/steipete/CodexBar",
|
|
32
|
-
"revision": "
|
|
32
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
33
33
|
"path": "Sources/CodexBarCore/Resources/Plugins/qwencloud-team.js",
|
|
34
34
|
"sha256": "11a7e231c1705a83f29b4509102abaa656b9888f63cfc132de0a520d94ee9301",
|
|
35
35
|
"license": "MIT"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/raycast.js",
|
|
29
29
|
"sha256": "df8f6d185cb67fd9ec9b622d2321a6d4e5395576b9ab54b1725aac272c95ecb7",
|
|
30
30
|
"license": "MIT"
|