@ogulcancelik/pi-minimal-footer 0.1.10 → 0.1.12

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.
Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/index.ts +65 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -24,6 +24,7 @@ Minimal footer for [pi](https://github.com/earendil-works/pi) that replaces the
24
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
+ | OpenCode Go | 5h + weekly + monthly usage windows |
27
28
 
28
29
  ## Install
29
30
 
@@ -39,6 +40,7 @@ Environment variables (all optional):
39
40
  | ------------------------------- | -------------------------------------------------------- | ------- |
40
41
  | `PI_MINIMAL_FOOTER_SHOW_CWD` | Show current working directory in footer status line | `1` |
41
42
  | `PI_MINIMAL_FOOTER_SHOW_BRANCH` | Show git branch/dirty/ahead/behind in footer status line | `1` |
43
+ | `PI_MINIMAL_FOOTER_SHOW_PROVIDER` | Show provider/full-model-id instead of the short model ID | `0` |
42
44
 
43
45
  Accepted false values: `0`, `false`, `no`, `off` (case-insensitive).
44
46
 
package/index.ts CHANGED
@@ -267,6 +267,10 @@ function getKimiToken(): string | undefined {
267
267
  return getApiKey("kimi-coding", "KIMI_API_KEY");
268
268
  }
269
269
 
270
+ function getOpencodeToken(): string | undefined {
271
+ return getApiKey("opencode-go", "OPENCODE_API_KEY");
272
+ }
273
+
270
274
  // ============ Time Formatting ============
271
275
 
272
276
  function formatResetTime(date: Date): string {
@@ -706,6 +710,58 @@ async function fetchKimiUsage(): Promise<UsageSnapshot> {
706
710
  }
707
711
  }
708
712
 
713
+ async function fetchOpencodeGoUsage(): Promise<UsageSnapshot> {
714
+ const providerLabel = "OpenCode Go";
715
+ const token = getOpencodeToken();
716
+ if (!token) {
717
+ return { provider: providerLabel, windows: [], error: "no-auth", fetchedAt: Date.now() };
718
+ }
719
+
720
+ try {
721
+ const res = await fetchWithTimeout("https://opencode.ai/zen/go/v1/usage", {
722
+ method: "GET",
723
+ headers: {
724
+ Authorization: `Bearer ${token}`,
725
+ },
726
+ });
727
+
728
+ if (!res.ok) {
729
+ return { provider: providerLabel, windows: [], error: `HTTP ${res.status}`, fetchedAt: Date.now() };
730
+ }
731
+
732
+ const data = (await res.json()) as any;
733
+ const windows: RateWindow[] = [];
734
+
735
+ if (data.rollingUsage) {
736
+ const usedPercent = clampPercent(data.rollingUsage.usagePercent ?? 0);
737
+ const resetsIn = Number.isFinite(data.rollingUsage.resetInSec)
738
+ ? formatResetTime(new Date(Date.now() + data.rollingUsage.resetInSec * 1000))
739
+ : undefined;
740
+ windows.push({ label: "5h", usedPercent, resetsIn });
741
+ }
742
+
743
+ if (data.weeklyUsage) {
744
+ const usedPercent = clampPercent(data.weeklyUsage.usagePercent ?? 0);
745
+ const resetsIn = Number.isFinite(data.weeklyUsage.resetInSec)
746
+ ? formatResetTime(new Date(Date.now() + data.weeklyUsage.resetInSec * 1000))
747
+ : undefined;
748
+ windows.push({ label: "Week", usedPercent, resetsIn });
749
+ }
750
+
751
+ if (data.monthlyUsage) {
752
+ const usedPercent = clampPercent(data.monthlyUsage.usagePercent ?? 0);
753
+ const resetsIn = Number.isFinite(data.monthlyUsage.resetInSec)
754
+ ? formatResetTime(new Date(Date.now() + data.monthlyUsage.resetInSec * 1000))
755
+ : undefined;
756
+ windows.push({ label: "Month", usedPercent, resetsIn });
757
+ }
758
+
759
+ return { provider: providerLabel, windows, fetchedAt: Date.now() };
760
+ } catch (e) {
761
+ return { provider: providerLabel, windows: [], error: String(e), fetchedAt: Date.now() };
762
+ }
763
+ }
764
+
709
765
  // ============ Provider Detection ============
710
766
 
711
767
  // Map pi provider names to our internal usage provider keys
@@ -717,6 +773,7 @@ const PROVIDER_MAP: Record<string, string> = {
717
773
  minimax: "minimax", // MiniMax Token Plan / Coding Plan
718
774
  "minimax-cn": "minimax-cn", // MiniMax China plan
719
775
  "kimi-coding": "kimi-coding", // Kimi plan
776
+ "opencode-go": "opencode-go", // OpenCode Go plan
720
777
  };
721
778
 
722
779
  function detectProvider(modelProvider: string): string | null {
@@ -739,6 +796,8 @@ async function fetchUsageForProvider(provider: string): Promise<UsageSnapshot> {
739
796
  return fetchMinimaxUsage("minimax-cn");
740
797
  case "kimi-coding":
741
798
  return fetchKimiUsage();
799
+ case "opencode-go":
800
+ return fetchOpencodeGoUsage();
742
801
  default:
743
802
  return { provider: "Unknown", windows: [], error: "unknown-provider", fetchedAt: Date.now() };
744
803
  }
@@ -756,6 +815,7 @@ export default function (pi: ExtensionAPI) {
756
815
  // Optional visibility toggles (default: enabled)
757
816
  const showCwd = parseBooleanEnv(process.env.PI_MINIMAL_FOOTER_SHOW_CWD, true);
758
817
  const showBranch = parseBooleanEnv(process.env.PI_MINIMAL_FOOTER_SHOW_BRANCH, true);
818
+ const showProvider = parseBooleanEnv(process.env.PI_MINIMAL_FOOTER_SHOW_PROVIDER, false);
759
819
 
760
820
  function formatTokenCount(tokens: number): string {
761
821
  if (tokens >= 1_000_000) {
@@ -1028,7 +1088,11 @@ export default function (pi: ExtensionAPI) {
1028
1088
  }
1029
1089
 
1030
1090
  // Model + thinking
1031
- const modelName = ctx.model?.id?.split("/").pop() || "no-model";
1091
+ const modelName = ctx.model
1092
+ ? showProvider
1093
+ ? `${ctx.model.provider}/${ctx.model.id}`
1094
+ : ctx.model.id.split("/").pop() || "no-model"
1095
+ : "no-model";
1032
1096
  const plainModelStr = theme.fg("muted", modelName);
1033
1097
  let modelStr = plainModelStr;
1034
1098
  if (ctx.model?.reasoning) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ogulcancelik/pi-minimal-footer",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Minimal footer for pi with context gauge and subscription usage bars",
5
5
  "type": "module",
6
6
  "keywords": [