/** `glob` (legacy `find`) — glob-based file finder; results are paths sorted by mtime. */ import type { ReactNode } from "react"; import { Badge, Badges, InvalidArg, Note, ResultText } from "../parts"; import type { ToolRenderer, ToolRenderProps } from "../types"; import { detailsRecord, isRecord, num, scopePaths, shortenPath, str, truncate } from "../util"; function Summary({ args }: ToolRenderProps): ReactNode { const raw = args.path ?? args.paths; if (raw !== undefined && typeof raw !== "string" && !Array.isArray(raw)) return ; const globs = scopePaths(args).map(shortenPath).join(", "); return {truncate(globs || "*", 120)}; } function Body({ args, result }: ToolRenderProps): ReactNode { const details = detailsRecord(result); const limit = num(args.limit); const timeout = num(args.timeout); const fileCount = num(details?.fileCount); const resultLimit = num(details?.resultLimitReached); const scopePath = str(details?.scopePath); const error = str(details?.error); const meta = details && isRecord(details.meta) ? details.meta : null; const limits = meta && isRecord(meta.limits) ? meta.limits : null; const truncated = Boolean(details?.truncated) || resultLimit !== null || (details !== null && isRecord(details.truncation)) || (meta !== null && isRecord(meta.truncation)) || Boolean(limits?.resultLimit); const missing = Array.isArray(details?.missingPaths) ? details.missingPaths.filter((p): p is string => typeof p === "string") : []; return ( <> limit {limit}, args.gitignore === false && no-gitignore, args.hidden === false && no-hidden, timeout !== null && timeout {timeout}s, fileCount !== null && ( {fileCount} file{fileCount === 1 ? "" : "s"} ), scopePath !== null && in {shortenPath(scopePath)}, truncated && ( {resultLimit !== null ? `truncated at ${resultLimit}` : "truncated"} ), ]} /> {missing.length > 0 && skipped missing: {missing.map(shortenPath).join(", ")}} {error !== null && !result?.isError && {error}} ); } export const globRenderer: ToolRenderer = { Summary, Body };