@earendil-works/pi-coding-agent
Version:
Coding agent CLI with read, bash, edit, write tools and session management
69 lines • 3.08 kB
JavaScript
/**
* Presentation for the grep tool.
*
* Renderers live apart from the implementation so a process that only displays tool output does not
* load the execution path or its typebox parameter schema. `grep.ts` spreads these into its
* definition, so the tool's public shape is unchanged.
*/
import { Text } from "@earendil-works/pi-tui";
import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
import { getTextOutput, invalidArgText, shortenPath, str } from "../render-utils.js";
import { DEFAULT_MAX_BYTES, formatSize } from "../truncate.js";
function formatGrepCall(args, theme) {
const pattern = str(args?.pattern);
const rawPath = str(args?.path);
const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
const glob = str(args?.glob);
const limit = args?.limit;
const invalidArg = invalidArgText(theme);
let text = theme.fg("toolTitle", theme.bold("grep")) +
" " +
(pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) +
theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
if (glob)
text += theme.fg("toolOutput", ` (${glob})`);
if (limit !== undefined)
text += theme.fg("toolOutput", ` limit ${limit}`);
return text;
}
function formatGrepResult(result, options, theme, showImages) {
const output = getTextOutput(result, showImages).trim();
let text = "";
if (output) {
const lines = output.split("\n");
const maxLines = options.expanded ? lines.length : 15;
const displayLines = lines.slice(0, maxLines);
const remaining = lines.length - maxLines;
text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
if (remaining > 0) {
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
}
}
const matchLimit = result.details?.matchLimitReached;
const truncation = result.details?.truncation;
const linesTruncated = result.details?.linesTruncated;
if (matchLimit || truncation?.truncated || linesTruncated) {
const warnings = [];
if (matchLimit)
warnings.push(`${matchLimit} matches limit`);
if (truncation?.truncated)
warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
if (linesTruncated)
warnings.push("some lines truncated");
text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
}
return text;
}
export const grepRenderers = {
renderCall(args, theme, context) {
const text = context.lastComponent ?? new Text("", 0, 0);
text.setText(formatGrepCall(args, theme));
return text;
},
renderResult(result, options, theme, context) {
const text = context.lastComponent ?? new Text("", 0, 0);
text.setText(formatGrepResult(result, options, theme, context.showImages));
return text;
},
};
//# sourceMappingURL=grep.js.map