@heyhuynhgiabuu/pi-pretty 0.6.4 → 0.6.6

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 (96) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/autocomplete.d.ts +10 -0
  3. package/dist/autocomplete.d.ts.map +1 -0
  4. package/dist/autocomplete.js +64 -0
  5. package/dist/autocomplete.js.map +1 -0
  6. package/dist/config.d.ts +33 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +225 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/fff-helpers.d.ts +25 -0
  11. package/dist/fff-helpers.d.ts.map +1 -0
  12. package/dist/fff-helpers.js +83 -0
  13. package/dist/fff-helpers.js.map +1 -0
  14. package/dist/fff.d.ts +37 -0
  15. package/dist/fff.d.ts.map +1 -0
  16. package/dist/fff.js +135 -0
  17. package/dist/fff.js.map +1 -0
  18. package/dist/helpers.d.ts +21 -0
  19. package/dist/helpers.d.ts.map +1 -0
  20. package/dist/helpers.js +133 -0
  21. package/dist/helpers.js.map +1 -0
  22. package/dist/image.d.ts +24 -0
  23. package/dist/image.d.ts.map +1 -0
  24. package/dist/image.js +144 -0
  25. package/dist/image.js.map +1 -0
  26. package/dist/index.d.ts +16 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +227 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/multi-grep-fallback.d.ts +30 -0
  31. package/dist/multi-grep-fallback.d.ts.map +1 -0
  32. package/dist/multi-grep-fallback.js +205 -0
  33. package/dist/multi-grep-fallback.js.map +1 -0
  34. package/dist/notices.d.ts +3 -0
  35. package/dist/notices.d.ts.map +1 -0
  36. package/dist/notices.js +6 -0
  37. package/dist/notices.js.map +1 -0
  38. package/dist/render.d.ts +25 -0
  39. package/dist/render.d.ts.map +1 -0
  40. package/dist/render.js +366 -0
  41. package/dist/render.js.map +1 -0
  42. package/dist/tools/bash.d.ts +6 -0
  43. package/dist/tools/bash.d.ts.map +1 -0
  44. package/dist/tools/bash.js +101 -0
  45. package/dist/tools/bash.js.map +1 -0
  46. package/dist/tools/find.d.ts +6 -0
  47. package/dist/tools/find.d.ts.map +1 -0
  48. package/dist/tools/find.js +109 -0
  49. package/dist/tools/find.js.map +1 -0
  50. package/dist/tools/grep.d.ts +6 -0
  51. package/dist/tools/grep.d.ts.map +1 -0
  52. package/dist/tools/grep.js +122 -0
  53. package/dist/tools/grep.js.map +1 -0
  54. package/dist/tools/ls.d.ts +6 -0
  55. package/dist/tools/ls.d.ts.map +1 -0
  56. package/dist/tools/ls.js +63 -0
  57. package/dist/tools/ls.js.map +1 -0
  58. package/dist/tools/metrics.d.ts +10 -0
  59. package/dist/tools/metrics.d.ts.map +1 -0
  60. package/dist/tools/metrics.js +34 -0
  61. package/dist/tools/metrics.js.map +1 -0
  62. package/dist/tools/multi-grep.d.ts +7 -0
  63. package/dist/tools/multi-grep.d.ts.map +1 -0
  64. package/dist/tools/multi-grep.js +198 -0
  65. package/dist/tools/multi-grep.js.map +1 -0
  66. package/dist/tools/read.d.ts +6 -0
  67. package/dist/tools/read.d.ts.map +1 -0
  68. package/dist/tools/read.js +125 -0
  69. package/dist/tools/read.js.map +1 -0
  70. package/dist/types.d.ts +168 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/types.js +6 -0
  73. package/dist/types.js.map +1 -0
  74. package/package.json +32 -26
  75. package/src/index.ts +30 -22
  76. package/src/notices.ts +3 -0
  77. package/src/tools/find.ts +2 -1
  78. package/src/tools/grep.ts +2 -1
  79. package/src/tools/multi-grep.ts +2 -1
  80. package/biome.json +0 -22
  81. package/bun.lock +0 -598
  82. package/media/bash-and-read.png +0 -0
  83. package/media/icons-and-grep.png +0 -0
  84. package/media/inline-image.png +0 -0
  85. package/pi-pretty.example.json +0 -6
  86. package/release-notes/v0.3.2.md +0 -34
  87. package/release-notes/v0.3.3.md +0 -48
  88. package/release-notes/v0.4.0.md +0 -58
  89. package/release-notes/v0.4.1.md +0 -28
  90. package/release-notes/v0.4.2.md +0 -36
  91. package/release-notes/v0.4.4.md +0 -28
  92. package/release-notes/v0.5.3.md +0 -29
  93. package/test/bash-rendering.test.ts +0 -269
  94. package/test/fff-integration.test.ts +0 -800
  95. package/test/image-rendering.test.ts +0 -153
  96. package/tsconfig.json +0 -19
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ /* 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 config_js_1 = require("../config.js");
6
+ const helpers_js_1 = require("../helpers.js");
7
+ const metrics_js_1 = require("./metrics.js");
8
+ const render_js_1 = require("../render.js");
9
+ // Simple terminal image support check
10
+ function isImageTerminal() {
11
+ const term = (process.env.TERM_PROGRAM ?? process.env.TERM ?? "").toLowerCase();
12
+ const proto = (process.env.PRETTY_IMAGE_PROTOCOL ?? "").toLowerCase();
13
+ if (proto === "kitty" || proto === "iterm2")
14
+ return true;
15
+ if (proto === "none")
16
+ return false;
17
+ return ["ghostty", "kitty", "iterm.app", "wezterm", "mintty"].some((t) => term.includes(t)) || process.env.LC_TERMINAL === "iTerm2";
18
+ }
19
+ function registerReadTool(pi, cwd, _fffService, sdkTool, TextComp) {
20
+ const TC = TextComp ?? (() => {
21
+ const { Text } = require("@earendil-works/pi-tui");
22
+ return Text;
23
+ })();
24
+ const home = process.env.HOME ?? "";
25
+ pi.registerTool({
26
+ name: "read",
27
+ label: "Read",
28
+ description: sdkTool.description ?? "Read file contents",
29
+ parameters: sdkTool.parameters,
30
+ renderShell: "self",
31
+ execute: (0, metrics_js_1.wrapExecuteWithMetrics)(async (tid, params, sig, _upd, ctx) => {
32
+ const p = params;
33
+ const result = await sdkTool.execute(tid, p, sig, undefined, ctx);
34
+ const imageBlock = result.content?.find((c) => c.type === "image");
35
+ if (imageBlock) {
36
+ result.details = { _type: "readImage", filePath: String(p.path ?? ""), data: imageBlock.data, mimeType: imageBlock.mimeType ?? "image/png" };
37
+ return result;
38
+ }
39
+ const tc = (0, helpers_js_1.normalizeLineEndings)(getText(result));
40
+ result.details = { _type: "readFile", filePath: String(p.path ?? ""), content: tc, offset: typeof p.offset === "number" ? p.offset : 0, lineCount: tc ? tc.split("\n").length : 0 };
41
+ return result;
42
+ }),
43
+ renderCall(args, theme, ctx) {
44
+ (0, config_js_1.resolveBaseBackground)(theme);
45
+ const text = ctx.lastComponent ?? new TC("", 0, 0);
46
+ text.setText("");
47
+ return text;
48
+ },
49
+ renderResult(result, _opt, theme, ctx) {
50
+ (0, config_js_1.resolveBaseBackground)(theme);
51
+ const text = ctx.lastComponent ?? new TC("", 0, 0);
52
+ if (ctx.isError) {
53
+ text.setText((0, render_js_1.renderToolError)(getText(result) || "Error", theme));
54
+ return text;
55
+ }
56
+ const d = result.details;
57
+ // Image rendering
58
+ if (d?._type === "readImage") {
59
+ if (ctx.showImages && isImageTerminal()) {
60
+ try {
61
+ const T = require("@earendil-works/pi-tui").Text;
62
+ const img = new T("", 0, 0);
63
+ if (d.mimeType.startsWith("image/svg")) {
64
+ img.setText(d.data);
65
+ }
66
+ else {
67
+ const pngData = require("@earendil-works/pi-coding-agent").convertToPng?.(d.data) ?? d.data;
68
+ img.setText(`\x1b_Ga=T,f=100,m=${d.mimeType === "image/png" ? "1" : "0"};${pngData}\x1b\\\\`);
69
+ }
70
+ return img;
71
+ }
72
+ catch { /* fall through */ }
73
+ }
74
+ const fc = result.content?.[0];
75
+ text.setText((0, render_js_1.fillToolBackground)(` ${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 80) : `[image: ${d.filePath}]`)}`));
76
+ return text;
77
+ }
78
+ // File content — line-numbered display
79
+ if (d?._type === "readFile" && d.content) {
80
+ const tw = (0, config_js_1.termWidth)();
81
+ const lines = d.content.split("\n");
82
+ const total = lines.length;
83
+ const maxShow = ctx.expanded ? lines.length : Math.min(lines.length, config_js_1.MAX_PREVIEW_LINES);
84
+ const show = lines.slice(0, maxShow);
85
+ const nw = Math.max(3, String(total).length);
86
+ const gw = nw + 3;
87
+ const cw = Math.max(1, tw - gw);
88
+ const p2 = (0, helpers_js_1.shortPath)(cwd, home, String(d.filePath ?? ""));
89
+ const off2 = typeof d.offset === "number" ? `:${d.offset}` : "";
90
+ const header = `${theme.fg("toolTitle", theme.bold("read"))} ${theme.fg("accent", p2)}${theme.fg("dim", off2)}`;
91
+ const out = ["", ` ${header}`];
92
+ out.push(` ${config_js_1.FG_RULE}${"─".repeat(tw - 2)}${config_js_1.RST}`);
93
+ for (let i = 0; i < show.length; i++) {
94
+ const ln = (d.offset || 0) + i + 1;
95
+ const code = show[i] ?? "";
96
+ const display = code.length > cw ? code.slice(0, cw) + `${config_js_1.FG_DIM}›${config_js_1.RST}` : code;
97
+ const lineNo = String(ln);
98
+ out.push(` ${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}`);
99
+ }
100
+ if (total > maxShow) {
101
+ out.push(` ${config_js_1.FG_DIM} … ${total - maxShow} more lines (${total} total)${config_js_1.RST}`);
102
+ }
103
+ out.push("");
104
+ const rendered = out.join("\n");
105
+ text.setText((0, render_js_1.fillToolBackground)(rendered));
106
+ ctx.state._rt = rendered;
107
+ // Async syntax highlighting via Shiki
108
+ (0, render_js_1.renderFileContent)(d.content, d.filePath, d.offset || 0, maxShow, tw).then(hl => {
109
+ const padded = hl.split("\n").map(l => ` ${l}`).join("\n");
110
+ const rendered = `\n ${header}\n${padded}\n`;
111
+ text.setText((0, render_js_1.fillToolBackground)(rendered));
112
+ ctx.state._rt = rendered;
113
+ }).catch(() => { });
114
+ return text;
115
+ }
116
+ const fc = result.content?.[0];
117
+ text.setText((0, render_js_1.fillToolBackground)(` ${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 120) : "done")}`));
118
+ return text;
119
+ },
120
+ });
121
+ }
122
+ function getText(result) {
123
+ return (result.content ?? []).filter((c) => c.type === "text").map((c) => c.text).join("\n") ?? "";
124
+ }
125
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * pi-pretty shared types.
3
+ */
4
+ import type { TextContent, ImageContent } from "@earendil-works/pi-ai";
5
+ import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
6
+ export type { FileFinder, FileItem, GrepResult, SearchResult, GrepMatch, GrepCursor } from "@ff-labs/fff-node";
7
+ export type ToolContent = TextContent | ImageContent;
8
+ export type { TextContent, ImageContent };
9
+ export interface ThemeLike {
10
+ fg: (key: string, text: string) => string;
11
+ bold: (text: string) => string;
12
+ getBgAnsi?: (key: string) => string;
13
+ }
14
+ export interface RenderCtxLike {
15
+ lastComponent?: ComponentLike;
16
+ isError?: boolean;
17
+ state: Record<string, string | undefined>;
18
+ expanded?: boolean;
19
+ }
20
+ export interface TextLike {
21
+ setText(v: string): void;
22
+ getText?(): string;
23
+ }
24
+ /** Minimal Component interface matching pi-tui's Component. */
25
+ export interface ComponentLike {
26
+ setText(v: string): void;
27
+ render(width: number): string[];
28
+ invalidate?(): void;
29
+ }
30
+ export type ReadDetails = {
31
+ _type: "readImage";
32
+ filePath: string;
33
+ data: string;
34
+ mimeType: string;
35
+ } | {
36
+ _type: "readFile";
37
+ filePath: string;
38
+ content: string;
39
+ offset: number;
40
+ lineCount: number;
41
+ };
42
+ export interface BashDetails extends Record<string, unknown> {
43
+ _type: "bashResult";
44
+ text: string;
45
+ exitCode: number | null;
46
+ command: string;
47
+ }
48
+ export interface LsDetails extends Record<string, unknown> {
49
+ _type: "lsResult";
50
+ text: string;
51
+ path: string;
52
+ entryCount: number;
53
+ }
54
+ export interface FindDetails extends Record<string, unknown> {
55
+ _type: "findResult";
56
+ text: string;
57
+ pattern: string;
58
+ matchCount: number;
59
+ }
60
+ export interface GrepDetails extends Record<string, unknown> {
61
+ _type: "grepResult";
62
+ text: string;
63
+ pattern: string;
64
+ matchCount: number;
65
+ }
66
+ export type AnyDetails = ReadDetails | BashDetails | LsDetails | FindDetails | GrepDetails;
67
+ export interface ReadInput {
68
+ path: string;
69
+ offset?: number;
70
+ limit?: number;
71
+ }
72
+ export interface BashInput {
73
+ command: string;
74
+ timeout?: number;
75
+ }
76
+ export interface LsInput {
77
+ path?: string;
78
+ }
79
+ export interface FindInput {
80
+ pattern: string;
81
+ path?: string;
82
+ limit?: number;
83
+ }
84
+ export interface GrepInput {
85
+ pattern: string;
86
+ path?: string;
87
+ glob?: string;
88
+ context?: number;
89
+ limit?: number;
90
+ literal?: boolean;
91
+ ignoreCase?: boolean;
92
+ }
93
+ export interface MultiGrepInput {
94
+ patterns: string[];
95
+ path?: string;
96
+ constraints?: string;
97
+ context?: number;
98
+ limit?: number;
99
+ }
100
+ /**
101
+ * Minimal structural type for an SDK-produced tool definition.
102
+ * Accepts both the real SDK's ToolDefinition<> return type and test mocks.
103
+ */
104
+ export interface SdkToolDef {
105
+ name?: string;
106
+ description?: string;
107
+ label?: string;
108
+ parameters?: unknown;
109
+ execute: (...args: any[]) => Promise<AgentToolResult<any>>;
110
+ }
111
+ export interface SdkTools {
112
+ createReadTool?: (cwd: string) => SdkToolDef;
113
+ createBashTool?: (cwd: string) => SdkToolDef;
114
+ createLsTool?: (cwd: string) => SdkToolDef;
115
+ createFindTool?: (cwd: string) => SdkToolDef;
116
+ createGrepTool?: (cwd: string) => SdkToolDef;
117
+ getAgentDir?: () => string;
118
+ }
119
+ export interface MultiGrepFallbackParams {
120
+ cwd: string;
121
+ patterns: string[];
122
+ path?: string;
123
+ constraints?: string;
124
+ context?: number;
125
+ limit: number;
126
+ ignoreCase: boolean;
127
+ signal?: AbortSignal;
128
+ }
129
+ export interface MultiGrepFallbackResult {
130
+ text: string;
131
+ matchCount: number;
132
+ limitReached: boolean;
133
+ }
134
+ export type MultiGrepFallback = (params: MultiGrepFallbackParams) => Promise<MultiGrepFallbackResult>;
135
+ /** Minimal FFF service shape for tools that only need fileSearch. */
136
+ export interface FffServiceLike {
137
+ readonly isAvailable: boolean;
138
+ readonly partialIndex: boolean;
139
+ getFinder(): import("@ff-labs/fff-node").FileFinder | null;
140
+ }
141
+ /** Full FFF service for grep tools that also need cursor store. */
142
+ export interface FffServiceWithCursor extends FffServiceLike {
143
+ getCursorStore(): CursorStore;
144
+ }
145
+ /** FFF lifecycle interface (used by session lifecycle code). */
146
+ export interface FffService extends FffServiceWithCursor {
147
+ ensureFinder(cwd: string): Promise<void>;
148
+ destroy(): void;
149
+ isModuleLoaded(): boolean;
150
+ tryLoadModule(): Promise<boolean>;
151
+ }
152
+ export interface CursorStore {
153
+ store(cursor: unknown): string;
154
+ get(id: string): unknown | undefined;
155
+ }
156
+ export interface ConstraintParseResult {
157
+ ok: boolean;
158
+ globs: string[];
159
+ tokens: string[];
160
+ error?: string;
161
+ }
162
+ export interface PiPrettyDeps {
163
+ sdk?: SdkTools;
164
+ TextComponent?: new (text?: string, x?: number, y?: number) => ComponentLike;
165
+ fffModule?: typeof import("@ff-labs/fff-node");
166
+ multiGrepRipgrepFallback?: MultiGrepFallback;
167
+ }
168
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * pi-pretty shared types.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
package/package.json CHANGED
@@ -1,49 +1,55 @@
1
1
  {
2
2
  "name": "@heyhuynhgiabuu/pi-pretty",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "Pretty terminal output for pi — syntax-highlighted file reads, colored bash output, tree-view directory listings, and more.",
5
- "author": "huynhgiabuu",
5
+ "keywords": [
6
+ "pi",
7
+ "pi-extension",
8
+ "pi-package",
9
+ "pretty-print",
10
+ "shiki",
11
+ "syntax-highlighting",
12
+ "terminal"
13
+ ],
14
+ "homepage": "https://github.com/heyhuynhgiabuu/pi-pretty#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/heyhuynhgiabuu/pi-pretty/issues"
17
+ },
6
18
  "license": "MIT",
