@heyhuynhgiabuu/pi-pretty 0.4.4 → 0.5.1
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 +1 -0
- package/package.json +5 -1
- package/src/index.ts +24 -11
- package/test/bash-rendering.test.ts +1 -1
- package/test/fff-integration.test.ts +38 -0
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ Optional environment variables:
|
|
|
140
140
|
- `PRETTY_MAX_PREVIEW_LINES` (default: `80`)
|
|
141
141
|
- `PRETTY_CACHE_LIMIT` (default: `128`)
|
|
142
142
|
- `PRETTY_ICONS` (`nerd` by default, set to `none` to disable icons)
|
|
143
|
+
- `PRETTY_DISABLE_TOOLS` — comma-separated list of tool names to skip during registration (e.g. `read,grep`). Useful when another extension already owns one of these tool names. All tools (read, bash, ls, find, grep, multi_grep) are registered by default.
|
|
143
144
|
|
|
144
145
|
## Development
|
|
145
146
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heyhuynhgiabuu/pi-pretty",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Pretty terminal output for pi — syntax-highlighted file reads, colored bash output, tree-view directory listings, and more.",
|
|
5
5
|
"author": "huynhgiabuu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,10 +26,14 @@
|
|
|
26
26
|
"@shikijs/cli": "^4.0.2"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
30
|
+
"@earendil-works/pi-tui": "*",
|
|
29
31
|
"@mariozechner/pi-coding-agent": "*",
|
|
30
32
|
"@mariozechner/pi-tui": "*"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
35
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
36
|
+
"@earendil-works/pi-tui": "*",
|
|
33
37
|
"@types/node": "^20.0.0",
|
|
34
38
|
"typescript": "^5.0.0",
|
|
35
39
|
"@biomejs/biome": "^2.3.5",
|
package/src/index.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { mkdirSync, readFileSync } from "node:fs";
|
|
|
28
28
|
import { basename, dirname, extname, join, relative } from "node:path";
|
|
29
29
|
|
|
30
30
|
import type { FileFinder, FileItem, GrepResult, SearchResult } from "@ff-labs/fff-node";
|
|
31
|
-
import type { ImageContent, TextContent } from "@
|
|
31
|
+
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
32
32
|
import type {
|
|
33
33
|
AgentToolResult,
|
|
34
34
|
AgentToolUpdateCallback,
|
|
@@ -40,8 +40,8 @@ import type {
|
|
|
40
40
|
LsToolInput,
|
|
41
41
|
ReadToolInput,
|
|
42
42
|
ToolRenderResultOptions,
|
|
43
|
-
} from "@
|
|
44
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
43
|
+
} from "@earendil-works/pi-coding-agent";
|
|
44
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
45
45
|
import { codeToANSI } from "@shikijs/cli";
|
|
46
46
|
import type { BundledLanguage, BundledTheme } from "shiki";
|
|
47
47
|
|
|
@@ -1017,13 +1017,13 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1017
1017
|
_fffDbDir = null;
|
|
1018
1018
|
} else {
|
|
1019
1019
|
try {
|
|
1020
|
-
sdk = require("@
|
|
1020
|
+
sdk = require("@earendil-works/pi-coding-agent");
|
|
1021
1021
|
createReadTool = sdk.createReadToolDefinition ?? sdk.createReadTool;
|
|
1022
1022
|
createBashTool = sdk.createBashToolDefinition ?? sdk.createBashTool;
|
|
1023
1023
|
createLsTool = sdk.createLsToolDefinition ?? sdk.createLsTool;
|
|
1024
1024
|
createFindTool = sdk.createFindToolDefinition ?? sdk.createFindTool;
|
|
1025
1025
|
createGrepTool = sdk.createGrepToolDefinition ?? sdk.createGrepTool;
|
|
1026
|
-
TextComponent = require("@
|
|
1026
|
+
TextComponent = require("@earendil-works/pi-tui").Text;
|
|
1027
1027
|
} catch {
|
|
1028
1028
|
return;
|
|
1029
1029
|
}
|
|
@@ -1035,6 +1035,17 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1035
1035
|
const sp = (p: string) => shortPath(cwd, home, p);
|
|
1036
1036
|
const multiGrepRipgrepFallback = deps?.multiGrepRipgrepFallback ?? runMultiGrepRipgrepFallback;
|
|
1037
1037
|
|
|
1038
|
+
// Parse PRETTY_DISABLE_TOOLS — comma-separated tool names to skip
|
|
1039
|
+
const disabledTools = new Set(
|
|
1040
|
+
(process.env.PRETTY_DISABLE_TOOLS ?? "")
|
|
1041
|
+
.split(",")
|
|
1042
|
+
.map((s) => s.trim().toLowerCase())
|
|
1043
|
+
.filter(Boolean),
|
|
1044
|
+
);
|
|
1045
|
+
function isToolEnabled(name: string): boolean {
|
|
1046
|
+
return !disabledTools.has(name.toLowerCase());
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1038
1049
|
// ===================================================================
|
|
1039
1050
|
// FFF initialization (optional — graceful fallback to SDK)
|
|
1040
1051
|
// ===================================================================
|
|
@@ -1111,7 +1122,8 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1111
1122
|
|
|
1112
1123
|
const origRead = createReadTool(cwd);
|
|
1113
1124
|
|
|
1114
|
-
|
|
1125
|
+
if (isToolEnabled("read")) {
|
|
1126
|
+
pi.registerTool({
|
|
1115
1127
|
...origRead,
|
|
1116
1128
|
name: "read",
|
|
1117
1129
|
|
|
@@ -1218,12 +1230,13 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1218
1230
|
return text;
|
|
1219
1231
|
},
|
|
1220
1232
|
});
|
|
1233
|
+
}
|
|
1221
1234
|
|
|
1222
1235
|
// ===================================================================
|
|
1223
1236
|
// bash — colored exit status
|
|
1224
1237
|
// ===================================================================
|
|
1225
1238
|
|
|
1226
|
-
if (createBashTool) {
|
|
1239
|
+
if (createBashTool && isToolEnabled("bash")) {
|
|
1227
1240
|
const origBash = createBashTool(cwd);
|
|
1228
1241
|
|
|
1229
1242
|
pi.registerTool({
|
|
@@ -1321,7 +1334,7 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1321
1334
|
// ls — tree view with icons
|
|
1322
1335
|
// ===================================================================
|
|
1323
1336
|
|
|
1324
|
-
if (createLsTool) {
|
|
1337
|
+
if (createLsTool && isToolEnabled("ls")) {
|
|
1325
1338
|
const origLs = createLsTool(cwd);
|
|
1326
1339
|
|
|
1327
1340
|
pi.registerTool({
|
|
@@ -1387,7 +1400,7 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1387
1400
|
// find — grouped file list with icons
|
|
1388
1401
|
// ===================================================================
|
|
1389
1402
|
|
|
1390
|
-
if (createFindTool) {
|
|
1403
|
+
if (createFindTool && isToolEnabled("find")) {
|
|
1391
1404
|
const origFind = createFindTool(cwd);
|
|
1392
1405
|
|
|
1393
1406
|
pi.registerTool({
|
|
@@ -1490,7 +1503,7 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1490
1503
|
// grep — highlighted matches with line numbers
|
|
1491
1504
|
// ===================================================================
|
|
1492
1505
|
|
|
1493
|
-
if (createGrepTool) {
|
|
1506
|
+
if (createGrepTool && isToolEnabled("grep")) {
|
|
1494
1507
|
const origGrep = createGrepTool(cwd);
|
|
1495
1508
|
|
|
1496
1509
|
pi.registerTool({
|
|
@@ -1626,7 +1639,7 @@ export default function piPrettyExtension(pi: PiPrettyApi, deps?: PiPrettyDeps):
|
|
|
1626
1639
|
// SDK grep fallback otherwise)
|
|
1627
1640
|
// ===================================================================
|
|
1628
1641
|
|
|
1629
|
-
if (_fffModule || createGrepTool) {
|
|
1642
|
+
if ((_fffModule || createGrepTool) && isToolEnabled("multi_grep")) {
|
|
1630
1643
|
const multiGrepFallback = createGrepTool ? createGrepTool(cwd) : null;
|
|
1631
1644
|
|
|
1632
1645
|
pi.registerTool({
|
|
@@ -373,6 +373,44 @@ describe("piPrettyExtension integration", () => {
|
|
|
373
373
|
expect(events.has("session_start")).toBe(true);
|
|
374
374
|
expect(events.has("session_shutdown")).toBe(true);
|
|
375
375
|
});
|
|
376
|
+
|
|
377
|
+
it("skips tools listed in PRETTY_DISABLE_TOOLS", () => {
|
|
378
|
+
process.env.PRETTY_DISABLE_TOOLS = "read,find";
|
|
379
|
+
load();
|
|
380
|
+
expect(tools.has("read"), "read should be disabled").toBe(false);
|
|
381
|
+
expect(tools.has("find"), "find should be disabled").toBe(false);
|
|
382
|
+
expect(tools.has("bash"), "bash should be enabled").toBe(true);
|
|
383
|
+
expect(tools.has("grep"), "grep should be enabled").toBe(true);
|
|
384
|
+
expect(tools.has("ls"), "ls should be enabled").toBe(true);
|
|
385
|
+
delete process.env.PRETTY_DISABLE_TOOLS;
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it("skips multi_grep when listed in PRETTY_DISABLE_TOOLS", () => {
|
|
389
|
+
process.env.PRETTY_DISABLE_TOOLS = "multi_grep";
|
|
390
|
+
load(true);
|
|
391
|
+
expect(tools.has("multi_grep"), "multi_grep should be disabled").toBe(false);
|
|
392
|
+
expect(tools.has("read"), "read should still be enabled").toBe(true);
|
|
393
|
+
delete process.env.PRETTY_DISABLE_TOOLS;
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it("handles whitespace in PRETTY_DISABLE_TOOLS", () => {
|
|
397
|
+
process.env.PRETTY_DISABLE_TOOLS = " bash , ls ";
|
|
398
|
+
load();
|
|
399
|
+
expect(tools.has("bash"), "bash should be disabled").toBe(false);
|
|
400
|
+
expect(tools.has("ls"), "ls should be disabled").toBe(false);
|
|
401
|
+
expect(tools.has("read"), "read should be enabled").toBe(true);
|
|
402
|
+
expect(tools.has("grep"), "grep should be enabled").toBe(true);
|
|
403
|
+
delete process.env.PRETTY_DISABLE_TOOLS;
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it("empty PRETTY_DISABLE_TOOLS registers all tools", () => {
|
|
407
|
+
process.env.PRETTY_DISABLE_TOOLS = "";
|
|
408
|
+
load();
|
|
409
|
+
for (const n of ["find", "grep", "read", "bash", "ls"]) {
|
|
410
|
+
expect(tools.has(n), `missing: ${n}`).toBe(true);
|
|
411
|
+
}
|
|
412
|
+
delete process.env.PRETTY_DISABLE_TOOLS;
|
|
413
|
+
});
|
|
376
414
|
});
|
|
377
415
|
|
|
378
416
|
// ---- find: SDK fallback (no FFF) -----------------------------------
|