@howaboua/opencode-usage-plugin 0.1.0 → 0.1.2
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/README.md +11 -9
- package/dist/hooks/command.js +1 -1
- package/dist/providers/copilot/auth.d.ts +2 -5
- package/dist/providers/copilot/auth.d.ts.map +1 -1
- package/dist/providers/copilot/auth.js +3 -38
- package/dist/providers/copilot/index.d.ts +1 -1
- package/dist/providers/copilot/index.d.ts.map +1 -1
- package/dist/providers/copilot/index.js +23 -46
- package/dist/providers/copilot/response.d.ts.map +1 -1
- package/dist/providers/copilot/response.js +19 -10
- package/dist/providers/copilot/types.d.ts +0 -5
- package/dist/providers/copilot/types.d.ts.map +1 -1
- package/dist/providers/proxy/format.d.ts.map +1 -1
- package/dist/providers/proxy/format.js +0 -4
- package/dist/providers/proxy/index.d.ts.map +1 -1
- package/dist/providers/proxy/index.js +28 -51
- package/dist/providers/proxy/types.d.ts +0 -2
- package/dist/providers/proxy/types.d.ts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/status.d.ts.map +1 -1
- package/dist/ui/status.js +4 -5
- package/dist/usage/config.d.ts.map +1 -1
- package/dist/usage/config.js +0 -9
- package/dist/usage/fetch.d.ts.map +1 -1
- package/dist/usage/fetch.js +0 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ Track AI provider rate limits and quotas in real-time.
|
|
|
6
6
|
|
|
7
7
|
- **Live rate limits** – See Codex/OpenAI hourly/weekly limits at a glance
|
|
8
8
|
- **Proxy quota stats** – Monitor Mirrowel Proxy credentials and tier usage
|
|
9
|
+
- **Copilot usage** – Track GitHub Copilot chat + completions quotas
|
|
9
10
|
- **Inline status** – Results appear directly in your chat, no context switching
|
|
10
11
|
- **Zero setup** – Auto-detects providers from your existing config
|
|
11
12
|
|
|
@@ -18,7 +19,7 @@ Add to your `opencode.json`:
|
|
|
18
19
|
```json
|
|
19
20
|
{
|
|
20
21
|
"$schema": "https://opencode.ai/config.json",
|
|
21
|
-
"
|
|
22
|
+
"plugin": ["@howaboua/opencode-usage-plugin"]
|
|
22
23
|
}
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -37,6 +38,7 @@ OpenCode installs dependencies automatically on next launch.
|
|
|
37
38
|
```
|
|
38
39
|
/usage codex
|
|
39
40
|
/usage proxy
|
|
41
|
+
/usage copilot
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
### Support the proxy
|
|
@@ -51,6 +53,7 @@ OpenCode installs dependencies automatically on next launch.
|
|
|
51
53
|
|----------|--------|
|
|
52
54
|
| **Codex / OpenAI** | Auth tokens + `/wham/usage` endpoint |
|
|
53
55
|
| **Mirrowel Proxy** | Local `/v1/quota-stats` endpoint |
|
|
56
|
+
| **GitHub Copilot** | GitHub internal usage APIs |
|
|
54
57
|
|
|
55
58
|
## Configuration
|
|
56
59
|
|
|
@@ -70,21 +73,20 @@ Optional config at `~/.config/opencode/usage-config.jsonc`:
|
|
|
70
73
|
// Show/hide providers in /usage output
|
|
71
74
|
"providers": {
|
|
72
75
|
"openai": true,
|
|
73
|
-
"proxy": true
|
|
76
|
+
"proxy": true,
|
|
77
|
+
"copilot": true
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
80
|
```
|
|
77
81
|
|
|
78
82
|
If missing, the plugin creates a default template on first run.
|
|
79
83
|
|
|
80
|
-
|
|
84
|
+
### Copilot auth
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
# Check DB contents
|
|
84
|
-
bun run debug-db.ts
|
|
86
|
+
Copilot is detected from either of these locations:
|
|
85
87
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
- `~/.local/share/opencode/copilot-usage-token.json`
|
|
89
|
+
- `~/.local/share/opencode/auth.json` with a `github-copilot` entry
|
|
90
|
+
- `~/.config/opencode/copilot-quota-token.json` (optional override)
|
|
89
91
|
|
|
90
92
|
See `AGENTS.md` for internal architecture.
|
package/dist/hooks/command.js
CHANGED
|
@@ -33,7 +33,7 @@ export function commandHooks(options) {
|
|
|
33
33
|
const snapshots = await fetchUsageSnapshots(effectiveFilter);
|
|
34
34
|
const filteredSnapshots = snapshots.filter(s => {
|
|
35
35
|
if (targetProvider)
|
|
36
|
-
return true;
|
|
36
|
+
return true;
|
|
37
37
|
if (s.provider === "codex")
|
|
38
38
|
return options.state.availableProviders.codex;
|
|
39
39
|
if (s.provider === "proxy")
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* providers/copilot/auth.ts
|
|
3
3
|
* Provides authentication and configuration helpers for GitHub Copilot.
|
|
4
|
-
* Handles local auth token discovery and
|
|
4
|
+
* Handles local auth token discovery and standard OpenCode credentials.
|
|
5
5
|
*/
|
|
6
|
-
import { type CopilotAuthData
|
|
7
|
-
export declare function getQuotaConfigPath(): string;
|
|
8
|
-
export declare function getUsageTokenPath(): string;
|
|
6
|
+
import { type CopilotAuthData } from "./types.js";
|
|
9
7
|
export declare function readCopilotAuth(): Promise<CopilotAuthData | null>;
|
|
10
|
-
export declare function readQuotaConfig(): CopilotQuotaConfig | null;
|
|
11
8
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,wBAAsB,eAAe,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAevE"}
|
|
@@ -1,33 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* providers/copilot/auth.ts
|
|
3
3
|
* Provides authentication and configuration helpers for GitHub Copilot.
|
|
4
|
-
* Handles local auth token discovery and
|
|
4
|
+
* Handles local auth token discovery and standard OpenCode credentials.
|
|
5
5
|
*/
|
|
6
|
-
import { existsSync
|
|
6
|
+
import { existsSync } from "fs";
|
|
7
7
|
import { readFile } from "fs/promises";
|
|
8
|
-
import {
|
|
9
|
-
import { join } from "path";
|
|
10
|
-
import { getAppDataPath, getAuthFilePath } from "../../utils/paths.js";
|
|
11
|
-
export function getQuotaConfigPath() {
|
|
12
|
-
return join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "opencode", "copilot-quota-token.json");
|
|
13
|
-
}
|
|
14
|
-
export function getUsageTokenPath() {
|
|
15
|
-
return join(getAppDataPath(), "copilot-usage-token.json");
|
|
16
|
-
}
|
|
8
|
+
import { getAuthFilePath } from "../../utils/paths.js";
|
|
17
9
|
export async function readCopilotAuth() {
|
|
18
10
|
try {
|
|
19
|
-
const usagePath = getUsageTokenPath();
|
|
20
|
-
if (existsSync(usagePath)) {
|
|
21
|
-
const content = await readFile(usagePath, "utf-8");
|
|
22
|
-
const data = JSON.parse(content);
|
|
23
|
-
if (data?.token) {
|
|
24
|
-
return {
|
|
25
|
-
type: "oauth",
|
|
26
|
-
refresh: data.token,
|
|
27
|
-
access: data.token,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
11
|
const authPath = getAuthFilePath();
|
|
32
12
|
if (existsSync(authPath)) {
|
|
33
13
|
const content = await readFile(authPath, "utf-8");
|
|
@@ -43,18 +23,3 @@ export async function readCopilotAuth() {
|
|
|
43
23
|
return null;
|
|
44
24
|
}
|
|
45
25
|
}
|
|
46
|
-
export function readQuotaConfig() {
|
|
47
|
-
try {
|
|
48
|
-
const configPath = getQuotaConfigPath();
|
|
49
|
-
if (!existsSync(configPath))
|
|
50
|
-
return null;
|
|
51
|
-
const content = readFileSync(configPath, "utf-8");
|
|
52
|
-
const parsed = JSON.parse(content);
|
|
53
|
-
if (!parsed?.token || !parsed?.username || !parsed?.tier)
|
|
54
|
-
return null;
|
|
55
|
-
return parsed;
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* providers/copilot/index.ts
|
|
3
3
|
* Main entry point for the GitHub Copilot usage provider.
|
|
4
|
-
* Orchestrates token exchange and fetching from
|
|
4
|
+
* Orchestrates token exchange and fetching from the internal API.
|
|
5
5
|
*/
|
|
6
6
|
import type { UsageProvider } from "../base.js";
|
|
7
7
|
export declare const CopilotProvider: UsageProvider<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA8D/C,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,IAAI,CAuD/C,CAAA"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* providers/copilot/index.ts
|
|
3
3
|
* Main entry point for the GitHub Copilot usage provider.
|
|
4
|
-
* Orchestrates token exchange and fetching from
|
|
4
|
+
* Orchestrates token exchange and fetching from the internal API.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { toCopilotQuotaFromBilling, toCopilotQuotaFromInternal, } from "./response.js";
|
|
6
|
+
import { readCopilotAuth } from "./auth.js";
|
|
7
|
+
import { toCopilotQuotaFromInternal, } from "./response.js";
|
|
9
8
|
const GITHUB_API_BASE_URL = "https://api.github.com";
|
|
10
9
|
const COPILOT_INTERNAL_USER_URL = `${GITHUB_API_BASE_URL}/copilot_internal/user`;
|
|
11
10
|
const COPILOT_TOKEN_EXCHANGE_URL = `${GITHUB_API_BASE_URL}/copilot_internal/v2/token`;
|
|
@@ -57,57 +56,35 @@ export const CopilotProvider = {
|
|
|
57
56
|
async fetchUsage() {
|
|
58
57
|
const now = Date.now();
|
|
59
58
|
let quota = null;
|
|
60
|
-
const
|
|
61
|
-
|
|
59
|
+
const auth = await readCopilotAuth();
|
|
60
|
+
const oauthToken = auth?.refresh || auth?.access;
|
|
61
|
+
if (oauthToken) {
|
|
62
62
|
try {
|
|
63
|
-
|
|
63
|
+
let resp = await fetchWithTimeout(COPILOT_INTERNAL_USER_URL, {
|
|
64
64
|
headers: {
|
|
65
|
-
Accept: "application/
|
|
66
|
-
Authorization: `
|
|
67
|
-
|
|
65
|
+
Accept: "application/json",
|
|
66
|
+
Authorization: `token ${oauthToken}`,
|
|
67
|
+
...COPILOT_HEADERS,
|
|
68
68
|
},
|
|
69
69
|
});
|
|
70
|
+
if (!resp.ok) {
|
|
71
|
+
const copilotToken = await exchangeForCopilotToken(oauthToken);
|
|
72
|
+
if (copilotToken) {
|
|
73
|
+
resp = await fetchWithTimeout(COPILOT_INTERNAL_USER_URL, {
|
|
74
|
+
headers: {
|
|
75
|
+
Accept: "application/json",
|
|
76
|
+
Authorization: `Bearer ${copilotToken}`,
|
|
77
|
+
...COPILOT_HEADERS,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
70
82
|
if (resp.ok) {
|
|
71
83
|
const data = (await resp.json());
|
|
72
|
-
quota =
|
|
84
|
+
quota = toCopilotQuotaFromInternal(data);
|
|
73
85
|
}
|
|
74
86
|
}
|
|
75
87
|
catch {
|
|
76
|
-
// Fallback to internal API
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
if (!quota) {
|
|
80
|
-
const auth = await readCopilotAuth();
|
|
81
|
-
const oauthToken = auth?.refresh || auth?.access;
|
|
82
|
-
if (oauthToken) {
|
|
83
|
-
try {
|
|
84
|
-
let resp = await fetchWithTimeout(COPILOT_INTERNAL_USER_URL, {
|
|
85
|
-
headers: {
|
|
86
|
-
Accept: "application/json",
|
|
87
|
-
Authorization: `token ${oauthToken}`,
|
|
88
|
-
...COPILOT_HEADERS,
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
if (!resp.ok) {
|
|
92
|
-
const copilotToken = await exchangeForCopilotToken(oauthToken);
|
|
93
|
-
if (copilotToken) {
|
|
94
|
-
resp = await fetchWithTimeout(COPILOT_INTERNAL_USER_URL, {
|
|
95
|
-
headers: {
|
|
96
|
-
Accept: "application/json",
|
|
97
|
-
Authorization: `Bearer ${copilotToken}`,
|
|
98
|
-
...COPILOT_HEADERS,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (resp.ok) {
|
|
104
|
-
const data = (await resp.json());
|
|
105
|
-
quota = toCopilotQuotaFromInternal(data);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
// Ignore
|
|
110
|
-
}
|
|
111
88
|
}
|
|
112
89
|
}
|
|
113
90
|
if (!quota)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/response.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAElD,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,CAAC,EAAE;QACpB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE;QAChB,oBAAoB,CAAC,EAAE;YACrB,WAAW,EAAE,MAAM,CAAA;YACnB,iBAAiB,EAAE,MAAM,CAAA;YACzB,SAAS,EAAE,MAAM,CAAA;YACjB,SAAS,EAAE,OAAO,CAAA;SACnB,CAAA;KACF,CAAA;IACD,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,gBAAgB,EAAE,CAAA;CAC/B;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,2BAA2B,GAAG,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/response.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAElD,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,CAAC,EAAE;QACpB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE;QAChB,oBAAoB,CAAC,EAAE;YACrB,WAAW,EAAE,MAAM,CAAA;YACnB,iBAAiB,EAAE,MAAM,CAAA;YACzB,SAAS,EAAE,MAAM,CAAA;YACjB,SAAS,EAAE,OAAO,CAAA;SACnB,CAAA;KACF,CAAA;IACD,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,gBAAgB,EAAE,CAAA;CAC/B;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,2BAA2B,GAAG,YAAY,GAAG,IAAI,CA4CjG;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,oBAAoB,EAC1B,KAAK,EAAE,MAAM,GACZ,YAAY,CAed"}
|
|
@@ -4,27 +4,36 @@
|
|
|
4
4
|
* Handles both public billing and internal user API shapes.
|
|
5
5
|
*/
|
|
6
6
|
export function toCopilotQuotaFromInternal(data) {
|
|
7
|
-
// Handle "limited" user format (Free/Pro limited)
|
|
8
7
|
if (data.limited_user_quotas) {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
8
|
+
const chatRemainingRaw = data.limited_user_quotas.chat ?? 0;
|
|
9
|
+
const chatTotalRaw = data.monthly_quotas?.chat ?? 0;
|
|
10
|
+
const chatScale = chatTotalRaw === 500 ? 10 : 1;
|
|
11
|
+
const chatRemaining = Math.floor(chatRemainingRaw / chatScale);
|
|
12
|
+
const chatTotal = Math.floor(chatTotalRaw / chatScale);
|
|
13
|
+
const completionsRemainingRaw = data.limited_user_quotas.completions ?? 0;
|
|
14
|
+
const completionsTotalRaw = data.monthly_quotas?.completions ?? 2000;
|
|
15
|
+
const compScale = completionsTotalRaw === 4000 ? 2 : 1;
|
|
16
|
+
const completionsRemaining = Math.floor(completionsRemainingRaw / compScale);
|
|
17
|
+
const completionsTotal = Math.floor(completionsTotalRaw / compScale);
|
|
13
18
|
return {
|
|
14
|
-
used:
|
|
19
|
+
used: chatRemaining,
|
|
15
20
|
total: chatTotal,
|
|
16
21
|
percentRemaining: chatTotal > 0 ? Math.round((chatRemaining / chatTotal) * 100) : 0,
|
|
17
22
|
resetTime: data.limited_user_reset_date || data.quota_reset_date,
|
|
18
|
-
completionsUsed:
|
|
23
|
+
completionsUsed: completionsRemaining,
|
|
19
24
|
completionsTotal: completionsTotal,
|
|
20
25
|
};
|
|
21
26
|
}
|
|
22
|
-
// Handle standard format
|
|
23
27
|
if (data.quota_snapshots?.premium_interactions) {
|
|
24
28
|
const premium = data.quota_snapshots.premium_interactions;
|
|
29
|
+
const totalRaw = premium.unlimited ? -1 : premium.entitlement;
|
|
30
|
+
const remainingRaw = premium.remaining;
|
|
31
|
+
const scaleFactor = totalRaw === 500 ? 10 : 1;
|
|
32
|
+
const chatRemaining = totalRaw === -1 ? -1 : Math.floor(remainingRaw / scaleFactor);
|
|
33
|
+
const chatTotal = totalRaw === -1 ? -1 : Math.floor(totalRaw / scaleFactor);
|
|
25
34
|
return {
|
|
26
|
-
used:
|
|
27
|
-
total:
|
|
35
|
+
used: chatRemaining,
|
|
36
|
+
total: chatTotal,
|
|
28
37
|
percentRemaining: Math.round(premium.percent_remaining),
|
|
29
38
|
resetTime: data.quota_reset_date,
|
|
30
39
|
};
|
|
@@ -4,11 +4,6 @@
|
|
|
4
4
|
* Includes auth data shapes and plan limit configurations.
|
|
5
5
|
*/
|
|
6
6
|
export type CopilotTier = "free" | "pro" | "pro+" | "business" | "enterprise";
|
|
7
|
-
export interface CopilotQuotaConfig {
|
|
8
|
-
token: string;
|
|
9
|
-
username: string;
|
|
10
|
-
tier: CopilotTier;
|
|
11
|
-
}
|
|
12
7
|
export interface CopilotAuthData {
|
|
13
8
|
type: string;
|
|
14
9
|
refresh?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAA;AAE7E,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/copilot/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAA;AAE7E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAM3D,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,SAAS,CAAA;AAoHxE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAoC7D"}
|
|
@@ -12,7 +12,6 @@ const GROUP_MAPPING = {
|
|
|
12
12
|
"25-flash": "25-flash",
|
|
13
13
|
"25-lite": "25-lite"
|
|
14
14
|
};
|
|
15
|
-
// Display name ordering priority
|
|
16
15
|
const GROUP_ORDER = ["claude", "g3-pro", "g3-flash", "25-flash", "25-lite"];
|
|
17
16
|
function sortGroupNames(groups) {
|
|
18
17
|
return Array.from(groups.keys()).sort((a, b) => {
|
|
@@ -72,10 +71,8 @@ function aggregateCredentialsByTier(credentials) {
|
|
|
72
71
|
if (!(name in GROUP_MAPPING))
|
|
73
72
|
continue;
|
|
74
73
|
const mappedName = GROUP_MAPPING[name];
|
|
75
|
-
// Find the best window from group_usage
|
|
76
74
|
const windows = groupData.windows || {};
|
|
77
75
|
let bestWindow = null;
|
|
78
|
-
// Priority order for windows
|
|
79
76
|
const windowPriority = ["daily", "5h", "1h", "15m"];
|
|
80
77
|
for (const windowName of windowPriority) {
|
|
81
78
|
if (windows[windowName]) {
|
|
@@ -83,7 +80,6 @@ function aggregateCredentialsByTier(credentials) {
|
|
|
83
80
|
break;
|
|
84
81
|
}
|
|
85
82
|
}
|
|
86
|
-
// Fallback to any available window
|
|
87
83
|
if (!bestWindow && Object.keys(windows).length > 0) {
|
|
88
84
|
bestWindow = Object.values(windows)[0];
|
|
89
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAM5C,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAM5C,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAyI5C,eAAO,MAAM,aAAa,EAAE,aAwB3B,CAAA"}
|
|
@@ -17,34 +17,28 @@ const GROUP_MAPPING = {
|
|
|
17
17
|
"25-flash": "25-flash",
|
|
18
18
|
"25-lite": "25-lite"
|
|
19
19
|
};
|
|
20
|
-
// Display name ordering priority
|
|
21
20
|
const GROUP_ORDER = ["claude", "g3-pro", "g3-flash", "25-flash", "25-lite"];
|
|
22
21
|
function sortQuotaGroups(groups) {
|
|
23
22
|
return groups.sort((a, b) => {
|
|
24
23
|
const aIndex = GROUP_ORDER.indexOf(a.name);
|
|
25
24
|
const bIndex = GROUP_ORDER.indexOf(b.name);
|
|
26
|
-
// Both in priority list: sort by index
|
|
27
25
|
if (aIndex !== -1 && bIndex !== -1)
|
|
28
26
|
return aIndex - bIndex;
|
|
29
|
-
// Only a in priority list: a comes first
|
|
30
27
|
if (aIndex !== -1)
|
|
31
28
|
return -1;
|
|
32
|
-
// Only b in priority list: b comes first
|
|
33
29
|
if (bIndex !== -1)
|
|
34
30
|
return 1;
|
|
35
|
-
// Neither in priority list: alphabetical
|
|
36
31
|
return a.name.localeCompare(b.name);
|
|
37
32
|
});
|
|
38
33
|
}
|
|
39
34
|
function normalizeTier(tier) {
|
|
40
35
|
if (!tier)
|
|
41
36
|
return "free";
|
|
42
|
-
|
|
37
|
+
const t = tier.toLowerCase();
|
|
38
|
+
if (t === "paid" || t === "pro" || t === "premium" || t === "individual" || t.includes("paid"))
|
|
39
|
+
return "paid";
|
|
40
|
+
return "free";
|
|
43
41
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Extract quota groups from group_usage data
|
|
46
|
-
* New API structure: group_usage[groupName].windows[windowName]
|
|
47
|
-
*/
|
|
48
42
|
function parseQuotaGroupsFromCredential(groupUsage) {
|
|
49
43
|
if (!groupUsage)
|
|
50
44
|
return [];
|
|
@@ -53,10 +47,8 @@ function parseQuotaGroupsFromCredential(groupUsage) {
|
|
|
53
47
|
const mappedName = GROUP_MAPPING[groupName];
|
|
54
48
|
if (!mappedName)
|
|
55
49
|
continue;
|
|
56
|
-
// Find the window with the best data (prefer daily, then 5h, then any)
|
|
57
50
|
const windows = groupData.windows || {};
|
|
58
51
|
let bestWindow = null;
|
|
59
|
-
// Priority order for windows
|
|
60
52
|
const windowPriority = ["daily", "5h", "1h", "15m"];
|
|
61
53
|
for (const windowName of windowPriority) {
|
|
62
54
|
if (windows[windowName]) {
|
|
@@ -64,55 +56,42 @@ function parseQuotaGroupsFromCredential(groupUsage) {
|
|
|
64
56
|
break;
|
|
65
57
|
}
|
|
66
58
|
}
|
|
67
|
-
// Fallback to any available window
|
|
68
59
|
if (!bestWindow && Object.keys(windows).length > 0) {
|
|
69
60
|
bestWindow = Object.values(windows)[0];
|
|
70
61
|
}
|
|
71
62
|
if (!bestWindow)
|
|
72
63
|
continue;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (!existing.resetTime || new Date(newResetTime) > new Date(existing.resetTime)) {
|
|
81
|
-
existing.resetTime = newResetTime;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
result.set(mappedName, {
|
|
87
|
-
name: mappedName,
|
|
88
|
-
remaining: bestWindow.remaining,
|
|
89
|
-
max: bestWindow.limit || bestWindow.remaining,
|
|
90
|
-
remainingPct: bestWindow.limit ? Math.round((bestWindow.remaining / bestWindow.limit) * 100) : 0,
|
|
91
|
-
resetTime: bestWindow.reset_at ? new Date(bestWindow.reset_at * 1000).toISOString() : null,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
64
|
+
result.set(mappedName, {
|
|
65
|
+
name: mappedName,
|
|
66
|
+
remaining: bestWindow.remaining,
|
|
67
|
+
max: bestWindow.limit || bestWindow.remaining,
|
|
68
|
+
remainingPct: bestWindow.limit ? Math.round((bestWindow.remaining / bestWindow.limit) * 100) : 0,
|
|
69
|
+
resetTime: bestWindow.reset_at ? new Date(bestWindow.reset_at * 1000).toISOString() : null,
|
|
70
|
+
});
|
|
94
71
|
}
|
|
95
72
|
return Array.from(result.values());
|
|
96
73
|
}
|
|
97
|
-
function
|
|
74
|
+
function aggregateByProvider(provider) {
|
|
98
75
|
const tiers = {
|
|
99
76
|
paid: new Map(),
|
|
100
77
|
free: new Map(),
|
|
101
78
|
};
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
existing
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
existing.resetTime
|
|
79
|
+
if (provider.credentials) {
|
|
80
|
+
for (const cred of Object.values(provider.credentials)) {
|
|
81
|
+
const tier = normalizeTier(cred.tier);
|
|
82
|
+
const groups = parseQuotaGroupsFromCredential(cred.group_usage);
|
|
83
|
+
for (const group of groups) {
|
|
84
|
+
const existing = tiers[tier].get(group.name);
|
|
85
|
+
if (existing) {
|
|
86
|
+
existing.remaining += group.remaining;
|
|
87
|
+
existing.max += group.max;
|
|
88
|
+
if (group.resetTime && (!existing.resetTime || new Date(group.resetTime) > new Date(existing.resetTime))) {
|
|
89
|
+
existing.resetTime = group.resetTime;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
tiers[tier].set(group.name, { ...group });
|
|
112
94
|
}
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
tiers[tier].set(group.name, { ...group });
|
|
116
95
|
}
|
|
117
96
|
}
|
|
118
97
|
}
|
|
@@ -134,11 +113,9 @@ function parseProviders(data) {
|
|
|
134
113
|
if (!data.providers)
|
|
135
114
|
return [];
|
|
136
115
|
return Object.entries(data.providers).map(([name, provider]) => {
|
|
137
|
-
// Convert credentials object to array
|
|
138
|
-
const credentialsArray = Object.values(provider.credentials || {});
|
|
139
116
|
return {
|
|
140
117
|
name,
|
|
141
|
-
tiers:
|
|
118
|
+
tiers: aggregateByProvider(provider),
|
|
142
119
|
};
|
|
143
120
|
});
|
|
144
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,SAAS,0IAcZ,CAAA;AAEV,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAEjD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,WAAW,EAAE,eAAe,EAAE,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,iBAAiB,EAAE,CAAA;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;CACF;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAA;IAC/B,SAAS,EAAE,eAAe,GAAG,IAAI,CAAA;IACjC,UAAU,EAAE,eAAe,GAAG,IAAI,CAAA;IAClC,OAAO,EAAE,eAAe,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/ui/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,KAAK,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAExC,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/ui/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,KAAK,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAExC,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,CAqChB;AAyID,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BhB"}
|
package/dist/ui/status.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Renders usage snapshots into readable status text.
|
|
3
3
|
*/
|
|
4
4
|
export async function sendStatusMessage(options) {
|
|
5
|
-
// 1. Send to Companion via Bus
|
|
6
5
|
// @ts-ignore
|
|
7
6
|
const bus = options.client.bus;
|
|
8
7
|
if (bus) {
|
|
@@ -18,7 +17,6 @@ export async function sendStatusMessage(options) {
|
|
|
18
17
|
}
|
|
19
18
|
catch { }
|
|
20
19
|
}
|
|
21
|
-
// 2. Send plain message to TUI
|
|
22
20
|
await options.client.session
|
|
23
21
|
.prompt({
|
|
24
22
|
path: { id: options.sessionID },
|
|
@@ -34,7 +32,6 @@ export async function sendStatusMessage(options) {
|
|
|
34
32
|
},
|
|
35
33
|
})
|
|
36
34
|
.catch(async () => {
|
|
37
|
-
// 3. Fallback: Toast
|
|
38
35
|
await options.client.tui
|
|
39
36
|
.showToast({
|
|
40
37
|
body: { title: "Usage Status", message: options.text, variant: "info" },
|
|
@@ -111,11 +108,13 @@ function formatCopilotSnapshot(snapshot) {
|
|
|
111
108
|
const resetSuffix = copilot.resetTime ? formatResetSuffixISO(copilot.resetTime) : "";
|
|
112
109
|
const totalLabel = copilot.total === -1 ? "∞" : copilot.total.toString();
|
|
113
110
|
const chatLabel = "Chat:".padEnd(13);
|
|
114
|
-
|
|
111
|
+
const chatRemaining = copilot.used;
|
|
112
|
+
const chatPct = copilot.percentRemaining;
|
|
113
|
+
lines.push(` ${chatLabel} ${formatBar(chatPct)} ${chatRemaining}/${totalLabel}${resetSuffix}`);
|
|
115
114
|
if (copilot.completionsUsed !== undefined && copilot.completionsTotal !== undefined) {
|
|
116
115
|
const compLabel = "Completions:".padEnd(13);
|
|
117
116
|
const compPct = copilot.completionsTotal > 0
|
|
118
|
-
? Math.round((
|
|
117
|
+
? Math.round((copilot.completionsUsed / copilot.completionsTotal) * 100)
|
|
119
118
|
: 0;
|
|
120
119
|
lines.push(` ${compLabel} ${formatBar(compPct)} ${copilot.completionsUsed}/${copilot.completionsTotal}`);
|
|
121
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/usage/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAI3C,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/usage/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAI3C,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CA6C5D"}
|
package/dist/usage/config.js
CHANGED
|
@@ -11,16 +11,9 @@ export async function loadUsageConfig() {
|
|
|
11
11
|
* Usage Plugin Configuration
|
|
12
12
|
*/
|
|
13
13
|
{
|
|
14
|
-
// Proxy endpoint (e.g. http://localhost:8000)
|
|
15
14
|
"endpoint": "",
|
|
16
|
-
|
|
17
|
-
// API key for authentication
|
|
18
15
|
"apiKey": "",
|
|
19
|
-
|
|
20
|
-
// Request timeout in milliseconds
|
|
21
16
|
"timeout": 10000,
|
|
22
|
-
|
|
23
|
-
// Provider visibility
|
|
24
17
|
"providers": {
|
|
25
18
|
"openai": true,
|
|
26
19
|
"proxy": true,
|
|
@@ -42,9 +35,7 @@ export async function loadUsageConfig() {
|
|
|
42
35
|
}
|
|
43
36
|
try {
|
|
44
37
|
const content = await file.text();
|
|
45
|
-
// Remove comments first (both // and /* */)
|
|
46
38
|
const withoutComments = content.replace(/(\".*?\"|\'.*?\')|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g1) => g1 ?? "");
|
|
47
|
-
// Remove trailing commas before closing brackets/braces
|
|
48
39
|
const cleanJson = withoutComments.replace(/,(\s*[}\]])/g, "$1");
|
|
49
40
|
const config = JSON.parse(cleanJson);
|
|
50
41
|
return config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/usage/fetch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAI7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAe5C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAWlD,CAAA;AAED,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIzE;AAED,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/usage/fetch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAI7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAe5C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAWlD,CAAA;AAED,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIzE;AAED,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA2CnF;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,CASrD"}
|
package/dist/usage/fetch.js
CHANGED
|
@@ -51,7 +51,6 @@ export async function fetchUsageSnapshots(filter) {
|
|
|
51
51
|
const auths = await loadAuths();
|
|
52
52
|
const entries = resolveProviderAuths(auths, null);
|
|
53
53
|
const snapshots = [];
|
|
54
|
-
// Fetch from auth-based providers
|
|
55
54
|
const fetches = entries
|
|
56
55
|
.filter((entry) => !targetProvider || entry.providerID === targetProvider)
|
|
57
56
|
.filter((entry) => isProviderEnabled(entry.providerID))
|
|
@@ -63,7 +62,6 @@ export async function fetchUsageSnapshots(filter) {
|
|
|
63
62
|
if (snapshot)
|
|
64
63
|
snapshots.push(snapshot);
|
|
65
64
|
});
|
|
66
|
-
// Always include special providers (no auth entries needed) if no filter or filter matches
|
|
67
65
|
const specialProviders = ["proxy", "copilot"];
|
|
68
66
|
for (const id of specialProviders) {
|
|
69
67
|
if ((!targetProvider || targetProvider === id) && isProviderEnabled(id)) {
|