import { readFile } from "node:fs/promises"; import { relative, resolve } from "node:path"; import { Lang, parse } from "@ast-grep/napi"; import { tool } from "ai"; import { globby } from "globby"; import z from "zod"; interface CodeMatch { file: string; line: number; column: number; text: string; context?: string; match?: Record; } interface CodeGrepResult { matches: CodeMatch[]; total: number; files_searched: number; } interface CodeGrepError { error: string; code?: string; } interface ScriptSection { content: string; startLine: number; language: Lang; } // Language mapping from file extensions (only supported languages) const LANGUAGE_MAP: Record = { ".js": Lang.JavaScript, ".jsx": Lang.JavaScript, ".ts": Lang.TypeScript, ".tsx": Lang.TypeScript, ".html": Lang.Html, ".htm": Lang.Html, ".css": Lang.Css, ".vue": Lang.Html, // Will be processed specially ".svelte": Lang.Html, // Will be processed specially ".astro": Lang.Html, // Will be processed specially }; function getLanguageFromFile(filePath: string): Lang | null { const ext = filePath.toLowerCase().match(/\.[^.]*$/)?.[0]; return ext ? LANGUAGE_MAP[ext] || null : null; } function isComponentFile(filePath: string): boolean { const ext = filePath.toLowerCase().match(/\.[^.]*$/)?.[0]; return ext === ".vue" || ext === ".svelte" || ext === ".astro"; } function extractScriptSections( content: string, filePath: string ): ScriptSection[] { const ext = filePath.toLowerCase().match(/\.[^.]*$/)?.[0]; const sections: ScriptSection[] = []; if (ext === ".vue") { // Extract