@heyhuynhgiabuu/pi-pretty 0.6.22 → 0.6.24

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +25 -7
  3. package/dist/autocomplete.js +1 -4
  4. package/dist/autocomplete.js.map +1 -1
  5. package/dist/config.d.ts +42 -4
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +174 -117
  8. package/dist/config.js.map +1 -1
  9. package/dist/fff-helpers.js +2 -7
  10. package/dist/fff-helpers.js.map +1 -1
  11. package/dist/fff.js +16 -23
  12. package/dist/fff.js.map +1 -1
  13. package/dist/find-glob.js +2 -6
  14. package/dist/find-glob.js.map +1 -1
  15. package/dist/helpers.js +11 -21
  16. package/dist/helpers.js.map +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +22 -60
  19. package/dist/index.js.map +1 -1
  20. package/dist/notices.js +1 -4
  21. package/dist/notices.js.map +1 -1
  22. package/dist/render.d.ts +19 -0
  23. package/dist/render.d.ts.map +1 -1
  24. package/dist/render.js +125 -96
  25. package/dist/render.js.map +1 -1
  26. package/dist/tools/bash.js +26 -29
  27. package/dist/tools/bash.js.map +1 -1
  28. package/dist/tools/find.js +31 -34
  29. package/dist/tools/find.js.map +1 -1
  30. package/dist/tools/grep.js +22 -25
  31. package/dist/tools/grep.js.map +1 -1
  32. package/dist/tools/labels.js +1 -4
  33. package/dist/tools/labels.js.map +1 -1
  34. package/dist/tools/ls.js +18 -21
  35. package/dist/tools/ls.js.map +1 -1
  36. package/dist/tools/metrics.js +4 -7
  37. package/dist/tools/metrics.js.map +1 -1
  38. package/dist/tools/read.js +35 -38
  39. package/dist/tools/read.js.map +1 -1
  40. package/dist/tui-text.js +5 -9
  41. package/dist/tui-text.js.map +1 -1
  42. package/dist/types.js +1 -2
  43. package/dist/types.js.map +1 -1
  44. package/package.json +7 -6
  45. package/src/config.ts +90 -19
  46. package/src/index.ts +9 -10
  47. package/src/render.ts +56 -9
@@ -1,15 +1,12 @@
1
- "use strict";
2
1
  /* pi-pretty: read tool -- file reading with syntax highlighting and inline image support. */
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.registerReadTool = registerReadTool;
5
- const node_path_1 = require("node:path");
6
- const config_js_1 = require("../config.js");
7
- const helpers_js_1 = require("../helpers.js");
8
- const render_js_1 = require("../render.js");
9
- const tui_text_js_1 = require("../tui-text.js");
10
- const metrics_js_1 = require("./metrics.js");
2
+ import { basename, dirname } from "node:path";
3
+ import { BG_BASE, BG_ERROR, FG_DIM, FG_LNUM, FG_RULE, RST, resolveBaseBackground, TOOL_RESULT_INDENT, termWidth, } from "../config.js";
4
+ import { normalizeLineEndings, shortPath } from "../helpers.js";
5
+ import { fillToolBackground, renderFileContent, renderToolError } from "../render.js";
6
+ import { resolveTextCtor } from "../tui-text.js";
7
+ import { wrapExecuteWithMetrics } from "./metrics.js";
11
8
  function getSkillName(filePath, content) {
12
- if ((0, node_path_1.basename)(filePath) !== "SKILL.md")
9
+ if (basename(filePath) !== "SKILL.md")
13
10
  return undefined;
14
11
  const lines = content.split("\n");
15
12
  if (lines[0]?.trim() === "---") {
@@ -20,12 +17,12 @@ function getSkillName(filePath, content) {
20
17
  continue;
21
18
  const value = match[1].trim();
22
19
  if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
23
- return value.slice(1, -1).trim() || (0, node_path_1.basename)((0, node_path_1.dirname)(filePath));
20
+ return value.slice(1, -1).trim() || basename(dirname(filePath));
24
21
  }
25
- return value || (0, node_path_1.basename)((0, node_path_1.dirname)(filePath));
22
+ return value || basename(dirname(filePath));
26
23
  }
27
24
  }
28
- return (0, node_path_1.basename)((0, node_path_1.dirname)(filePath));
25
+ return basename(dirname(filePath));
29
26
  }
