@xynogen/pix-pretty 1.7.24 → 1.7.26
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 +4 -2
- package/src/config.ts +3 -2
- package/src/diff-render.ts +3 -2
- package/src/icon-persist.test.ts +15 -11
- package/src/icon-persist.ts +18 -13
- package/src/renderers.ts +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-pretty",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.26",
|
|
4
4
|
"description": "Enhanced tool output rendering with syntax highlighting, file icons, tree views, diff rendering, and FFF search",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -58,7 +58,9 @@
|
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@xynogen/pix-data": "^0.
|
|
61
|
+
"@xynogen/pix-data": "^0.4.0",
|
|
62
|
+
"@xynogen/pix-runtime": "^0.3.0",
|
|
63
|
+
"chalk": "^4.1.2",
|
|
62
64
|
"cli-highlight": "^2.1.11",
|
|
63
65
|
"@ff-labs/fff-node": "^0.5.2",
|
|
64
66
|
"diff": "^8.0.3"
|
package/src/config.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { config } from "@xynogen/pix-runtime/config";
|
|
2
|
+
import { prettySection } from "@xynogen/pix-runtime/sections";
|
|
2
3
|
|
|
3
4
|
export function envInt(name: string, fallback: number): number {
|
|
4
5
|
const v = Number.parseInt(process.env[name] ?? "", 10);
|
|
@@ -15,7 +16,7 @@ function pixOrEnvInt(envName: string, pixValue: number, fallback: number): numbe
|
|
|
15
16
|
return pixValue !== fallback ? pixValue : fallback;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
const pc =
|
|
19
|
+
const pc = config(prettySection);
|
|
19
20
|
|
|
20
21
|
export const MAX_HL_CHARS = pixOrEnvInt("PRETTY_MAX_HL_CHARS", pc.maxHighlightChars, 80_000);
|
|
21
22
|
|
package/src/diff-render.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
// Engine note: pi-diff used Shiki's codeToANSI. pretty uses cli-highlight,
|
|
7
7
|
// shared with other pix-pretty renderers, and paints foreground tokens only.
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { config } from "@xynogen/pix-runtime/config";
|
|
10
|
+
import { prettySection } from "@xynogen/pix-runtime/sections";
|
|
10
11
|
import * as Diff from "diff";
|
|
11
12
|
import { BG_BASE, BOLD, FG_DIM, FG_GREEN, FG_LNUM, FG_RED, FG_RULE, RST } from "./ansi.js";
|
|
12
13
|
import { MAX_HL_CHARS, MAX_RENDER_LINES, WORD_DIFF_MIN_SIM } from "./config.js";
|
|
@@ -30,7 +31,7 @@ function envInt(name: string, fallback: number): number {
|
|
|
30
31
|
// ---------------------------------------------------------------------------
|
|
31
32
|
|
|
32
33
|
const DIM = "\x1b[2m";
|
|
33
|
-
const dc =
|
|
34
|
+
const dc = config(prettySection).diff;
|
|
34
35
|
|
|
35
36
|
// Diff add/remove share the canonical green/red from ansi.ts (single source).
|
|
36
37
|
const FG_ADD = FG_GREEN;
|
package/src/icon-persist.test.ts
CHANGED
|
@@ -2,26 +2,30 @@ import { afterAll, afterEach, beforeAll, describe, expect, it } from "bun:test";
|
|
|
2
2
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { reloadConfig } from "@xynogen/pix-runtime/config";
|
|
6
6
|
import { getIconMode, setIconMode } from "./icon-catalog.ts";
|
|
7
7
|
import { initIconMode, loadIconMode, saveIconMode } from "./icon-persist.ts";
|
|
8
8
|
|
|
9
9
|
let tmpAgentDir: string;
|
|
10
10
|
let origHome: string | undefined;
|
|
11
11
|
|
|
12
|
-
beforeAll(() => {
|
|
12
|
+
beforeAll(async () => {
|
|
13
13
|
tmpAgentDir = mkdtempSync(join(tmpdir(), "pretty-persist-test-"));
|
|
14
14
|
origHome = process.env.HOME;
|
|
15
|
-
// Point HOME at the temp dir so
|
|
15
|
+
// Point HOME at the temp dir so the runtime reads from there, not the real ~/.pi/agent/pix.json
|
|
16
16
|
process.env.HOME = tmpAgentDir;
|
|
17
17
|
process.env.PI_CODING_AGENT_DIR = tmpAgentDir;
|
|
18
|
-
//
|
|
19
|
-
|
|
18
|
+
// Drop any singleton created by earlier test files (it is bound to the old
|
|
19
|
+
// agent dir); the next accessor call lazily recreates it under the temp HOME.
|
|
20
|
+
delete (globalThis as Record<symbol, unknown>)[Symbol.for("@xynogen/pix-runtime")];
|
|
21
|
+
await reloadConfig();
|
|
20
22
|
});
|
|
21
23
|
|
|
22
24
|
afterAll(() => {
|
|
23
25
|
process.env.HOME = origHome;
|
|
24
26
|
delete process.env.PI_CODING_AGENT_DIR;
|
|
27
|
+
// Drop the temp-HOME-bound singleton so later test files get a fresh one.
|
|
28
|
+
delete (globalThis as Record<symbol, unknown>)[Symbol.for("@xynogen/pix-runtime")];
|
|
25
29
|
try {
|
|
26
30
|
rmSync(tmpAgentDir, { recursive: true });
|
|
27
31
|
} catch {
|
|
@@ -36,18 +40,18 @@ describe("icon-persist", () => {
|
|
|
36
40
|
expect(loadIconMode()).toBe("nerd");
|
|
37
41
|
});
|
|
38
42
|
|
|
39
|
-
it("round-trips a mode across save/load (new-session sim)", () => {
|
|
40
|
-
saveIconMode("unicode");
|
|
43
|
+
it("round-trips a mode across save/load (new-session sim)", async () => {
|
|
44
|
+
await saveIconMode("unicode");
|
|
41
45
|
expect(loadIconMode()).toBe("unicode");
|
|
42
46
|
});
|
|
43
47
|
|
|
44
|
-
it("rejects an invalid persisted mode", () => {
|
|
45
|
-
saveIconMode("ascii");
|
|
48
|
+
it("rejects an invalid persisted mode", async () => {
|
|
49
|
+
await saveIconMode("ascii");
|
|
46
50
|
expect(loadIconMode()).toBe("ascii");
|
|
47
51
|
});
|
|
48
52
|
|
|
49
|
-
it("initIconMode applies the persisted choice to the catalog", () => {
|
|
50
|
-
saveIconMode("ascii");
|
|
53
|
+
it("initIconMode applies the persisted choice to the catalog", async () => {
|
|
54
|
+
await saveIconMode("ascii");
|
|
51
55
|
setIconMode("nerd"); // pretend env default
|
|
52
56
|
initIconMode();
|
|
53
57
|
expect(getIconMode()).toBe("ascii");
|
package/src/icon-persist.ts
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* Precedence: env PRETTY_ICONS → pix.json pretty.icons → default ("nerd")
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { config, onConfigChange, updateConfig } from "@xynogen/pix-runtime/config";
|
|
13
|
+
import { prettySection } from "@xynogen/pix-runtime/sections";
|
|
13
14
|
import { ICON_MODES, type IconMode, setIconMode } from "./icon-catalog.js";
|
|
14
15
|
|
|
15
16
|
function isIconMode(m: string): m is IconMode {
|
|
@@ -19,7 +20,7 @@ function isIconMode(m: string): m is IconMode {
|
|
|
19
20
|
/** Read the persisted icon mode from pix.json, or undefined if unset/invalid. */
|
|
20
21
|
export function loadIconMode(): IconMode | undefined {
|
|
21
22
|
try {
|
|
22
|
-
const mode =
|
|
23
|
+
const mode = config(prettySection).icons;
|
|
23
24
|
if (mode == null) return undefined;
|
|
24
25
|
return isIconMode(mode) ? mode : undefined;
|
|
25
26
|
} catch {
|
|
@@ -28,12 +29,13 @@ export function loadIconMode(): IconMode | undefined {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
/** Persist the icon mode to pix.json (`pretty.icons`). */
|
|
31
|
-
export function saveIconMode(mode: IconMode): void {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
export function saveIconMode(mode: IconMode): Promise<void> {
|
|
33
|
+
return updateConfig(prettySection, { icons: mode }).then(
|
|
34
|
+
() => undefined,
|
|
35
|
+
(err) => {
|
|
36
|
+
console.error("pix-pretty: persist icon mode failed:", err);
|
|
37
|
+
},
|
|
38
|
+
);
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
/**
|
|
@@ -43,12 +45,15 @@ export function saveIconMode(mode: IconMode): void {
|
|
|
43
45
|
* Precedence: env PRETTY_ICONS → pix.json pretty.icons → default ("nerd")
|
|
44
46
|
*/
|
|
45
47
|
export function initIconMode(): void {
|
|
46
|
-
const pixIcons =
|
|
48
|
+
const pixIcons = config(prettySection).icons;
|
|
47
49
|
if (pixIcons && isIconMode(pixIcons)) setIconMode(pixIcons);
|
|
48
50
|
|
|
49
51
|
// Keep the in-memory icon mode in sync when /pix changes pretty.icons.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
onConfigChange(
|
|
53
|
+
(change) => {
|
|
54
|
+
const mode = change.current.get(prettySection).icons;
|
|
55
|
+
if (mode && isIconMode(mode)) setIconMode(mode);
|
|
56
|
+
},
|
|
57
|
+
{ paths: ["pretty.icons"] },
|
|
58
|
+
);
|
|
54
59
|
}
|
package/src/renderers.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
-
import {
|
|
2
|
+
import { config } from "@xynogen/pix-runtime/config";
|
|
3
|
+
import { prettySection } from "@xynogen/pix-runtime/sections";
|
|
3
4
|
|
|
4
5
|
import { FG_DIM, FG_RULE, RST } from "./ansi.js";
|
|
5
6
|
import { MAX_PREVIEW_LINES } from "./config.js";
|
|
@@ -75,7 +76,7 @@ export function renderBashOutput(
|
|
|
75
76
|
|
|
76
77
|
/** Render ls output using the configured style (grid or tree). */
|
|
77
78
|
export function renderTree(text: string, basePath: string, theme?: FgTheme): string {
|
|
78
|
-
return
|
|
79
|
+
return config(prettySection).lsStyle === "tree"
|
|
79
80
|
? renderLsTree(text, basePath, theme)
|
|
80
81
|
: renderLsGrid(text, basePath, theme);
|
|
81
82
|
}
|