19
+ "author": "huynhgiabuu",
7
20
  "repository": {
8
21
  "type": "git",
9
22
  "url": "git+https://github.com/heyhuynhgiabuu/pi-pretty.git"
10
23
  },
11
- "homepage": "https://github.com/heyhuynhgiabuu/pi-pretty#readme",
12
- "bugs": {
13
- "url": "https://github.com/heyhuynhgiabuu/pi-pretty/issues"
14
- },
15
- "keywords": [
16
- "pi-package",
17
- "pi",
18
- "pi-extension",
19
- "syntax-highlighting",
20
- "shiki",
21
- "terminal",
22
- "pretty-print"
24
+ "files": [
25
+ "dist/",
26
+ "CHANGELOG.md",
27
+ "src/"
23
28
  ],
29
+ "main": "dist/index.js",
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "typecheck": "tsc --noEmit",
33
+ "lint": "biome check src/",
34
+ "lint:fix": "biome check --fix src/",
35
+ "test": "vitest run --passWithNoTests",
36
+ "test:watch": "vitest --passWithNoTests"
37
+ },
24
38
  "dependencies": {
25
39
  "@ff-labs/fff-node": "^0.9.4",
26
40
  "@shikijs/cli": "^4.0.2"
27
41
  },
28
- "peerDependencies": {
29
- "@earendil-works/pi-coding-agent": "*",
30
- "@earendil-works/pi-tui": "*"
31
- },
32
42
  "devDependencies": {
43
+ "@biomejs/biome": "^2.3.5",
33
44
  "@earendil-works/pi-coding-agent": "*",
34
45
  "@earendil-works/pi-tui": "*",
35
46
  "@types/node": "^20.0.0",
36
47
  "typescript": "^5.0.0",
37
- "@biomejs/biome": "^2.3.5",
38
48
  "vitest": "^4.0.18"
39
49
  },
