pi-one-ui 0.3.1 → 0.4.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/CHANGELOG.md +19 -1
- package/README.en.md +30 -26
- package/README.md +6 -2
- package/extensions/app/commands/settings-previews.ts +1 -13
- package/extensions/app/config/shell.ts +11 -133
- package/extensions/app/panel.ts +1 -6
- package/extensions/app/runtime/tui-runtime.ts +1 -26
- package/extensions/layouts/editor/controller.ts +0 -54
- package/extensions/layouts/editor/factory.ts +2 -20
- package/extensions/layouts/editor/index.ts +0 -6
- package/extensions/layouts/editor/minimalist-editor.ts +1 -52
- package/extensions/layouts/editor/ui.ts +18 -250
- package/extensions/layouts/working-line/interaction-summary.ts +47 -7
- package/extensions/layouts/working-line/working-line.ts +24 -3
- package/extensions/shared/icons.ts +0 -4
- package/package.json +2 -3
- package/extensions/layouts/editor/accent-rail-editor.ts +0 -112
- package/extensions/layouts/editor/accent-rail-layout-patch.ts +0 -530
|
@@ -550,7 +550,12 @@ export type WorkingLineRuntimeSegments = {
|
|
|
550
550
|
tool?: string;
|
|
551
551
|
elapsedMs?: number;
|
|
552
552
|
thought?: { durationMs: number; active: boolean };
|
|
553
|
-
tokens?: {
|
|
553
|
+
tokens?: {
|
|
554
|
+
input: number;
|
|
555
|
+
output: number;
|
|
556
|
+
outputApproximate?: boolean;
|
|
557
|
+
outputTokensPerSecond?: number;
|
|
558
|
+
};
|
|
554
559
|
};
|
|
555
560
|
|
|
556
561
|
export type WorkingLineFrameState = {
|
|
@@ -617,11 +622,18 @@ export function formatWorkingLineTokens(
|
|
|
617
622
|
tokens.input < 0 ||
|
|
618
623
|
tokens.output < 0 ||
|
|
619
624
|
(tokens.outputApproximate !== undefined &&
|
|
620
|
-
typeof tokens.outputApproximate !== "boolean")
|
|
625
|
+
typeof tokens.outputApproximate !== "boolean") ||
|
|
626
|
+
(tokens.outputTokensPerSecond !== undefined &&
|
|
627
|
+
(!Number.isFinite(tokens.outputTokensPerSecond) ||
|
|
628
|
+
tokens.outputTokensPerSecond < 0))
|
|
621
629
|
) {
|
|
622
630
|
return undefined;
|
|
623
631
|
}
|
|
624
|
-
|
|
632
|
+
const outputRate =
|
|
633
|
+
tokens.outputTokensPerSecond && tokens.outputTokensPerSecond > 0
|
|
634
|
+
? ` ⚡${formatCount(Math.round(tokens.outputTokensPerSecond * 10) / 10)} tok/s`
|
|
635
|
+
: "";
|
|
636
|
+
return `↑${formatCount(tokens.input)} ↓${formatCount(tokens.output)}${outputRate}`;
|
|
625
637
|
}
|
|
626
638
|
|
|
627
639
|
function truncateWithEllipsis(value: string, capacity: number): string {
|
|
@@ -1174,6 +1186,15 @@ export class WorkingLineController {
|
|
|
1174
1186
|
startTurn(ctx: WorkingLineContext): WorkingLineReconcileResult {
|
|
1175
1187
|
const config = this.getConfig().components.workingLine;
|
|
1176
1188
|
this.activeTools.clear();
|
|
1189
|
+
if (this.tokens?.outputTokensPerSecond !== undefined) {
|
|
1190
|
+
this.tokens = {
|
|
1191
|
+
input: this.tokens.input,
|
|
1192
|
+
output: this.tokens.output,
|
|
1193
|
+
...(this.tokens.outputApproximate === undefined
|
|
1194
|
+
? {}
|
|
1195
|
+
: { outputApproximate: this.tokens.outputApproximate }),
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1177
1198
|
const selectedMessage = selectWorkingLineMessage(config, this.random);
|
|
1178
1199
|
if (!config.enabled) {
|
|
1179
1200
|
this.selectedMessage = selectedMessage;
|
|
@@ -23,7 +23,6 @@ export type IconGlyphs = {
|
|
|
23
23
|
deleted: string;
|
|
24
24
|
typechanged: string;
|
|
25
25
|
cacheHit: string;
|
|
26
|
-
editorPrompt: string;
|
|
27
26
|
rail: string;
|
|
28
27
|
username: string;
|
|
29
28
|
time: string;
|
|
@@ -48,7 +47,6 @@ export const ICON_GLYPH_KEYS = [
|
|
|
48
47
|
"deleted",
|
|
49
48
|
"typechanged",
|
|
50
49
|
"cacheHit",
|
|
51
|
-
"editorPrompt",
|
|
52
50
|
"rail",
|
|
53
51
|
"username",
|
|
54
52
|
"time",
|
|
@@ -79,7 +77,6 @@ export const NERD_DEFAULT_ICONS: IconGlyphs = {
|
|
|
79
77
|
deleted: "✘",
|
|
80
78
|
typechanged: "T",
|
|
81
79
|
cacheHit: "",
|
|
82
|
-
editorPrompt: "",
|
|
83
80
|
rail: "│",
|
|
84
81
|
username: "",
|
|
85
82
|
time: "",
|
|
@@ -103,7 +100,6 @@ export const ASCII_DEFAULT_ICONS: IconGlyphs = {
|
|
|
103
100
|
deleted: "x",
|
|
104
101
|
typechanged: "T",
|
|
105
102
|
cacheHit: "c",
|
|
106
|
-
editorPrompt: "",
|
|
107
103
|
rail: "|",
|
|
108
104
|
username: "@",
|
|
109
105
|
time: "t",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-one-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A single, customizable Pi UI package with layout-oriented Context and Shell rendering for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,8 +58,7 @@
|
|
|
58
58
|
"themes": [
|
|
59
59
|
"./themes/cc-dark.json",
|
|
60
60
|
"./themes/cc-light.json"
|
|
61
|
-
]
|
|
62
|
-
"image": "https://raw.githubusercontent.com/minuque/pi-cc-extensions/main/assets/readme/preview.png"
|
|
61
|
+
]
|
|
63
62
|
},
|
|
64
63
|
"devDependencies": {
|
|
65
64
|
"@biomejs/biome": "^2.5.5",
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
|
-
import type { ZentuiConfig } from "../../app/config/shell.ts";
|
|
4
|
-
import {
|
|
5
|
-
renderStyleForSourceOrFallback,
|
|
6
|
-
type SourceStyleFallback,
|
|
7
|
-
} from "../../shared/style.ts";
|
|
8
|
-
import {
|
|
9
|
-
applyOwnedLayoutBackground,
|
|
10
|
-
fillTerminalLine,
|
|
11
|
-
renderCompletionRows,
|
|
12
|
-
} from "./completion-menu.ts";
|
|
13
|
-
import { sanitizeEditorMetadataText } from "./editor-metadata-format.ts";
|
|
14
|
-
|
|
15
|
-
export const ACCENT_RAIL_CHROME_WIDTH = 2;
|
|
16
|
-
|
|
17
|
-
const ACCENT_RAIL_FALLBACK: SourceStyleFallback = {
|
|
18
|
-
theme: "syntaxNumber",
|
|
19
|
-
terminal: "fg:215",
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export type AccentRailViewport = {
|
|
23
|
-
above?: string;
|
|
24
|
-
below?: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type AccentRailEditorFrameOptions = {
|
|
28
|
-
width: number;
|
|
29
|
-
editorLines: string[];
|
|
30
|
-
autocompleteLines?: string[];
|
|
31
|
-
viewport?: AccentRailViewport;
|
|
32
|
-
uiTheme: Theme;
|
|
33
|
-
config: ZentuiConfig;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
function clampLines(lines: string[], width: number): string[] {
|
|
37
|
-
const maxWidth = Math.max(0, width);
|
|
38
|
-
return lines.map((line) => truncateToWidth(line, maxWidth, ""));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function selectedRail(config: ZentuiConfig): string {
|
|
42
|
-
const style = config.components.editor.styles["accent-rail"];
|
|
43
|
-
const fallback = config.icons.mode === "ascii" ? "|" : "▎";
|
|
44
|
-
const configured =
|
|
45
|
-
config.icons.mode === "ascii" ? style.asciiRail : style.rail;
|
|
46
|
-
const sanitized = sanitizeEditorMetadataText(configured);
|
|
47
|
-
const glyph = truncateToWidth(sanitized, 1, "");
|
|
48
|
-
return visibleWidth(glyph) === 1 ? glyph : fallback;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function viewportLabel(
|
|
52
|
-
direction: "above" | "below",
|
|
53
|
-
count: string | undefined,
|
|
54
|
-
): string | undefined {
|
|
55
|
-
if (!count || !/^[1-9]\d*$/.test(count)) return undefined;
|
|
56
|
-
return `${direction === "above" ? "↑" : "↓"} ${count} more`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** Pure compact accent-rail composition shared by live rendering and settings previews. */
|
|
60
|
-
export function renderAccentRailEditorFrame({
|
|
61
|
-
width,
|
|
62
|
-
editorLines,
|
|
63
|
-
autocompleteLines = [],
|
|
64
|
-
viewport = {},
|
|
65
|
-
uiTheme,
|
|
66
|
-
config,
|
|
67
|
-
}: AccentRailEditorFrameOptions): string[] {
|
|
68
|
-
if (width < ACCENT_RAIL_CHROME_WIDTH + 1) {
|
|
69
|
-
return clampLines([...editorLines, ...autocompleteLines], width);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const contentWidth = width - ACCENT_RAIL_CHROME_WIDTH;
|
|
73
|
-
const rail = renderStyleForSourceOrFallback(
|
|
74
|
-
uiTheme,
|
|
75
|
-
config.components.editor.colorSource,
|
|
76
|
-
config.colors.editorRail,
|
|
77
|
-
ACCENT_RAIL_FALLBACK,
|
|
78
|
-
selectedRail(config),
|
|
79
|
-
);
|
|
80
|
-
const above = config.components.editor.viewportIndicators
|
|
81
|
-
? viewportLabel("above", viewport.above)
|
|
82
|
-
: undefined;
|
|
83
|
-
const below = config.components.editor.viewportIndicators
|
|
84
|
-
? viewportLabel("below", viewport.below)
|
|
85
|
-
: undefined;
|
|
86
|
-
const rows = [
|
|
87
|
-
...(above ? [above] : []),
|
|
88
|
-
...editorLines,
|
|
89
|
-
...(below ? [below] : []),
|
|
90
|
-
];
|
|
91
|
-
const transparent =
|
|
92
|
-
config.components.editor.styles["accent-rail"].transparent;
|
|
93
|
-
const layout = rows.map((line) => {
|
|
94
|
-
const railCell = transparent
|
|
95
|
-
? rail
|
|
96
|
-
: applyOwnedLayoutBackground(uiTheme, rail);
|
|
97
|
-
const bodyText = ` ${fillTerminalLine(line, contentWidth)}`;
|
|
98
|
-
const body = transparent
|
|
99
|
-
? bodyText
|
|
100
|
-
: applyOwnedLayoutBackground(uiTheme, bodyText);
|
|
101
|
-
return `${railCell}${body}`;
|
|
102
|
-
});
|
|
103
|
-
const autocompleteLayout = renderCompletionRows({
|
|
104
|
-
lines: autocompleteLines,
|
|
105
|
-
width,
|
|
106
|
-
theme: uiTheme,
|
|
107
|
-
selectedPrefix: `${rail} `,
|
|
108
|
-
ownedBackground: !transparent,
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return clampLines([...layout, ...autocompleteLayout], width);
|
|
112
|
-
}
|