@pi-archimedes/ui 2.9.2 → 2.10.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/README.md +1 -0
- package/package.json +2 -2
- package/src/config.test.ts +2 -0
- package/src/config.ts +2 -0
- package/src/settings.test.ts +3 -2
- package/src/settings.ts +7 -0
- package/src/startup/index.ts +2 -1
- package/src/startup/logo.test.ts +20 -0
- package/src/startup/logo.ts +18 -1
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@ TUI enhancements for the Pi Archimedes monorepo.
|
|
|
48
48
|
| `labelText` | string | `"Thinking..."` | Text shown before thinking blocks |
|
|
49
49
|
| `labelColor` | string | `"255,215,0"` | RGB color for the thinking label (e.g. `255,215,0`) |
|
|
50
50
|
| `animationStyle` | "diagonal" \| "top-right" \| "bottom-left" \| "bottom-right" \| "center-out" \| "wave" \| "horizontal" \| "vertical" \| "vertical-up" | `"vertical-up"` | Startup logo animation |
|
|
51
|
+
| `colorfulLogo` | boolean | `false` | Use pi's brand colors for the splash logo |
|
|
51
52
|
| `editorSpinBorder` | boolean | `true` | Animated spinner border on editor |
|
|
52
53
|
| `editorSpinSpeed` | "slow" \| "normal" \| "fast" | `"normal"` | Editor border spinner speed |
|
|
53
54
|
| `editorSpinStyle` | "typing" \| "pulse" \| "rain" \| "cascade" \| "columns" \| "wave-rows" \| "diagonal-swipe" \| "sparkle" \| "pendulum" \| "marquee" | `"pendulum"` | Editor spinner style |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-archimedes/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
4
4
|
"description": "Terminal UI enhancements, styled bash tool rendering, and visual presentation components for Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"./config": "./src/config.ts"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pi-archimedes/core": "2.
|
|
31
|
+
"@pi-archimedes/core": "2.10.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@earendil-works/pi-ai": "^0.87.0",
|
package/src/config.test.ts
CHANGED
|
@@ -44,6 +44,7 @@ describe("loadUIConfig", () => {
|
|
|
44
44
|
labelText: "Thinking...",
|
|
45
45
|
labelColor: "255,215,0",
|
|
46
46
|
animationStyle: "vertical-up",
|
|
47
|
+
colorfulLogo: false,
|
|
47
48
|
editorSpinBorder: true,
|
|
48
49
|
editorSpinSpeed: "normal",
|
|
49
50
|
editorSpinLabel: "Working",
|
|
@@ -89,6 +90,7 @@ describe("DEFAULT_UI_CONFIG", () => {
|
|
|
89
90
|
labelText: "Thinking...",
|
|
90
91
|
labelColor: "255,215,0",
|
|
91
92
|
animationStyle: "vertical-up",
|
|
93
|
+
colorfulLogo: false,
|
|
92
94
|
editorSpinBorder: true,
|
|
93
95
|
editorSpinSpeed: "normal",
|
|
94
96
|
editorSpinLabel: "Working",
|
package/src/config.ts
CHANGED
|
@@ -87,6 +87,7 @@ export interface UIConfig {
|
|
|
87
87
|
labelText: string;
|
|
88
88
|
labelColor: string;
|
|
89
89
|
animationStyle: AnimationStyle;
|
|
90
|
+
colorfulLogo: boolean;
|
|
90
91
|
editorSpinBorder: boolean;
|
|
91
92
|
editorSpinSpeed: "slow" | "normal" | "fast";
|
|
92
93
|
editorSpinLabel: string;
|
|
@@ -106,6 +107,7 @@ export const DEFAULT_UI_CONFIG: UIConfig = {
|
|
|
106
107
|
labelText: "Thinking...",
|
|
107
108
|
labelColor: "255,215,0",
|
|
108
109
|
animationStyle: "vertical-up",
|
|
110
|
+
colorfulLogo: false,
|
|
109
111
|
editorSpinBorder: true,
|
|
110
112
|
editorSpinSpeed: "normal",
|
|
111
113
|
editorSpinLabel: "Working",
|
package/src/settings.test.ts
CHANGED
|
@@ -3,9 +3,9 @@ import { getUISettingsItems } from "./settings.js";
|
|
|
3
3
|
import { DEFAULT_UI_CONFIG, ANIMATION_STYLES, type UIConfig } from "./config.js";
|
|
4
4
|
|
|
5
5
|
describe("getUISettingsItems", () => {
|
|
6
|
-
it("exposes all
|
|
6
|
+
it("exposes all 15 UI setting items with correct defaults", () => {
|
|
7
7
|
const items = getUISettingsItems(DEFAULT_UI_CONFIG);
|
|
8
|
-
expect(items).toHaveLength(
|
|
8
|
+
expect(items).toHaveLength(15);
|
|
9
9
|
|
|
10
10
|
const ids = items.map((i) => i.id);
|
|
11
11
|
expect(ids).toEqual([
|
|
@@ -19,6 +19,7 @@ describe("getUISettingsItems", () => {
|
|
|
19
19
|
"labelText",
|
|
20
20
|
"labelColor",
|
|
21
21
|
"animationStyle",
|
|
22
|
+
"colorfulLogo",
|
|
22
23
|
"editorSpinBorder",
|
|
23
24
|
"editorSpinSpeed",
|
|
24
25
|
"editorSpinStyle",
|
package/src/settings.ts
CHANGED
|
@@ -76,6 +76,13 @@ export function getUISettingsItems(config: UIConfig): SettingItem[] {
|
|
|
76
76
|
currentValue: config.animationStyle,
|
|
77
77
|
values: [...ANIMATION_STYLES],
|
|
78
78
|
},
|
|
79
|
+
{
|
|
80
|
+
id: "colorfulLogo",
|
|
81
|
+
label: "Colorful Logo",
|
|
82
|
+
description: "Use pi's brand colors for the splash logo",
|
|
83
|
+
currentValue: config.colorfulLogo ? "On" : "Off",
|
|
84
|
+
values: ["On", "Off"],
|
|
85
|
+
},
|
|
79
86
|
{
|
|
80
87
|
id: "editorSpinBorder",
|
|
81
88
|
label: "Editor Spin Border",
|
package/src/startup/index.ts
CHANGED
|
@@ -42,7 +42,8 @@ export interface ListingRef {
|
|
|
42
42
|
export function renderHeader(theme: Theme, ref: ListingRef, width: number, height: number): string[] {
|
|
43
43
|
const dim = (t: string) => theme.fg("dim", t);
|
|
44
44
|
const accent = (t: string) => theme.fg("accent", t);
|
|
45
|
-
const
|
|
45
|
+
const cfg = loadUIConfig();
|
|
46
|
+
const logoLines = getShinedLogo(ref.frame, cfg.animationStyle, cfg.colorfulLogo);
|
|
46
47
|
|
|
47
48
|
// Use cached text lines if settled (no more animations)
|
|
48
49
|
let listingLines: string[];
|
package/src/startup/logo.test.ts
CHANGED
|
@@ -180,6 +180,26 @@ describe("getShinedLogo (truecolor)", () => {
|
|
|
180
180
|
const result2 = mod.getShinedLogo(50, "wave");
|
|
181
181
|
expect(result1).toEqual(result2);
|
|
182
182
|
});
|
|
183
|
+
|
|
184
|
+
it("colorful logo paints every pixel with its pi brand color", () => {
|
|
185
|
+
const C = "228;138;122", B = "79;142;179", Y = "234;182;93", W = "255;255;255";
|
|
186
|
+
const pixels = [
|
|
187
|
+
[C, C, C, null],
|
|
188
|
+
[B, null, C, null],
|
|
189
|
+
[B, B, null, Y],
|
|
190
|
+
[B, null, null, Y],
|
|
191
|
+
];
|
|
192
|
+
const cellColors = (row: string) =>
|
|
193
|
+
[...row.matchAll(/\x1b\[38;2;(\d+;\d+;\d+)m.\x1b\[0m| /g)].map((m) => m[1] ?? null);
|
|
194
|
+
|
|
195
|
+
const colorful = mod.getShinedLogo(500, "wave", true);
|
|
196
|
+
const plain = mod.getShinedLogo(500, "wave", false);
|
|
197
|
+
for (let y = 0; y < 8; y++) {
|
|
198
|
+
const expected = Array.from({ length: 16 }, (_, x) => pixels[Math.floor(y / 2)]![Math.floor(x / 4)]);
|
|
199
|
+
expect(cellColors(colorful[y]!)).toEqual(expected);
|
|
200
|
+
expect(cellColors(plain[y]!)).toEqual(expected.map((c) => (c ? W : null)));
|
|
201
|
+
}
|
|
202
|
+
});
|
|
183
203
|
});
|
|
184
204
|
|
|
185
205
|
// ── All animation styles ─────────────────────────────────────────────────────
|
package/src/startup/logo.ts
CHANGED
|
@@ -23,6 +23,17 @@ export const LOGO = [
|
|
|
23
23
|
"████ ████",
|
|
24
24
|
];
|
|
25
25
|
|
|
26
|
+
// Pi brand colors per logo pixel (4x4). Copied from pi-coding-agent's pi-logo.js, which is not exported.
|
|
27
|
+
const CORAL: [number, number, number] = [228, 138, 122];
|
|
28
|
+
const BLUE: [number, number, number] = [79, 142, 179];
|
|
29
|
+
const YELLOW: [number, number, number] = [234, 182, 93];
|
|
30
|
+
const PI_COLORS: ([number, number, number] | null)[][] = [
|
|
31
|
+
[CORAL, CORAL, CORAL, null],
|
|
32
|
+
[BLUE, null, CORAL, null],
|
|
33
|
+
[BLUE, BLUE, null, YELLOW],
|
|
34
|
+
[BLUE, null, null, YELLOW],
|
|
35
|
+
];
|
|
36
|
+
|
|
26
37
|
export const CHAR_FADE_FRAMES = 22;
|
|
27
38
|
export const LOGO_SETTLE_FRAME = 90;
|
|
28
39
|
export const LOGO_PAD = 0;
|
|
@@ -61,7 +72,7 @@ function computeRevealAt(x: number, y: number, style: AnimationStyle): number {
|
|
|
61
72
|
}
|
|
62
73
|
}
|
|
63
74
|
|
|
64
|
-
export function getShinedLogo(frame: number, style: AnimationStyle = "wave"): string[] {
|
|
75
|
+
export function getShinedLogo(frame: number, style: AnimationStyle = "wave", colorful = false): string[] {
|
|
65
76
|
if (!TRUECOLOR) return LOGO;
|
|
66
77
|
|
|
67
78
|
return LOGO.map((line, y) => {
|
|
@@ -77,6 +88,12 @@ export function getShinedLogo(frame: number, style: AnimationStyle = "wave"): st
|
|
|
77
88
|
|
|
78
89
|
const t = Math.min(1, age / CHAR_FADE_FRAMES);
|
|
79
90
|
const eased = 1 - (1 - t) * (1 - t);
|
|
91
|
+
const pi = colorful ? PI_COLORS[Math.floor(y / 2)]![Math.floor(x / 4)] : null;
|
|
92
|
+
if (pi) {
|
|
93
|
+
result += rgb(lerp(50, pi[0], eased), lerp(50, pi[1], eased), lerp(50, pi[2], eased), char);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
80
97
|
const brightness = Math.floor(lerp(50, 255, eased));
|
|
81
98
|
result += gray(brightness, char);
|
|
82
99
|
}
|