@narumitw/pi-usage 0.60.2 → 0.60.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-usage",
3
- "version": "0.60.2",
3
+ "version": "0.60.3",
4
4
  "description": "Pi extension that shows current-account usage and DeepSeek API balance for supported providers.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -70,6 +70,6 @@
70
70
  "directory": "packages/pi-usage"
71
71
  },
72
72
  "dependencies": {
73
- "@narumitw/pi-tui-kit": "^0.49.1"
73
+ "@narumitw/pi-tui-kit": "^0.59.0"
74
74
  }
75
75
  }
@@ -1,3 +1,4 @@
1
+ import { stripVTControlCharacters } from "node:util";
1
2
  import {
2
3
  type ExtensionCommandContext,
3
4
  getSettingsListTheme,
@@ -18,6 +19,26 @@ const ON = "On";
18
19
 
19
20
  type UsageSettingId = "codexFastMode" | "codexStatusResetCountdown";
20
21
 
22
+ function fitSettingsRows(lines: string[], maxRows: number): string[] {
23
+ if (lines.length <= maxRows) return lines;
24
+ const content = lines.filter((line) => stripVTControlCharacters(line).trim().length > 0);
25
+ if (content.length <= maxRows) return content;
26
+ const selectedIndex = content.findIndex((line) =>
27
+ /^[→›]\s/u.test(stripVTControlCharacters(line)),
28
+ );
29
+ if (selectedIndex < 0) return content.slice(0, maxRows);
30
+ return content
31
+ .map((line, index) => ({ index, line }))
32
+ .sort(
33
+ (left, right) =>
34
+ Math.abs(left.index - selectedIndex) - Math.abs(right.index - selectedIndex) ||
35
+ left.index - right.index,
36
+ )
37
+ .slice(0, maxRows)
38
+ .sort((left, right) => left.index - right.index)
39
+ .map(({ line }) => line);
40
+ }
41
+
21
42
  export async function showUsageSettings(
22
43
  ctx: ExtensionCommandContext,
23
44
  settingsRuntime: UsageSettingsRuntime,
@@ -29,6 +50,8 @@ export async function showUsageSettings(
29
50
  if (ctx.hasUI) ctx.ui.notify(`Edit settings manually: ${settingsRuntime.get().path}`, "info");
30
51
  return false;
31
52
  }
53
+ const { HorizontalRule } = await import("@narumitw/pi-tui-kit");
54
+ if (parentSignal.aborted || !isCurrent()) return false;
32
55
  return (
33
56
  (await ctx.ui.custom<boolean>((tui, theme, _keybindings, done) => {
34
57
  const localController = new AbortController();
@@ -54,6 +77,7 @@ export async function showUsageSettings(
54
77
  },
55
78
  ];
56
79
  const container = new Container();
80
+ const rule = new HorizontalRule({ ruleStyle: (text) => theme.fg("border", text) });
57
81
  container.addChild(new Text(theme.fg("accent", theme.bold("pi-usage Settings")), 1, 1));
58
82
 
59
83
  let settingsList: SettingsList;
@@ -106,7 +130,18 @@ export async function showUsageSettings(
106
130
 
107
131
  parentSignal.addEventListener("abort", cancel, { once: true });
108
132
  return {
109
- render: (width: number) => container.render(width),
133
+ render(width: number) {
134
+ const content = container.render(width);
135
+ const terminalRows = Number.isFinite(tui.terminal?.rows)
136
+ ? Math.floor(tui.terminal.rows)
137
+ : 24;
138
+ const availableRows = Math.max(1, terminalRows - 3);
139
+ if (content.length + 2 > availableRows) {
140
+ return fitSettingsRows(content, availableRows);
141
+ }
142
+ const [ruleLine = ""] = rule.render(width);
143
+ return [ruleLine, ...content, ruleLine];
144
+ },
110
145
  invalidate: () => container.invalidate(),
111
146
  handleInput(data: string) {
112
147
  if (closing) return;