40
- "scripts": {
41
- "build": "tsc",
42
- "typecheck": "tsc --noEmit",
43
- "lint": "biome check src/",
44
- "lint:fix": "biome check --fix src/",
45
- "test": "vitest run --passWithNoTests",
46
- "test:watch": "vitest --passWithNoTests"
50
+ "peerDependencies": {
51
+ "@earendil-works/pi-coding-agent": "*",
52
+ "@earendil-works/pi-tui": "*"
47
53
  },
48
54
  "pi": {
49
55
  "extensions": [
package/src/index.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  // Re-export for tests
13
- export { __imageInternals } from "./image.js";
13
+ export { __imageInternals } from "./image.js";
14
14
 
15
15
  import { mkdirSync } from "node:fs";
16
16
  import { join } from "node:path";
@@ -48,7 +48,7 @@ function envDisabledTools(): Set<string> {
48
48
 
49
49
  export type { PiPrettyDeps };
50
50
 
51
- export default function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps): void {
51
+ export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps): Promise<void> {
52
52
  const disabledTools = envDisabledTools();
53
53
  const isToolEnabled = (name: string) => !disabledTools.has(name.toLowerCase());
54
54
  const cwd = process.cwd();
@@ -75,7 +75,11 @@ export default function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps)
75
75
  getAgentDir = sdk.getAgentDir;
76
76
  } else {
77
77
  try {
78
- sdk = require("@earendil-works/pi-coding-agent");
78
+ // Dynamic import() uses ESM resolution (not CJS interop), so it
79
+ // correctly resolves subpath exports like @earendil-works/pi-ai/base
80
+ // which only have "import" conditions in their exports map.
81
+ const mod = await import("@earendil-works/pi-coding-agent");
82
+ sdk = mod;
79
83
  createReadTool = sdk.createReadToolDefinition ?? sdk.createReadTool;
80
84
  createBashTool = sdk.createBashToolDefinition ?? sdk.createBashTool;
81
85
  createLsTool = sdk.createLsToolDefinition ?? sdk.createLsTool;
@@ -127,7 +131,9 @@ export default function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps)
127
131
  }
128
132
  if (isToolEnabled("multi_grep") && (fffService || createGrepTool)) {
129
133
  registerMultiGrepTool(
130
- pi, cwd, fffService,
134
+ pi,
135
+ cwd,
136
+ fffService,
131
137
  createGrepTool ? createGrepTool(cwd) : undefined,
132
138
  multiGrepFallback,
133
139
  TextComp,
@@ -168,7 +174,9 @@ export default function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps)
168
174
  ];
169
175
  const progress = finder.getScanProgress();
170
176
  if (progress.ok) {
171
- lines.push(`Scanning: ${progress.value.isScanning ? "yes" : "no"} (${progress.value.scannedFilesCount} files)`);
177
+ lines.push(
178
+ `Scanning: ${progress.value.isScanning ? "yes" : "no"} (${progress.value.scannedFilesCount} files)`,
179
+ );
172
180
  }
173
181
  ctx.ui.notify(lines.join("\n"), "info");
174
182
  },
@@ -237,21 +245,21 @@ export default function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps)
237
245
  // Fallback padding for SDK-rendered tool bodies. The SDK reads
