@bacnh85/pi-sub 0.1.1 → 0.1.3

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 +4 -4
  2. package/index.ts +10 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Pi extension that shows subscription usage for the currently selected supported model provider.
4
4
 
5
- V1 supports OpenAI Codex models by reading Pi's auth state from `~/.pi/agent/auth.json` (or `$PI_CODING_AGENT_DIR/auth.json`) and displays a separate subscription line below the editor only while the active Pi model provider is `openai-codex`.
5
+ V1 supports OpenAI Codex models by reading Pi's auth state from `~/.pi/agent/auth.json` (or `$PI_CODING_AGENT_DIR/auth.json`) and displays a subscription footer status after Pi's built-in status/token usage line only while the active Pi model provider is `openai-codex`.
6
6
 
7
7
  ## Install
8
8
 
@@ -26,7 +26,7 @@ pi -e ./extensions/pi-sub
26
26
 
27
27
  ## What it shows
28
28
 
29
- The footer status includes:
29
+ The footer status appears after Pi's built-in status/token usage line and includes:
30
30
 
31
31
  - active account email;
32
32
  - subscription plan, such as `Plus`;
@@ -37,7 +37,7 @@ The footer status includes:
37
37
  Example subscription line:
38
38
 
39
39
  ```text
40
- Sub Plus user@example.com 5H 85%→18:12 W 80%→2 Jul 08:00 · gpt-5-codex
40
+ Sub · Plus · user@example.com · 5H 85% (18:12) · W 80% (08:00 on 2 Jul) · gpt-5-codex
41
41
  ```
42
42
 
43
43
  When the current model provider is not supported, `pi-sub` clears its subscription line and does not refresh subscription data.
@@ -54,7 +54,7 @@ When Pi OpenAI Codex auth is available, `/sub` shows the active account usage:
54
54
 
55
55
  ```text
56
56
  ACCOUNT PLAN 5H USAGE WEEKLY USAGE LAST ACTIVITY
57
- * hangdanchi@gmail.com Plus 85% (18:12) 80% (08:00 on 2 Jul) Now
57
+ * user@example.com Plus 85% (18:12) 80% (08:00 on 2 Jul) Now
58
58
  ```
59
59
 
60
60
  ## Refresh behavior
package/index.ts CHANGED
@@ -146,7 +146,9 @@ function formatReset(timestampSeconds: number | undefined): string | undefined {
146
146
  const now = new Date();
147
147
  const time = date.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit", hour12: false });
148
148
  if (date.toDateString() === now.toDateString()) return time;
149
- return `${time} on ${date.toLocaleDateString(undefined, { day: "numeric", month: "short" })}`;
149
+ const day = date.toLocaleDateString(undefined, { day: "numeric" });
150
+ const month = date.toLocaleDateString(undefined, { month: "short" });
151
+ return `${time} on ${day} ${month}`;
150
152
  }
151
153
 
152
154
  function usageWindowFromApi(window: UsageApiWindow | undefined): UsageWindow | undefined {
@@ -260,26 +262,22 @@ function supportedAdapter(model: ModelLike): SubscriptionProviderAdapter | undef
260
262
  return adapters.find((adapter) => adapter.isModelSupported(model));
261
263
  }
262
264
 
263
- function formatWindow(window: UsageWindow | undefined, compact = true): string {
265
+ function formatWindow(window: UsageWindow | undefined, _compact = true): string {
264
266
  if (!window) return "?";
265
- if (window.percent !== undefined && window.resetLabel) return compact ? `${window.percent}%→${compactResetLabel(window.resetLabel)}` : `${window.percent}% (${window.resetLabel})`;
267
+ if (window.percent !== undefined && window.resetLabel) return `${window.percent}% (${window.resetLabel})`;
266
268
  if (window.label) return window.label;
267
269
  if (window.percent !== undefined) return `${window.percent}%`;
268
270
  if (window.used !== undefined && window.limit !== undefined) return `${window.used}/${window.limit}`;
269
271
  return "?";
270
272
  }
271
273
 
272
- function compactResetLabel(label: string): string {
273
- return label.replace(/^0?(\d+:\d+) on (\d+ \w+)$/i, "$2 $1");
274
- }
275
-
276
274
  function maxPercent(account: SubscriptionAccountSnapshot | undefined): number {
277
275
  return Math.max(account?.fiveHour?.percent ?? 0, account?.weekly?.percent ?? 0);
278
276
  }
279
277
 
280
278
  function renderSubscriptionLine(ctx: ExtensionContext, state: State): void {
281
279
  if (!state.adapter) {
282
- ctx.ui.setWidget(STATUS_KEY, undefined);
280
+ ctx.ui.setStatus(STATUS_KEY, undefined);
283
281
  return;
284
282
  }
285
283
  const theme = ctx.ui.theme;
@@ -299,11 +297,11 @@ function renderSubscriptionLine(ctx: ExtensionContext, state: State): void {
299
297
  pieces.push(account?.accountLabel ?? "unknown account");
300
298
  pieces.push(`5H ${formatWindow(account?.fiveHour)}`);
301
299
  pieces.push(`W ${formatWindow(account?.weekly)}`);
302
- pieces.push("·", modelId);
303
- line = pieces.join(" ");
300
+ pieces.push(modelId);
301
+ line = pieces.join(" · ");
304
302
  color = maxPercent(account) >= 90 ? "error" : maxPercent(account) >= 80 ? "warning" : "dim";
305
303
  }
306
- ctx.ui.setWidget(STATUS_KEY, [theme.fg(color, line)], { placement: "belowEditor" });
304
+ ctx.ui.setStatus(STATUS_KEY, theme.fg(color, line));
307
305
  }
308
306
 
309
307
  function startTimer(ctx: ExtensionContext, state: State): void {
@@ -415,7 +413,7 @@ export default function (pi: ExtensionAPI) {
415
413
 
416
414
  pi.on("session_shutdown", async (_event, ctx) => {
417
415
  stopTimer(state);
418
- ctx.ui.setWidget(STATUS_KEY, undefined);
416
+ ctx.ui.setStatus(STATUS_KEY, undefined);
419
417
  });
420
418
 
421
419
  pi.registerCommand("sub", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bacnh85/pi-sub",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Pi extension showing subscription usage for supported model providers.",
5
5
  "type": "module",
6
6
  "license": "MIT",