search.tsā¢1.18 kB
import fg from "fast-glob";
import fs from "node:fs/promises";
export interface SearchResultItem {
type: "text";
text: string;
[k: string]: unknown;
}
export interface SearchOptions {
maxResults?: number;
listOnly?: boolean;
}
export async function searchFiles(
query: string,
include: string[],
options: SearchOptions = {}
): Promise<SearchResultItem[]> {
const { maxResults = 100, listOnly = false } = options;
const files = await fg(include, {
dot: false,
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
unique: true,
});
const results: SearchResultItem[] = [];
for (const file of files) {
if (listOnly) {
results.push({ type: "text", text: file });
if (results.length >= maxResults) break;
continue;
}
try {
const content = await fs.readFile(file, "utf8");
if (!query || content.toLowerCase().includes(query.toLowerCase())) {
const preview = content.slice(0, 2000);
results.push({ type: "text", text: `# ${file}\n\n${preview}` });
}
if (results.length >= maxResults) break;
} catch {
// ignore unreadable files
}
}
return results;
}