import { z } from 'zod';
import { PathResolver } from '../utils/path-resolver.js';
import { searchInMdxFile } from '../utils/mdx-processor.js';
import { ToolResponse } from '../types/index.js';
/**
* Input schema for search_mdx tool
*/
export const searchMdxInputSchema = z.object({
path: z.string().describe('Path to the MDX file relative to workspace root'),
query: z.string().describe('Search query string'),
contextLines: z.number().optional().default(2).describe('Number of lines of context around matches')
});
/**
* Output schema for search_mdx tool
*/
export const searchMdxOutputSchema = z.object({
matches: z.array(z.object({
lineNumber: z.number(),
content: z.string(),
context: z.object({
before: z.array(z.string()),
after: z.array(z.string())
})
})),
totalMatches: z.number()
});
/**
* Search for content within an MDX file
*
* @param input - Tool input with path, query, and contextLines parameters
* @param pathResolver - PathResolver instance
* @returns Tool response with search matches
*/
export async function searchMdxTool(
input: z.infer<typeof searchMdxInputSchema>,
pathResolver: PathResolver
): Promise<ToolResponse> {
try {
const { path, query, contextLines } = input;
// Resolve the path
const resolvedPath = pathResolver.resolveWorkspacePath(path);
// Validate path safety
if (!pathResolver.isPathSafe(path)) {
return {
content: [{
type: 'text',
text: `Error: Path is outside workspace root: ${path}`
}],
isError: true
};
}
// Validate file exists
if (!pathResolver.validateFilePath(path)) {
return {
content: [{
type: 'text',
text: `Error: File not found at path: ${path}`
}],
isError: true
};
}
// Search in the file
const matches = await searchInMdxFile(resolvedPath, query, contextLines);
const result = {
matches,
totalMatches: matches.length
};
return {
content: [{
type: 'text',
text: JSON.stringify(result, null, 2)
}]
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [{
type: 'text',
text: `Error searching MDX file: ${errorMessage}`
}],
isError: true
};
}
}