pi-powerline 0.7.1 → 0.8.1
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/CHANGELOG.md +14 -0
- package/extensions/editor.ts +25 -7
- package/extensions/footer.ts +9 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [0.8.1](https://github.com/jwu/pi-powerline/compare/v0.8.0...v0.8.1) (2026-06-28)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **editor:** prevent over-wide lines in narrow terminals ([12c8ced](https://github.com/jwu/pi-powerline/commit/12c8ced96573d76480d52ffafc7addd6516bac66))
|
|
7
|
+
|
|
8
|
+
# [0.8.0](https://github.com/jwu/pi-powerline/compare/v0.7.1...v0.8.0) (2026-06-09)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **footer:** show cache hit rate ([e2c5535](https://github.com/jwu/pi-powerline/commit/e2c5535577792432e7007d504cfb1f9a37d86562))
|
|
14
|
+
|
|
1
15
|
## [0.7.1](https://github.com/jwu/pi-powerline/compare/v0.7.0...v0.7.1) (2026-05-27)
|
|
2
16
|
|
|
3
17
|
|
package/extensions/editor.ts
CHANGED
|
@@ -76,16 +76,34 @@ export interface PromptPrefixColorTokens {
|
|
|
76
76
|
|
|
77
77
|
/** Custom editor with a ❯ prompt prefix. Colors use `PromptPrefixColorTokens`. */
|
|
78
78
|
export class PromptPrefixEditor extends CustomEditor {
|
|
79
|
+
private readonly tuiRef: any;
|
|
80
|
+
|
|
79
81
|
static colorTokens: PromptPrefixColorTokens = {
|
|
80
82
|
border: 'borderAccent',
|
|
81
83
|
prefix: 'dim',
|
|
82
84
|
indent: 'border',
|
|
83
85
|
};
|
|
84
86
|
|
|
87
|
+
constructor(tui: any, theme: EditorTheme, keybindings: any) {
|
|
88
|
+
super(tui, theme, keybindings);
|
|
89
|
+
this.tuiRef = tui;
|
|
90
|
+
}
|
|
91
|
+
|
|
85
92
|
render(width: number): string[] {
|
|
86
|
-
const
|
|
93
|
+
const terminalColumns = Number(this.tuiRef?.terminal?.columns);
|
|
94
|
+
const renderWidth = Math.max(
|
|
95
|
+
1,
|
|
96
|
+
Math.floor(
|
|
97
|
+
Number.isFinite(terminalColumns) && terminalColumns > 0
|
|
98
|
+
? Math.min(width, terminalColumns)
|
|
99
|
+
: width,
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
const contentWidth = Math.max(1, renderWidth - 2);
|
|
87
103
|
const lines = super.render(contentWidth);
|
|
88
|
-
if (lines.length < 3)
|
|
104
|
+
if (lines.length < 3) {
|
|
105
|
+
return lines.map((line) => truncateToWidth(line, renderWidth, ''));
|
|
106
|
+
}
|
|
89
107
|
|
|
90
108
|
const theme = currentTheme;
|
|
91
109
|
const color = (token: ThemeColor | undefined, text: string) =>
|
|
@@ -103,7 +121,7 @@ export class PromptPrefixEditor extends CustomEditor {
|
|
|
103
121
|
|
|
104
122
|
const result = renderPromptPrefix(
|
|
105
123
|
lines,
|
|
106
|
-
|
|
124
|
+
renderWidth,
|
|
107
125
|
color(tokens.border, '─'),
|
|
108
126
|
color(tokens.prefix, '❯'),
|
|
109
127
|
tokens.indent ? color(tokens.indent, ' ') : ' ',
|
|
@@ -118,16 +136,16 @@ export class PromptPrefixEditor extends CustomEditor {
|
|
|
118
136
|
|
|
119
137
|
const infoWidth = visibleWidth(infoPart);
|
|
120
138
|
// '─ ' (2) + info + ' ' (1) + dashes → total width
|
|
121
|
-
let paddingLen =
|
|
139
|
+
let paddingLen = renderWidth - 3 - infoWidth;
|
|
122
140
|
let displayInfo = infoPart;
|
|
123
141
|
|
|
124
142
|
if (paddingLen < 2) {
|
|
125
143
|
// info too wide or not enough dashes, truncate with ellipsis, keep at least 2 dashes
|
|
126
144
|
const minDashes = 2;
|
|
127
|
-
const availForInfo =
|
|
145
|
+
const availForInfo = renderWidth - 3 - minDashes;
|
|
128
146
|
if (availForInfo > 0) {
|
|
129
147
|
displayInfo = truncateToWidth(infoPart, availForInfo, '...');
|
|
130
|
-
paddingLen =
|
|
148
|
+
paddingLen = renderWidth - 3 - visibleWidth(displayInfo);
|
|
131
149
|
}
|
|
132
150
|
}
|
|
133
151
|
|
|
@@ -139,7 +157,7 @@ export class PromptPrefixEditor extends CustomEditor {
|
|
|
139
157
|
}
|
|
140
158
|
}
|
|
141
159
|
|
|
142
|
-
return result;
|
|
160
|
+
return result.map((line) => truncateToWidth(line, renderWidth, ''));
|
|
143
161
|
}
|
|
144
162
|
}
|
|
145
163
|
|
package/extensions/footer.ts
CHANGED
|
@@ -90,6 +90,11 @@ function getUsageTokenTotal(usage: SessionAssistantUsage): number {
|
|
|
90
90
|
);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
function getCacheHitRate(usage: SessionAssistantUsage): number | undefined {
|
|
94
|
+
const promptTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
95
|
+
return promptTokens > 0 ? (usage.cacheRead / promptTokens) * 100 : undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
93
98
|
function isSessionAssistantMessage(value: unknown): value is AssistantMessage {
|
|
94
99
|
return (
|
|
95
100
|
typeof value === 'object' &&
|
|
@@ -209,6 +214,10 @@ function createFooterRenderer(ctx: ExtensionContext) {
|
|
|
209
214
|
if (totalOutput) statsParts.push(`↓${formatTokens(totalOutput)}`);
|
|
210
215
|
if (totalCacheRead) statsParts.push(`R${formatTokens(totalCacheRead)}`);
|
|
211
216
|
if (totalCacheWrite) statsParts.push(`W${formatTokens(totalCacheWrite)}`);
|
|
217
|
+
const latestCacheHitRate = latestUsage ? getCacheHitRate(latestUsage) : undefined;
|
|
218
|
+
if ((totalCacheRead > 0 || totalCacheWrite > 0) && latestCacheHitRate !== undefined) {
|
|
219
|
+
statsParts.push(`CH${latestCacheHitRate.toFixed(1)}%`);
|
|
220
|
+
}
|
|
212
221
|
|
|
213
222
|
const usingSubscription = ctx.model ? ctx.modelRegistry.isUsingOAuth(ctx.model) : false;
|
|
214
223
|
if (totalCost || usingSubscription) {
|
package/package.json
CHANGED