pi-tidy-footer 0.4.0 → 0.5.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/CHANGELOG.md +34 -0
- package/README.md +8 -6
- package/extensions/pi-tidy-footer.ts +75 -16
- package/package.json +19 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
[中文](#中文)
|
|
4
4
|
|
|
5
|
+
## [0.5.0] - 2026-07-23
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `/es` command: extension sort (renamed from `/se`), show or set sort order
|
|
10
|
+
- `/ew` command: toggle extension wrap mode (on/off), persisted across sessions; when on, extension statuses wrap at entry boundaries instead of truncating with `...`
|
|
11
|
+
- `peerDependencies` declared for `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui`
|
|
12
|
+
- `homepage` field added to package.json
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Extension status wrapping: entries now wrap atomically at extension boundary (single-entry overflow still truncates); replaces the native footer's single-line truncation behaviour
|
|
17
|
+
- `pi.extensions` value changed from a single-file path (`./extensions/pi-tidy-footer.ts`) to a directory path (`./extensions`) for compatibility with pi.dev indexing
|
|
18
|
+
- `package.json` fields reordered to standard convention
|
|
19
|
+
- `/se` renamed to `/es` for consistency with other `/e-` prefixed extension commands
|
|
20
|
+
- Description and README updated
|
|
21
|
+
|
|
5
22
|
## [0.4.0] - 2026-07-22
|
|
6
23
|
|
|
7
24
|
### Added
|
|
@@ -63,6 +80,23 @@
|
|
|
63
80
|
|
|
64
81
|
## 中文
|
|
65
82
|
|
|
83
|
+
## [0.5.0] - 2026-07-23
|
|
84
|
+
|
|
85
|
+
### 新增
|
|
86
|
+
|
|
87
|
+
- `/es` 命令:扩展排序(原 `/se` 重命名),查看或设置排列顺序
|
|
88
|
+
- `/ew` 命令:切换扩展换行模式(开/关),持久化存储;开启后扩展状态按条目边界换行,不再截断加 `...`
|
|
89
|
+
- 声明 `peerDependencies`:`@earendil-works/pi-ai`、`@earendil-works/pi-coding-agent`、`@earendil-works/pi-tui`
|
|
90
|
+
- 新增 `homepage` 字段
|
|
91
|
+
|
|
92
|
+
### 变更
|
|
93
|
+
|
|
94
|
+
- 扩展状态换行:以扩展条目为原子换行(单条超宽仍截断),替代原生 footer 的单行截断行为
|
|
95
|
+
- `pi.extensions` 从单文件路径改为目录路径(`./extensions`),兼容 pi.dev 索引
|
|
96
|
+
- `package.json` 字段顺序按行业规范重新排列
|
|
97
|
+
- 描述与 README 更新:「插件自定义排序与换行、token 余额显示、Git 文件状态、工具活动指示」
|
|
98
|
+
- `/se` 重命名为 `/es`,与后续 `e-` 前缀扩展命令统一
|
|
99
|
+
|
|
66
100
|
## [0.4.0] - 2026-07-22
|
|
67
101
|
|
|
68
102
|
### 新增
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[中文](#中文)
|
|
4
4
|
|
|
5
|
-
Tidy footer for Pi coding agent — native layout, layered with new features: extension
|
|
5
|
+
Tidy footer for Pi coding agent — native layout, layered with new features: extension sorting and wrapping, token balance display (color-coded warnings with configurable thresholds), git file status, and tool activity indicators; minor display tweaks for extension labels, keeping it clean.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -12,8 +12,8 @@ pi install npm:pi-tidy-footer
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
- **Account balance** — Shows DeepSeek or Kimi account balance after the model name (`¤¥` format), yellow below warn threshold, red below alert threshold, both configurable
|
|
16
15
|
- **Extension sort order** — Custom sort order for extension statuses, persisted across sessions; run empty command to view the current order prompt
|
|
16
|
+
- **Account balance** — Shows DeepSeek or Kimi account balance after the model name (`¤¥` format), yellow below warn threshold, red below alert threshold, both configurable
|
|
17
17
|
- **Git status tokens** — Repo state next to the branch name: `⇡` ahead, `⇣` behind, `+` staged, `~` modified, `?` untracked, `!` conflicts; hidden when clean
|
|
18
18
|
- **Tool activity indicator** — Shows the running tool (highlighted) before the model name with brief hold for fast tools; hidden when idle
|
|
19
19
|
- **Hide per-session cost** — Removes `$0.604` from the left stats area, keeping it token-focused
|
|
@@ -32,13 +32,14 @@ pi install npm:pi-tidy-footer
|
|
|
32
32
|
| --- | --- |
|
|
33
33
|
| `/tf` | Toggle pi-tidy-footer (on/off) |
|
|
34
34
|
| `/bt <warn> <alert>` | Set balance yellow/red thresholds (warn > alert required) |
|
|
35
|
-
| `/
|
|
35
|
+
| `/es` | Extension sort (no args = show order, args = set order) |
|
|
36
|
+
| `/ew` | Toggle extension wrap (on/off) |
|
|
36
37
|
|
|
37
38
|
---
|
|
38
39
|
|
|
39
40
|
## 中文
|
|
40
41
|
|
|
41
|
-
为 Pi coding agent 打造的整洁页脚 —
|
|
42
|
+
为 Pi coding agent 打造的整洁页脚 — 沿用原生布局,叠加了新的功能:插件自定义排序与换行、token 余额显示(颜色警告、自定义警告阈值)、Git 文件状态、工具活动指示;对插件标签进行显示微调,保持简洁。
|
|
42
43
|
|
|
43
44
|
## 安装
|
|
44
45
|
|
|
@@ -48,8 +49,8 @@ pi install npm:pi-tidy-footer
|
|
|
48
49
|
|
|
49
50
|
## 功能
|
|
50
51
|
|
|
51
|
-
- **账户余额** — 模型名后显示 DeepSeek / Kimi 账户余额(`¤¥` 格式),低于预警值(warn)变黄,低于警报值(alert)变红,阈值可自定义
|
|
52
52
|
- **插件自定义排序** — 扩展状态按自定义顺序排列,持久化存储;可使用空命令查看排序字段提示
|
|
53
|
+
- **账户余额** — 模型名后显示 DeepSeek / Kimi 账户余额(`¤¥` 格式),低于预警值(warn)变黄,低于警报值(alert)变红,阈值可自定义
|
|
53
54
|
- **Git 状态标记** — 分支名旁显示仓库状态:`⇡` 领先、`⇣` 落后、`+` 已暂存、`~` 已修改、`?` 未跟踪、`!` 冲突;干净仓库不显示
|
|
54
55
|
- **工具活动指示** — 模型名前实时显示正在运行的工具(高亮),快工具至少有短暂停留;空闲时不显示
|
|
55
56
|
- **去除会话费用显示** — 从左侧统计模块移除 `$0.604`,让统计专注 token
|
|
@@ -68,4 +69,5 @@ pi install npm:pi-tidy-footer
|
|
|
68
69
|
| --- | --- |
|
|
69
70
|
| `/tf` | 切换 pi-tidy-footer 页脚(开/关) |
|
|
70
71
|
| `/bt <warn> <alert>` | 设置余额黄/红阈值(warn > alert) |
|
|
71
|
-
| `/
|
|
72
|
+
| `/es` | 扩展排序(空参查看,传参设置) |
|
|
73
|
+
| `/ew` | 切换扩展换行模式(开/关) |
|
|
@@ -73,6 +73,30 @@ function writePersistedEnabled(enabled: boolean): void {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
function readWrapEnabled(): boolean {
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(readFileSync(STATE_FILE, "utf-8")).wrapEnabled === true;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function writeWrapEnabled(wrap: boolean): void {
|
|
85
|
+
try {
|
|
86
|
+
const prev: any = existsSync(STATE_FILE)
|
|
87
|
+
? JSON.parse(readFileSync(STATE_FILE, "utf-8"))
|
|
88
|
+
: {};
|
|
89
|
+
mkdirSync(STATE_DIR, { recursive: true });
|
|
90
|
+
writeFileSync(
|
|
91
|
+
STATE_FILE,
|
|
92
|
+
JSON.stringify({ ...prev, wrapEnabled: wrap }),
|
|
93
|
+
"utf-8",
|
|
94
|
+
);
|
|
95
|
+
} catch {
|
|
96
|
+
/* no-op */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
76
100
|
function readExtensionOrder(): string[] {
|
|
77
101
|
const fallback = ["caveman", "ponytail", "mcp", "pi-lens-lsp"];
|
|
78
102
|
try {
|
|
@@ -271,6 +295,8 @@ function makeFooter(
|
|
|
271
295
|
let balanceLastFetch = 0;
|
|
272
296
|
let balanceInFlight = false;
|
|
273
297
|
|
|
298
|
+
const wrapEnabled = readWrapEnabled();
|
|
299
|
+
|
|
274
300
|
const runGitStatus = () => {
|
|
275
301
|
if (disposed) return;
|
|
276
302
|
if (gitInFlight) {
|
|
@@ -517,8 +543,8 @@ function makeFooter(
|
|
|
517
543
|
line2 = theme.fg("dim", left);
|
|
518
544
|
}
|
|
519
545
|
|
|
520
|
-
/* extension statuses */
|
|
521
|
-
const extItems: string[] = [];
|
|
546
|
+
/* extension statuses — keep key for grouped wrapping */
|
|
547
|
+
const extItems: [string, string][] = [];
|
|
522
548
|
const raw = fd.getExtensionStatuses();
|
|
523
549
|
let mcpRgb = ""; // capture original MCP accent colour so theme changes work
|
|
524
550
|
if (raw.size > 0) {
|
|
@@ -535,7 +561,7 @@ function makeFooter(
|
|
|
535
561
|
const s = (v as string)
|
|
536
562
|
.replace("caveman level:", "Caveman:")
|
|
537
563
|
.replace(/(FULL|ULTRA|LITE|OFF)/g, (w) => w.toLowerCase());
|
|
538
|
-
return s;
|
|
564
|
+
return [k, s] as [string, string];
|
|
539
565
|
}
|
|
540
566
|
if (k === "ponytail") {
|
|
541
567
|
const s = (v as string)
|
|
@@ -545,11 +571,11 @@ function makeFooter(
|
|
|
545
571
|
" 🐴 \x1b[38;2;128;128;128mponytail:",
|
|
546
572
|
" 🐴\x1b[38;2;128;128;128mponytail:",
|
|
547
573
|
);
|
|
548
|
-
return s;
|
|
574
|
+
return [k, s] as [string, string];
|
|
549
575
|
}
|
|
550
|
-
return (v as string).trim();
|
|
576
|
+
return [k, (v as string).trim()] as [string, string];
|
|
551
577
|
})
|
|
552
|
-
.filter(Boolean);
|
|
578
|
+
.filter(([, v]) => Boolean(v));
|
|
553
579
|
extItems.push(...sorted);
|
|
554
580
|
}
|
|
555
581
|
|
|
@@ -565,13 +591,34 @@ function makeFooter(
|
|
|
565
591
|
line2,
|
|
566
592
|
];
|
|
567
593
|
if (extItems.length > 0) {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
594
|
+
if (wrapEnabled) {
|
|
595
|
+
let current = "";
|
|
596
|
+
for (const [, text] of extItems) {
|
|
597
|
+
// MCP colour rewrite
|
|
598
|
+
const seg = text.replace(
|
|
599
|
+
/MCP:/,
|
|
600
|
+
`\x1b[38;2;128;128;128mMCP:${mcpRgb || "\x1b[38;2;138;190;183m"}`,
|
|
601
|
+
);
|
|
602
|
+
const test = current ? `${current} ${seg}` : seg;
|
|
603
|
+
if (visibleWidth(test) > width) {
|
|
604
|
+
if (current) lines.push(current);
|
|
605
|
+
current = seg;
|
|
606
|
+
} else {
|
|
607
|
+
current = test;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
// ponytail: last-resort truncation only if a single entry exceeds terminal width
|
|
611
|
+
if (current && visibleWidth(current) > width) {
|
|
612
|
+
lines.push(truncateToWidth(current, width, theme.fg("dim", "...")));
|
|
613
|
+
} else if (current) {
|
|
614
|
+
lines.push(current);
|
|
615
|
+
}
|
|
616
|
+
} else {
|
|
617
|
+
const statusLine = extItems.map(([, t]) => t).join(" ");
|
|
618
|
+
lines.push(
|
|
619
|
+
truncateToWidth(statusLine, width, theme.fg("dim", "...")),
|
|
620
|
+
);
|
|
621
|
+
}
|
|
575
622
|
}
|
|
576
623
|
|
|
577
624
|
return lines;
|
|
@@ -716,9 +763,21 @@ export default function (pi: any) {
|
|
|
716
763
|
},
|
|
717
764
|
});
|
|
718
765
|
|
|
719
|
-
pi.registerCommand("
|
|
720
|
-
description:
|
|
721
|
-
|
|
766
|
+
pi.registerCommand("ew", {
|
|
767
|
+
description: "Toggle extension wrap (on/off)",
|
|
768
|
+
handler: async (_args: string, ctx: any) => {
|
|
769
|
+
const next = !readWrapEnabled();
|
|
770
|
+
writeWrapEnabled(next);
|
|
771
|
+
if (enabled) applyFooter(ctx);
|
|
772
|
+
ctx.ui.notify(
|
|
773
|
+
next ? "Extension wrap ON" : "Extension wrap OFF (truncate)",
|
|
774
|
+
"info",
|
|
775
|
+
);
|
|
776
|
+
},
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
pi.registerCommand("es", {
|
|
780
|
+
description: "Extension sort (no args = show order, keys = set order)",
|
|
722
781
|
handler: async (args: string, ctx: any) => {
|
|
723
782
|
const trimmed = args.trim();
|
|
724
783
|
if (!trimmed) {
|
package/package.json
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-tidy-footer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Tidy footer for Pi coding agent — native layout, layered with new features: extension
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Tidy footer for Pi coding agent — native layout, layered with new features: extension sorting and wrapping, token balance display (color-coded warnings with configurable thresholds), git file status, and tool activity indicators; minor display tweaks for extension labels, keeping it clean.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "extensions/pi-tidy-footer.ts",
|
|
7
6
|
"license": "MIT",
|
|
7
|
+
"author": "eriiic7z",
|
|
8
|
+
"homepage": "https://github.com/eriiic7z/pi-tidy-footer#readme",
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
10
11
|
"url": "git+https://github.com/eriiic7z/pi-tidy-footer.git"
|
|
11
12
|
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"pi-package",
|
|
15
|
+
"pi-extension",
|
|
16
|
+
"extension"
|
|
17
|
+
],
|
|
18
|
+
"main": "extensions/pi-tidy-footer.ts",
|
|
12
19
|
"files": [
|
|
13
20
|
"extensions",
|
|
14
21
|
"README.md",
|
|
15
22
|
"CHANGELOG.md",
|
|
16
23
|
"LICENSE"
|
|
17
24
|
],
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@earendil-works/pi-ai": "*",
|
|
27
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
28
|
+
"@earendil-works/pi-tui": "*"
|
|
22
29
|
},
|
|
23
|
-
"keywords": [
|
|
24
|
-
"pi-package",
|
|
25
|
-
"pi-extension",
|
|
26
|
-
"extension"
|
|
27
|
-
],
|
|
28
|
-
"author": "eriiic7z",
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@types/node": "^26.1.1"
|
|
32
|
+
},
|
|
33
|
+
"pi": {
|
|
34
|
+
"extensions": [
|
|
35
|
+
"./extensions"
|
|
36
|
+
]
|
|
31
37
|
}
|
|
32
38
|
}
|