pi-zentui 0.20.0 → 0.20.2
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
|
@@ -441,6 +441,7 @@ Default config values — copy this and change any value you want:
|
|
|
441
441
|
- `editorAccent` styles Editor and User-message accent rails and the labeled message label.
|
|
442
442
|
- `editorPrompt` styles the `opencode-copy-friendly` Editor prompt glyph. Omit it to use `editorAccent`, then the default accent fallback.
|
|
443
443
|
- `editorBorder` styles the `framed` and `framed-copy-friendly` previous-message top/bottom borders and the active editor in static border color mode; the border glyph stays `─`.
|
|
444
|
+
- `editorGitBranch` and `editorThinkingMax` are optional editor-owned overrides, omitted above so source-specific and adaptive defaults remain active. `editorGitBranch` owns the minimalist Editor branch color independently from Footer `gitBranch`; where Zentui resolves configured thinking colors, `max` falls back through `editorThinkingXhigh` and then `editorThinking`.
|
|
444
445
|
- `editorModel`, `editorProvider`, and `editorThinking*` style the editor metadata. `editorThinking` applies to every non-`off` thinking level unless a level-specific key is set.
|
|
445
446
|
|
|
446
447
|
Tip: with `opencode-copy-friendly`, setting Pi's `editorPaddingX` to `1` in `~/.pi/agent/settings.json` keeps a small left gutter without copying a rail glyph.
|
|
@@ -314,6 +314,7 @@ export type PolishedTuiColors = {
|
|
|
314
314
|
editorAccent?: ColorSpec;
|
|
315
315
|
editorPrompt?: ColorSpec;
|
|
316
316
|
editorBorder?: ColorSpec;
|
|
317
|
+
editorGitBranch?: ColorSpec;
|
|
317
318
|
editorModel?: ColorSpec;
|
|
318
319
|
editorProvider?: ColorSpec;
|
|
319
320
|
editorThinking?: ColorSpec;
|
|
@@ -322,6 +323,7 @@ export type PolishedTuiColors = {
|
|
|
322
323
|
editorThinkingMedium?: ColorSpec;
|
|
323
324
|
editorThinkingHigh?: ColorSpec;
|
|
324
325
|
editorThinkingXhigh?: ColorSpec;
|
|
326
|
+
editorThinkingMax?: ColorSpec;
|
|
325
327
|
workingLineLow?: ColorSpec;
|
|
326
328
|
workingLineMid?: ColorSpec;
|
|
327
329
|
workingLineHigh?: ColorSpec;
|
|
@@ -709,6 +711,7 @@ function normalizeColors(record: Record<string, unknown>): Partial<PolishedTuiCo
|
|
|
709
711
|
editorAccent: colorValue(record, "editorAccent"),
|
|
710
712
|
editorPrompt: colorValue(record, "editorPrompt"),
|
|
711
713
|
editorBorder: colorValue(record, "editorBorder"),
|
|
714
|
+
editorGitBranch: colorValue(record, "editorGitBranch"),
|
|
712
715
|
editorModel: colorValue(record, "editorModel"),
|
|
713
716
|
editorProvider: colorValue(record, "editorProvider"),
|
|
714
717
|
editorThinking: colorValue(record, "editorThinking"),
|
|
@@ -717,6 +720,7 @@ function normalizeColors(record: Record<string, unknown>): Partial<PolishedTuiCo
|
|
|
717
720
|
editorThinkingMedium: colorValue(record, "editorThinkingMedium"),
|
|
718
721
|
editorThinkingHigh: colorValue(record, "editorThinkingHigh"),
|
|
719
722
|
editorThinkingXhigh: colorValue(record, "editorThinkingXhigh"),
|
|
723
|
+
editorThinkingMax: colorValue(record, "editorThinkingMax"),
|
|
720
724
|
workingLineLow: colorValue(record, "workingLineLow"),
|
|
721
725
|
workingLineMid: colorValue(record, "workingLineMid"),
|
|
722
726
|
workingLineHigh: colorValue(record, "workingLineHigh"),
|
|
@@ -1425,13 +1429,20 @@ export function mergeConfig(parsed: unknown): PolishedTuiConfig {
|
|
|
1425
1429
|
const config = isRecord(parsed) ? parsed : {};
|
|
1426
1430
|
const iconsRecord = recordValue(config.icons);
|
|
1427
1431
|
const colorsRecord = recordValue(config.colors);
|
|
1432
|
+
const colors = normalizeColors(colorsRecord);
|
|
1428
1433
|
const canonical: ZentuiConfig = {
|
|
1429
1434
|
projectRefreshIntervalMs: parseProjectRefreshIntervalMs(config.projectRefreshIntervalMs),
|
|
1430
1435
|
icons: resolveConfiguredIcons(
|
|
1431
1436
|
normalizeIconMode(iconsRecord.mode),
|
|
1432
1437
|
normalizeIconOverrides(iconsRecord),
|
|
1433
1438
|
),
|
|
1434
|
-
colors: {
|
|
1439
|
+
colors: {
|
|
1440
|
+
...defaultConfig.colors,
|
|
1441
|
+
...colors,
|
|
1442
|
+
...(colors.editorGitBranch === undefined && colors.gitBranch !== undefined
|
|
1443
|
+
? { editorGitBranch: colors.gitBranch }
|
|
1444
|
+
: {}),
|
|
1445
|
+
},
|
|
1435
1446
|
components: resolveComponents(config),
|
|
1436
1447
|
};
|
|
1437
1448
|
const view = compatibilityView(canonical);
|
|
@@ -132,6 +132,12 @@ function editorThinkingStyle(config: ZentuiConfig, level: string): string | unde
|
|
|
132
132
|
return config.colors.editorThinkingHigh ?? config.colors.editorThinking;
|
|
133
133
|
case "xhigh":
|
|
134
134
|
return config.colors.editorThinkingXhigh ?? config.colors.editorThinking;
|
|
135
|
+
case "max":
|
|
136
|
+
return (
|
|
137
|
+
config.colors.editorThinkingMax ??
|
|
138
|
+
config.colors.editorThinkingXhigh ??
|
|
139
|
+
config.colors.editorThinking
|
|
140
|
+
);
|
|
135
141
|
default:
|
|
136
142
|
return config.colors.editorThinking;
|
|
137
143
|
}
|
|
@@ -21,6 +21,21 @@ import {
|
|
|
21
21
|
safeThemeFg,
|
|
22
22
|
} from "./style";
|
|
23
23
|
|
|
24
|
+
const MINIMALIST_MODEL_FALLBACK = {
|
|
25
|
+
theme: "syntaxKeyword",
|
|
26
|
+
terminal: "bold purple",
|
|
27
|
+
};
|
|
28
|
+
const MINIMALIST_THINKING_FALLBACK = { theme: "warning", terminal: "bold yellow" };
|
|
29
|
+
const MINIMALIST_ADAPTIVE_TERMINAL_THINKING_FALLBACKS: Record<string, string> = {
|
|
30
|
+
minimal: "bright-black",
|
|
31
|
+
low: "blue",
|
|
32
|
+
medium: "cyan",
|
|
33
|
+
high: "yellow",
|
|
34
|
+
xhigh: "red",
|
|
35
|
+
max: "bright-red",
|
|
36
|
+
};
|
|
37
|
+
const MINIMALIST_BRANCH_FALLBACK = { theme: "bold syntaxKeyword", terminal: "bold blue" };
|
|
38
|
+
|
|
24
39
|
export type MinimalistEditorMetadata = {
|
|
25
40
|
cwd: string;
|
|
26
41
|
projectRoot?: string;
|
|
@@ -100,6 +115,12 @@ function thinkingStyle(config: ZentuiConfig, level: string): string | undefined
|
|
|
100
115
|
return config.colors.editorThinkingHigh ?? config.colors.editorThinking;
|
|
101
116
|
case "xhigh":
|
|
102
117
|
return config.colors.editorThinkingXhigh ?? config.colors.editorThinking;
|
|
118
|
+
case "max":
|
|
119
|
+
return (
|
|
120
|
+
config.colors.editorThinkingMax ??
|
|
121
|
+
config.colors.editorThinkingXhigh ??
|
|
122
|
+
config.colors.editorThinking
|
|
123
|
+
);
|
|
103
124
|
default:
|
|
104
125
|
return config.colors.editorThinking;
|
|
105
126
|
}
|
|
@@ -155,6 +176,7 @@ function renderTopRight(
|
|
|
155
176
|
config: ZentuiConfig,
|
|
156
177
|
availableWidth: number,
|
|
157
178
|
renderBorder: (text: string) => string,
|
|
179
|
+
renderThinking: (text: string) => string,
|
|
158
180
|
): string {
|
|
159
181
|
const source = config.components.editor.colorSource;
|
|
160
182
|
const parts: string[] = [];
|
|
@@ -173,22 +195,14 @@ function renderTopRight(
|
|
|
173
195
|
uiTheme,
|
|
174
196
|
source,
|
|
175
197
|
config.colors.editorModel,
|
|
176
|
-
|
|
198
|
+
MINIMALIST_MODEL_FALLBACK,
|
|
177
199
|
model,
|
|
178
200
|
),
|
|
179
201
|
);
|
|
180
202
|
}
|
|
181
203
|
const thinking = sanitizeEditorMetadataText(metadata.thinkingLevel ?? "");
|
|
182
204
|
if (thinking && thinking.toLowerCase() !== "off") {
|
|
183
|
-
parts.push(
|
|
184
|
-
renderStyleForSourceOrFallback(
|
|
185
|
-
uiTheme,
|
|
186
|
-
source,
|
|
187
|
-
thinkingStyle(config, thinking),
|
|
188
|
-
"muted",
|
|
189
|
-
thinking,
|
|
190
|
-
),
|
|
191
|
-
);
|
|
205
|
+
parts.push(renderThinking(thinking));
|
|
192
206
|
}
|
|
193
207
|
if (metadata.contextPercent !== undefined && Number.isFinite(metadata.contextPercent)) {
|
|
194
208
|
const percent = Math.round(Math.max(0, Math.min(999, metadata.contextPercent)));
|
|
@@ -236,7 +250,15 @@ function renderBottomLeft(
|
|
|
236
250
|
const source = config.components.editor.colorSource;
|
|
237
251
|
const branch = sanitizeEditorMetadataText(metadata.branch ?? "");
|
|
238
252
|
const parts = branch
|
|
239
|
-
? [
|
|
253
|
+
? [
|
|
254
|
+
renderStyleForSourceOrFallback(
|
|
255
|
+
uiTheme,
|
|
256
|
+
source,
|
|
257
|
+
config.colors.editorGitBranch,
|
|
258
|
+
MINIMALIST_BRANCH_FALLBACK,
|
|
259
|
+
branch,
|
|
260
|
+
),
|
|
261
|
+
]
|
|
240
262
|
: [];
|
|
241
263
|
if (metadata.dirty) {
|
|
242
264
|
parts.push(renderStyleForSource(uiTheme, source, config.colors.gitStatus, "*"));
|
|
@@ -354,18 +376,31 @@ export function renderMinimalistFrame({
|
|
|
354
376
|
}: MinimalistFrameOptions): string[] {
|
|
355
377
|
if (width <= 4) return clampLines(editorLines, width);
|
|
356
378
|
const contentWidth = Math.max(0, width - 4);
|
|
379
|
+
const source = config.components.editor.colorSource;
|
|
380
|
+
const adaptive = config.components.editor.borderColorMode === "adaptive";
|
|
381
|
+
const thinking = sanitizeEditorMetadataText(metadata.thinkingLevel ?? "");
|
|
382
|
+
const activeThinking = thinking && thinking.toLowerCase() !== "off" ? thinking : "";
|
|
357
383
|
const renderStaticBorder = (text: string) =>
|
|
358
384
|
renderStyleForSourceOrFallback(
|
|
359
385
|
uiTheme,
|
|
360
|
-
|
|
386
|
+
source,
|
|
361
387
|
config.colors.editorBorder,
|
|
362
388
|
EDITOR_BORDER_FALLBACK,
|
|
363
389
|
text,
|
|
364
390
|
);
|
|
391
|
+
const terminalAdaptiveThinkingStyle = activeThinking
|
|
392
|
+
? (thinkingStyle(config, activeThinking) ??
|
|
393
|
+
MINIMALIST_ADAPTIVE_TERMINAL_THINKING_FALLBACKS[activeThinking.toLowerCase()] ??
|
|
394
|
+
MINIMALIST_THINKING_FALLBACK.terminal)
|
|
395
|
+
: undefined;
|
|
365
396
|
const renderBorder = (text: string) => {
|
|
366
|
-
if (
|
|
367
|
-
|
|
397
|
+
if (!adaptive) return renderStaticBorder(text);
|
|
398
|
+
if (source === "terminal") {
|
|
399
|
+
return terminalAdaptiveThinkingStyle
|
|
400
|
+
? renderStyleForSource(uiTheme, source, terminalAdaptiveThinkingStyle, text)
|
|
401
|
+
: renderStaticBorder(text);
|
|
368
402
|
}
|
|
403
|
+
if (!borderColor) return renderStaticBorder(text);
|
|
369
404
|
try {
|
|
370
405
|
const rendered = borderColor(text);
|
|
371
406
|
return typeof rendered === "string" ? rendered : renderStaticBorder(text);
|
|
@@ -373,6 +408,15 @@ export function renderMinimalistFrame({
|
|
|
373
408
|
return renderStaticBorder(text);
|
|
374
409
|
}
|
|
375
410
|
};
|
|
411
|
+
const renderStaticThinking = (text: string) =>
|
|
412
|
+
renderStyleForSourceOrFallback(
|
|
413
|
+
uiTheme,
|
|
414
|
+
source,
|
|
415
|
+
thinkingStyle(config, text),
|
|
416
|
+
MINIMALIST_THINKING_FALLBACK,
|
|
417
|
+
text,
|
|
418
|
+
);
|
|
419
|
+
const renderThinking = adaptive ? renderBorder : renderStaticThinking;
|
|
376
420
|
const separator = safeThemeFg(uiTheme, "muted", " · ");
|
|
377
421
|
const viewportLabel = (direction: "above" | "below", count: string | undefined) => {
|
|
378
422
|
if (!count || !/^[1-9]\d*$/.test(count)) return "";
|
|
@@ -391,7 +435,7 @@ export function renderMinimalistFrame({
|
|
|
391
435
|
width,
|
|
392
436
|
left: topLeft,
|
|
393
437
|
leftFallbacks: topFallbacks,
|
|
394
|
-
right: renderTopRight(metadata, uiTheme, config, topRightBudget, renderBorder),
|
|
438
|
+
right: renderTopRight(metadata, uiTheme, config, topRightBudget, renderBorder, renderThinking),
|
|
395
439
|
leftCorner: "╭",
|
|
396
440
|
rightCorner: "╮",
|
|
397
441
|
renderBorder,
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
WorkingLineTextAnimation,
|
|
8
8
|
ZentuiConfig,
|
|
9
9
|
} from "./config";
|
|
10
|
+
import { formatCount } from "./format";
|
|
10
11
|
import {
|
|
11
12
|
isSafeSgrStylePrefix,
|
|
12
13
|
isSupportedColorSpec,
|
|
@@ -561,7 +562,7 @@ export function formatWorkingLineTokens(
|
|
|
561
562
|
) {
|
|
562
563
|
return undefined;
|
|
563
564
|
}
|
|
564
|
-
return `↑${tokens.input} ↓${tokens.output}`;
|
|
565
|
+
return `↑${formatCount(tokens.input)} ↓${formatCount(tokens.output)}`;
|
|
565
566
|
}
|
|
566
567
|
|
|
567
568
|
function truncateWithEllipsis(value: string, capacity: number): string {
|