pi-bar 0.3.40 → 0.3.41
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 +36 -2
- package/extensions/status-footer.ts +51 -4
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ pi-bar works out of the box. Run `/bar` inside pi to choose which footer segment
|
|
|
43
43
|
/bar
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Toggle `Model`, `Thinking level`, `Context usage`, `Progress update`, and `Extension statuses` between `shown` and `hidden`. If other extensions have published status badges, `/bar` also shows fine-grained `Status: <key>` rows plus a `New extension statuses` default. You can also use commands:
|
|
46
|
+
Toggle `Model`, `Thinking level`, `Context usage`, `Current directory`, `Progress update`, and `Extension statuses` between `shown` and `hidden`. If other extensions have published status badges, `/bar` also shows fine-grained `Status: <key>` rows plus a `New extension statuses` default. You can also use commands:
|
|
47
47
|
|
|
48
48
|
```text
|
|
49
49
|
/bar segments list
|
|
@@ -52,7 +52,7 @@ Toggle `Model`, `Thinking level`, `Context usage`, `Progress update`, and `Exten
|
|
|
52
52
|
/bar segments show thinking
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
Allowed segments are `model`, `thinking`, `context`, `progress`, and `extensions`. The `progress` segment stays hidden until pi-bar has a current update. The `extensions` segment stays hidden when no extension has set a status.
|
|
55
|
+
Allowed segments are `model`, `thinking`, `context`, `cwd`, `progress`, and `extensions`. The `cwd` segment is off by default. The `progress` segment stays hidden until pi-bar has a current update. The `extensions` segment stays hidden when no extension has set a status.
|
|
56
56
|
|
|
57
57
|
You can also set startup defaults with environment variables before launching pi:
|
|
58
58
|
|
|
@@ -61,6 +61,30 @@ PI_BAR_SHOW=model,thinking,context,progress,extensions pi
|
|
|
61
61
|
PI_BAR_SHOW=model,context pi
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
### Show the session directory
|
|
65
|
+
|
|
66
|
+
Enable the optional `cwd` segment to distinguish projects and sessions:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
/bar segments show cwd
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or set startup segments with `PI_BAR_SHOW=model,thinking,context,cwd,progress,extensions`.
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
claude-opus-4.7 ❯ think:med ❯ 2.6% / 1.0M ❯ ~/projects/pi-bar
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Your home directory becomes `~`. Long paths omit middle directories, retaining trailing directory names where possible. The segment is capped at 36 terminal columns, including wide Unicode characters. Override the cap before starting pi:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
PI_BAR_CWD_MAX_WIDTH=48 pi
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The cap must be an integer of at least 8; invalid values use 36. Very long directory names are truncated. Paths are stripped of terminal controls before display.
|
|
85
|
+
|
|
86
|
+
This is Pi's session working directory (`ctx.cwd`), not a live shell directory: `cd` inside a tool command does not change it. Visibility persists through the existing `/bar` configuration.
|
|
87
|
+
|
|
64
88
|
### Configure live progress updates
|
|
65
89
|
|
|
66
90
|
pi-bar shows a short, plain-English description of what pi is working on right now. It refreshes as pi works and resets when you switch branches in the session tree, so stale updates never follow you across tasks. Hide `Progress update` in `/bar`, run `/bar segments hide progress`, or set `PI_BAR_SHOW` without `progress` to disable it.
|
|
@@ -98,6 +122,16 @@ The first number is the warning/yellow threshold. The second number is the dange
|
|
|
98
122
|
- **[pi-chrome](https://www.npmjs.com/package/pi-chrome)** — give your Pi agent your real, signed-in Chrome. Use pi-bar's red-context threshold as the signal to wrap up long browser scrapes before context overflows.
|
|
99
123
|
- **[pi-qq](https://www.npmjs.com/package/pi-qq)** — ask side questions about what the agent just did without polluting the transcript.
|
|
100
124
|
|
|
125
|
+
## Development
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm ci --ignore-scripts
|
|
129
|
+
npm test
|
|
130
|
+
npm run check
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Tests cover path formatting, terminal safety, width limits, and segment visibility/persistence. Test configuration mirrors Pi's `pi-ai/compat` loader alias; runtime dependencies remain optional peers supplied by Pi.
|
|
134
|
+
|
|
101
135
|
## Security note
|
|
102
136
|
|
|
103
137
|
Pi extensions run with your local user permissions. Review any pi package source before installing it.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* pi-bar — footer / statusline extension.
|
|
3
3
|
*
|
|
4
4
|
* Replaces pi's built-in footer with left-aligned segments:
|
|
5
|
-
* <model> ❯ think:<level> ❯ <context% / window> ❯ <progress> ❯ <extensions>
|
|
5
|
+
* <model> ❯ think:<level> ❯ <context% / window> ❯ [cwd] ❯ <progress> ❯ <extensions>
|
|
6
6
|
*
|
|
7
7
|
* Example:
|
|
8
8
|
* claude-opus-4.7 ❯ think:med ❯ 2.6% / 1.0M ❯ Reviewing package structure
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
* PI_BAR_THRESHOLDS warning,danger context-usage percentages
|
|
16
16
|
* PI_BAR_PROGRESS_MODEL provider/id for the progress update model
|
|
17
17
|
* PI_BAR_CONFIG override the persisted pi-bar config path
|
|
18
|
+
* PI_BAR_CWD_MAX_WIDTH maximum cwd segment width in terminal columns (default 36)
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
21
22
|
import { homedir } from "node:os";
|
|
22
|
-
import { dirname, join } from "node:path";
|
|
23
|
+
import { dirname, join, posix, win32 } from "node:path";
|
|
23
24
|
import { complete, type UserMessage } from "@earendil-works/pi-ai";
|
|
24
25
|
import {
|
|
25
26
|
getSettingsListTheme,
|
|
@@ -33,9 +34,10 @@ import {
|
|
|
33
34
|
type SettingItem,
|
|
34
35
|
SettingsList,
|
|
35
36
|
truncateToWidth,
|
|
37
|
+
visibleWidth,
|
|
36
38
|
} from "@earendil-works/pi-tui";
|
|
37
39
|
|
|
38
|
-
type SegmentName = "model" | "thinking" | "context" | "progress" | "extensions";
|
|
40
|
+
type SegmentName = "model" | "thinking" | "context" | "cwd" | "progress" | "extensions";
|
|
39
41
|
type StatusFilter =
|
|
40
42
|
| { mode: "all"; hidden: Set<string> }
|
|
41
43
|
| { mode: "only"; shown: Set<string> };
|
|
@@ -75,7 +77,7 @@ type ProgressModelPreference = { provider: string; id: string };
|
|
|
75
77
|
type FastModelAuth = {
|
|
76
78
|
model: Parameters<typeof complete>[0];
|
|
77
79
|
apiKey: string;
|
|
78
|
-
headers?:
|
|
80
|
+
headers?: NonNullable<Parameters<typeof complete>[2]>["headers"];
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
const STATUS_FILTER_ENTRY_TYPE = "pi-bar-status-filter";
|
|
@@ -118,6 +120,7 @@ const ALL_SEGMENTS: readonly SegmentName[] = [
|
|
|
118
120
|
"model",
|
|
119
121
|
"thinking",
|
|
120
122
|
"context",
|
|
123
|
+
"cwd",
|
|
121
124
|
"progress",
|
|
122
125
|
"extensions",
|
|
123
126
|
];
|
|
@@ -125,6 +128,7 @@ const SEGMENT_LABELS: Record<SegmentName, string> = {
|
|
|
125
128
|
model: "Model",
|
|
126
129
|
thinking: "Thinking level",
|
|
127
130
|
context: "Context usage",
|
|
131
|
+
cwd: "Current directory",
|
|
128
132
|
progress: "Progress update",
|
|
129
133
|
extensions: "Extension statuses",
|
|
130
134
|
};
|
|
@@ -152,6 +156,45 @@ function formatModelName(id: string | undefined): string {
|
|
|
152
156
|
return base.replace(/-\d{8}$/, "").replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
153
157
|
}
|
|
154
158
|
|
|
159
|
+
const DEFAULT_CWD_MAX_WIDTH = 36;
|
|
160
|
+
|
|
161
|
+
export function parseCwdMaxWidth(raw: string | undefined): number {
|
|
162
|
+
const value = raw?.trim() ?? "";
|
|
163
|
+
const width = /^\d+$/.test(value) ? Number(value) : NaN;
|
|
164
|
+
return Number.isSafeInteger(width) && width >= 8 ? width : DEFAULT_CWD_MAX_WIDTH;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Format the session directory, preserving the leaf when middle components fit poorly. */
|
|
168
|
+
export function formatCwd(
|
|
169
|
+
cwd: string,
|
|
170
|
+
home = homedir(),
|
|
171
|
+
maxWidth = DEFAULT_CWD_MAX_WIDTH,
|
|
172
|
+
paths = process.platform === "win32" ? win32 : posix,
|
|
173
|
+
): string {
|
|
174
|
+
if (maxWidth <= 0) return "";
|
|
175
|
+
if (!cwd) return truncateToWidth("—", maxWidth);
|
|
176
|
+
|
|
177
|
+
const relative = home ? paths.relative(home, cwd) : undefined;
|
|
178
|
+
const insideHome = relative !== undefined &&
|
|
179
|
+
!paths.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${paths.sep}`);
|
|
180
|
+
const prefix = insideHome ? `~${paths.sep}` : paths.parse(cwd).root;
|
|
181
|
+
const tail = insideHome ? relative! : cwd.slice(prefix.length);
|
|
182
|
+
const display = stripTerminalControls(insideHome ? (tail ? `${prefix}${tail}` : "~") : cwd);
|
|
183
|
+
if (visibleWidth(display) <= maxWidth) return display;
|
|
184
|
+
|
|
185
|
+
const parts = tail.split(paths.sep).filter(Boolean);
|
|
186
|
+
if (parts.length < 2) return truncateToWidth(display, maxWidth);
|
|
187
|
+
|
|
188
|
+
// Keep as many trailing directories as the column budget allows.
|
|
189
|
+
let compact = stripTerminalControls(`${prefix}…${paths.sep}${parts.at(-1)}`);
|
|
190
|
+
for (let index = parts.length - 2; index > 0; index--) {
|
|
191
|
+
const candidate = stripTerminalControls(`${prefix}…${paths.sep}${parts.slice(index).join(paths.sep)}`);
|
|
192
|
+
if (visibleWidth(candidate) > maxWidth) break;
|
|
193
|
+
compact = candidate;
|
|
194
|
+
}
|
|
195
|
+
return truncateToWidth(compact, maxWidth);
|
|
196
|
+
}
|
|
197
|
+
|
|
155
198
|
function thinkingColor(level: string): ThemeColor {
|
|
156
199
|
switch (level) {
|
|
157
200
|
case "off":
|
|
@@ -2078,6 +2121,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
2078
2121
|
if (!ctx.hasUI) return;
|
|
2079
2122
|
|
|
2080
2123
|
const { warningThreshold, errorThreshold } = parseThresholds();
|
|
2124
|
+
const cwdWidth = parseCwdMaxWidth(process.env.PI_BAR_CWD_MAX_WIDTH);
|
|
2081
2125
|
|
|
2082
2126
|
ctx.ui.setFooter((tui, theme, footerData) => {
|
|
2083
2127
|
requestRender = () => tui.requestRender();
|
|
@@ -2116,6 +2160,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
2116
2160
|
model: theme.fg("accent", modelName),
|
|
2117
2161
|
thinking: theme.fg(thinkingColor(thinkingLevel), `think:${thinkingLevel}`),
|
|
2118
2162
|
context: theme.fg(contextSegmentColor, contextText),
|
|
2163
|
+
cwd: visibleSegments.includes("cwd")
|
|
2164
|
+
? theme.fg("accent", formatCwd(ctx.cwd, homedir(), Math.min(cwdWidth, width)))
|
|
2165
|
+
: null,
|
|
2119
2166
|
progress: progressText ? theme.fg("text", progressText) : null,
|
|
2120
2167
|
extensions: extensionStatuses,
|
|
2121
2168
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-bar",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.41",
|
|
4
4
|
"description": "Pi footer/statusline showing active model, thinking level, context pressure, live progress updates, and extension statuses.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -52,5 +52,17 @@
|
|
|
52
52
|
"./extensions/status-footer.ts"
|
|
53
53
|
],
|
|
54
54
|
"image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.38/assets/screenshot-yellow.png"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"test": "tsx --tsconfig tests/tsconfig.json --test tests/*.test.ts",
|
|
58
|
+
"check": "tsc -p tests/tsconfig.json"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@earendil-works/pi-ai": "^0.85.1",
|
|
62
|
+
"@earendil-works/pi-coding-agent": "^0.85.1",
|
|
63
|
+
"@earendil-works/pi-tui": "^0.85.1",
|
|
64
|
+
"@types/node": "^22.20.2",
|
|
65
|
+
"tsx": "^4.23.13",
|
|
66
|
+
"typescript": "^5.9.3"
|
|
55
67
|
}
|
|
56
68
|
}
|