30
27
  function renderSkillHeader(skillName, expanded, theme) {
31
28
  const label = theme.fg("accent", "[skill]");
@@ -33,8 +30,8 @@ function renderSkillHeader(skillName, expanded, theme) {
33
30
  const hint = theme.fg("dim", `ctrl+o to ${expanded ? "collapse" : "expand"}`);
34
31
  return `${label} ${name} ${hint}`;
35
32
  }
36
- function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
37
- const TC = (0, tui_text_js_1.resolveTextCtor)(TextComp);
33
+ export function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
34
+ const TC = resolveTextCtor(TextComp);
38
35
  const home = process.env.HOME ?? "";
39
36
  pi.registerTool({
40
37
  name: "read",
@@ -42,7 +39,7 @@ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
42
39
  description: sdkTool.description ?? "Read file contents",
43
40
  parameters: sdkTool.parameters,
44
41
  renderShell: "self",
45
- execute: (0, metrics_js_1.wrapExecuteWithMetrics)(async (tid, params, sig, _upd, ctx) => {
42
+ execute: wrapExecuteWithMetrics(async (tid, params, sig, _upd, ctx) => {
46
43
  const p = params;
47
44
  const result = (await sdkTool.execute(tid, p, sig, undefined, ctx));
48
45
  const imageBlock = result.content?.find((c) => c.type === "image");
@@ -53,7 +50,7 @@ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
53
50
  };
54
51
  return result;
55
52
  }
56
- const tc = (0, helpers_js_1.normalizeLineEndings)(getText(result));
53
+ const tc = normalizeLineEndings(getText(result));
57
54
  result.details = {
58
55
  _type: "readFile",
59
56
  filePath: String(p.path ?? ""),
@@ -64,7 +61,7 @@ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
64
61
  return result;
65
62
  }),
66
63
  renderCall(args, theme, ctx) {
67
- (0, config_js_1.resolveBaseBackground)(theme);
64
+ resolveBaseBackground(theme);
68
65
  const text = ctx.lastComponent ?? new TC("", 0, 0);
69
66
  if (!ctx.isError) {
70
67
  text.setText("");
@@ -72,14 +69,14 @@ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
72
69
  }
73
70
  const path = String(args.path ?? "");
74
71
  const label = theme.fg("error", theme.bold("→ read"));
75
- text.setText((0, render_js_1.fillToolBackground)(`\n${config_js_1.TOOL_RESULT_INDENT}${label} ${theme.fg("toolTitle", path)}\n`, config_js_1.BG_ERROR));
72
+ text.setText(fillToolBackground(`\n${TOOL_RESULT_INDENT}${label} ${theme.fg("toolTitle", path)}\n`, BG_ERROR));
76
73
  return text;
77
74
  },
78
75
  renderResult(result, _opt, theme, ctx) {
79
- (0, config_js_1.resolveBaseBackground)(theme);
76
+ resolveBaseBackground(theme);
80
77
  const text = ctx.lastComponent ?? new TC("", 0, 0);
81
78
  if (ctx.isError) {
82
- text.setText((0, render_js_1.fillToolBackground)((0, render_js_1.renderToolError)(getText(result) || "Error", theme), config_js_1.BG_ERROR));
79
+ text.setText(fillToolBackground(renderToolError(getText(result) || "Error", theme), BG_ERROR));
83
80
  return text;
84
81
  }
85
82
  const d = result.details;
@@ -88,25 +85,25 @@ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
88
85
  // or unsupported by the terminal.
89
86
  if (d?._type === "readImage") {
90
87
  const note = getText(result);
91
- text.setText(note ? (0, render_js_1.fillToolBackground)(note, config_js_1.BG_BASE) : "");
88
+ text.setText(note ? fillToolBackground(note, BG_BASE) : "");
92
89
  return text;
93
90
  }
94
91
  // File content — line-numbered display
95
92
  if (d?._type === "readFile" && d.content) {
96
- const tw = (0, config_js_1.termWidth)();
93
+ const tw = termWidth();
97
94
  const lines = d.content.split("\n");
98
95
  const total = lines.length;
99
96
  const filePath = String(d.filePath ?? "");
100
97
  const skillName = getSkillName(filePath, d.content);
101
- const p2 = (0, helpers_js_1.shortPath)(cwd, home, filePath);
98
+ const p2 = shortPath(cwd, home, filePath);
102
99
  const off2 = typeof d.offset === "number" ? `:${d.offset}` : "";
103
100
  if (!ctx.expanded) {
104
101
  if (skillName) {
105
102
  const header = renderSkillHeader(skillName, false, theme);
106
- text.setText((0, render_js_1.fillToolBackground)(`\n${config_js_1.TOOL_RESULT_INDENT}${header}\n`, config_js_1.BG_BASE));
103
+ text.setText(fillToolBackground(`\n${TOOL_RESULT_INDENT}${header}\n`, BG_BASE));
107
104
  return text;
108
105
  }
109
- text.setText((0, render_js_1.fillToolBackground)(`\n${config_js_1.TOOL_RESULT_INDENT}${theme.fg("toolTitle", theme.bold("→ read"))} ${theme.fg("toolTitle", p2)}${theme.fg("dim", off2)}\n${config_js_1.TOOL_RESULT_INDENT}${config_js_1.FG_DIM}${total} lines — ctrl+o to expand${config_js_1.RST}\n`, config_js_1.BG_BASE));
106
+ text.setText(fillToolBackground(`\n${TOOL_RESULT_INDENT}${theme.fg("toolTitle", theme.bold("→ read"))} ${theme.fg("toolTitle", p2)}${theme.fg("dim", off2)}\n${TOOL_RESULT_INDENT}${FG_DIM}${total} lines — ctrl+o to expand${RST}\n`, BG_BASE));
110
107
  return text;
111
108
  }
112
109
  const maxShow = lines.length;
@@ -117,44 +114,44 @@ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
117
114
  const header = skillName
118
115
  ? renderSkillHeader(skillName, true, theme)
119
116
  : `${theme.fg("toolTitle", theme.bold("→ read"))} ${theme.fg("toolTitle", p2)}${theme.fg("dim", off2)}`;
120
- const out = ["", `${config_js_1.TOOL_RESULT_INDENT}${header}`];
121
- out.push(`${config_js_1.TOOL_RESULT_INDENT}${config_js_1.FG_RULE}${"─".repeat(tw - 1)}${config_js_1.RST}`);
117
+ const out = ["", `${TOOL_RESULT_INDENT}${header}`];
118
+ out.push(`${TOOL_RESULT_INDENT}${FG_RULE}${"─".repeat(tw - 1)}${RST}`);
122
119
  for (let i = 0; i < show.length; i++) {
123
120
  const ln = (d.offset || 0) + i + 1;
124
121
  const code = show[i] ?? "";
125
- const display = code.length > cw ? code.slice(0, Math.max(0, cw - 1)) + `${config_js_1.FG_DIM}›${config_js_1.RST}` : code;
122
+ const display = code.length > cw ? code.slice(0, Math.max(0, cw - 1)) + `${FG_DIM}›${RST}` : code;
126
123
  const lineNo = String(ln);
127
- out.push(`${config_js_1.TOOL_RESULT_INDENT}${config_js_1.FG_LNUM}${" ".repeat(Math.max(0, nw - lineNo.length))}${lineNo}${config_js_1.RST} ${config_js_1.FG_RULE}│${config_js_1.RST} ${display}${config_js_1.RST}`);
124
+ out.push(`${TOOL_RESULT_INDENT}${FG_LNUM}${" ".repeat(Math.max(0, nw - lineNo.length))}${lineNo}${RST} ${FG_RULE}│${RST} ${display}${RST}`);
128
125
  }
129
126
  if (total > maxShow) {
130
- out.push(`${config_js_1.TOOL_RESULT_INDENT}${config_js_1.FG_DIM}… ${total - maxShow} more lines (${total} total)${config_js_1.RST}`);
127
+ out.push(`${TOOL_RESULT_INDENT}${FG_DIM}… ${total - maxShow} more lines (${total} total)${RST}`);
131
128
  }
132
129
  out.push("");
133
130
  const rendered = out.join("\n");
134
- text.setText((0, render_js_1.fillToolBackground)(rendered, config_js_1.BG_BASE));
131
+ text.setText(fillToolBackground(rendered, BG_BASE));
135
132
  ctx.state._rt = rendered;
136
133
  // Async syntax highlighting via Shiki
137
- (0, render_js_1.renderFileContent)(d.content, d.filePath, d.offset || 0, maxShow, cw)
134
+ renderFileContent(d.content, d.filePath, d.offset || 0, maxShow, cw)
138
135
  .then((hl) => {
139
136
  const padded = hl
140
137
  .split("\n")
141
138
  .map((line, index) => {
142
139
  const lineNo = String((d.offset || 0) + index + 1);
143
- return `${config_js_1.TOOL_RESULT_INDENT}${config_js_1.FG_LNUM}${" ".repeat(Math.max(0, nw - lineNo.length))}${lineNo}${config_js_1.RST} ${config_js_1.FG_RULE}│${config_js_1.RST} ${line}${config_js_1.RST}`;
140
+ return `${TOOL_RESULT_INDENT}${FG_LNUM}${" ".repeat(Math.max(0, nw - lineNo.length))}${lineNo}${RST} ${FG_RULE}│${RST} ${line}${RST}`;
144
141
  })
145
142
  .join("\n");
146
143
  const divider = skillName
147
- ? `${config_js_1.TOOL_RESULT_INDENT}${config_js_1.FG_RULE}${"─".repeat(Math.max(1, tw - 1))}${config_js_1.RST}\n`
144
+ ? `${TOOL_RESULT_INDENT}${FG_RULE}${"─".repeat(Math.max(1, tw - 1))}${RST}\n`
148
145
  : "";
149
- const rendered = `\n${config_js_1.TOOL_RESULT_INDENT}${header}\n${divider}${padded}\n`;
150
- text.setText((0, render_js_1.fillToolBackground)(rendered, config_js_1.BG_BASE));
146
+ const rendered = `\n${TOOL_RESULT_INDENT}${header}\n${divider}${padded}\n`;
147
+ text.setText(fillToolBackground(rendered, BG_BASE));
151
148
  ctx.state._rt = rendered;
152
149
  })
153
150
  .catch(() => { });
154
151
  return text;
155
152
  }
156
153
  const fc = result.content?.[0];
157
- text.setText((0, render_js_1.fillToolBackground)(`${config_js_1.TOOL_RESULT_INDENT}${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 120) : "done")}`, config_js_1.BG_BASE));
154
+ text.setText(fillToolBackground(`${TOOL_RESULT_INDENT}${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 120) : "done")}`, BG_BASE));
158
155
  return text;
159
156
  },
160
157
  });
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
package/dist/tui-text.js CHANGED
@@ -1,12 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTextCtor = getTextCtor;
4
- exports.resolveTextCtor = resolveTextCtor;
5
- const pi_tui_1 = require("@earendil-works/pi-tui");
6
- function getTextCtor() {
7
- return pi_tui_1.Text;
1
+ import { Text } from "@earendil-works/pi-tui";
2
+ export function getTextCtor() {
3
+ return Text;
8
4
  }
9
- function resolveTextCtor(TextComp) {
10
- return TextComp ?? pi_tui_1.Text;
5
+ export function resolveTextCtor(TextComp) {
6
+ return TextComp ?? Text;
11
7
  }
12
8
  //# sourceMappingURL=tui-text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tui-text.js","sourceRoot":"","sources":["../src/tui-text.ts"],"names":[],"mappings":";;AAUA,kCAEC;AAED,0CAEC;AAhBD,mDAA8C;AAU9C,SAAgB,WAAW;IAC1B,OAAO,aAAI,CAAC;AACb,CAAC;AAED,SAAgB,eAAe,CAAC,QAAmB;IAClD,OAAO,QAAQ,IAAI,aAAI,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"tui-text.js","sourceRoot":"","sources":["../src/tui-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAU9C,MAAM,UAAU,WAAW;IAC1B,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAmB;IAClD,OAAO,QAAQ,IAAI,IAAI,CAAC;AACzB,CAAC"}
package/dist/types.js CHANGED
@@ -1,6 +1,5 @@
1
- "use strict";
2
1
  /**
3
2
  * pi-pretty shared types.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
4
+ export {};
6
5
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@heyhuynhgiabuu/pi-pretty",
3
- "version": "0.6.22",
4
- "description": "Pretty terminal output for pi — syntax-highlighted file reads, colored bash output, tree-view directory listings, and more.",
3
+ "version": "0.6.24",
4
+ "description": "Pretty terminal output for pi \u2014 syntax-highlighted file reads, colored bash output, tree-view directory listings, and more.",
5
5
  "keywords": [
6
6
  "pi",
7
7
  "pi-extension",
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@biomejs/biome": "^2.3.5",
45
- "@earendil-works/pi-ai": "^0.82.0",
46
- "@earendil-works/pi-coding-agent": "^0.82.0",
47
- "@earendil-works/pi-tui": "^0.82.0",
45
+ "@earendil-works/pi-ai": "^0.84.3",
46
+ "@earendil-works/pi-coding-agent": "^0.84.3",
47
+ "@earendil-works/pi-tui": "^0.84.3",
48
48
  "@types/node": "^20.0.0",
49
49
  "typescript": "^5.0.0",
50
50
  "vitest": "^4.0.18"
@@ -58,5 +58,6 @@
58
58
  "extensions": [
59
59
  "./dist/index.js"
60
60
  ]
61
- }
61
+ },
62
+ "type": "module"
62
63
  }
package/src/config.ts CHANGED
@@ -67,37 +67,93 @@ function hexToAnsiBg(hex: string): string | null {
67
67
  return `\x1b[48;2;${r};${g};${b}m`;
68
68
  }
69
69
 
70
- interface PrettyConfig {
70
+ export interface PrettyConfig {
71
71
  background?: {
72
72
  tool?: string;
73
73
  error?: string;
74
74
  };
75
+ theme?: string;
76
+ icons?: string;
77
+ enableTools?: string[];
78
+ disableTools?: string[];
79
+ maxHlChars?: number;
80
+ maxPreviewLines?: number;
81
+ cacheLimit?: number;
75
82
  }
76
83
 
77
- function readPrettyConfig(agentDir?: string): PrettyConfig {
84
+ /** Normalize a comma-separated env value or JSON array into tool names. */
85
+ export function normalizeToolList(value: unknown): string[] {
86
+ if (!Array.isArray(value)) return [];
87
+ return value
88
+ .filter((v): v is string => typeof v === "string")
89
+ .map((v) => v.trim().toLowerCase())
90
+ .filter(Boolean);
91
+ }
92
+
93
+ function positiveInt(value: unknown): number | undefined {
94
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
95
+ }
96
+
97
+ /**
98
+ * Read and validate `pi-pretty.json` from the config directory. Invalid
99
+ * fields are silently skipped, matching the historical `background`
100
+ * behavior. The file is re-read on each call; callers that need a stable
101
+ * value (extension activation, theme resolution) cache the result.
102
+ */
103
+ export function loadConfig(agentDir = getConfigDir()): PrettyConfig {
78
104
  if (!agentDir) return {};
79
105
  try {
80
- const raw = readFileSync(join(agentDir, "pi-pretty.json"), "utf8");
81
- const parsed = JSON.parse(raw) as PrettyConfig;
106
+ const parsed = JSON.parse(readFileSync(join(agentDir, "pi-pretty.json"), "utf8")) as PrettyConfig;
107
+ const config: PrettyConfig = {};
82
108
  if (parsed.background) {
83
- if (parsed.background.tool && !hexToAnsiBg(parsed.background.tool)) {
84
- parsed.background.tool = undefined;
85
- }
86
- if (parsed.background.error && !hexToAnsiBg(parsed.background.error)) {
87
- parsed.background.error = undefined;
109
+ const background: NonNullable<PrettyConfig["background"]> = {};
110
+ if (parsed.background.tool && hexToAnsiBg(parsed.background.tool)) {
111
+ background.tool = parsed.background.tool;
88
112
  }
89
- if (!parsed.background.tool && !parsed.background.error) {
90
- parsed.background = undefined;
113
+ if (parsed.background.error && hexToAnsiBg(parsed.background.error)) {
114
+ background.error = parsed.background.error;
91
115
  }
116
+ if (background.tool || background.error) config.background = background;
92
117
  }
93
- return parsed;
118
+ if (typeof parsed.theme === "string" && parsed.theme.trim() !== "") config.theme = parsed.theme;
119
+ if (typeof parsed.icons === "string") config.icons = parsed.icons;
120
+ const enableTools = normalizeToolList(parsed.enableTools);
121
+ const disableTools = normalizeToolList(parsed.disableTools);
122
+ if (enableTools.length) config.enableTools = enableTools;
123
+ if (disableTools.length) config.disableTools = disableTools;
124
+ const maxHlChars = positiveInt(parsed.maxHlChars);
125
+ const maxPreviewLines = positiveInt(parsed.maxPreviewLines);
126
+ const cacheLimit = positiveInt(parsed.cacheLimit);
127
+ if (maxHlChars) config.maxHlChars = maxHlChars;
128
+ if (maxPreviewLines) config.maxPreviewLines = maxPreviewLines;
129
+ if (cacheLimit) config.cacheLimit = cacheLimit;
130
+ return config;
94
131
  } catch {
95
132
  return {};
96
133
  }
97
134
  }
98
135
 
136
+ export function getConfigDir(): string | undefined {
137
+ return process.env.PRETTY_CONFIG_DIR ?? getDefaultAgentDir();
138
+ }
139
+
140
+ /**
141
+ * Merge env tool sets with config-file tool lists: a non-empty env set wins
142
+ * over the config file (12-factor precedence); otherwise config applies.
143
+ */
144
+ export function resolveToolSets(
145
+ envDisabled: Set<string>,
146
+ envEnabled: Set<string>,
147
+ config: Pick<PrettyConfig, "disableTools" | "enableTools">,
148
+ ): { disabledTools: Set<string>; enabledTools: Set<string> } {
149
+ return {
150
+ disabledTools: envDisabled.size > 0 ? envDisabled : new Set(config.disableTools ?? []),
151
+ enabledTools: envEnabled.size > 0 ? envEnabled : new Set(config.enableTools ?? []),
152
+ };
153
+ }
154
+
99
155
  function applyPrettyConfigBg(agentDir?: string): boolean {
100
- const config = readPrettyConfig(agentDir);
156
+ const config = loadConfig(agentDir);
101
157
  if (!config.background?.tool) return false;
102
158
  const toolBg = hexToAnsiBg(config.background.tool);
103
159
  if (!toolBg) return false;
@@ -108,8 +164,7 @@ function applyPrettyConfigBg(agentDir?: string): boolean {
108
164
  }
109
165
 
110
166
  export function resolveBaseBackground(theme: BgThemeLike | null | undefined): void {
111
- const home = process.env.HOME;
112
- const configDir = process.env.PRETTY_CONFIG_DIR ?? (home ? join(home, ".pi/agent") : undefined);
167
+ const configDir = getConfigDir();
113
168
  if (applyPrettyConfigBg(configDir)) return;
114
169
  if (!theme?.getBgAnsi && !theme?.bg) return;
115
170
  BG_BASE =
@@ -139,7 +194,7 @@ export function termWidth(): number {
139
194
  // ---------------------------------------------------------------------------
140
195
 
141
196
  const ICONS_MODE = (process.env.PRETTY_ICONS ?? "nerd").toLowerCase();
142
- export const USE_ICONS = ICONS_MODE !== "none" && ICONS_MODE !== "off";
197
+ export let USE_ICONS = ICONS_MODE !== "none" && ICONS_MODE !== "off";
143
198
 
144
199
  export const NF_DIR = `${FG_BLUE}\ue5ff${RST}`;
145
200
  export const NF_DEFAULT = `${FG_DIM}\uf15b${RST}`;
@@ -284,9 +339,25 @@ export function envInt(name: string, fallback: number): number {
284
339
  return Number.isFinite(v) && v > 0 ? v : fallback;
285
340
  }
286
341
 
287
- export const MAX_HL_CHARS = envInt("PRETTY_MAX_HL_CHARS", 80_000);
288
- export const MAX_PREVIEW_LINES = envInt("PRETTY_MAX_PREVIEW_LINES", 80);
289
- export const CACHE_LIMIT = envInt("PRETTY_CACHE_LIMIT", 128);
342
+ export let MAX_HL_CHARS = envInt("PRETTY_MAX_HL_CHARS", 80_000);
343
+ export let MAX_PREVIEW_LINES = envInt("PRETTY_MAX_PREVIEW_LINES", 80);
344
+ export let CACHE_LIMIT = envInt("PRETTY_CACHE_LIMIT", 128);
345
+
346
+ /**
347
+ * Apply `pi-pretty.json` values to the env-backed module bindings. An env
348
+ * var wins over the config file whenever it is set to a non-empty value;
349
+ * empty strings are treated as unset. Call once at extension activation,
350
+ * before any render reads the bindings.
351
+ */
352
+ export function applyConfig(config: PrettyConfig): void {
353
+ if (!process.env.PRETTY_MAX_HL_CHARS && config.maxHlChars) MAX_HL_CHARS = config.maxHlChars;
354
+ if (!process.env.PRETTY_MAX_PREVIEW_LINES && config.maxPreviewLines) MAX_PREVIEW_LINES = config.maxPreviewLines;
355
+ if (!process.env.PRETTY_CACHE_LIMIT && config.cacheLimit) CACHE_LIMIT = config.cacheLimit;
356
+ if (!process.env.PRETTY_ICONS && config.icons) {
357
+ const mode = config.icons.toLowerCase();
358
+ USE_ICONS = mode !== "none" && mode !== "off";
359
+ }
360
+ }
290
361
 
291
362
  // ---------------------------------------------------------------------------
292
363
  // Agent directory helpers
package/src/index.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
13
13
  import * as hostSdk from "@earendil-works/pi-coding-agent";
14
14
  import { createFffAutocompleteProvider } from "./autocomplete.js";
15
- import { getDefaultAgentDir } from "./config.js";
15
+ import { applyConfig, getDefaultAgentDir, loadConfig, normalizeToolList, resolveToolSets } from "./config.js";
16
16
  import { type FffService, getSharedFffService } from "./fff.js";
17
17
  import { registerBashTool } from "./tools/bash.js";
18
18
  import { registerFindTool } from "./tools/find.js";
@@ -28,12 +28,7 @@ import type { PiPrettyDeps, SdkTools } from "./types.js";
28
28
  const DEFAULT_DISABLED_TOOLS = new Set(["ls"]);
29
29
 
30
30
  function envTools(name: "PRETTY_DISABLE_TOOLS" | "PRETTY_ENABLE_TOOLS"): Set<string> {
31
- return new Set(
32
- (process.env[name] ?? "")
33
- .split(",")
34
- .map((tool) => tool.trim().toLowerCase())
35
- .filter(Boolean),
36
- );
31
+ return new Set(normalizeToolList((process.env[name] ?? "").split(",")));
37
32
  }
38
33
 
39
34
  // ---------------------------------------------------------------------------
@@ -43,8 +38,13 @@ function envTools(name: "PRETTY_DISABLE_TOOLS" | "PRETTY_ENABLE_TOOLS"): Set<str
43
38
  export type { PiPrettyDeps };
44
39
 
45
40
  export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps): Promise<void> {
46
- const disabledTools = envTools("PRETTY_DISABLE_TOOLS");
47
- const enabledTools = envTools("PRETTY_ENABLE_TOOLS");
41
+ const config = loadConfig();
42
+ applyConfig(config);
43
+ const { disabledTools, enabledTools } = resolveToolSets(
44
+ envTools("PRETTY_DISABLE_TOOLS"),
45
+ envTools("PRETTY_ENABLE_TOOLS"),
46
+ config,
47
+ );
48
48
  const isToolEnabled = (name: string) => {
49
49
  const normalizedName = name.toLowerCase();
50
50
  return (
@@ -216,5 +216,4 @@ export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrett
216
216
  if (isToolEnabled("grep") && createGrepTool) {
217
217
  registerGrepTool(pi, cwd, fffService, createGrepTool(cwd), TextComp);
218
218
  }
219
-
220
219
  }
package/src/render.ts CHANGED
@@ -11,7 +11,7 @@ import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
11
11
  // static top-level import/require, not function-body require — see tui-text.ts).
12
12
  import { Text as TuiText, truncateToWidth } from "@earendil-works/pi-tui";
13
13
  import { codeToANSI } from "@shikijs/cli";
14
- import type { BundledLanguage, BundledTheme } from "shiki";
14
+ import { type BundledLanguage, type BundledTheme, bundledThemes } from "shiki";
15
15
  import {
16
16
  BG_BASE,
17
17
  BG_ERROR,
@@ -23,6 +23,7 @@ import {
23
23
  FG_LNUM,
24
24
  FG_RULE,
25
25
  FG_YELLOW,
26
+ loadConfig,
26
27
  MAX_HL_CHARS,
27
28
  MAX_PREVIEW_LINES,
28
29
  RST,
@@ -51,22 +52,68 @@ function _truncateToWidth(text: string, maxWidth: number, ellipsis?: string, pad
51
52
 
52
53
  const DEFAULT_THEME: BundledTheme = "github-dark";
53
54
 
54
- function resolveTheme(): BundledTheme {
55
- const env = process.env.PRETTY_THEME as BundledTheme | undefined;
56
- if (env) return env;
55
+ function isBundledTheme(name: string): name is BundledTheme {
56
+ return Object.hasOwn(bundledThemes, name);
57
+ }
58
+
59
+ function pickValidTheme(candidate: string, source: string): BundledTheme {
60
+ if (isBundledTheme(candidate)) return candidate;
61
+ console.warn(
62
+ `pi-pretty: theme "${candidate}" from ${source} is not a bundled Shiki theme; falling back to "${DEFAULT_THEME}"`,
63
+ );
64
+ return DEFAULT_THEME;
65
+ }
66
+
67
+ /**
68
+ * Resolve the Shiki theme used for syntax highlighting.
69
+ *
70
+ * `~/.pi/agent/settings.json`'s `theme` field is pi's TUI appearance setting
71
+ * (e.g. `dark`, `light`, or a custom pi theme name), which is not a valid
72
+ * Shiki theme for native users. Validate the candidate against Shiki's
73
+ * bundled themes; warn once and fall back to {@link DEFAULT_THEME} when it is
74
+ * not a bundled theme, instead of silently degrading every highlighted block
75
+ * to plain text.
76
+ */
77
+ export function resolveTheme(env = process.env.PRETTY_THEME, home = process.env.HOME): BundledTheme {
78
+ if (env) return pickValidTheme(env, "PRETTY_THEME");
57
79
  try {
58
- const home = process.env.HOME;
59
80
  if (!home) return DEFAULT_THEME;
60
81
  const settings = JSON.parse(
61
82
  require("node:fs").readFileSync(require("node:path").join(home, ".pi/agent/settings.json"), "utf8"),
62
83
  );
63
- return (settings.theme as BundledTheme) ?? DEFAULT_THEME;
84
+ const candidate = settings.theme;
85
+ if (typeof candidate === "string") return pickValidTheme(candidate, "~/.pi/agent/settings.json");
86
+ return DEFAULT_THEME;
64
87
  } catch {
65
88
  return DEFAULT_THEME;
66
89
  }
67
90
  }
68
91
 
69
- const THEME: BundledTheme = resolveTheme();
92
+ let _theme: BundledTheme | undefined;
93
+
94
+ /**
95
+ * Resolve the effective theme once per session: `PRETTY_THEME` env →
96
+ * `pi-pretty.json` → `~/.pi/agent/settings.json` → {@link DEFAULT_THEME}.
97
+ * Resolution is lazy so config-file values applied at extension activation
98
+ * take effect, and the result is cached (at most one warning per source).
99
+ */
100
+ export function getTheme(): BundledTheme {
101
+ if (_theme) return _theme;
102
+ const env = process.env.PRETTY_THEME;
103
+ let theme: BundledTheme;
104
+ if (env) {
105
+ theme = resolveTheme(env, "");
106
+ } else {
107
+ const configTheme = loadConfig().theme;
108
+ theme =
109
+ typeof configTheme === "string"
110
+ ? pickValidTheme(configTheme, "pi-pretty.json")
111
+ : resolveTheme(undefined, process.env.HOME);
112
+ }
113
+ _theme = theme;
114
+ return theme;
115
+ }
116
+
70
117
  const _cache = new Map<string, string[]>();
71
118
 
72
119
  function _touch(k: string, v: string[]): string[] {
@@ -84,12 +131,12 @@ async function hlBlock(code: string, language: BundledLanguage | undefined): Pro
84
131
  if (!code) return [""];
85
132
  if (!language || code.length > MAX_HL_CHARS) return code.split("\n");
86
133
 
87
- const k = `${THEME}\0${language}\0${code}`;
134
+ const k = `${getTheme()}\0${language}\0${code}`;
88
135
  const hit = _cache.get(k);
89
136
  if (hit) return _touch(k, hit);
90
137
 
91
138
  try {
92
- const ansi = normalizeShikiContrast(await codeToANSI(code, language, THEME));
139
+ const ansi = normalizeShikiContrast(await codeToANSI(code, language, getTheme()));
93
140
  const out = (ansi.endsWith("\n") ? ansi.slice(0, -1) : ansi).split("\n");
94
141
  return _touch(k, out);
95
142
  } catch {