@rosetears/aili-pi 0.1.8 → 0.1.9
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 -1
- package/extensions/matrix/index.ts +24 -8
- package/extensions/zentui/config.ts +13 -13
- package/extensions/zentui/format.ts +15 -1
- package/extensions/zentui/gradient.ts +22 -13
- package/extensions/zentui/tool-execution.ts +7 -4
- package/manifests/sbom.json +1 -1
- package/package.json +1 -1
- package/themes/rose-cyberdeck.json +5 -9
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ That command creates or updates only the AILI marker block in `~/.pi/agent/APPEN
|
|
|
53
53
|
|
|
54
54
|
The package supplies the dark `rose-cyberdeck` theme plus three additional Pi Extensions: a Rose header, Rose Shimmer + four-row Rose Code Rain working surface, and Zentui footer/editor surface. Select it through Pi's `/settings` theme selector or set `"theme": "rose-cyberdeck"` in `~/.pi/agent/settings.json`. The visual extensions are adapted from `pi-sakura-cyberdeck` at revision `165a1f8011a12a58a6409b56b8a6c0416cd9b589` under MIT; see `THIRD_PARTY_NOTICES.md` and `notices/pi-sakura-cyberdeck-NOTICE.txt`.
|
|
55
55
|
|
|
56
|
-
Rose Code Rain
|
|
56
|
+
Rose Code Rain uses the original sparse, fixed-column waterfall geometry: `density` selects even-cell tracks, at most 96 tracks span ultra-wide terminals, and each track falls vertically with a randomized tail and gap. The default 12 FPS cadence and 8–16 rows/second fall speed sit between the released and dense-preview profiles. `/rose-matrix status`, `/rose-matrix fps <8-18>`, `/rose-matrix density <0.45-0.95>`, and `/rose-matrix appearance <auto|dark|light>` change active preferences. `/sakura-matrix` remains a deprecated compatibility alias. Header, rain, frames, footer, and editor use the Rose six-color system: Blue, Ice, Cyan, Violet, Rose, and Soft Rose.
|
|
57
57
|
|
|
58
58
|
### Migrating from Rem/Sakura names
|
|
59
59
|
|
|
@@ -22,11 +22,12 @@ const SHIMMER_STEP_MS = 120;
|
|
|
22
22
|
const TOOL_GRADIENT: readonly RGB[] = [[188, 167, 255], [125, 228, 255]];
|
|
23
23
|
|
|
24
24
|
export const ROSE_MATRIX_GLYPHS = [..."0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモラリルレロワン"];
|
|
25
|
+
/** The six user-selected rain colors, assigned by the exact weights below. */
|
|
25
26
|
export const ROSE_RAIN_PALETTE: readonly RGB[] = [
|
|
26
|
-
[136, 184, 255], [
|
|
27
|
-
[
|
|
28
|
-
[214, 244, 255], [136, 184, 255], [199, 91, 122], [232, 167, 184],
|
|
27
|
+
[136, 184, 255], [214, 244, 255], [125, 228, 255],
|
|
28
|
+
[188, 167, 255], [199, 91, 122], [232, 167, 184],
|
|
29
29
|
];
|
|
30
|
+
export const ROSE_RAIN_WEIGHTS = { blue: 50, ice: 20, cyan: 15, violet: 8, rose: 4, roseSoft: 3 } as const;
|
|
30
31
|
export const ROSE_SHIMMER_INDICATOR = ["·", "✢", "✳", "✶", "✻", "✽", "✻", "✶", "✳", "✢"] as const;
|
|
31
32
|
|
|
32
33
|
type RGB = readonly [number, number, number];
|
|
@@ -45,6 +46,7 @@ export interface MatrixConfig {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export interface Drop {
|
|
49
|
+
/** Fixed terminal-cell column; vertical motion never changes this value. */
|
|
48
50
|
x: number;
|
|
49
51
|
offset: number;
|
|
50
52
|
speed: number;
|
|
@@ -59,7 +61,7 @@ type ConfigLoadResult = { config: MatrixConfig; migrated: boolean; warning?: str
|
|
|
59
61
|
const DEFAULT_CONFIG: MatrixConfig = {
|
|
60
62
|
version: 2,
|
|
61
63
|
enabled: true,
|
|
62
|
-
fps:
|
|
64
|
+
fps: 12,
|
|
63
65
|
density: 0.65,
|
|
64
66
|
height: 4,
|
|
65
67
|
appearance: "auto",
|
|
@@ -204,6 +206,19 @@ function selectBoundedColumns(columns: readonly number[]): number[] {
|
|
|
204
206
|
return Array.from({ length: MAX_DROPS }, (_, index) => columns[Math.round((index * lastIndex) / (MAX_DROPS - 1))] ?? 0);
|
|
205
207
|
}
|
|
206
208
|
|
|
209
|
+
/** Exact 50/20/15/8/4/3 distribution over each deterministic 100-track cycle. */
|
|
210
|
+
export function roseRainColor(index: number): RGB {
|
|
211
|
+
// A coprime stride distributes all weights through the 96-track ceiling,
|
|
212
|
+
// instead of leaving the final Rose/Soft Rose buckets unreachable.
|
|
213
|
+
const bucket = (((index * 37) % 100) + 100) % 100;
|
|
214
|
+
if (bucket < 50) return ROSE_RAIN_PALETTE[0]!;
|
|
215
|
+
if (bucket < 70) return ROSE_RAIN_PALETTE[1]!;
|
|
216
|
+
if (bucket < 85) return ROSE_RAIN_PALETTE[2]!;
|
|
217
|
+
if (bucket < 93) return ROSE_RAIN_PALETTE[3]!;
|
|
218
|
+
if (bucket < 97) return ROSE_RAIN_PALETTE[4]!;
|
|
219
|
+
return ROSE_RAIN_PALETTE[5]!;
|
|
220
|
+
}
|
|
221
|
+
|
|
207
222
|
export function createDrops(width: number, density: number, height = 4): Drop[] {
|
|
208
223
|
const random = mulberry32((width * 2654435761) ^ 0x53414b55);
|
|
209
224
|
const columns = Array.from({ length: Math.ceil(width / 2) }, (_, index) => index * 2);
|
|
@@ -216,11 +231,12 @@ export function createDrops(width: number, density: number, height = 4): Drop[]
|
|
|
216
231
|
return {
|
|
217
232
|
x,
|
|
218
233
|
offset: random() * cycle,
|
|
219
|
-
|
|
234
|
+
// Between the released waterfall (5.5–13) and dense preview (18).
|
|
235
|
+
speed: 8 + random() * 8,
|
|
220
236
|
length,
|
|
221
237
|
gap,
|
|
222
238
|
seed: Math.floor(random() * 0x7fffffff) ^ (index * 7919),
|
|
223
|
-
color:
|
|
239
|
+
color: roseRainColor(index),
|
|
224
240
|
};
|
|
225
241
|
});
|
|
226
242
|
}
|
|
@@ -229,8 +245,8 @@ function appearanceColor(color: RGB, appearance: ResolvedAppearance): RGB {
|
|
|
229
245
|
if (appearance === "dark") return color;
|
|
230
246
|
if (color[0] === 199 && color[1] === 91) return LIGHT.indicator;
|
|
231
247
|
if (color[0] === 232 && color[1] === 167) return [168, 69, 95];
|
|
232
|
-
if (color[0] ===
|
|
233
|
-
if (color[1] === 228) return [78, 120, 129];
|
|
248
|
+
if (color[0] === 188 && color[1] === 167) return [119, 106, 151];
|
|
249
|
+
if (color[0] === 214 || color[1] === 228) return [78, 120, 129];
|
|
234
250
|
return LIGHT.base;
|
|
235
251
|
}
|
|
236
252
|
|
|
@@ -235,27 +235,27 @@ export const defaultConfig: PolishedTuiConfig = {
|
|
|
235
235
|
cwd: "bold #88B8FF",
|
|
236
236
|
gitBranch: "bold #BCA7FF",
|
|
237
237
|
gitStatus: "bold #D6F4FF",
|
|
238
|
-
contextNormal: "#
|
|
239
|
-
contextWarning: "bold #
|
|
240
|
-
contextError: "bold #
|
|
238
|
+
contextNormal: "#7DE4FF",
|
|
239
|
+
contextWarning: "bold #BCA7FF",
|
|
240
|
+
contextError: "bold #C75B7A",
|
|
241
241
|
tokens: "#9DA9C8",
|
|
242
|
-
cost: "bold #
|
|
242
|
+
cost: "bold #7DE4FF",
|
|
243
243
|
separator: "#64708F",
|
|
244
244
|
runtimePrefix: "#7DE4FF",
|
|
245
245
|
extensionStatus: "#BCA7FF",
|
|
246
|
-
sessionDuration: "#
|
|
246
|
+
sessionDuration: "#BCA7FF",
|
|
247
247
|
packageVersion: "#D6F4FF",
|
|
248
|
-
gitCommit: "#
|
|
249
|
-
gitMetricsAdded: "#
|
|
250
|
-
gitMetricsDeleted: "#
|
|
251
|
-
username: "#
|
|
252
|
-
time: "#
|
|
253
|
-
os: "#
|
|
248
|
+
gitCommit: "#7DE4FF",
|
|
249
|
+
gitMetricsAdded: "#7DE4FF",
|
|
250
|
+
gitMetricsDeleted: "#C75B7A",
|
|
251
|
+
username: "#BCA7FF",
|
|
252
|
+
time: "#BCA7FF",
|
|
253
|
+
os: "#D6F4FF",
|
|
254
254
|
editorAccent: "bold #88B8FF",
|
|
255
255
|
editorPrompt: "bold #88B8FF",
|
|
256
256
|
editorBorder: "rose-cyberdeck-gradient",
|
|
257
257
|
editorModel: "bold #88B8FF",
|
|
258
|
-
editorProvider: "#
|
|
258
|
+
editorProvider: "#D6F4FF",
|
|
259
259
|
editorThinking: "#BCA7FF",
|
|
260
260
|
editorThinkingMinimal: "#64708F",
|
|
261
261
|
editorThinkingLow: "#7DE4FF",
|
|
@@ -264,7 +264,7 @@ export const defaultConfig: PolishedTuiConfig = {
|
|
|
264
264
|
editorThinkingXhigh: "bold #BCA7FF",
|
|
265
265
|
},
|
|
266
266
|
colorSources: {
|
|
267
|
-
starship: "
|
|
267
|
+
starship: "theme",
|
|
268
268
|
editor: "terminal",
|
|
269
269
|
userMessages: "theme",
|
|
270
270
|
},
|
|
@@ -288,6 +288,20 @@ export function buildContextLabel(ctx: ExtensionContext): string {
|
|
|
288
288
|
return formatContextPercentLabel(usage?.percent, contextWindow);
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Normalize inherited Starship runtime hints into Rose-owned semantic colors.
|
|
293
|
+
* The source strings remain detection metadata; package rendering never emits
|
|
294
|
+
* their traffic-light or indexed terminal colors.
|
|
295
|
+
*/
|
|
296
|
+
export function roseRuntimeStyle(style: string): ColorSpec {
|
|
297
|
+
const normalized = style.toLowerCase();
|
|
298
|
+
if (/(?:red|202|208|orange)/.test(normalized)) return "rose";
|
|
299
|
+
if (/(?:yellow|purple|105|147)/.test(normalized)) return "violet";
|
|
300
|
+
if (/(?:white|149)/.test(normalized)) return "ice";
|
|
301
|
+
if (/(?:green|cyan|blue|0093a7)/.test(normalized)) return "cyan";
|
|
302
|
+
return "blue";
|
|
303
|
+
}
|
|
304
|
+
|
|
291
305
|
export function formatRuntimeSegment(
|
|
292
306
|
theme: Pick<Theme, "fg">,
|
|
293
307
|
runtime: RuntimeInfo | undefined,
|
|
@@ -298,7 +312,7 @@ export function formatRuntimeSegment(
|
|
|
298
312
|
if (!runtime) return "";
|
|
299
313
|
const symbol = resolveRuntimeSymbol(runtime.name, runtime.symbol, mode);
|
|
300
314
|
const label = runtime.version ? `${symbol} ${runtime.version}` : symbol;
|
|
301
|
-
return `${renderStyleForSource(theme, colorSource, prefixStyle, "via")} ${renderStyleForSource(theme, colorSource, runtime.style, label)}`;
|
|
315
|
+
return `${renderStyleForSource(theme, colorSource, prefixStyle, "via")} ${renderStyleForSource(theme, colorSource, roseRuntimeStyle(runtime.style), label)}`;
|
|
302
316
|
}
|
|
303
317
|
|
|
304
318
|
/**
|
|
@@ -11,6 +11,10 @@ export const ROSE_GRADIENT_STOPS: readonly RGB[] = [
|
|
|
11
11
|
[125, 228, 255], // cyan #7DE4FF
|
|
12
12
|
[214, 244, 255], // ice #D6F4FF
|
|
13
13
|
];
|
|
14
|
+
/** Completed tool frames use a cool, restrained completion gradient. */
|
|
15
|
+
export const ROSE_TOOL_COMPLETE_STOPS: readonly RGB[] = [
|
|
16
|
+
[136, 184, 255], [125, 228, 255], [214, 244, 255],
|
|
17
|
+
];
|
|
14
18
|
|
|
15
19
|
const RESET = "\x1b[0m";
|
|
16
20
|
const GRADIENT_CACHE_LIMIT = 128;
|
|
@@ -25,32 +29,37 @@ function mix(from: RGB, to: RGB, amount: number): RGB {
|
|
|
25
29
|
];
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
function sampleGradient(position: number): RGB {
|
|
29
|
-
const normalized = Math.max(0, Math.min(1, position));
|
|
30
|
-
const scaled = normalized * (ROSE_GRADIENT_STOPS.length - 1);
|
|
31
|
-
const index = Math.min(ROSE_GRADIENT_STOPS.length - 2, Math.floor(scaled));
|
|
32
|
-
const from = ROSE_GRADIENT_STOPS[index] ?? ROSE_GRADIENT_STOPS[0]!;
|
|
33
|
-
const to = ROSE_GRADIENT_STOPS[index + 1] ?? from;
|
|
34
|
-
return mix(from, to, scaled - index);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
32
|
function foreground(color: RGB, text: string): string {
|
|
38
33
|
return `\x1b[38;2;${color[0]};${color[1]};${color[2]}m${text}`;
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
/** Render the stable Rose-to-ice gradient for Zentui chrome and markers. */
|
|
42
|
-
|
|
43
|
-
const
|
|
37
|
+
function renderGradient(text: string, stops: readonly RGB[]): string {
|
|
38
|
+
const cacheKey = `${stops.flat().join(",")}:${text}`;
|
|
39
|
+
const cached = gradientCache.get(cacheKey);
|
|
44
40
|
if (cached !== undefined) return cached;
|
|
45
41
|
const chars = [...text];
|
|
46
42
|
if (chars.length === 0) return text;
|
|
47
43
|
const span = Math.max(1, chars.length - 1);
|
|
48
|
-
const rendered = `${chars.map((char, index) =>
|
|
44
|
+
const rendered = `${chars.map((char, index) => {
|
|
45
|
+
const position = Math.max(0, Math.min(1, index / span));
|
|
46
|
+
const scaled = position * (stops.length - 1);
|
|
47
|
+
const stop = Math.min(stops.length - 2, Math.floor(scaled));
|
|
48
|
+
return foreground(mix(stops[stop] ?? stops[0]!, stops[stop + 1] ?? stops[stop] ?? stops[0]!, scaled - stop), char);
|
|
49
|
+
}).join("")}${RESET}`;
|
|
49
50
|
if (gradientCache.size >= GRADIENT_CACHE_LIMIT) gradientCache.delete(gradientCache.keys().next().value ?? "");
|
|
50
|
-
gradientCache.set(
|
|
51
|
+
gradientCache.set(cacheKey, rendered);
|
|
51
52
|
return rendered;
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
export function renderRoseGradient(text: string): string {
|
|
56
|
+
return renderGradient(text, ROSE_GRADIENT_STOPS);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function renderRoseToolCompleteGradient(text: string): string {
|
|
60
|
+
return renderGradient(text, ROSE_TOOL_COMPLETE_STOPS);
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
/** Add symmetric colored side rails while preserving the terminal width contract. */
|
|
55
64
|
export function renderBoxedLine(line: string, width: number, leftRail: string, rightRail: string): string {
|
|
56
65
|
if (width <= 0) return "";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Theme, ToolExecutionComponent } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { visibleWidth } from "@earendil-works/pi-tui";
|
|
3
|
-
import { renderBoxedLine, renderRoseGradient } from "./gradient.js";
|
|
3
|
+
import { renderBoxedLine, renderRoseGradient, renderRoseToolCompleteGradient } from "./gradient.js";
|
|
4
4
|
import { installPrototypePatch } from "./prototype-patch-registry.js";
|
|
5
5
|
|
|
6
6
|
const SETTLED_CACHE_MAX_LINES = 80;
|
|
@@ -141,7 +141,10 @@ export function installToolExecutionStyle(getTheme: () => Theme | undefined): Cl
|
|
|
141
141
|
if (blank !== undefined) prefix.push(blank);
|
|
142
142
|
}
|
|
143
143
|
const label = fitBorderLabel(statusLabel(runtime), width);
|
|
144
|
-
const
|
|
144
|
+
const completeGradient = !pending && !runtime.result?.isError
|
|
145
|
+
? renderRoseToolCompleteGradient
|
|
146
|
+
: renderRoseGradient;
|
|
147
|
+
const top = completeGradient(label);
|
|
145
148
|
// Keep only the status rail slightly heavier. State is expressed in the
|
|
146
149
|
// Rose palette rather than traffic-light red/green: violet while running,
|
|
147
150
|
// ice blue when complete, and Rose when failed.
|
|
@@ -150,8 +153,8 @@ export function installToolExecutionStyle(getTheme: () => Theme | undefined): Cl
|
|
|
150
153
|
: runtime.result?.isError
|
|
151
154
|
? theme.fg("accent", "┃ ")
|
|
152
155
|
: theme.fg("syntaxFunction", "┃ ");
|
|
153
|
-
const rightRail =
|
|
154
|
-
const bottom =
|
|
156
|
+
const rightRail = completeGradient(" │");
|
|
157
|
+
const bottom = completeGradient(bottomBorder(width));
|
|
155
158
|
|
|
156
159
|
const boxed = [
|
|
157
160
|
...prefix,
|
package/manifests/sbom.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
5
|
"name": "@rosetears/aili-pi-0.0.0-development",
|
|
6
|
-
"documentNamespace": "https://github.com/Rosetears520/aili-pi/sbom/
|
|
6
|
+
"documentNamespace": "https://github.com/Rosetears520/aili-pi/sbom/01e1201c78bfb1b604ad872b36621ba1",
|
|
7
7
|
"creationInfo": {
|
|
8
8
|
"creators": [
|
|
9
9
|
"Tool: @rosetears/aili-pi scripts/generate-provenance.ts"
|
package/package.json
CHANGED
|
@@ -14,22 +14,18 @@
|
|
|
14
14
|
"ice": "#D6F4FF",
|
|
15
15
|
"rose": "#C75B7A",
|
|
16
16
|
"roseSoft": "#E8A7B8",
|
|
17
|
-
"roseDeep": "#A8455F",
|
|
18
|
-
"successGreen": "#5A8A72",
|
|
19
|
-
"gold": "#F3CE83",
|
|
20
|
-
"coral": "#FF93B1",
|
|
21
17
|
"border": "#4C5B86",
|
|
22
18
|
"borderMuted": "#303A5B"
|
|
23
19
|
},
|
|
24
20
|
"colors": {
|
|
25
21
|
"accent": "rose", "border": "border", "borderAccent": "cyan", "borderMuted": "borderMuted",
|
|
26
|
-
"success": "
|
|
22
|
+
"success": "cyan", "error": "rose", "warning": "violet", "muted": "muted", "dim": "dim", "text": "text", "thinkingText": "ice",
|
|
27
23
|
"selectedBg": "raised", "userMessageBg": "", "userMessageText": "text", "customMessageBg": "", "customMessageText": "text", "customMessageLabel": "violet",
|
|
28
24
|
"toolPendingBg": "", "toolSuccessBg": "", "toolErrorBg": "", "toolTitle": "cyan", "toolOutput": "ice",
|
|
29
|
-
"mdHeading": "rose", "mdLink": "cyan", "mdLinkUrl": "muted", "mdCode": "
|
|
30
|
-
"toolDiffAdded": "
|
|
31
|
-
"syntaxComment": "muted", "syntaxKeyword": "violet", "syntaxFunction": "cyan", "syntaxVariable": "blue", "syntaxString": "
|
|
32
|
-
"thinkingOff": "dim", "thinkingMinimal": "muted", "thinkingLow": "cyan", "thinkingMedium": "violet", "thinkingHigh": "blue", "thinkingXhigh": "rose", "thinkingMax": "
|
|
25
|
+
"mdHeading": "rose", "mdLink": "cyan", "mdLinkUrl": "muted", "mdCode": "ice", "mdCodeBlock": "text", "mdCodeBlockBorder": "borderMuted", "mdQuote": "ice", "mdQuoteBorder": "violet", "mdHr": "borderMuted", "mdListBullet": "rose",
|
|
26
|
+
"toolDiffAdded": "cyan", "toolDiffRemoved": "rose", "toolDiffContext": "muted",
|
|
27
|
+
"syntaxComment": "muted", "syntaxKeyword": "violet", "syntaxFunction": "cyan", "syntaxVariable": "blue", "syntaxString": "roseSoft", "syntaxNumber": "violet", "syntaxType": "ice", "syntaxOperator": "violet", "syntaxPunctuation": "text",
|
|
28
|
+
"thinkingOff": "dim", "thinkingMinimal": "muted", "thinkingLow": "cyan", "thinkingMedium": "violet", "thinkingHigh": "blue", "thinkingXhigh": "rose", "thinkingMax": "rose", "bashMode": "violet"
|
|
33
29
|
},
|
|
34
30
|
"export": { "pageBg": "#10121D", "cardBg": "#191D2E", "infoBg": "#242A42" }
|
|
35
31
|
}
|