@lokiyou/pi-nano-footer 0.7.0 → 0.9.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/index.ts +27 -29
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -46,9 +46,6 @@ const C = {
|
|
|
46
46
|
border: "#dfe6e9",
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
// ── ANSI 24-bit true color 正则(用于从 borderColor 函数提取颜色) ──
|
|
50
|
-
const ANSI_RE = /\x1b\[38;2;(\d+);(\d+);(\d+)m/;
|
|
51
|
-
|
|
52
49
|
// ── Rainbow 色表(high / xhigh 思考等级用) ──
|
|
53
50
|
const RAINBOW = [
|
|
54
51
|
"#b281d6", "#d787af", "#febc38", "#e4c00f",
|
|
@@ -60,17 +57,10 @@ const RAINBOW = [
|
|
|
60
57
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
61
58
|
|
|
62
59
|
let working = false;
|
|
60
|
+
let animInterval: ReturnType<typeof setInterval> | undefined;
|
|
63
61
|
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
*/
|
|
67
|
-
function extractRGB(fn: (str: string) => string): [number, number, number] | null {
|
|
68
|
-
const sample = fn("─");
|
|
69
|
-
// borderColor 输出格式:\x1b[38;2;R;G;Bm─\x1b[0m
|
|
70
|
-
const m = sample.match(ANSI_RE);
|
|
71
|
-
if (!m) return null;
|
|
72
|
-
return [parseInt(m[1]), parseInt(m[2]), parseInt(m[3])];
|
|
73
|
-
}
|
|
62
|
+
/** 工作状态呼吸色:暖橙 #ff9f1c,代表 processing/运行中 */
|
|
63
|
+
const WORK_RGB: [number, number, number] = [0xff, 0x9f, 0x1c];
|
|
74
64
|
|
|
75
65
|
/** 保存原始 render */
|
|
76
66
|
const origRender = Editor.prototype.render;
|
|
@@ -78,21 +68,17 @@ const origRender = Editor.prototype.render;
|
|
|
78
68
|
Editor.prototype.render = function (width: number): string[] {
|
|
79
69
|
if (working) {
|
|
80
70
|
const saved = this.borderColor;
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const nb = Math.round(Math.min(255, b * bright + (255 - b) * glow));
|
|
93
|
-
this.borderColor = (str: string) =>
|
|
94
|
-
`\x1b[38;2;${nr};${ng};${nb}m${str}\x1b[0m`;
|
|
95
|
-
}
|
|
71
|
+
const [r, g, b] = WORK_RGB;
|
|
72
|
+
// 更快呼吸 + 暖橙 processing 色
|
|
73
|
+
// 周期 ~600ms(比之前快一倍),60fps 驱动
|
|
74
|
+
const t = 0.5 + 0.5 * Math.sin(performance.now() / 300);
|
|
75
|
+
const bright = 0.25 + 0.75 * t;
|
|
76
|
+
const glow = t * t * 0.35;
|
|
77
|
+
const nr = Math.round(Math.min(255, r * bright + (255 - r) * glow));
|
|
78
|
+
const ng = Math.round(Math.min(255, g * bright + (255 - g) * glow));
|
|
79
|
+
const nb = Math.round(Math.min(255, b * bright + (255 - b) * glow));
|
|
80
|
+
this.borderColor = (str: string) =>
|
|
81
|
+
`\x1b[38;2;${nr};${ng};${nb}m${str}\x1b[0m`;
|
|
96
82
|
try {
|
|
97
83
|
return origRender.call(this, width);
|
|
98
84
|
} finally {
|
|
@@ -166,13 +152,21 @@ export default function (pi: ExtensionAPI) {
|
|
|
166
152
|
});
|
|
167
153
|
pi.on("model_select", () => refresh());
|
|
168
154
|
|
|
169
|
-
// 工作状态切换 →
|
|
155
|
+
// 工作状态切换 → 控制呼吸发光
|
|
170
156
|
pi.on("agent_start", () => {
|
|
171
157
|
working = true;
|
|
158
|
+
// 50ms 间隔主动刷新,保证呼吸动画 20fps 流畅
|
|
159
|
+
if (requestRender) {
|
|
160
|
+
animInterval = setInterval(requestRender, 50);
|
|
161
|
+
}
|
|
172
162
|
refresh();
|
|
173
163
|
});
|
|
174
164
|
pi.on("agent_end", () => {
|
|
175
165
|
working = false;
|
|
166
|
+
if (animInterval) {
|
|
167
|
+
clearInterval(animInterval);
|
|
168
|
+
animInterval = undefined;
|
|
169
|
+
}
|
|
176
170
|
refresh();
|
|
177
171
|
});
|
|
178
172
|
|
|
@@ -182,6 +176,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
182
176
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
183
177
|
ctx.ui.setFooter(undefined);
|
|
184
178
|
requestRender = undefined;
|
|
179
|
+
if (animInterval) {
|
|
180
|
+
clearInterval(animInterval);
|
|
181
|
+
animInterval = undefined;
|
|
182
|
+
}
|
|
185
183
|
});
|
|
186
184
|
}
|
|
187
185
|
|