@heyhuynhgiabuu/pi-pretty 0.6.15 → 0.6.17
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/CHANGELOG.md +19 -116
- package/README.md +8 -16
- package/dist/collapsed-hint.d.ts +7 -0
- package/dist/collapsed-hint.d.ts.map +1 -0
- package/dist/collapsed-hint.js +17 -0
- package/dist/collapsed-hint.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +64 -19
- package/dist/config.js.map +1 -1
- package/dist/expand.d.ts +7 -0
- package/dist/expand.d.ts.map +1 -0
- package/dist/expand.js +11 -0
- package/dist/expand.js.map +1 -0
- package/dist/find-glob.d.ts +9 -0
- package/dist/find-glob.d.ts.map +1 -0
- package/dist/find-glob.js +29 -0
- package/dist/find-glob.js.map +1 -0
- package/dist/image.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -19
- package/dist/index.js.map +1 -1
- package/dist/render.d.ts +3 -5
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +24 -19
- package/dist/render.js.map +1 -1
- package/dist/tools/bash.d.ts +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +22 -26
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/find.d.ts +3 -3
- package/dist/tools/find.d.ts.map +1 -1
- package/dist/tools/find.js +99 -50
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/grep.d.ts +2 -2
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +12 -8
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/labels.d.ts +2 -0
- package/dist/tools/labels.d.ts.map +1 -0
- package/dist/tools/labels.js +7 -0
- package/dist/tools/labels.js.map +1 -0
- package/dist/tools/ls.d.ts +1 -1
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +9 -5
- package/dist/tools/ls.js.map +1 -1
- package/dist/tools/read.d.ts +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +34 -48
- package/dist/tools/read.js.map +1 -1
- package/dist/tui-text.d.ts.map +1 -1
- package/dist/tui-text.js +1 -5
- package/dist/tui-text.js.map +1 -1
- package/dist/types.d.ts +4 -27
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/collapsed-hint.ts +14 -0
- package/src/config.ts +70 -22
- package/src/expand.ts +10 -0
- package/src/find-glob.ts +21 -0
- package/src/image.ts +1 -1
- package/src/index.ts +25 -32
- package/src/notices.ts +1 -1
- package/src/render.ts +50 -41
- package/src/tools/bash.ts +27 -48
- package/src/tools/find.ts +131 -86
- package/src/tools/grep.ts +23 -17
- package/src/tools/labels.ts +3 -0
- package/src/tools/ls.ts +27 -13
- package/src/tools/metrics.ts +1 -1
- package/src/tools/read.ts +55 -66
- package/src/tui-text.ts +1 -5
- package/src/types.ts +4 -35
- package/dist/multi-grep-fallback.d.ts +0 -30
- package/dist/multi-grep-fallback.d.ts.map +0 -1
- package/dist/multi-grep-fallback.js +0 -205
- package/dist/multi-grep-fallback.js.map +0 -1
- package/dist/tools/multi-grep.d.ts +0 -7
- package/dist/tools/multi-grep.d.ts.map +0 -1
- package/dist/tools/multi-grep.js +0 -294
- package/dist/tools/multi-grep.js.map +0 -1
- package/src/multi-grep-fallback.ts +0 -248
- package/src/tools/multi-grep.ts +0 -331
package/src/tools/grep.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
/* pi-pretty: grep tool -- FFF-backed text search with SDK fallback. */
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
type ExtensionAPI,
|
|
6
|
-
type ExtensionContext,
|
|
7
|
-
type AgentToolResult,
|
|
8
|
-
} from "@earendil-works/pi-coding-agent";
|
|
9
|
-
import type { SdkToolDef, GrepDetails, FffServiceWithCursor, TextContent, ThemeLike, RenderCtxLike } from "../types.js";
|
|
10
|
-
import { MAX_PREVIEW_LINES, BG_ERROR, resolveBaseBackground } from "../config.js";
|
|
11
|
-
import { shortPath, normalizeLineEndings } from "../helpers.js";
|
|
12
|
-
import { wrapExecuteWithMetrics } from "./metrics.js";
|
|
13
|
-
import { renderToolError, fillToolBackground } from "../render.js";
|
|
14
|
-
import { resolveTextCtor } from "../tui-text.js";
|
|
3
|
+
import type { AgentToolResult, ExtensionAPI, ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { BG_ERROR, FG_DIM, MAX_PREVIEW_LINES, RST, resolveBaseBackground, TOOL_RESULT_INDENT } from "../config.js";
|
|
15
5
|
import { fffFormatGrepText } from "../fff-helpers.js";
|
|
6
|
+
import { normalizeLineEndings, shortPath } from "../helpers.js";
|
|
16
7
|
import { NOTICE_PARTIAL_FILE_INDEX } from "../notices.js";
|
|
8
|
+
import { fillToolBackground, renderToolError } from "../render.js";
|
|
9
|
+
import { resolveTextCtor } from "../tui-text.js";
|
|
10
|
+
import type { FffServiceWithCursor, GrepDetails, RenderCtxLike, SdkToolDef, TextContent, ThemeLike } from "../types.js";
|
|
11
|
+
import { wrapExecuteWithMetrics } from "./metrics.js";
|
|
17
12
|
|
|
18
13
|
const invalidArg = "<missing>";
|
|
19
14
|
|
|
@@ -111,12 +106,12 @@ export function registerGrepTool(
|
|
|
111
106
|
const limit = args.limit;
|
|
112
107
|
const literal = args.literal === true;
|
|
113
108
|
const caseInsensitive = args.caseInsensitive === true || args.ignoreCase === true;
|
|
114
|
-
let out = `${theme.fg("toolTitle", theme.bold("grep"))} ${theme.fg("
|
|
109
|
+
let out = `${theme.fg(ctx.isError ? "error" : "toolTitle", theme.bold("✱ grep"))} ${theme.fg("toolTitle", `/${pattern || ""}/`)}${theme.fg("toolOutput", ` in ${path}`)}`;
|
|
115
110
|
if (glob) out += theme.fg("dim", ` (${String(glob)})`);
|
|
116
111
|
if (limit !== undefined && limit !== null) out += theme.fg("dim", ` limit ${limit}`);
|
|
117
112
|
if (literal) out += theme.fg("dim", ` (literal)`);
|
|
118
113
|
if (caseInsensitive) out += theme.fg("dim", ` (case-insensitive)`);
|
|
119
|
-
text.setText(fillToolBackground(`\n
|
|
114
|
+
text.setText(fillToolBackground(`\n${TOOL_RESULT_INDENT}${out}`, ctx.isError ? BG_ERROR : undefined));
|
|
120
115
|
return text;
|
|
121
116
|
},
|
|
122
117
|
|
|
@@ -138,7 +133,16 @@ export function registerGrepTool(
|
|
|
138
133
|
const d = result.details as GrepDetails | undefined;
|
|
139
134
|
if (d?._type === "grepResult" && d.text) {
|
|
140
135
|
const lines = d.text.split("\n");
|
|
141
|
-
|
|
136
|
+
if (!ctx.expanded) {
|
|
137
|
+
text.setText(
|
|
138
|
+
fillToolBackground(
|
|
139
|
+
`${TOOL_RESULT_INDENT}${FG_DIM}${lines.length} lines — ctrl+o to expand${RST}\n`,
|
|
140
|
+
ctx.isError ? BG_ERROR : undefined,
|
|
141
|
+
),
|
|
142
|
+
);
|
|
143
|
+
return text;
|
|
144
|
+
}
|
|
145
|
+
const maxShow = lines.length;
|
|
142
146
|
const show = lines.slice(0, maxShow);
|
|
143
147
|
const remaining = lines.length - maxShow;
|
|
144
148
|
const out: string[] = [];
|
|
@@ -149,13 +153,15 @@ export function registerGrepTool(
|
|
|
149
153
|
if (remaining > 0) {
|
|
150
154
|
out.push(theme.fg("muted", `… (${remaining} more ${remaining === 1 ? "line" : "lines"}, to expand)`));
|
|
151
155
|
}
|
|
152
|
-
const body = out.map((l) =>
|
|
156
|
+
const body = `${out.map((l) => `${TOOL_RESULT_INDENT}${l}`).join("\n")}\n\n`;
|
|
153
157
|
text.setText(fillToolBackground(body, ctx.isError ? BG_ERROR : undefined));
|
|
154
158
|
return text;
|
|
155
159
|
}
|
|
156
160
|
const fc = result.content?.[0];
|
|
157
161
|
const fallback = fc && "text" in fc ? String(fc.text).slice(0, 120) : "no matches";
|
|
158
|
-
text.setText(
|
|
162
|
+
text.setText(
|
|
163
|
+
fillToolBackground(`${TOOL_RESULT_INDENT}${theme.fg("dim", fallback)}`, ctx.isError ? BG_ERROR : undefined),
|
|
164
|
+
);
|
|
159
165
|
return text;
|
|
160
166
|
},
|
|
161
167
|
} as unknown as ToolDefinition<any, any, any>);
|
package/src/tools/ls.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/* pi-pretty: ls tool -- directory listing with styled output. */
|
|
2
2
|
|
|
3
|
+
import type { AgentToolResult, ExtensionAPI, ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
BG_BASE,
|
|
6
|
+
BG_ERROR,
|
|
7
|
+
FG_DIM,
|
|
8
|
+
MAX_PREVIEW_LINES,
|
|
9
|
+
RST,
|
|
10
|
+
resolveBaseBackground,
|
|
11
|
+
TOOL_RESULT_INDENT,
|
|
12
|
+
termWidth,
|
|
13
|
+
} from "../config.js";
|
|
11
14
|
import { shortPath } from "../helpers.js";
|
|
12
|
-
import {
|
|
13
|
-
import { renderTree, renderToolError, renderToolMetrics, fillToolBackground } from "../render.js";
|
|
15
|
+
import { fillToolBackground, renderToolError, renderToolMetrics, renderTree } from "../render.js";
|
|
14
16
|
import { resolveTextCtor } from "../tui-text.js";
|
|
17
|
+
import type { ComponentLike, LsDetails, RenderCtxLike, SdkToolDef, TextContent, ThemeLike } from "../types.js";
|
|
18
|
+
import { wrapExecuteWithMetrics } from "./metrics.js";
|
|
15
19
|
|
|
16
20
|
type Result = AgentToolResult<Record<string, unknown>>;
|
|
17
21
|
|
|
@@ -56,7 +60,7 @@ export function registerLsTool(
|
|
|
56
60
|
let out = theme.fg("toolTitle", theme.bold("ls"));
|
|
57
61
|
if (path) out += ` ${theme.fg("accent", path)}`;
|
|
58
62
|
if (limit !== undefined && limit !== null) out += theme.fg("toolOutput", ` (limit ${limit})`);
|
|
59
|
-
text.setText(fillToolBackground(
|
|
63
|
+
text.setText(fillToolBackground(`\n${TOOL_RESULT_INDENT}${out}`, ctx.isError ? BG_ERROR : undefined));
|
|
60
64
|
return text;
|
|
61
65
|
},
|
|
62
66
|
|
|
@@ -70,20 +74,30 @@ export function registerLsTool(
|
|
|
70
74
|
}
|
|
71
75
|
const d = result.details as LsDetails | undefined;
|
|
72
76
|
if (d?._type === "lsResult" && d.text) {
|
|
77
|
+
if (!ctx.expanded) {
|
|
78
|
+
text.setText(
|
|
79
|
+
fillToolBackground(
|
|
80
|
+
`${TOOL_RESULT_INDENT}${FG_DIM}${d.entryCount} entries — ctrl+o to expand${RST}${renderToolMetrics(result)}\n`,
|
|
81
|
+
),
|
|
82
|
+
);
|
|
83
|
+
return text;
|
|
84
|
+
}
|
|
73
85
|
const rendered = renderTree(d.text, d.path)
|
|
74
86
|
.split("\n")
|
|
75
|
-
.map((l) =>
|
|
87
|
+
.map((l) => `${TOOL_RESULT_INDENT}${l}`)
|
|
76
88
|
.join("\n");
|
|
77
89
|
text.setText(
|
|
78
90
|
fillToolBackground(
|
|
79
|
-
|
|
91
|
+
`\n${TOOL_RESULT_INDENT}${FG_DIM}${d.entryCount} entries${RST}${renderToolMetrics(result)}\n${rendered}\n`,
|
|
80
92
|
),
|
|
81
93
|
);
|
|
82
94
|
return text;
|
|
83
95
|
}
|
|
84
96
|
const fc = result.content?.[0];
|
|
85
97
|
text.setText(
|
|
86
|
-
fillToolBackground(
|
|
98
|
+
fillToolBackground(
|
|
99
|
+
`${TOOL_RESULT_INDENT}${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 120) : "done")}`,
|
|
100
|
+
),
|
|
87
101
|
);
|
|
88
102
|
return text;
|
|
89
103
|
},
|
package/src/tools/metrics.ts
CHANGED
package/src/tools/read.ts
CHANGED
|
@@ -1,39 +1,24 @@
|
|
|
1
1
|
/* pi-pretty: read tool -- file reading with syntax highlighting and inline image support. */
|
|
2
2
|
|
|
3
|
+
import type { AgentToolResult, ExtensionAPI, ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { Image as TuiImage } from "@earendil-works/pi-tui";
|
|
3
5
|
import {
|
|
4
|
-
type ToolDefinition,
|
|
5
|
-
type ExtensionAPI,
|
|
6
|
-
type ExtensionContext,
|
|
7
|
-
type AgentToolResult,
|
|
8
|
-
} from "@earendil-works/pi-coding-agent";
|
|
9
|
-
import type { SdkToolDef, ReadDetails, TextContent, ComponentLike, ThemeLike, RenderCtxLike } from "../types.js";
|
|
10
|
-
import {
|
|
11
|
-
resolveBaseBackground,
|
|
12
|
-
termWidth,
|
|
13
|
-
MAX_PREVIEW_LINES,
|
|
14
6
|
BG_BASE,
|
|
15
7
|
BG_ERROR,
|
|
16
8
|
FG_DIM,
|
|
17
9
|
FG_LNUM,
|
|
18
10
|
FG_RULE,
|
|
11
|
+
MAX_PREVIEW_LINES,
|
|
19
12
|
RST,
|
|
13
|
+
resolveBaseBackground,
|
|
14
|
+
TOOL_RESULT_INDENT,
|
|
15
|
+
termWidth,
|
|
20
16
|
} from "../config.js";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { renderToolError, renderToolMetrics, fillToolBackground, renderFileContent } from "../render.js";
|
|
17
|
+
import { normalizeLineEndings, shortPath } from "../helpers.js";
|
|
18
|
+
import { fillToolBackground, renderFileContent, renderToolError, renderToolMetrics } from "../render.js";
|
|
24
19
|
import { resolveTextCtor } from "../tui-text.js";
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function isImageTerminal(): boolean {
|
|
28
|
-
const term = (process.env.TERM_PROGRAM ?? process.env.TERM ?? "").toLowerCase();
|
|
29
|
-
const proto = (process.env.PRETTY_IMAGE_PROTOCOL ?? "").toLowerCase();
|
|
30
|
-
if (proto === "kitty" || proto === "iterm2") return true;
|
|
31
|
-
if (proto === "none") return false;
|
|
32
|
-
return (
|
|
33
|
-
["ghostty", "kitty", "iterm.app", "wezterm", "mintty"].some((t) => term.includes(t)) ||
|
|
34
|
-
process.env.LC_TERMINAL === "iTerm2"
|
|
35
|
-
);
|
|
36
|
-
}
|
|
20
|
+
import type { ReadDetails, RenderCtxLike, SdkToolDef, TextContent, ThemeLike } from "../types.js";
|
|
21
|
+
import { wrapExecuteWithMetrics } from "./metrics.js";
|
|
37
22
|
|
|
38
23
|
type Result = AgentToolResult<Record<string, unknown>>;
|
|
39
24
|
|
|
@@ -84,7 +69,14 @@ export function registerReadTool(
|
|
|
84
69
|
resolveBaseBackground(theme);
|
|
85
70
|
|
|
86
71
|
const text = ctx.lastComponent ?? new TC("", 0, 0);
|
|
87
|
-
|
|
72
|
+
if (!ctx.isError) {
|
|
73
|
+
text.setText("");
|
|
74
|
+
return text;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const path = String(args.path ?? "");
|
|
78
|
+
const label = theme.fg("error", theme.bold("→ read"));
|
|
79
|
+
text.setText(fillToolBackground(`\n${TOOL_RESULT_INDENT}${label} ${theme.fg("toolTitle", path)}`, BG_ERROR));
|
|
88
80
|
return text;
|
|
89
81
|
},
|
|
90
82
|
|
|
@@ -94,40 +86,25 @@ export function registerReadTool(
|
|
|
94
86
|
const text = ctx.lastComponent ?? new TC("", 0, 0);
|
|
95
87
|
|
|
96
88
|
if (ctx.isError) {
|
|
97
|
-
text.setText(renderToolError(getText(result) || "Error", theme));
|
|
89
|
+
text.setText(fillToolBackground(renderToolError(getText(result) || "Error", theme), BG_ERROR));
|
|
98
90
|
return text;
|
|
99
91
|
}
|
|
100
92
|
|
|
101
93
|
const d = result.details as ReadDetails | undefined;
|
|
102
94
|
|
|
103
|
-
// Image rendering
|
|
95
|
+
// Image rendering — use pi-tui Image component
|
|
104
96
|
if (d?._type === "readImage") {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
} else {
|
|
116
|
-
const pngData = (require("@earendil-works/pi-coding-agent") as any).convertToPng?.(d.data) ?? d.data;
|
|
117
|
-
img.setText(`\x1b_Ga=T,f=100,m=${d.mimeType === "image/png" ? "1" : "0"};${pngData}\x1b\\\\`);
|
|
118
|
-
}
|
|
119
|
-
return img;
|
|
120
|
-
} catch {
|
|
121
|
-
/* fall through */
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const fc = result.content?.[0];
|
|
125
|
-
text.setText(
|
|
126
|
-
fillToolBackground(
|
|
127
|
-
` ${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 80) : `[image: ${d.filePath}]`)}`,
|
|
128
|
-
),
|
|
97
|
+
const mimeType = d.mimeType.startsWith("image/svg") ? "image/svg+xml" : d.mimeType;
|
|
98
|
+
return new TuiImage(
|
|
99
|
+
d.data,
|
|
100
|
+
mimeType,
|
|
101
|
+
{
|
|
102
|
+
fallbackColor: (text) => theme.fg("toolTitle", text),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
filename: d.filePath,
|
|
106
|
+
},
|
|
129
107
|
);
|
|
130
|
-
return text;
|
|
131
108
|
}
|
|
132
109
|
|
|
133
110
|
// File content — line-numbered display
|
|
@@ -135,32 +112,41 @@ export function registerReadTool(
|
|
|
135
112
|
const tw = termWidth();
|
|
136
113
|
const lines = d.content.split("\n");
|
|
137
114
|
const total = lines.length;
|
|
138
|
-
const
|
|
115
|
+
const p2 = shortPath(cwd, home, String(d.filePath ?? ""));
|
|
116
|
+
const off2 = typeof d.offset === "number" ? `:${d.offset}` : "";
|
|
117
|
+
if (!ctx.expanded) {
|
|
118
|
+
text.setText(
|
|
119
|
+
fillToolBackground(
|
|
120
|
+
`\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`,
|
|
121
|
+
BG_BASE,
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
return text;
|
|
125
|
+
}
|
|
126
|
+
const maxShow = lines.length;
|
|
139
127
|
const show = lines.slice(0, maxShow);
|
|
140
128
|
const nw = Math.max(3, String(total).length);
|
|
141
129
|
const gw = nw + 3;
|
|
142
130
|
const cw = Math.max(1, tw - gw);
|
|
143
131
|
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
const out: string[] = ["", ` ${header}`];
|
|
148
|
-
out.push(` ${FG_RULE}${"─".repeat(tw - 2)}${RST}`);
|
|
132
|
+
const header = `${theme.fg("toolTitle", theme.bold("→ read"))} ${theme.fg("toolTitle", p2)}${theme.fg("dim", off2)}`;
|
|
133
|
+
const out: string[] = ["", `${TOOL_RESULT_INDENT}${header}`];
|
|
134
|
+
out.push(`${TOOL_RESULT_INDENT}${FG_RULE}${"─".repeat(tw - 1)}${RST}`);
|
|
149
135
|
for (let i = 0; i < show.length; i++) {
|
|
150
136
|
const ln = (d.offset || 0) + i + 1;
|
|
151
137
|
const code = show[i] ?? "";
|
|
152
138
|
const display = code.length > cw ? code.slice(0, cw) + `${FG_DIM}›${RST}` : code;
|
|
153
139
|
const lineNo = String(ln);
|
|
154
140
|
out.push(
|
|
155
|
-
|
|
141
|
+
`${TOOL_RESULT_INDENT}${FG_LNUM}${" ".repeat(Math.max(0, nw - lineNo.length))}${lineNo}${RST} ${FG_RULE}│${RST} ${display}${RST}`,
|
|
156
142
|
);
|
|
157
143
|
}
|
|
158
144
|
if (total > maxShow) {
|
|
159
|
-
out.push(
|
|
145
|
+
out.push(`${TOOL_RESULT_INDENT}${FG_DIM}… ${total - maxShow} more lines (${total} total)${RST}`);
|
|
160
146
|
}
|
|
161
147
|
out.push("");
|
|
162
148
|
const rendered = out.join("\n");
|
|
163
|
-
text.setText(fillToolBackground(rendered));
|
|
149
|
+
text.setText(fillToolBackground(rendered, BG_BASE));
|
|
164
150
|
(ctx as any).state._rt = rendered;
|
|
165
151
|
|
|
166
152
|
// Async syntax highlighting via Shiki
|
|
@@ -168,10 +154,10 @@ export function registerReadTool(
|
|
|
168
154
|
.then((hl) => {
|
|
169
155
|
const padded = hl
|
|
170
156
|
.split("\n")
|
|
171
|
-
.map((l) =>
|
|
157
|
+
.map((l) => `${TOOL_RESULT_INDENT}${l}`)
|
|
172
158
|
.join("\n");
|
|
173
|
-
const rendered = `\n
|
|
174
|
-
text.setText(fillToolBackground(rendered));
|
|
159
|
+
const rendered = `\n${TOOL_RESULT_INDENT}${header}\n${padded}\n`;
|
|
160
|
+
text.setText(fillToolBackground(rendered, BG_BASE));
|
|
175
161
|
(ctx as any).state._rt = rendered;
|
|
176
162
|
})
|
|
177
163
|
.catch(() => {});
|
|
@@ -181,7 +167,10 @@ export function registerReadTool(
|
|
|
181
167
|
|
|
182
168
|
const fc = result.content?.[0];
|
|
183
169
|
text.setText(
|
|
184
|
-
fillToolBackground(
|
|
170
|
+
fillToolBackground(
|
|
171
|
+
`${TOOL_RESULT_INDENT}${theme.fg("dim", fc && "text" in fc ? String(fc.text).slice(0, 120) : "done")}`,
|
|
172
|
+
BG_BASE,
|
|
173
|
+
),
|
|
185
174
|
);
|
|
186
175
|
return text;
|
|
187
176
|
},
|
package/src/tui-text.ts
CHANGED
|
@@ -13,10 +13,6 @@ type TextCtor = new (t?: string, x?: number, y?: number) => { setText(v: string)
|
|
|
13
13
|
|
|
14
14
|
/** No-op stub that satisfies the Text interface so rendering doesn't crash. */
|
|
15
15
|
class StubText {
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
-
constructor(_t?: string, _x?: number, _y?: number) {
|
|
18
|
-
// no-op
|
|
19
|
-
}
|
|
20
16
|
setText(_v: string): void {
|
|
21
17
|
// no-op — pi-tui not available
|
|
22
18
|
}
|
|
@@ -26,7 +22,7 @@ let _ctor: TextCtor | null = null;
|
|
|
26
22
|
let _resolved = false;
|
|
27
23
|
|
|
28
24
|
function resolve(): TextCtor {
|
|
29
|
-
if (
|
|
25
|
+
if (_ctor) return _ctor;
|
|
30
26
|
_resolved = true;
|
|
31
27
|
try {
|
|
32
28
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
package/src/types.ts
CHANGED
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
* pi-pretty shared types.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
6
6
|
import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
9
|
// Re-export FFF types needed by tools
|
|
10
10
|
// ---------------------------------------------------------------------------
|
|
11
11
|
|
|
12
|
-
export type { FileFinder, FileItem,
|
|
12
|
+
export type { FileFinder, FileItem, GrepCursor, GrepMatch, GrepResult, SearchResult } from "@ff-labs/fff-node";
|
|
13
13
|
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
15
|
// Content / Result types
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
|
|
18
18
|
export type ToolContent = TextContent | ImageContent;
|
|
19
|
-
export type {
|
|
19
|
+
export type { ImageContent, TextContent };
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
// Theme / rendering context types
|
|
22
22
|
// ---------------------------------------------------------------------------
|
|
@@ -73,6 +73,7 @@ export interface FindDetails extends Record<string, unknown> {
|
|
|
73
73
|
text: string;
|
|
74
74
|
pattern: string;
|
|
75
75
|
matchCount: number;
|
|
76
|
+
notices?: string[];
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface GrepDetails extends Record<string, unknown> {
|
|
@@ -119,14 +120,6 @@ export interface GrepInput {
|
|
|
119
120
|
ignoreCase?: boolean;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
export interface MultiGrepInput {
|
|
123
|
-
patterns: string[];
|
|
124
|
-
path?: string;
|
|
125
|
-
constraints?: string;
|
|
126
|
-
context?: number;
|
|
127
|
-
limit?: number;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
123
|
// ---------------------------------------------------------------------------
|
|
131
124
|
// SDK tool definition shape (DI-friendly — accepts both mock and real SDK)
|
|
132
125
|
// ---------------------------------------------------------------------------
|
|
@@ -152,29 +145,6 @@ export interface SdkTools {
|
|
|
152
145
|
getAgentDir?: () => string;
|
|
153
146
|
}
|
|
154
147
|
|
|
155
|
-
// ---------------------------------------------------------------------------
|
|
156
|
-
// Multi-grep fallback types
|
|
157
|
-
// ---------------------------------------------------------------------------
|
|
158
|
-
|
|
159
|
-
export interface MultiGrepFallbackParams {
|
|
160
|
-
cwd: string;
|
|
161
|
-
patterns: string[];
|
|
162
|
-
path?: string;
|
|
163
|
-
constraints?: string;
|
|
164
|
-
context?: number;
|
|
165
|
-
limit: number;
|
|
166
|
-
ignoreCase: boolean;
|
|
167
|
-
signal?: AbortSignal;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export interface MultiGrepFallbackResult {
|
|
171
|
-
text: string;
|
|
172
|
-
matchCount: number;
|
|
173
|
-
limitReached: boolean;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export type MultiGrepFallback = (params: MultiGrepFallbackParams) => Promise<MultiGrepFallbackResult>;
|
|
177
|
-
|
|
178
148
|
// ---------------------------------------------------------------------------
|
|
179
149
|
// FFF service interfaces
|
|
180
150
|
// ---------------------------------------------------------------------------
|
|
@@ -223,5 +193,4 @@ export interface PiPrettyDeps {
|
|
|
223
193
|
sdk?: SdkTools;
|
|
224
194
|
TextComponent?: new (text?: string, x?: number, y?: number) => ComponentLike;
|
|
225
195
|
fffModule?: typeof import("@ff-labs/fff-node");
|
|
226
|
-
multiGrepRipgrepFallback?: MultiGrepFallback;
|
|
227
196
|
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export type ConstraintParseResult = {
|
|
2
|
-
ok: true;
|
|
3
|
-
globs: string[];
|
|
4
|
-
tokens: string[];
|
|
5
|
-
} | {
|
|
6
|
-
ok: false;
|
|
7
|
-
error: string;
|
|
8
|
-
};
|
|
9
|
-
export type MultiGrepRipgrepFallbackParams = {
|
|
10
|
-
cwd: string;
|
|
11
|
-
patterns: string[];
|
|
12
|
-
path?: string;
|
|
13
|
-
constraints?: string;
|
|
14
|
-
context?: number;
|
|
15
|
-
limit: number;
|
|
16
|
-
ignoreCase: boolean;
|
|
17
|
-
signal?: AbortSignal;
|
|
18
|
-
};
|
|
19
|
-
export type MultiGrepRipgrepFallbackResult = {
|
|
20
|
-
text: string;
|
|
21
|
-
matchCount: number;
|
|
22
|
-
limitReached: boolean;
|
|
23
|
-
};
|
|
24
|
-
export type MultiGrepRipgrepFallback = (params: MultiGrepRipgrepFallbackParams) => Promise<MultiGrepRipgrepFallbackResult>;
|
|
25
|
-
export declare function parseMultiGrepConstraints(constraints: string | undefined): ConstraintParseResult;
|
|
26
|
-
export declare function getMultiGrepRipgrepArgs(params: MultiGrepRipgrepFallbackParams): ConstraintParseResult & {
|
|
27
|
-
args?: string[];
|
|
28
|
-
};
|
|
29
|
-
export declare function runMultiGrepRipgrepFallback(params: MultiGrepRipgrepFallbackParams): Promise<MultiGrepRipgrepFallbackResult>;
|
|
30
|
-
//# sourceMappingURL=multi-grep-fallback.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multi-grep-fallback.d.ts","sourceRoot":"","sources":["../src/multi-grep-fallback.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnH,MAAM,MAAM,8BAA8B,GAAG;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,CACtC,MAAM,EAAE,8BAA8B,KAClC,OAAO,CAAC,8BAA8B,CAAC,CAAC;AA8E7C,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,qBAAqB,CAehG;AAqBD,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,8BAA8B,GACpC,qBAAqB,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAI7C;AAED,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,8BAA8B,GACpC,OAAO,CAAC,8BAA8B,CAAC,CAoGzC"}
|