@ogulcancelik/pi-minimal-footer 0.1.8 → 0.1.10
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 +1 -1
- package/index.ts +31 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Minimal footer for [pi](https://github.com/earendil-works/pi) that replaces the
|
|
|
21
21
|
| OpenAI Codex | Primary + secondary rolling windows |
|
|
22
22
|
| GitHub Copilot | Premium interactions + chat quotas |
|
|
23
23
|
| Google Gemini | Pro + Flash remaining quotas |
|
|
24
|
-
| MiniMax | 5h + weekly rolling windows (Token Plan
|
|
24
|
+
| MiniMax | 5h + weekly rolling windows (Token Plan, credit-based) |
|
|
25
25
|
| MiniMax CN | Same as MiniMax, China endpoint |
|
|
26
26
|
| Kimi Coding | 5h + weekly rolling windows (Plan) |
|
|
27
27
|
|
package/index.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Custom footer with context gauge + subscription usage bars.
|
|
5
5
|
* Auto-detects provider from current model and shows relevant usage.
|
|
6
6
|
*
|
|
7
|
-
* Supports: Claude Max, Codex, Copilot, Gemini
|
|
7
|
+
* Supports: Claude Max, Codex, Copilot, Gemini, MiniMax Token Plan, Kimi Coding
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
@@ -544,10 +544,12 @@ async function fetchGeminiUsage(): Promise<UsageSnapshot> {
|
|
|
544
544
|
async function fetchMinimaxUsage(provider: "minimax" | "minimax-cn"): Promise<UsageSnapshot> {
|
|
545
545
|
const token = getMinimaxToken(provider);
|
|
546
546
|
const providerLabel = provider === "minimax-cn" ? "MiniMax CN" : "MiniMax";
|
|
547
|
+
// Docs-recommended Token Plan endpoint. The legacy /coding_plan/remains path
|
|
548
|
+
// still works but the response field names differ from the current UI.
|
|
547
549
|
const endpoint =
|
|
548
550
|
provider === "minimax-cn"
|
|
549
|
-
? "https://api.minimaxi.com/v1/
|
|
550
|
-
: "https://api.minimax.io/v1/
|
|
551
|
+
? "https://api.minimaxi.com/v1/token_plan/remains"
|
|
552
|
+
: "https://api.minimax.io/v1/token_plan/remains";
|
|
551
553
|
|
|
552
554
|
if (!token) {
|
|
553
555
|
return { provider: providerLabel, windows: [], error: "no-auth", fetchedAt: Date.now() };
|
|
@@ -578,9 +580,16 @@ async function fetchMinimaxUsage(provider: "minimax" | "minimax-cn"): Promise<Us
|
|
|
578
580
|
}
|
|
579
581
|
|
|
580
582
|
const remains = Array.isArray(data?.model_remains) ? data.model_remains : [];
|
|
583
|
+
// Token Plan returns one bucket per capability (general = text/code, video, etc.).
|
|
584
|
+
// Prefer the active "general" bucket since M-series chat models land there.
|
|
585
|
+
// status === 1 = window is active/limiting, 3 = inactive (no usage). Fall back
|
|
586
|
+
// to the first active bucket, then the first bucket of any kind.
|
|
581
587
|
const textBucket =
|
|
582
|
-
remains.find(
|
|
583
|
-
|
|
588
|
+
remains.find(
|
|
589
|
+
(entry: any) => entry?.model_name === "general" && Number(entry?.current_interval_status) === 1
|
|
590
|
+
) ||
|
|
591
|
+
remains.find((entry: any) => entry?.model_name === "general") ||
|
|
592
|
+
remains.find((entry: any) => Number(entry?.current_interval_status) === 1) ||
|
|
584
593
|
remains[0];
|
|
585
594
|
|
|
586
595
|
if (!textBucket) {
|
|
@@ -589,12 +598,12 @@ async function fetchMinimaxUsage(provider: "minimax" | "minimax-cn"): Promise<Us
|
|
|
589
598
|
|
|
590
599
|
const windows: RateWindow[] = [];
|
|
591
600
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const usedPercent = clampPercent(
|
|
601
|
+
// Source of truth: *_remaining_percent (the *_total_count / *_usage_count
|
|
602
|
+
// fields are zeroed in the credit-based model and cannot be used to compute
|
|
603
|
+
// a fraction). The UI usage bar maps 100 - remainingPercent -> used.
|
|
604
|
+
const intervalRemaining = Number(textBucket.current_interval_remaining_percent);
|
|
605
|
+
if (Number.isFinite(intervalRemaining)) {
|
|
606
|
+
const usedPercent = clampPercent(100 - intervalRemaining);
|
|
598
607
|
const resetDate = textBucket.end_time ? new Date(Number(textBucket.end_time)) : undefined;
|
|
599
608
|
const durationMs =
|
|
600
609
|
textBucket.start_time && textBucket.end_time
|
|
@@ -607,13 +616,12 @@ async function fetchMinimaxUsage(provider: "minimax" | "minimax-cn"): Promise<Us
|
|
|
607
616
|
});
|
|
608
617
|
}
|
|
609
618
|
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const resetDate = textBucket.weekly_end_time ? new Date(Number(textBucket.weekly_end_time)) : undefined;
|
|
619
|
+
const weeklyRemaining = Number(textBucket.current_weekly_remaining_percent);
|
|
620
|
+
if (Number.isFinite(weeklyRemaining)) {
|
|
621
|
+
const usedPercent = clampPercent(100 - weeklyRemaining);
|
|
622
|
+
const resetDate = textBucket.weekly_end_time
|
|
623
|
+
? new Date(Number(textBucket.weekly_end_time))
|
|
624
|
+
: undefined;
|
|
617
625
|
const durationMs =
|
|
618
626
|
textBucket.weekly_start_time && textBucket.weekly_end_time
|
|
619
627
|
? Number(textBucket.weekly_end_time) - Number(textBucket.weekly_start_time)
|
|
@@ -625,6 +633,10 @@ async function fetchMinimaxUsage(provider: "minimax" | "minimax-cn"): Promise<Us
|
|
|
625
633
|
});
|
|
626
634
|
}
|
|
627
635
|
|
|
636
|
+
if (windows.length === 0) {
|
|
637
|
+
return { provider: providerLabel, windows: [], error: "no-usage-data", fetchedAt: Date.now() };
|
|
638
|
+
}
|
|
639
|
+
|
|
628
640
|
return { provider: providerLabel, windows, fetchedAt: Date.now() };
|
|
629
641
|
} catch (e) {
|
|
630
642
|
return { provider: providerLabel, windows: [], error: String(e), fetchedAt: Date.now() };
|
|
@@ -1000,7 +1012,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1000
1012
|
const { percentage, used: ctxUsed, total: ctxTotal } = getContextInfo(ctx);
|
|
1001
1013
|
|
|
1002
1014
|
// Build parts for status line
|
|
1003
|
-
let pwd =
|
|
1015
|
+
let pwd = ctx.cwd;
|
|
1004
1016
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
1005
1017
|
if (home && pwd.startsWith(home)) {
|
|
1006
1018
|
pwd = `~${pwd.slice(home.length)}`;
|