@ravshansbox/pi-statusline 1.5.0 → 1.7.0
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 -2
- package/index.ts +22 -60
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,9 +14,8 @@ Add `-l` to install it in project settings.
|
|
|
14
14
|
|
|
15
15
|
Pi loads the extension from `./index.ts`. It replaces the built-in footer with a statusline that shows:
|
|
16
16
|
|
|
17
|
-
- the
|
|
17
|
+
- the directory name, git branch, model and thinking level
|
|
18
18
|
- token usage, cache hit rate and context usage
|
|
19
|
-
- the provider, model and thinking level
|
|
20
19
|
- statuses set by other extensions
|
|
21
20
|
|
|
22
21
|
## Development
|
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
2
|
import { type ExtensionAPI, type ExtensionContext } from '@earendil-works/pi-coding-agent';
|
|
3
|
-
import { truncateToWidth
|
|
3
|
+
import { truncateToWidth } from '@earendil-works/pi-tui';
|
|
4
4
|
|
|
5
5
|
type Usage = {
|
|
6
6
|
input: number;
|
|
@@ -22,14 +22,6 @@ function formatTokens(count: number): string {
|
|
|
22
22
|
return `${Math.round(count / 1000000)}m`;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function formatCwd(cwd: string, home: string | undefined): string {
|
|
26
|
-
if (!home) return cwd;
|
|
27
|
-
const rel = relative(resolve(home), resolve(cwd));
|
|
28
|
-
const inside = rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
|
|
29
|
-
if (!inside) return cwd;
|
|
30
|
-
return rel === '' ? '~' : `~${sep}${rel}`;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
25
|
function getUsage(ctx: ExtensionContext) {
|
|
34
26
|
const totals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
35
27
|
let latestCacheHitRate: number | undefined;
|
|
@@ -77,24 +69,18 @@ export default function (pi: ExtensionAPI) {
|
|
|
77
69
|
const contextPercent =
|
|
78
70
|
contextUsage?.percent != null ? contextPercentValue.toFixed(0) : '?';
|
|
79
71
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
process.env['HOME'] || process.env['USERPROFILE'],
|
|
83
|
-
);
|
|
72
|
+
const modelName = model?.id.replace(/^claude-/, '') || 'no-model';
|
|
73
|
+
const topParts = [basename(ctx.sessionManager.getCwd())];
|
|
84
74
|
const branch = footerData.getGitBranch();
|
|
85
|
-
if (branch)
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (totals.input) statsParts.push(`↑${formatTokens(totals.input)}`);
|
|
91
|
-
if (totals.output) statsParts.push(`↓${formatTokens(totals.output)}`);
|
|
92
|
-
if (totals.cacheRead) statsParts.push(`R${formatTokens(totals.cacheRead)}`);
|
|
93
|
-
if (totals.cacheWrite) statsParts.push(`W${formatTokens(totals.cacheWrite)}`);
|
|
94
|
-
if ((totals.cacheRead > 0 || totals.cacheWrite > 0) && latestCacheHitRate !== undefined) {
|
|
95
|
-
statsParts.push(`CH${latestCacheHitRate.toFixed(0)}%`);
|
|
75
|
+
if (branch) topParts.push(branch);
|
|
76
|
+
topParts.push(modelName);
|
|
77
|
+
if (model?.reasoning) {
|
|
78
|
+
const level = ctx.thinkingLevel || 'off';
|
|
79
|
+
topParts.push(level === 'off' ? 'thinking off' : level);
|
|
96
80
|
}
|
|
81
|
+
const top = topParts.join(' • ');
|
|
97
82
|
|
|
83
|
+
const statsParts: string[] = [];
|
|
98
84
|
const contextDisplay =
|
|
99
85
|
contextPercent === '?'
|
|
100
86
|
? `?/${formatTokens(contextWindow)}`
|
|
@@ -103,45 +89,21 @@ export default function (pi: ExtensionAPI) {
|
|
|
103
89
|
else if (contextPercentValue > 70) statsParts.push(theme.fg('warning', contextDisplay));
|
|
104
90
|
else statsParts.push(contextDisplay);
|
|
105
91
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (statsLeftWidth > width) {
|
|
113
|
-
statsLeft = truncateToWidth(statsLeft, width, '...');
|
|
114
|
-
statsLeftWidth = visibleWidth(statsLeft);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const minPadding = 2;
|
|
118
|
-
const modelName = model?.id.replace(/^claude-/, '') || 'no-model';
|
|
119
|
-
let right = modelName;
|
|
120
|
-
if (model?.reasoning) {
|
|
121
|
-
const level = ctx.thinkingLevel || 'off';
|
|
122
|
-
right = level === 'off' ? `${modelName} • thinking off` : `${modelName} • ${level}`;
|
|
92
|
+
if (totals.input) statsParts.push(`↑${formatTokens(totals.input)}`);
|
|
93
|
+
if (totals.output) statsParts.push(`↓${formatTokens(totals.output)}`);
|
|
94
|
+
if (totals.cacheRead) statsParts.push(`R${formatTokens(totals.cacheRead)}`);
|
|
95
|
+
if (totals.cacheWrite) statsParts.push(`W${formatTokens(totals.cacheWrite)}`);
|
|
96
|
+
if ((totals.cacheRead > 0 || totals.cacheWrite > 0) && latestCacheHitRate !== undefined) {
|
|
97
|
+
statsParts.push(`CH${latestCacheHitRate.toFixed(0)}%`);
|
|
123
98
|
}
|
|
124
99
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (statsLeftWidth + minPadding + rightWidth <= width) {
|
|
128
|
-
statsLine = statsLeft + ' '.repeat(width - statsLeftWidth - rightWidth) + right;
|
|
129
|
-
} else {
|
|
130
|
-
const available = width - statsLeftWidth - minPadding;
|
|
131
|
-
if (available > 0) {
|
|
132
|
-
const truncatedRight = truncateToWidth(right, available, '');
|
|
133
|
-
const padding = ' '.repeat(
|
|
134
|
-
Math.max(0, width - statsLeftWidth - visibleWidth(truncatedRight)),
|
|
135
|
-
);
|
|
136
|
-
statsLine = statsLeft + padding + truncatedRight;
|
|
137
|
-
} else {
|
|
138
|
-
statsLine = statsLeft;
|
|
139
|
-
}
|
|
100
|
+
if (process.env['PI_EXPERIMENTAL'] === '1') {
|
|
101
|
+
statsParts.push(`${theme.fg('dim', '•')} ${theme.bold(theme.fg('warning', 'xp'))}`);
|
|
140
102
|
}
|
|
141
103
|
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const lines = [
|
|
104
|
+
const statsLine = truncateToWidth(statsParts.join(' '), width, '...');
|
|
105
|
+
const topLine = truncateToWidth(theme.fg('dim', top), width, theme.fg('dim', '...'));
|
|
106
|
+
const lines = [topLine, theme.fg('dim', statsLine)];
|
|
145
107
|
|
|
146
108
|
const statuses = footerData.getExtensionStatuses();
|
|
147
109
|
if (statuses.size > 0) {
|