pi-bar 0.3.5 → 0.3.6
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 +28 -10
- package/extensions/status-footer.ts +129 -6
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -3,22 +3,23 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/pi-bar)
|
|
4
4
|
[](https://www.npmjs.com/package/pi-bar)
|
|
5
5
|
|
|
6
|
-
**Never accidentally run Opus on a typo again.** pi-bar puts the active model, thinking level, context usage, and extension statuses in pi's footer so you catch wrong-model / wrong-reasoning / context-pressure problems before they cost you.
|
|
6
|
+
**Never accidentally run Opus on a typo again.** pi-bar puts the active model, thinking level, context usage, live TLDR, and extension statuses in pi's footer so you catch wrong-model / wrong-reasoning / context-pressure problems before they cost you.
|
|
7
7
|
|
|
8
8
|
```text
|
|
9
|
-
◈ claude-opus-4.7 ❯ ✦ think:med ❯ ◷ 2.6% / 1.0M ❯ ✧ plan:active
|
|
9
|
+
◈ claude-opus-4.7 ❯ ✦ think:med ❯ ◷ 2.6% / 1.0M ❯ ⓘ Inspecting package structure ❯ ✧ plan:active
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-

|
|
13
13
|
|
|
14
14
|
## Why use it?
|
|
15
15
|
|
|
16
16
|
- **See the active model at a glance** — catch accidental model switches before an expensive or sensitive task starts.
|
|
17
17
|
- **Track thinking level in place** — immediately notice when you are using the wrong reasoning setting.
|
|
18
18
|
- **Watch context pressure early** — context usage turns green, yellow, then red as you approach the limit.
|
|
19
|
+
- **Show pi-tldr inline** — when `pi-tldr` is installed, its current TLDR appears as a compact footer segment.
|
|
19
20
|
- **Keep extension statuses visible** — statuses set with `ctx.ui.setStatus()` still appear in the custom footer.
|
|
20
21
|
|
|
21
|
-
pi-bar is intentionally tiny: one small extension, no broad behavior changes, and no commands to learn. It replaces pi's built-in footer with a compact model / thinking / context / extension-status line that refreshes when model, thinking level, context usage, or extension statuses change.
|
|
22
|
+
pi-bar is intentionally tiny: one small extension, no broad behavior changes, and no commands to learn. It replaces pi's built-in footer with a compact model / thinking / context / tldr / extension-status line that refreshes when model, thinking level, context usage, pi-tldr, or extension statuses change.
|
|
22
23
|
|
|
23
24
|
## Install
|
|
24
25
|
|
|
@@ -39,11 +40,27 @@ pi-bar works out of the box, but you can tune it with environment variables befo
|
|
|
39
40
|
### Show or hide segments
|
|
40
41
|
|
|
41
42
|
```bash
|
|
42
|
-
PI_BAR_SHOW=model,thinking,context,extensions pi
|
|
43
|
+
PI_BAR_SHOW=model,thinking,context,tldr,extensions pi
|
|
43
44
|
PI_BAR_SHOW=model,context pi
|
|
44
45
|
```
|
|
45
46
|
|
|
46
|
-
Allowed segments are `model`, `thinking`, `context`, and `extensions`. The `extensions` segment is hidden when no extension has set a status.
|
|
47
|
+
Allowed segments are `model`, `thinking`, `context`, `tldr`, and `extensions`. The `tldr` segment is hidden unless `pi-tldr` has a current TLDR. The `extensions` segment is hidden when no extension has set a status.
|
|
48
|
+
|
|
49
|
+
### Show pi-tldr in the footer
|
|
50
|
+
|
|
51
|
+
Install [pi-tldr](https://www.npmjs.com/package/pi-tldr) alongside pi-bar:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pi install npm:pi-tldr
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
pi-bar captures pi-tldr's `pi-tldr` widget and renders its current text as the `tldr` segment. Limit segment width with:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
PI_BAR_TLDR_MAX_WIDTH=48 pi
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Default is `64`. Set `PI_BAR_SHOW` without `tldr` to hide it.
|
|
47
64
|
|
|
48
65
|
### Configure extension statuses
|
|
49
66
|
|
|
@@ -76,10 +93,10 @@ PI_BAR_ICONS=nerdfont pi
|
|
|
76
93
|
|
|
77
94
|
Supported presets:
|
|
78
95
|
|
|
79
|
-
- `unicode` — default, e.g. `◈ gpt-5.5 ❯ ✦ think:medium ❯ ◷ 42.7% / 272k ❯ ✧ plan:active`
|
|
80
|
-
- `plain` — maximum compatibility, e.g. `model:gpt-5.5 | think:medium | ctx:42.7% / 272k | ext:plan:active`
|
|
81
|
-
- `emoji` — colorful emoji markers, e.g. `🤖 gpt-5.5 › ✨ think:medium › 🧭 42.7% / 272k › 🧩 plan:active`
|
|
82
|
-
- `nerdfont` — icon-font glyphs for terminals configured with a Nerd Font, e.g. ` gpt-5.5 think:medium 42.7% / 272k plan:active`
|
|
96
|
+
- `unicode` — default, e.g. `◈ gpt-5.5 ❯ ✦ think:medium ❯ ◷ 42.7% / 272k ❯ ⓘ Reading files ❯ ✧ plan:active`
|
|
97
|
+
- `plain` — maximum compatibility, e.g. `model:gpt-5.5 | think:medium | ctx:42.7% / 272k | tldr:Reading files | ext:plan:active`
|
|
98
|
+
- `emoji` — colorful emoji markers, e.g. `🤖 gpt-5.5 › ✨ think:medium › 🧭 42.7% / 272k › 📝 Reading files › 🧩 plan:active`
|
|
99
|
+
- `nerdfont` — icon-font glyphs for terminals configured with a Nerd Font, e.g. ` gpt-5.5 think:medium 42.7% / 272k Reading files plan:active`
|
|
83
100
|
|
|
84
101
|
## Compatibility
|
|
85
102
|
|
|
@@ -91,6 +108,7 @@ PI_BAR_ICONS=plain pi
|
|
|
91
108
|
|
|
92
109
|
## Pairs well with
|
|
93
110
|
|
|
111
|
+
- **[pi-tldr](https://www.npmjs.com/package/pi-tldr)** — show live summaries above the input bar; pi-bar mirrors them into the footer.
|
|
94
112
|
- **[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.
|
|
95
113
|
- **[pi-qq](https://www.npmjs.com/package/pi-qq)** — ask side questions about what the agent just did without polluting the transcript.
|
|
96
114
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* pi-bar — footer/statusline extension.
|
|
3
3
|
*
|
|
4
4
|
* Replaces the built-in footer with left-aligned segments:
|
|
5
|
-
* ◈ <model name> ❯ ✦ think:<level> ❯ ◷ <context% / window> ❯ ✧ <extension statuses>
|
|
5
|
+
* ◈ <model name> ❯ ✦ think:<level> ❯ ◷ <context% / window> ❯ ⓘ <tldr> ❯ ✧ <extension statuses>
|
|
6
6
|
*
|
|
7
7
|
* Examples:
|
|
8
8
|
* ◈ claude-opus-4.7 ❯ ✦ think:med ❯ ◷ 2.6% / 1.0M
|
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
* and after each assistant turn so context usage stays current.
|
|
12
12
|
*
|
|
13
13
|
* Configuration env vars:
|
|
14
|
-
* PI_BAR_SHOW=model,thinking,context,extensions
|
|
14
|
+
* PI_BAR_SHOW=model,thinking,context,tldr,extensions
|
|
15
15
|
* PI_BAR_THRESHOLDS=70,90
|
|
16
16
|
* PI_BAR_ICONS=unicode|plain|emoji|nerdfont
|
|
17
|
+
* PI_BAR_TLDR_MAX_WIDTH=64
|
|
17
18
|
*/
|
|
18
19
|
|
|
19
20
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
@@ -23,15 +24,19 @@ import {
|
|
|
23
24
|
getSettingsListTheme,
|
|
24
25
|
type ExtensionAPI,
|
|
25
26
|
type ExtensionContext,
|
|
27
|
+
type Theme,
|
|
28
|
+
type ThemeColor,
|
|
26
29
|
} from "@earendil-works/pi-coding-agent";
|
|
27
30
|
import {
|
|
28
31
|
Container,
|
|
32
|
+
type Component,
|
|
29
33
|
type SettingItem,
|
|
30
34
|
SettingsList,
|
|
35
|
+
type TUI,
|
|
31
36
|
truncateToWidth,
|
|
32
37
|
} from "@earendil-works/pi-tui";
|
|
33
38
|
|
|
34
|
-
type SegmentName = "model" | "thinking" | "context" | "extensions";
|
|
39
|
+
type SegmentName = "model" | "thinking" | "context" | "tldr" | "extensions";
|
|
35
40
|
type IconPreset = "unicode" | "plain" | "emoji" | "nerdfont";
|
|
36
41
|
type StatusFilter =
|
|
37
42
|
| { mode: "all"; hidden: Set<string> }
|
|
@@ -39,8 +44,17 @@ type StatusFilter =
|
|
|
39
44
|
type SerializedStatusFilter =
|
|
40
45
|
| { mode: "all"; hidden: string[] }
|
|
41
46
|
| { mode: "only"; shown: string[] };
|
|
47
|
+
type TldrWidgetFactory = (tui: TUI, theme: Theme) => Component & {
|
|
48
|
+
dispose?(): void;
|
|
49
|
+
};
|
|
50
|
+
type CapturedTldrWidget =
|
|
51
|
+
| { kind: "lines"; lines: string[] }
|
|
52
|
+
| { kind: "factory"; factory: TldrWidgetFactory };
|
|
42
53
|
|
|
43
54
|
const STATUS_FILTER_ENTRY_TYPE = "pi-bar-status-filter";
|
|
55
|
+
const TLDR_WIDGET_KEY = "pi-tldr";
|
|
56
|
+
const DEFAULT_TLDR_MAX_WIDTH = 64;
|
|
57
|
+
const ANSI_PATTERN = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
44
58
|
const CONFIG_PATH =
|
|
45
59
|
process.env.PI_BAR_CONFIG ?? join(homedir(), ".pi", "agent", "pi-bar.json");
|
|
46
60
|
|
|
@@ -48,6 +62,7 @@ const DEFAULT_SEGMENTS: SegmentName[] = [
|
|
|
48
62
|
"model",
|
|
49
63
|
"thinking",
|
|
50
64
|
"context",
|
|
65
|
+
"tldr",
|
|
51
66
|
"extensions",
|
|
52
67
|
];
|
|
53
68
|
const DEFAULT_WARNING_THRESHOLD = 70;
|
|
@@ -59,6 +74,7 @@ const ICON_PRESETS: Record<
|
|
|
59
74
|
model: string;
|
|
60
75
|
thinking: string;
|
|
61
76
|
context: string;
|
|
77
|
+
tldr: string;
|
|
62
78
|
extensions: string;
|
|
63
79
|
separator: string;
|
|
64
80
|
}
|
|
@@ -67,6 +83,7 @@ const ICON_PRESETS: Record<
|
|
|
67
83
|
model: "◈",
|
|
68
84
|
thinking: "✦",
|
|
69
85
|
context: "◷",
|
|
86
|
+
tldr: "ⓘ",
|
|
70
87
|
extensions: "✧",
|
|
71
88
|
separator: "❯",
|
|
72
89
|
},
|
|
@@ -74,6 +91,7 @@ const ICON_PRESETS: Record<
|
|
|
74
91
|
model: "model",
|
|
75
92
|
thinking: "think",
|
|
76
93
|
context: "ctx",
|
|
94
|
+
tldr: "tldr",
|
|
77
95
|
extensions: "ext",
|
|
78
96
|
separator: "|",
|
|
79
97
|
},
|
|
@@ -81,6 +99,7 @@ const ICON_PRESETS: Record<
|
|
|
81
99
|
model: "🤖",
|
|
82
100
|
thinking: "✨",
|
|
83
101
|
context: "🧭",
|
|
102
|
+
tldr: "📝",
|
|
84
103
|
extensions: "🧩",
|
|
85
104
|
separator: "›",
|
|
86
105
|
},
|
|
@@ -88,6 +107,7 @@ const ICON_PRESETS: Record<
|
|
|
88
107
|
model: "",
|
|
89
108
|
thinking: "",
|
|
90
109
|
context: "",
|
|
110
|
+
tldr: "",
|
|
91
111
|
extensions: "",
|
|
92
112
|
separator: "",
|
|
93
113
|
},
|
|
@@ -111,7 +131,7 @@ function formatModelName(id: string | undefined): string {
|
|
|
111
131
|
return base.replace(/-\d{8}$/, "").replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
112
132
|
}
|
|
113
133
|
|
|
114
|
-
function thinkingColor(level: string):
|
|
134
|
+
function thinkingColor(level: string): ThemeColor {
|
|
115
135
|
switch (level) {
|
|
116
136
|
case "off":
|
|
117
137
|
return "thinkingOff";
|
|
@@ -137,7 +157,7 @@ function contextColor(
|
|
|
137
157
|
percent: number | null | undefined,
|
|
138
158
|
warningThreshold: number,
|
|
139
159
|
errorThreshold: number,
|
|
140
|
-
):
|
|
160
|
+
): ThemeColor {
|
|
141
161
|
if (percent === null || percent === undefined) return "muted";
|
|
142
162
|
if (percent >= errorThreshold) return "error";
|
|
143
163
|
if (percent >= warningThreshold) return "warning";
|
|
@@ -152,7 +172,7 @@ function parseSegments(): SegmentName[] {
|
|
|
152
172
|
.split(",")
|
|
153
173
|
.map((segment) => segment.trim().toLowerCase())
|
|
154
174
|
.filter((segment): segment is SegmentName =>
|
|
155
|
-
["model", "thinking", "context", "extensions"].includes(segment),
|
|
175
|
+
["model", "thinking", "context", "tldr", "extensions"].includes(segment),
|
|
156
176
|
);
|
|
157
177
|
|
|
158
178
|
return requested.length > 0 ? requested : DEFAULT_SEGMENTS;
|
|
@@ -192,6 +212,63 @@ function parseIconPreset(): IconPreset {
|
|
|
192
212
|
return "unicode";
|
|
193
213
|
}
|
|
194
214
|
|
|
215
|
+
function parseTldrMaxWidth(): number {
|
|
216
|
+
const raw = process.env.PI_BAR_TLDR_MAX_WIDTH;
|
|
217
|
+
if (!raw) return DEFAULT_TLDR_MAX_WIDTH;
|
|
218
|
+
|
|
219
|
+
const value = Number.parseInt(raw, 10);
|
|
220
|
+
if (Number.isFinite(value) && value >= 10 && value <= 500) return value;
|
|
221
|
+
return DEFAULT_TLDR_MAX_WIDTH;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function stripAnsi(value: string): string {
|
|
225
|
+
return value.replace(ANSI_PATTERN, "");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function extractTldrText(lines: readonly string[]): string | null {
|
|
229
|
+
const parts = lines
|
|
230
|
+
.map(stripAnsi)
|
|
231
|
+
.map((line) => line.trimEnd())
|
|
232
|
+
.filter((line) => line.trim().length > 0)
|
|
233
|
+
.filter((line) => !/^[╭╰].*[╮╯]$/.test(line.trim()))
|
|
234
|
+
.map((line) => {
|
|
235
|
+
const trimmed = line.trim();
|
|
236
|
+
if (trimmed.startsWith("│") && trimmed.endsWith("│")) {
|
|
237
|
+
return trimmed.slice(1, -1).trim();
|
|
238
|
+
}
|
|
239
|
+
return trimmed.replace(/^tldr:\s*/i, "").trim();
|
|
240
|
+
})
|
|
241
|
+
.filter(Boolean);
|
|
242
|
+
|
|
243
|
+
const text = parts.join(" ").replace(/\s+/g, " ").trim();
|
|
244
|
+
return text.length > 0 ? text : null;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function renderCapturedTldr(
|
|
248
|
+
widget: CapturedTldrWidget | undefined,
|
|
249
|
+
tui: TUI,
|
|
250
|
+
theme: Theme,
|
|
251
|
+
width: number,
|
|
252
|
+
maxWidth: number,
|
|
253
|
+
): string | null {
|
|
254
|
+
if (!widget) return null;
|
|
255
|
+
|
|
256
|
+
let lines: string[];
|
|
257
|
+
if (widget.kind === "lines") {
|
|
258
|
+
lines = widget.lines;
|
|
259
|
+
} else {
|
|
260
|
+
const component = widget.factory(tui, theme);
|
|
261
|
+
try {
|
|
262
|
+
lines = component.render(Math.max(12, width));
|
|
263
|
+
} finally {
|
|
264
|
+
component.dispose?.();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const text = extractTldrText(lines);
|
|
269
|
+
return text ? truncateToWidth(text, maxWidth) : null;
|
|
270
|
+
}
|
|
271
|
+
|
|
195
272
|
function prefixed(icon: string, text: string, preset: IconPreset): string {
|
|
196
273
|
if (preset === "plain") return `${icon}:${text}`;
|
|
197
274
|
return `${icon} ${text}`;
|
|
@@ -291,8 +368,39 @@ function getKnownStatusKeys(filter: StatusFilter, seenStatusKeys: Set<string>):
|
|
|
291
368
|
export default function (pi: ExtensionAPI) {
|
|
292
369
|
let requestRender: (() => void) | undefined;
|
|
293
370
|
let statusFilter: StatusFilter = { mode: "all", hidden: new Set() };
|
|
371
|
+
let capturedTldrWidget: CapturedTldrWidget | undefined;
|
|
294
372
|
const seenStatusKeys = new Set<string>();
|
|
373
|
+
const patchedUis = new WeakSet<object>();
|
|
295
374
|
const refresh = () => requestRender?.();
|
|
375
|
+
const installTldrWidgetCapture = (ctx: ExtensionContext) => {
|
|
376
|
+
if (!ctx.hasUI) return;
|
|
377
|
+
const ui = ctx.ui as ExtensionContext["ui"];
|
|
378
|
+
if (patchedUis.has(ui)) return;
|
|
379
|
+
patchedUis.add(ui);
|
|
380
|
+
|
|
381
|
+
const originalSetWidget = ui.setWidget.bind(ui);
|
|
382
|
+
ui.setWidget = ((key: string, content: unknown, options?: unknown) => {
|
|
383
|
+
if (key === TLDR_WIDGET_KEY) {
|
|
384
|
+
if (Array.isArray(content)) {
|
|
385
|
+
capturedTldrWidget = { kind: "lines", lines: content };
|
|
386
|
+
} else if (typeof content === "function") {
|
|
387
|
+
capturedTldrWidget = {
|
|
388
|
+
kind: "factory",
|
|
389
|
+
factory: content as TldrWidgetFactory,
|
|
390
|
+
};
|
|
391
|
+
} else {
|
|
392
|
+
capturedTldrWidget = undefined;
|
|
393
|
+
}
|
|
394
|
+
refresh();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return originalSetWidget(
|
|
398
|
+
key,
|
|
399
|
+
content as Parameters<ExtensionContext["ui"]["setWidget"]>[1],
|
|
400
|
+
options as Parameters<ExtensionContext["ui"]["setWidget"]>[2],
|
|
401
|
+
);
|
|
402
|
+
}) as ExtensionContext["ui"]["setWidget"];
|
|
403
|
+
};
|
|
296
404
|
const restoreStatusFilter = (ctx: ExtensionContext) => {
|
|
297
405
|
let restoredFilter = readGlobalStatusFilter();
|
|
298
406
|
if (!restoredFilter) {
|
|
@@ -481,11 +589,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
481
589
|
pi.on("turn_end", async () => refresh());
|
|
482
590
|
pi.on("message_end", async () => refresh());
|
|
483
591
|
pi.on("session_tree", async (_event, ctx) => {
|
|
592
|
+
installTldrWidgetCapture(ctx);
|
|
484
593
|
restoreStatusFilter(ctx);
|
|
485
594
|
refresh();
|
|
486
595
|
});
|
|
487
596
|
|
|
488
597
|
pi.on("session_start", async (_event, ctx) => {
|
|
598
|
+
capturedTldrWidget = undefined;
|
|
599
|
+
installTldrWidgetCapture(ctx);
|
|
489
600
|
restoreStatusFilter(ctx);
|
|
490
601
|
|
|
491
602
|
if (!ctx.hasUI) return;
|
|
@@ -494,6 +605,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
494
605
|
const iconPreset = parseIconPreset();
|
|
495
606
|
const icons = ICON_PRESETS[iconPreset];
|
|
496
607
|
const { warningThreshold, errorThreshold } = parseThresholds();
|
|
608
|
+
const tldrMaxWidth = parseTldrMaxWidth();
|
|
497
609
|
|
|
498
610
|
ctx.ui.setFooter((tui, theme, footerData) => {
|
|
499
611
|
requestRender = () => tui.requestRender();
|
|
@@ -521,6 +633,13 @@ export default function (pi: ExtensionAPI) {
|
|
|
521
633
|
const contextText = usage
|
|
522
634
|
? `${usage.percent !== null ? `${usage.percent.toFixed(1)}%` : "—%"} / ${formatTokens(usage.contextWindow)}`
|
|
523
635
|
: "—";
|
|
636
|
+
const tldrText = renderCapturedTldr(
|
|
637
|
+
capturedTldrWidget,
|
|
638
|
+
tui,
|
|
639
|
+
theme,
|
|
640
|
+
width,
|
|
641
|
+
tldrMaxWidth,
|
|
642
|
+
);
|
|
524
643
|
|
|
525
644
|
const segmentRenderers: Record<SegmentName, string | null> = {
|
|
526
645
|
model: theme.fg(
|
|
@@ -535,6 +654,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
535
654
|
contextSegmentColor,
|
|
536
655
|
prefixed(icons.context, contextText, iconPreset),
|
|
537
656
|
),
|
|
657
|
+
tldr: tldrText
|
|
658
|
+
? theme.fg("muted", prefixed(icons.tldr, tldrText, iconPreset))
|
|
659
|
+
: null,
|
|
538
660
|
extensions: extensionStatuses
|
|
539
661
|
? theme.fg(
|
|
540
662
|
"muted",
|
|
@@ -556,6 +678,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
556
678
|
});
|
|
557
679
|
|
|
558
680
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
681
|
+
capturedTldrWidget = undefined;
|
|
559
682
|
if (ctx.hasUI) ctx.ui.setFooter(undefined);
|
|
560
683
|
});
|
|
561
684
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-bar",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Never accidentally run Opus on a typo. Pi footer/statusline showing active model, thinking level, context usage, and extension statuses.",
|
|
3
|
+
"version": "0.3.6",
|
|
4
|
+
"description": "Never accidentally run Opus on a typo. Pi footer/statusline showing active model, thinking level, context usage, pi-tldr, and extension statuses.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"pi-package",
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"model",
|
|
14
14
|
"thinking",
|
|
15
15
|
"context",
|
|
16
|
-
"context-window"
|
|
16
|
+
"context-window",
|
|
17
|
+
"tldr",
|
|
18
|
+
"pi-tldr"
|
|
17
19
|
],
|
|
18
20
|
"license": "MIT",
|
|
19
21
|
"repository": {
|
|
@@ -46,6 +48,6 @@
|
|
|
46
48
|
"extensions": [
|
|
47
49
|
"./extensions/status-footer.ts"
|
|
48
50
|
],
|
|
49
|
-
"image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.
|
|
51
|
+
"image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.6/assets/screenshot.png"
|
|
50
52
|
}
|
|
51
53
|
}
|