@xynogen/pix-pretty 1.11.2 → 1.12.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/package.json +1 -1
- package/src/icon-catalog.ts +2 -0
- package/src/utils.test.ts +17 -2
- package/src/utils.ts +32 -1
package/package.json
CHANGED
package/src/icon-catalog.ts
CHANGED
|
@@ -65,6 +65,8 @@ const CATALOG = {
|
|
|
65
65
|
// part of this set.
|
|
66
66
|
"status.ok": { nerd: "\u2713", unicode: `\u2713${VS}`, ascii: "ok" },
|
|
67
67
|
"status.error": { nerd: "\u2717", unicode: `\u2717${VS}`, ascii: "x" },
|
|
68
|
+
// `⚠` is East-Asian wide (2 cells); consumers that place it in an aligned
|
|
69
|
+
// marker column must normalize width via `padIcon` (pix-pretty/utils).
|
|
68
70
|
"status.warn": { nerd: "\u26A0", unicode: `\u26A0${VS}`, ascii: "!" },
|
|
69
71
|
"status.pending": { nerd: "\u25CB", unicode: `\u25CB${VS}`, ascii: "o" },
|
|
70
72
|
"status.running": { nerd: "\u25D0", unicode: `\u25D0${VS}`, ascii: "*" },
|
package/src/utils.test.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
formatCollapsedToolRow,
|
|
7
7
|
formatJson,
|
|
8
8
|
hideCollapsedToolCall,
|
|
9
|
+
padIcon,
|
|
9
10
|
pluralize,
|
|
10
11
|
renderCollapsedToolRow,
|
|
11
12
|
renderDimPreview,
|
|
@@ -108,11 +109,25 @@ describe("collapsed tool rows", () => {
|
|
|
108
109
|
const rowTheme = { fg: (_key: string, text: string) => text, bold: (text: string) => text };
|
|
109
110
|
|
|
110
111
|
it("renders a consistent status, tool, target, and metadata row", () => {
|
|
112
|
+
// The status marker is width-normalized to 2 cells (padIcon) so wide glyphs
|
|
113
|
+
// align with narrow ones; a 1-cell `✓` therefore carries one pad space.
|
|
111
114
|
expect(formatCollapsedToolRow(rowTheme, "read", "src/a.ts", "12 lines")).toBe(
|
|
112
|
-
"✓
|
|
115
|
+
"✓ read src/a.ts · 12 lines",
|
|
113
116
|
);
|
|
114
117
|
const rendered = plain(renderCollapsedToolRow(rowTheme, "read", "src/a.ts", "12 lines"));
|
|
115
|
-
expect(rendered).toStartWith("✓
|
|
118
|
+
expect(rendered).toStartWith("✓ read src/a.ts · 12 lines");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("padIcon normalizes markers to a fixed cell width (per pi-tui visibleWidth)", () => {
|
|
122
|
+
// pi-tui's width table drives the actual TUI column math, so padIcon trusts
|
|
123
|
+
// it: `✓`/`✗`/`⚠` measure 1 cell and gain a pad space; `⚡` measures 2 and
|
|
124
|
+
// is left as-is. All markers then occupy the same 2-cell column.
|
|
125
|
+
expect(padIcon("✓")).toBe("✓ ");
|
|
126
|
+
expect(padIcon("✗")).toBe("✗ ");
|
|
127
|
+
expect(padIcon("⚠")).toBe("⚠ ");
|
|
128
|
+
expect(padIcon("⚡")).toBe("⚡"); // already 2 cells — unchanged
|
|
129
|
+
expect(padIcon("x", 4)).toBe("x "); // explicit width
|
|
130
|
+
expect(padIcon("⚡", 1)).toBe("⚡"); // never truncated below its own width
|
|
116
131
|
});
|
|
117
132
|
|
|
118
133
|
it("hides only collapsed, non-expanded call rows", () => {
|
package/src/utils.ts
CHANGED
|
@@ -125,6 +125,37 @@ export function formatJson(value: unknown, options: FormatJsonOptions = {}): str
|
|
|
125
125
|
|
|
126
126
|
export type CollapsedToolStatus = "success" | "error" | "warning";
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Status glyphs for collapsed tool rows. `⚠` (warning) is East-Asian *wide*
|
|
130
|
+
* (2 cells) while `✓`/`✗` are 1 cell — render them through `padIcon` so every
|
|
131
|
+
* marker occupies the same fixed column and rows stay vertically aligned.
|
|
132
|
+
* (`⚡` is reserved for strength / model-score badges, not warnings.)
|
|
133
|
+
*/
|
|
134
|
+
export const COLLAPSED_TOOL_GLYPH: Record<CollapsedToolStatus, string> = {
|
|
135
|
+
success: "✓",
|
|
136
|
+
warning: "⚠",
|
|
137
|
+
error: "✗",
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Normalize a marker glyph to a fixed display width so mixed 1-cell and 2-cell
|
|
142
|
+
* (East-Asian wide / emoji) icons align in a column and the following text
|
|
143
|
+
* always starts at the same offset. Measures actual terminal cells via pi-tui's
|
|
144
|
+
* `visibleWidth` (ANSI-aware), then right-pads with spaces. A glyph already
|
|
145
|
+
* at/over `width` is returned unchanged (never truncated — clipping a marker is
|
|
146
|
+
* worse than a 1-cell overflow).
|
|
147
|
+
*
|
|
148
|
+
* The default width (2) makes every marker occupy exactly two cells, so with a
|
|
149
|
+
* single separator space the following text always starts at the same column:
|
|
150
|
+
*
|
|
151
|
+
* `${padIcon("✓")} bash` // "✓ bash" (1 cell + 1 pad + separator)
|
|
152
|
+
* `${padIcon("⚠")} bash` // "⚠ bash" (2 cells + separator — same column)
|
|
153
|
+
*/
|
|
154
|
+
export function padIcon(glyph: string, width = 2): string {
|
|
155
|
+
const pad = width - visibleWidth(glyph);
|
|
156
|
+
return pad > 0 ? glyph + " ".repeat(pad) : glyph;
|
|
157
|
+
}
|
|
158
|
+
|
|
128
159
|
type CollapsedToolTheme = {
|
|
129
160
|
fg: (
|
|
130
161
|
key: "success" | "error" | "warning" | "toolTitle" | "muted" | "dim",
|
|
@@ -141,7 +172,7 @@ export function formatCollapsedToolRow(
|
|
|
141
172
|
meta = "",
|
|
142
173
|
status: CollapsedToolStatus = "success",
|
|
143
174
|
): string {
|
|
144
|
-
const icon = status
|
|
175
|
+
const icon = padIcon(COLLAPSED_TOOL_GLYPH[status]);
|
|
145
176
|
const parts = [
|
|
146
177
|
`${theme.fg(status, icon)} ${theme.fg("toolTitle", theme.bold(tool))}`,
|
|
147
178
|
target ? theme.fg("muted", target) : "",
|