@xynogen/pix-pretty 1.18.1 → 1.18.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/package.json +1 -1
- package/src/gate-overlay.test.ts +43 -1
- package/src/gate-overlay.ts +19 -1
package/package.json
CHANGED
package/src/gate-overlay.test.ts
CHANGED
|
@@ -31,6 +31,7 @@ interface Wired {
|
|
|
31
31
|
function makeUI(
|
|
32
32
|
onReady: (comp: Wired, finish: (v: unknown) => void) => void,
|
|
33
33
|
onOptions?: (options: unknown) => void,
|
|
34
|
+
renderTheme = theme,
|
|
34
35
|
): OverlayUI {
|
|
35
36
|
return {
|
|
36
37
|
custom: async <T>(
|
|
@@ -47,7 +48,7 @@ function makeUI(
|
|
|
47
48
|
const done = (v: T) => {
|
|
48
49
|
resolved = v;
|
|
49
50
|
};
|
|
50
|
-
const comp = cb({ requestRender: () => {} },
|
|
51
|
+
const comp = cb({ requestRender: () => {} }, renderTheme, undefined, done);
|
|
51
52
|
comp.render(80); // initialise render path
|
|
52
53
|
onReady(comp, done as (v: unknown) => void);
|
|
53
54
|
return resolved;
|
|
@@ -136,6 +137,47 @@ describe("showOverlay — confirm mode", () => {
|
|
|
136
137
|
expect(joined).toContain("body-line-x");
|
|
137
138
|
});
|
|
138
139
|
|
|
140
|
+
test("uses semantic colors for transfer details", async () => {
|
|
141
|
+
const coloredTheme = {
|
|
142
|
+
fg: (color: string, text: string) => `<${color}>${text}</${color}>`,
|
|
143
|
+
bg: (_color: string, text: string) => text,
|
|
144
|
+
bold: (text: string) => text,
|
|
145
|
+
};
|
|
146
|
+
let captured: string[] = [];
|
|
147
|
+
await showOverlay(
|
|
148
|
+
makeUI(
|
|
149
|
+
(comp) => {
|
|
150
|
+
captured = comp.render(100);
|
|
151
|
+
comp.handleInput(ENTER);
|
|
152
|
+
},
|
|
153
|
+
undefined,
|
|
154
|
+
coloredTheme,
|
|
155
|
+
),
|
|
156
|
+
{
|
|
157
|
+
mode: "confirm",
|
|
158
|
+
title: "SSH FILE TRANSFER",
|
|
159
|
+
body: [
|
|
160
|
+
"Intent: Copy a release artifact",
|
|
161
|
+
"Host: deploy@example.com",
|
|
162
|
+
"Direction: Download",
|
|
163
|
+
"From: /srv/releases/app.tar.gz",
|
|
164
|
+
"To: /tmp/app.tar.gz",
|
|
165
|
+
"Mode: Single item",
|
|
166
|
+
"Warning: existing destination may be overwritten",
|
|
167
|
+
"Auth: SSH key (no password)",
|
|
168
|
+
],
|
|
169
|
+
timeoutMs: 0,
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
const joined = captured.join("\n");
|
|
173
|
+
expect(joined).toContain("<dim>Host:</dim> <accent>deploy@example.com</accent>");
|
|
174
|
+
expect(joined).toContain("<dim>Direction:</dim> <warning>Download</warning>");
|
|
175
|
+
expect(joined).toContain("<dim>From:</dim> <text>/srv/releases/app.tar.gz</text>");
|
|
176
|
+
expect(joined).toContain("<dim>To:</dim> <accent>/tmp/app.tar.gz</accent>");
|
|
177
|
+
expect(joined).toContain("<warning>Warning: existing destination may be overwritten</warning>");
|
|
178
|
+
expect(joined).toContain("<dim>Auth:</dim> <success>SSH key (no password)</success>");
|
|
179
|
+
});
|
|
180
|
+
|
|
139
181
|
test("wraps a long body command instead of truncating it", async () => {
|
|
140
182
|
// A command far wider than any modal width — must survive in full, wrapped.
|
|
141
183
|
const longCmd = `echo ${"pix-gate-installed-or-linked ".repeat(8)}done`;
|
package/src/gate-overlay.ts
CHANGED
|
@@ -178,7 +178,25 @@ function buildSections(opts: {
|
|
|
178
178
|
const body = (config.body ?? []).map((line) => {
|
|
179
179
|
if (line.startsWith("Intent:")) return theme.fg("text", line.slice(7).trimStart());
|
|
180
180
|
if (line.startsWith("Command:")) return theme.fg("dim", line.slice(8).trimStart());
|
|
181
|
-
return theme.fg("
|
|
181
|
+
if (line.startsWith("Warning:")) return theme.fg("warning", line);
|
|
182
|
+
if (line.startsWith("(") && line.endsWith(")")) return theme.fg("dim", line);
|
|
183
|
+
|
|
184
|
+
const separator = line.indexOf(":");
|
|
185
|
+
if (separator < 1) return theme.fg("text", line);
|
|
186
|
+
const label = line.slice(0, separator + 1);
|
|
187
|
+
const value = line.slice(separator + 1).trimStart();
|
|
188
|
+
const valueColors: Record<string, string> = {
|
|
189
|
+
"Host:": "accent",
|
|
190
|
+
"Direction:": "warning",
|
|
191
|
+
"From:": "text",
|
|
192
|
+
"To:": "accent",
|
|
193
|
+
"Mode:": "muted",
|
|
194
|
+
"Auth:": "success",
|
|
195
|
+
};
|
|
196
|
+
const valueColor = valueColors[label];
|
|
197
|
+
return valueColor
|
|
198
|
+
? `${theme.fg("dim", label)} ${theme.fg(valueColor, value)}`
|
|
199
|
+
: theme.fg("text", line);
|
|
182
200
|
});
|
|
183
201
|
const footer = [theme.fg("dim", "─".repeat(inner))];
|
|
184
202
|
|