@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 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 retains the pinned sparse waterfall geometry and default `density=0.65`, while bounded ultra-wide tracks are spread across the complete terminal-cell width instead of truncating to a left prefix. `/rose-matrix status` reports its settings; use `/rose-matrix density <0.45-0.95>` or `/rose-matrix appearance <auto|dark|light>` for explicit preferences. `/sakura-matrix` remains a deprecated compatibility alias. The `✦ REASONING` trail uses the Rose-to-ice gradient.
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], [125, 228, 255], [214, 244, 255], [136, 184, 255],
27
- [125, 228, 255], [214, 244, 255], [136, 184, 255], [125, 228, 255],
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: 10,
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
- speed: 5.5 + random() * 7.5,
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: ROSE_RAIN_PALETTE[index % ROSE_RAIN_PALETTE.length] ?? ROSE_RAIN_PALETTE[0]!,
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] === 214) return [78, 120, 129];
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: "#8CE6C2",
239
- contextWarning: "bold #F3CE83",
240
- contextError: "bold #FF93B1",
238
+ contextNormal: "#7DE4FF",
239
+ contextWarning: "bold #BCA7FF",
240
+ contextError: "bold #C75B7A",
241
241
  tokens: "#9DA9C8",
242
- cost: "bold #8CE6C2",
242
+ cost: "bold #7DE4FF",
243
243
  separator: "#64708F",
244
244
  runtimePrefix: "#7DE4FF",
245
245
  extensionStatus: "#BCA7FF",
246
- sessionDuration: "#F3CE83",
246
+ sessionDuration: "#BCA7FF",
247
247
  packageVersion: "#D6F4FF",
248
- gitCommit: "#8CE6C2",
249
- gitMetricsAdded: "#8CE6C2",
250
- gitMetricsDeleted: "#FF93B1",
251
- username: "#F3CE83",
252
- time: "#F3CE83",
253
- os: "#F7EEF8",
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: "#B8BEDD",
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: "terminal",
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
- export function renderRoseGradient(text: string): string {
43
- const cached = gradientCache.get(text);
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) => foreground(sampleGradient(index / span), char)).join("")}${RESET}`;
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(text, rendered);
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 top = renderRoseGradient(label);
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 = renderRoseGradient(" │");
154
- const bottom = renderRoseGradient(bottomBorder(width));
156
+ const rightRail = completeGradient(" │");
157
+ const bottom = completeGradient(bottomBorder(width));
155
158
 
156
159
  const boxed = [
157
160
  ...prefix,
@@ -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/4a5b950286a6867acf10e709f49f1448",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosetears/aili-pi",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "AILI and ROSE distribution for official Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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": "successGreen", "error": "coral", "warning": "gold", "muted": "muted", "dim": "dim", "text": "text", "thinkingText": "ice",
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": "gold", "mdCodeBlock": "text", "mdCodeBlockBorder": "borderMuted", "mdQuote": "ice", "mdQuoteBorder": "violet", "mdHr": "borderMuted", "mdListBullet": "rose",
30
- "toolDiffAdded": "successGreen", "toolDiffRemoved": "coral", "toolDiffContext": "muted",
31
- "syntaxComment": "muted", "syntaxKeyword": "violet", "syntaxFunction": "cyan", "syntaxVariable": "blue", "syntaxString": "successGreen", "syntaxNumber": "gold", "syntaxType": "ice", "syntaxOperator": "violet", "syntaxPunctuation": "text",
32
- "thinkingOff": "dim", "thinkingMinimal": "muted", "thinkingLow": "cyan", "thinkingMedium": "violet", "thinkingHigh": "blue", "thinkingXhigh": "rose", "thinkingMax": "roseDeep", "bashMode": "successGreen"
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
  }