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 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 sort order, token balance display (color-coded warnings with configurable thresholds), git status tokens, and tool activity indicators; minor display tweaks for selected third-party extensions, keeping it clean.
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
- | `/se` | Show or set extension status sort order |
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 打造的整洁页脚 — 沿用原生布局,叠加了新的功能:插件自定义排序、token 余额显示(颜色警告、自定义警告阈值)、Git 状态标记、工具活动指示;对部分第三方插件进行名称显示微调,保持简洁。
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
- | `/se` | 查看或设置扩展状态排列顺序 |
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
- let statusLine = extItems.join(" ");
569
- // Rewrite MCP: prefix with dim colour, reset after the colon
570
- statusLine = statusLine.replace(
571
- /MCP:/,
572
- `\x1b[38;2;128;128;128mMCP:${mcpRgb || "\x1b[38;2;138;190;183m"}`,
573
- );
574
- lines.push(truncateToWidth(statusLine, width, theme.fg("dim", "...")));
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("se", {
720
- description:
721
- "Sort extension statuses (no args = show order, keys = set order)",
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.0",
4
- "description": "Tidy footer for Pi coding agent — native layout, layered with new features: extension sort order, token balance display (color-coded warnings with configurable thresholds), git status tokens, and tool activity indicators; minor display tweaks for selected third-party extensions, keeping it clean.",
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
- "pi": {
19
- "extensions": [
20
- "./extensions/pi-tidy-footer.ts"
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
  }