import { tool } from '@qwen-code/sdk'; import { z } from 'zod'; import { readFileSync, readdirSync, statSync } from 'fs'; import { join, extname } from 'path';
export const fileAnalyzerTool = tool( 'analyze_file', '分析文件的详细信息,包括大小、行数、语言等', { filePath: z.string().describe('要分析的文件路径'), includeContent: z.boolean().default(false).describe('是否包含文件内容预览') }, async (args) => { try { const stats = statSync(args.filePath); const content = readFileSync(args.filePath, 'utf-8'); const lines = content.split('\n').length; const ext = extname(args.filePath);
let language = 'unknown'; const langMap: Record<string, string> = { '.ts': 'TypeScript', '.js': 'JavaScript', '.py': 'Python', '.java': 'Java', '.cpp': 'C++', '.c': 'C', '.go': 'Go', '.rs': 'Rust', '.php': 'PHP', '.rb': 'Ruby' }; language = langMap[ext] || ext.substring(1).toUpperCase() || 'unknown';
const analysis = { path: args.filePath, size: `${(stats.size / 1024).toFixed(2)} KB`, lines: lines, language: language, lastModified: stats.mtime.toISOString(), contentPreview: args.includeContent ? content.substring(0, 200) + '...' : undefined };
return { content: [{ type: 'text', text: JSON.stringify(analysis, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: `文件分析失败: ${error.message}` }], isError: true }; } } );
export const directoryAnalyzerTool = tool( 'analyze_directory', '分析目录结构,统计文件类型和数量', { dirPath: z.string().describe('要分析的目录路径'), depth: z.number().default(2).describe('分析深度'), includeHidden: z.boolean().default(false).describe('是否包含隐藏文件') }, async (args) => { try { const analyze = (dirPath: string, currentDepth: number): any => { if (currentDepth <= 0) return null;
try { const items = readdirSync(dirPath); let fileCount = 0; let dirCount = 0; const fileTypes: Record<string, number> = {}; const structure: any[] = [];
for (const item of items) { if (!args.includeHidden && item.startsWith('.')) { continue; }
const fullPath = join(dirPath, item); const stat = statSync(fullPath);
if (stat.isDirectory() && currentDepth > 1) { dirCount++; const subAnalysis = analyze(fullPath, currentDepth - 1); structure.push({ name: item, type: 'directory', children: subAnalysis?.structure || [] }); } else if (stat.isFile()) { fileCount++; const ext = extname(item); fileTypes[ext] = (fileTypes[ext] || 0) + 1;
structure.push({ name: item, type: 'file', size: `${(stat.size / 1024).toFixed(2)} KB` }); } }
return { path: dirPath, fileCount, dirCount, fileTypes, structure: structure.slice(0, 10) }; } catch (error) { return { error: error.message }; } };
const result = analyze(args.dirPath, args.depth);
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: `目录分析失败: ${error.message}` }], isError: true }; } } );
|