@narumitw/pi-statusline 0.1.17 → 0.1.19
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 +10 -8
- package/package.json +1 -1
- package/src/statusline.ts +22 -21
package/README.md
CHANGED
|
@@ -10,8 +10,9 @@ Use it to monitor model selection, thinking level, git branch, working directory
|
|
|
10
10
|
|
|
11
11
|
- Replaces the default Pi footer with a compact rich statusline.
|
|
12
12
|
- Shows model, thinking level, git branch, project directory, active tool, context usage, tokens, cost, and clock.
|
|
13
|
-
- Displays compact
|
|
14
|
-
-
|
|
13
|
+
- Displays compact statuses from other extensions without knowing about specific packages.
|
|
14
|
+
- Preserves extension-provided status icons when the status text starts with one.
|
|
15
|
+
- Shows active subagent count and execution mode while subagent tools are running.
|
|
15
16
|
- Warns when the same extension package is installed from multiple sources.
|
|
16
17
|
- Uses emoji-labeled segments for readability.
|
|
17
18
|
- Adapts to terminal width and truncates safely.
|
|
@@ -50,15 +51,16 @@ The default statusline includes:
|
|
|
50
51
|
- 💰 estimated cost.
|
|
51
52
|
- 🕒 clock.
|
|
52
53
|
|
|
53
|
-
Statuses from other extensions
|
|
54
|
+
Statuses from other extensions appear on their own compact line below the main statusline and are separated with ``.
|
|
55
|
+
|
|
56
|
+
`pi-statusline` is extension-agnostic: it does not map package names to icons. If an extension wants a custom icon, it should include that icon at the start of its status text, for example `ctx.ui.setStatus("goal", "🎯 active")`. Statuses without a leading icon use the generic `🔌` icon.
|
|
54
57
|
|
|
55
58
|
Examples:
|
|
56
59
|
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- `🧑🤝🧑 2 parallel` while subagents are active.
|
|
60
|
+
- `🔌 active` for a plain status such as `goal: active`.
|
|
61
|
+
- `🎯 active` when the producing extension sets `🎯 active`.
|
|
62
|
+
- `🐍 ty ✓ ruff ✓` when the producing extension sets a Python status with a leading icon.
|
|
63
|
+
- `🧑🤝🧑 2 parallel` while subagent tool calls are active.
|
|
62
64
|
- `⚠️ dup biome-lsp` when local and npm installs register the same extension.
|
|
63
65
|
|
|
64
66
|
## 🧠 Use cases
|
package/package.json
CHANGED
package/src/statusline.ts
CHANGED
|
@@ -423,10 +423,11 @@ function formatExtensionStatuses(
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
function formatExtensionStatus(key: string, value: string, theme: Theme): string {
|
|
426
|
-
const
|
|
426
|
+
const status = splitExtensionStatusIcon(stripExtensionStatusPrefix(key, value));
|
|
427
|
+
const text = truncateToWidth(simplifyExtensionStatusText(status.text), 22, "…");
|
|
427
428
|
const color = extensionColor(key, value);
|
|
428
|
-
const textColor =
|
|
429
|
-
return `${theme.fg(color,
|
|
429
|
+
const textColor = color === "warning" ? "warning" : "muted";
|
|
430
|
+
return `${theme.fg(color, status.icon)} ${theme.fg(textColor, text)}`;
|
|
430
431
|
}
|
|
431
432
|
|
|
432
433
|
function formatSubagentStatus(runtime: RuntimeState, theme: Theme): string[] {
|
|
@@ -446,20 +447,19 @@ function formatDuplicateExtensionStatus(runtime: RuntimeState, theme: Theme): st
|
|
|
446
447
|
return [`${theme.fg("warning", "⚠️")} ${theme.fg("warning", `dup ${names}${suffix}`)}`];
|
|
447
448
|
}
|
|
448
449
|
|
|
449
|
-
function
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
if (
|
|
453
|
-
return "
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
return "🔌";
|
|
450
|
+
function splitExtensionStatusIcon(value: string): { icon: string; text: string } {
|
|
451
|
+
const trimmed = value.trim();
|
|
452
|
+
const [firstToken, ...restTokens] = trimmed.split(/\s+/);
|
|
453
|
+
if (firstToken && isEmojiOnlyToken(firstToken)) {
|
|
454
|
+
return { icon: firstToken, text: restTokens.join(" ") };
|
|
455
|
+
}
|
|
456
|
+
return { icon: "🔌", text: trimmed };
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function isEmojiOnlyToken(value: string): boolean {
|
|
460
|
+
return /^(?=.*(?:\p{Extended_Pictographic}|\p{Regional_Indicator}|[0-9#*]\ufe0f?\u20e3))(?:\p{Extended_Pictographic}|\p{Emoji_Modifier}|\p{Regional_Indicator}|\u200d|\ufe0f|[0-9#*]\ufe0f?\u20e3)+$/u.test(
|
|
461
|
+
value,
|
|
462
|
+
);
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
function extensionColor(key: string, value: string): ThemeColor {
|
|
@@ -470,12 +470,13 @@ function extensionColor(key: string, value: string): ThemeColor {
|
|
|
470
470
|
return "muted";
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
-
function
|
|
473
|
+
function stripExtensionStatusPrefix(key: string, value: string): string {
|
|
474
|
+
return value.trim().replace(new RegExp(`^${escapeRegExp(key)}\\s*:\\s*`, "iu"), "");
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function simplifyExtensionStatusText(value: string): string {
|
|
474
478
|
return value
|
|
475
479
|
.trim()
|
|
476
|
-
.replace(new RegExp(`^${escapeRegExp(key)}\\s*:\\s*`, "iu"), "")
|
|
477
|
-
.replace(/^python-lsp\s*:\s*/iu, "")
|
|
478
|
-
.replace(/^biome-lsp\s*:\s*/iu, "")
|
|
479
480
|
.replace(/\bready\b/giu, "✓")
|
|
480
481
|
.replace(/\bmissing\b/giu, "✗")
|
|
481
482
|
.replace(/,\s*/g, " ")
|