Skip to content

Commit 51ded33

Browse files
authored
Merge pull request #7 from narumiruna/feat/pi-statusline
style(statusline): add emoji markers
2 parents 2840438 + 42db422 commit 51ded33

2 files changed

Lines changed: 40 additions & 26 deletions

File tree

extensions/pi-statusline/README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ pi -e ./extensions/pi-statusline
2525
The default statusline includes:
2626

2727
- `π` brand marker
28-
- current model
29-
- thinking level
30-
- git branch
31-
- current project directory
32-
- active or last tool
33-
- context usage percentage
34-
- token totals
35-
- estimated cost
36-
- clock
37-
38-
Statuses from other extensions, such as goal mode, appear on their own line below the main statusline and are separated with ``.
28+
- emoji-labeled current model
29+
- emoji-labeled thinking level
30+
- emoji-labeled git branch
31+
- emoji-labeled current project directory
32+
- emoji-labeled active or last tool
33+
- emoji-labeled context usage percentage
34+
- emoji-labeled token totals
35+
- emoji-labeled estimated cost
36+
- emoji-labeled clock
37+
38+
Statuses from other extensions, such as goal mode, appear on their own emoji-labeled line below the main statusline and are separated with ``.
3939
The layout adapts to terminal width and truncates safely.
4040

4141
## Package layout

extensions/pi-statusline/src/statusline.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -253,41 +253,47 @@ function buildSegment(
253253
case "brand":
254254
return { name, text: "π", color: "accent", emphasis: true };
255255
case "model":
256-
return labeled(name, shortenModel(ctx.model?.id ?? "no-model"), color, config);
256+
return labeled(name, `🤖 ${shortenModel(ctx.model?.id ?? "no-model")}`, color, config);
257257
case "thinking":
258-
return labeled(name, runtime.thinkingLevel, thinkingColor(runtime.thinkingLevel), config);
258+
return labeled(
259+
name,
260+
`🧠 ${runtime.thinkingLevel}`,
261+
thinkingColor(runtime.thinkingLevel),
262+
config,
263+
);
259264
case "branch":
260-
return labeled(name, footerData.getGitBranch() ?? "no-git", color, config);
265+
return labeled(name, `🌿 ${footerData.getGitBranch() ?? "no-git"}`, color, config);
261266
case "cwd":
262-
return labeled(name, basename(ctx.cwd) || ctx.cwd, color, config);
267+
return labeled(name, `📁 ${basename(ctx.cwd) || ctx.cwd}`, color, config);
263268
case "tools":
264269
return labeled(name, formatToolActivity(runtime), color, config);
265270
case "context": {
266271
const usage = ctx.getContextUsage();
267272
const value =
268273
usage?.percent === null || usage?.percent === undefined
269-
? "ctx ?"
270-
: `ctx ${usage.percent.toFixed(0)}%`;
274+
? "🪟 ctx ?"
275+
: `🪟 ctx ${usage.percent.toFixed(0)}%`;
271276
return labeled(name, value, contextColor(usage?.percent), config);
272277
}
273278
case "tokens": {
274279
const totals = getTokenTotals(ctx);
275-
if (totals.input === 0 && totals.output === 0) return labeled(name, "tok 0", color, config);
280+
if (totals.input === 0 && totals.output === 0)
281+
return labeled(name, "🔢 tok 0", color, config);
276282
return labeled(
277283
name,
278-
`↑${formatCount(totals.input)}${formatCount(totals.output)}`,
284+
`🔢 ${formatCount(totals.input)}${formatCount(totals.output)}`,
279285
color,
280286
config,
281287
);
282288
}
283289
case "cost": {
284290
const totals = getTokenTotals(ctx);
285-
return labeled(name, `$${totals.cost.toFixed(totals.cost >= 1 ? 2 : 3)}`, color, config);
291+
return labeled(name, `💸 $${totals.cost.toFixed(totals.cost >= 1 ? 2 : 3)}`, color, config);
286292
}
287293
case "time":
288-
return labeled(name, formatTime(), color, config);
294+
return labeled(name, `🕒 ${formatTime()}`, color, config);
289295
case "turn":
290-
return labeled(name, `#${runtime.turnCount}`, color, config);
296+
return labeled(name, `🔁 #${runtime.turnCount}`, color, config);
291297
}
292298
}
293299

@@ -377,9 +383,9 @@ function formatToolActivity(runtime: RuntimeState): string {
377383
return `⚙ ${name}${suffix}`;
378384
}
379385

380-
if (runtime.isStreaming) return "thinking";
381-
if (runtime.lastCompletedTool) return ` ${runtime.lastCompletedTool}`;
382-
return "idle";
386+
if (runtime.isStreaming) return "💭 thinking";
387+
if (runtime.lastCompletedTool) return ` ${runtime.lastCompletedTool}`;
388+
return "💤 idle";
383389
}
384390

385391
function formatExtensionStatuses(statuses: ReadonlyMap<string, string>, theme: Theme): string {
@@ -388,14 +394,22 @@ function formatExtensionStatuses(statuses: ReadonlyMap<string, string>, theme: T
388394
.filter(([key, value]) => key !== STATUSLINE_KEY && value.trim().length > 0)
389395
.slice(0, 3)
390396
.map(([key, value]) => {
391-
const label = theme.fg("dim", `${key}: `);
397+
const label = theme.fg("dim", `${extensionIcon(key)} ${key}: `);
392398
const text = truncateToWidth(simplifyExtensionStatus(key, value), 24, "…");
393399
return `${label}${text}`;
394400
});
395401

396402
return visibleStatuses.join(separator);
397403
}
398404

405+
function extensionIcon(key: string): string {
406+
if (key.includes("caffeinate")) return "☕";
407+
if (key.includes("chrome") || key.includes("devtools") || key === "cdp") return "🌐";
408+
if (key.includes("firecrawl")) return "🔥";
409+
if (key.includes("goal")) return "🎯";
410+
return "🔌";
411+
}
412+
399413
function simplifyExtensionStatus(key: string, value: string): string {
400414
return value
401415
.trim()

0 commit comments

Comments
 (0)