238
246
  // result.content[0].text and slices collapsed output to roughly the first
239
247
  // 10 lines, so insert bottom padding inside that visible slice.
240
- const PADDED_TOOLS = new Set(["read", "grep", "bash"]);
241
- const RESULT_LEFT_PAD = " ";
242
- const BOTTOM_PADDING_BY_TOOL: Record<string, number> = { read: 2, grep: 2, bash: 0 };
243
- pi.on("tool_result", (event, _ctx) => {
244
- if (!PADDED_TOOLS.has(event.toolName)) return undefined;
245
- const first = event.content[0];
246
- if (!first || first.type !== "text") return undefined;
247
- const lines = first.text.split("\n").map((line) => `${RESULT_LEFT_PAD}${line}`);
248
- if (lines.length === 0) return undefined;
249
-
250
- const padCount = BOTTOM_PADDING_BY_TOOL[event.toolName] ?? 0;
251
- lines.push(...Array.from({ length: padCount }, () => RESULT_LEFT_PAD));
252
-
253
- return {
254
- content: [{ type: "text" as const, text: lines.join("\n") }, ...event.content.slice(1)],
255
- };
256
- });
248
+ const PADDED_TOOLS = new Set(["read", "grep", "bash"]);
249
+ const RESULT_LEFT_PAD = " ";
250
+ const BOTTOM_PADDING_BY_TOOL: Record<string, number> = { read: 2, grep: 2, bash: 0 };
251
+ pi.on("tool_result", (event, _ctx) => {
252
+ if (!PADDED_TOOLS.has(event.toolName)) return undefined;
253
+ const first = event.content[0];
254
+ if (!first || first.type !== "text") return undefined;
255
+ const lines = first.text.split("\n").map((line) => `${RESULT_LEFT_PAD}${line}`);
256
+ if (lines.length === 0) return undefined;
257
+
258
+ const padCount = BOTTOM_PADDING_BY_TOOL[event.toolName] ?? 0;
259
+ lines.push(...Array.from({ length: padCount }, () => RESULT_LEFT_PAD));
260
+
261
+ return {
262
+ content: [{ type: "text" as const, text: lines.join("\n") }, ...event.content.slice(1)],
263
+ };
264
+ });
257
265
  }
