@lokiyou/pi-nano-footer 0.14.0 → 0.15.1
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 +21 -27
- package/index.ts +2 -79
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @lokiyou/pi-nano-footer
|
|
2
2
|
|
|
3
|
-
超轻量 powerline 风格 footer for **Pi Coding Agent
|
|
3
|
+
超轻量 powerline 风格 footer for **Pi Coding Agent**。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
它保留 Pi 内置的 `Working...` 指示器,同时在底部显示模型、思考等级、目录、上下文、token 和费用,整体走的是清爽、紧凑的霓虹风。
|
|
6
6
|
|
|
7
7
|
## 安装
|
|
8
8
|
|
|
@@ -10,35 +10,29 @@
|
|
|
10
10
|
pi install npm:@lokiyou/pi-nano-footer
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
安装后重载 Pi:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
deepseek-v4-flash think:high project 45.2%/128K 1.2k 0.03
|
|
15
|
+
```bash
|
|
16
|
+
/reload
|
|
19
17
|
```
|
|
20
18
|
|
|
19
|
+
## 展示内容
|
|
20
|
+
|
|
21
21
|
从左到右依次展示:
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
| thinking high/xhigh | rainbow | 彩虹渐变 |
|
|
37
|
-
| 上下文正常 | `#6c5ce7` | 紫色 |
|
|
38
|
-
| 上下文 >70% | `#fdcb6e` | 黄色警告 |
|
|
39
|
-
| 上下文 >90% | `#ff3366` | 红色错误 |
|
|
40
|
-
| 费用 | `#fdcb6e` | 明黄 |
|
|
41
|
-
| tokens | `#00ff87` | 荧光绿 |
|
|
22
|
+
|
|
23
|
+
- 🤖 模型名
|
|
24
|
+
- 💭 思考等级
|
|
25
|
+
- 📁 当前目录名
|
|
26
|
+
- 📊 上下文用量
|
|
27
|
+
- 💾 Token 用量
|
|
28
|
+
- 💰 费用
|
|
29
|
+
|
|
30
|
+
## 风格
|
|
31
|
+
|
|
32
|
+
- 采用 powerline 分隔符
|
|
33
|
+
- 颜色和 `pi-powerline-footer` 的默认 preset 保持一致
|
|
34
|
+
- 不替代内置工作状态指示器
|
|
35
|
+
- 适合想要简洁 footer、但不想丢掉 Pi 原生反馈的人
|
|
42
36
|
|
|
43
37
|
## 许可
|
|
44
38
|
|
package/index.ts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* pi-nano-footer — 超轻量 powerline 风格 footer
|
|
2
|
+
* pi-nano-footer — 超轻量 powerline 风格 footer
|
|
3
3
|
*
|
|
4
4
|
* 精确复刻 pi-powerline-footer default 预设的样式 +
|
|
5
5
|
* 用户自定义霓虹色配色方案。
|
|
6
|
-
*
|
|
7
|
-
* 当模型工作时:
|
|
8
|
-
* - 输入框边框基于当前颜色做呼吸发光(明暗渐变)
|
|
9
|
-
* - "Working..." 保持原样
|
|
10
|
-
* - Footer 不变
|
|
11
6
|
*/
|
|
12
7
|
|
|
13
8
|
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
14
9
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
15
|
-
import { Editor } from "@earendil-works/pi-tui";
|
|
16
10
|
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
17
11
|
|
|
18
12
|
// ── Nerd Font 图标(与 pi-powerline-footer 完全一致) ──
|
|
@@ -55,52 +49,6 @@ const RAINBOW = [
|
|
|
55
49
|
"#89d281", "#00afaf", "#178fb9", "#b281d6",
|
|
56
50
|
];
|
|
57
51
|
|
|
58
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
59
|
-
// 输入框呼吸发光(基于当前边框颜色做明暗呼吸)
|
|
60
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
61
|
-
|
|
62
|
-
let working = false;
|
|
63
|
-
let animInterval: ReturnType<typeof setInterval> | undefined;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 从 borderColor 函数采样字符,提取当前 RGB 色值
|
|
67
|
-
*/
|
|
68
|
-
function extractRGB(fn: (str: string) => string): [number, number, number] | null {
|
|
69
|
-
const sample = fn("─");
|
|
70
|
-
const m = sample.match(ANSI_RE);
|
|
71
|
-
if (!m) return null;
|
|
72
|
-
return [parseInt(m[1]), parseInt(m[2]), parseInt(m[3])];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** 保存原始 render */
|
|
76
|
-
const origRender = Editor.prototype.render;
|
|
77
|
-
|
|
78
|
-
Editor.prototype.render = function (width: number): string[] {
|
|
79
|
-
if (working) {
|
|
80
|
-
const saved = this.borderColor;
|
|
81
|
-
const rgb = extractRGB(saved);
|
|
82
|
-
if (rgb) {
|
|
83
|
-
const [r, g, b] = rgb;
|
|
84
|
-
// 纯前景呼吸:当前色 + 峰值白色辉光,0.8s 周期
|
|
85
|
-
// 无背景阴影,避免生硬灯管感
|
|
86
|
-
const t = 0.5 + 0.5 * Math.sin(performance.now() / 191);
|
|
87
|
-
const bright = 0.35 + 0.65 * t; // 35%~100%
|
|
88
|
-
const glow = t * t * 0.45; // 0~0.45 白色 blend
|
|
89
|
-
const nr = Math.round(Math.min(255, r * bright + (255 - r) * glow));
|
|
90
|
-
const ng = Math.round(Math.min(255, g * bright + (255 - g) * glow));
|
|
91
|
-
const nb = Math.round(Math.min(255, b * bright + (255 - b) * glow));
|
|
92
|
-
this.borderColor = (str: string) =>
|
|
93
|
-
`[38;2;${nr};${ng};${nb}m${str}[0m`;
|
|
94
|
-
}
|
|
95
|
-
try {
|
|
96
|
-
return origRender.call(this, width);
|
|
97
|
-
} finally {
|
|
98
|
-
this.borderColor = saved;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return origRender.call(this, width);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
52
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
105
53
|
// Extension
|
|
106
54
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -112,9 +60,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
112
60
|
|
|
113
61
|
pi.on("session_start", async (_event, ctx) => {
|
|
114
62
|
thinkingLevel = pi.getThinkingLevel();
|
|
115
|
-
|
|
116
|
-
// 隐藏内置的 "Working..." 指示器,用输入框呼吸代替
|
|
117
|
-
ctx.ui.setWorkingVisible(false);
|
|
63
|
+
ctx.ui.setWorkingVisible(true);
|
|
118
64
|
|
|
119
65
|
ctx.ui.setFooter((tui, theme, footerData) => {
|
|
120
66
|
requestRender = () => tui.requestRender();
|
|
@@ -164,35 +110,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
164
110
|
refresh();
|
|
165
111
|
});
|
|
166
112
|
pi.on("model_select", () => refresh());
|
|
167
|
-
|
|
168
|
-
// 工作状态切换 → 控制呼吸发光
|
|
169
|
-
pi.on("agent_start", () => {
|
|
170
|
-
working = true;
|
|
171
|
-
// 50ms 间隔主动刷新,保证呼吸动画 20fps 流畅
|
|
172
|
-
if (requestRender) {
|
|
173
|
-
animInterval = setInterval(requestRender, 50);
|
|
174
|
-
}
|
|
175
|
-
refresh();
|
|
176
|
-
});
|
|
177
|
-
pi.on("agent_end", () => {
|
|
178
|
-
working = false;
|
|
179
|
-
if (animInterval) {
|
|
180
|
-
clearInterval(animInterval);
|
|
181
|
-
animInterval = undefined;
|
|
182
|
-
}
|
|
183
|
-
refresh();
|
|
184
|
-
});
|
|
185
|
-
|
|
186
113
|
pi.on("turn_start", () => refresh());
|
|
187
114
|
pi.on("turn_end", () => refresh());
|
|
188
115
|
|
|
189
116
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
190
117
|
ctx.ui.setFooter(undefined);
|
|
191
118
|
requestRender = undefined;
|
|
192
|
-
if (animInterval) {
|
|
193
|
-
clearInterval(animInterval);
|
|
194
|
-
animInterval = undefined;
|
|
195
|
-
}
|
|
196
119
|
});
|
|
197
120
|
}
|
|
198
121
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lokiyou/pi-nano-footer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "超轻量 powerline 风格 footer for Pi Coding Agent
|
|
3
|
+
"version": "0.15.1",
|
|
4
|
+
"description": "超轻量 powerline 风格 footer for Pi Coding Agent,保留内置 Working... 指示器,霓虹配色,实时显示模型、目录、上下文、token 和费用",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"pi-package",
|