package/src/notices.ts ADDED
@@ -0,0 +1,3 @@
1
+ /** Stable user-facing strings for FFF/grep tool footers (not source-line titles). */
2
+
3
+ export const NOTICE_PARTIAL_FILE_INDEX = "FFF index incomplete; results may be missing files";
package/src/tools/find.ts CHANGED
@@ -7,6 +7,7 @@ import { resolveBaseBackground, BG_ERROR, FG_DIM, RST } from "../config.js";
7
7
  import { shortPath } from "../helpers.js";
8
8
  import { wrapExecuteWithMetrics } from "./metrics.js";
9
9
  import { renderFindResults, renderToolError, renderToolMetrics, fillToolBackground } from "../render.js";
10
+ import { NOTICE_PARTIAL_FILE_INDEX } from "../notices.js";
10
11
 
11
12
  type Result = AgentToolResult<Record<string, unknown>>;
12
13
 
@@ -55,7 +56,7 @@ export function registerFindTool(
55
56
  if (searchResult.ok) {
56
57
  const items: FileItem[] = searchResult.value.items.slice(0, effectiveLimit);
57
58
  const notices: string[] = [];
58
- if (fffService?.partialIndex) notices.push("Warning: partial file index");
59
+ if (fffService?.partialIndex) notices.push(NOTICE_PARTIAL_FILE_INDEX);
59
60
  if (items.length >= effectiveLimit) notices.push(`${effectiveLimit} limit reached`);
60
61
  if (searchResult.value.totalMatched > items.length) notices.push(`${searchResult.value.totalMatched} total matches`);
61
62
  const paths = items.map((i) => i.relativePath).join("\n");
package/src/tools/grep.ts CHANGED
@@ -8,6 +8,7 @@ import { shortPath, normalizeLineEndings } from "../helpers.js";
8
8
  import { wrapExecuteWithMetrics } from "./metrics.js";
9
9
  import { renderToolError, fillToolBackground } from "../render.js";
10
10
  import { fffFormatGrepText } from "../fff-helpers.js";
11
+ import { NOTICE_PARTIAL_FILE_INDEX } from "../notices.js";
11
12
 
12
13
  const invalidArg = "<missing>";
13
14
 
@@ -50,7 +51,7 @@ export function registerGrepTool(
50
51
  const items = grep.items.slice(0, effectiveLimit);
51
52
  const cursorStore = fffService.getCursorStore();
52
53
  const notices: string[] = [];
53
- if (fffService.partialIndex) notices.push("Warning: partial file index");
54
+ if (fffService.partialIndex) notices.push(NOTICE_PARTIAL_FILE_INDEX);
54
55
  if (items.length >= effectiveLimit) notices.push(`${effectiveLimit} limit reached`);
55
56
  if (grep.regexFallbackError) notices.push(`Regex failed: ${grep.regexFallbackError}, used literal match`);
56
57
  if (grep.nextCursor) {
@@ -9,6 +9,7 @@ import { wrapExecuteWithMetrics } from "./metrics.js";
9
9
  import { renderToolError, renderToolMetrics, fillToolBackground } from "../render.js";
10
10
  import { fffFormatGrepText } from "../fff-helpers.js";
11
11
  import { parseMultiGrepConstraints } from "../multi-grep-fallback.js";
12
+ import { NOTICE_PARTIAL_FILE_INDEX } from "../notices.js";
12
13
  import type { MultiGrepFallback } from "../types.js";
13
14
 
14
15
  type Result = AgentToolResult<Record<string, unknown>>;
@@ -84,7 +85,7 @@ export function registerMultiGrepTool(
84
85
  const items = grep.items.slice(0, effectiveLimit);
85
86
  const cursorStore = fffService.getCursorStore();
86
87
  const notices: string[] = [];
87
- if (fffService.partialIndex) notices.push("Warning: partial file index");
88
+ if (fffService.partialIndex) notices.push(NOTICE_PARTIAL_FILE_INDEX);
88
89
  if (items.length >= effectiveLimit) notices.push(`${effectiveLimit} limit reached`);
89
90
  if (grep.nextCursor) {
90
91
  const cursorId = cursorStore.store(grep.nextCursor);
package/biome.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/2.4.8/schema.json",
3
- "assist": {
4
- "enabled": true,
5
- "actions": {
6
- "source": {
7
- "organizeImports": "on"
8
- }
9
- }
10
- },
11
- "linter": {
12
- "enabled": true,
13
- "rules": {
14
- "recommended": true
15
- }
16
- },
17
- "formatter": {
18
- "enabled": true,
19
- "indentStyle": "tab",
20
- "lineWidth": 120
21
- }
22
- }