mcp-server-gemini 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +155 -0
- package/LICENSE +21 -0
- package/README.md +180 -0
- package/dist/config/constants.js +71 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/models.js +121 -0
- package/dist/config/models.js.map +1 -0
- package/dist/enhanced-stdio-server.js +1164 -0
- package/dist/enhanced-stdio-server.js.map +1 -0
- package/dist/i18n.js +109 -0
- package/dist/i18n.js.map +1 -0
- package/dist/server.js +251 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/analyze-codebase.js +373 -0
- package/dist/tools/analyze-codebase.js.map +1 -0
- package/dist/tools/analyze-content.js +295 -0
- package/dist/tools/analyze-content.js.map +1 -0
- package/dist/tools/brainstorm.js +237 -0
- package/dist/tools/brainstorm.js.map +1 -0
- package/dist/tools/definitions.js +375 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/fix-ui.js +262 -0
- package/dist/tools/fix-ui.js.map +1 -0
- package/dist/tools/generate-ui.js +311 -0
- package/dist/tools/generate-ui.js.map +1 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-models.js +30 -0
- package/dist/tools/list-models.js.map +1 -0
- package/dist/tools/multimodal-query.js +83 -0
- package/dist/tools/multimodal-query.js.map +1 -0
- package/dist/tools/search.js +94 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/error-handler.js +69 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/file-reader.js +470 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/dist/utils/gemini-client.js +184 -0
- package/dist/utils/gemini-client.js.map +1 -0
- package/dist/utils/security.js +370 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/validators.js +150 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/windows-utils.js +175 -0
- package/dist/windows-utils.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool 6: gemini_analyze_codebase
|
|
3
|
+
* Codebase analysis tool - Leveraging 1M token context to analyze entire codebase
|
|
4
|
+
* Priority: P1 - Phase 3
|
|
5
|
+
*
|
|
6
|
+
* Upgrade notes (v1.1):
|
|
7
|
+
* - Added directory parameter: Support direct directory path input
|
|
8
|
+
* - Added filePaths parameter: Support file path list input
|
|
9
|
+
* - Added include/exclude parameters: Support glob pattern filtering
|
|
10
|
+
* - Retained files parameter: Backward compatible with original usage
|
|
11
|
+
*/
|
|
12
|
+
import { GoogleGenAI } from '@google/genai';
|
|
13
|
+
import { validateRequired, validateArray } from '../utils/validators.js';
|
|
14
|
+
import { handleAPIError, logError } from '../utils/error-handler.js';
|
|
15
|
+
import { readDirectory, readFiles } from '../utils/file-reader.js';
|
|
16
|
+
import { SecurityError } from '../utils/security.js';
|
|
17
|
+
// Codebase analysis system prompt
|
|
18
|
+
const CODEBASE_ANALYSIS_SYSTEM_PROMPT = `You are a senior software architect with expertise in:
|
|
19
|
+
- System architecture and design patterns
|
|
20
|
+
- Code quality and best practices
|
|
21
|
+
- Security vulnerabilities and threats
|
|
22
|
+
- Performance optimization
|
|
23
|
+
- Dependency management
|
|
24
|
+
|
|
25
|
+
Analysis approach:
|
|
26
|
+
1. Overview:
|
|
27
|
+
- Understand the overall structure
|
|
28
|
+
- Identify main components and their relationships
|
|
29
|
+
- Recognize architectural patterns
|
|
30
|
+
|
|
31
|
+
2. Deep dive (based on focus):
|
|
32
|
+
- Architecture: Layers, modules, data flow
|
|
33
|
+
- Security: Vulnerabilities, exposure points
|
|
34
|
+
- Performance: Bottlenecks, inefficiencies
|
|
35
|
+
- Dependencies: Version conflicts, outdated packages
|
|
36
|
+
- Patterns: Design patterns, anti-patterns
|
|
37
|
+
|
|
38
|
+
3. Recommendations:
|
|
39
|
+
- Prioritize by impact and effort
|
|
40
|
+
- Provide actionable suggestions
|
|
41
|
+
- Include code examples when helpful
|
|
42
|
+
|
|
43
|
+
Output quality:
|
|
44
|
+
- Be thorough but concise
|
|
45
|
+
- Use clear, professional language
|
|
46
|
+
- Include file paths and line numbers
|
|
47
|
+
- Visualize architecture with Mermaid diagrams
|
|
48
|
+
- Focus on high-impact findings`;
|
|
49
|
+
/**
|
|
50
|
+
* Detect programming language of file
|
|
51
|
+
*/
|
|
52
|
+
function detectLanguage(filePath) {
|
|
53
|
+
const ext = filePath.split('.').pop()?.toLowerCase() || '';
|
|
54
|
+
const languageMap = {
|
|
55
|
+
'ts': 'TypeScript',
|
|
56
|
+
'tsx': 'TypeScript (React)',
|
|
57
|
+
'js': 'JavaScript',
|
|
58
|
+
'jsx': 'JavaScript (React)',
|
|
59
|
+
'py': 'Python',
|
|
60
|
+
'java': 'Java',
|
|
61
|
+
'kt': 'Kotlin',
|
|
62
|
+
'go': 'Go',
|
|
63
|
+
'rs': 'Rust',
|
|
64
|
+
'cpp': 'C++',
|
|
65
|
+
'c': 'C',
|
|
66
|
+
'h': 'C/C++ Header',
|
|
67
|
+
'hpp': 'C++ Header',
|
|
68
|
+
'cs': 'C#',
|
|
69
|
+
'rb': 'Ruby',
|
|
70
|
+
'php': 'PHP',
|
|
71
|
+
'swift': 'Swift',
|
|
72
|
+
'scala': 'Scala',
|
|
73
|
+
'vue': 'Vue',
|
|
74
|
+
'svelte': 'Svelte',
|
|
75
|
+
'html': 'HTML',
|
|
76
|
+
'css': 'CSS',
|
|
77
|
+
'scss': 'SCSS',
|
|
78
|
+
'less': 'LESS',
|
|
79
|
+
'json': 'JSON',
|
|
80
|
+
'yaml': 'YAML',
|
|
81
|
+
'yml': 'YAML',
|
|
82
|
+
'xml': 'XML',
|
|
83
|
+
'md': 'Markdown',
|
|
84
|
+
'sql': 'SQL',
|
|
85
|
+
'sh': 'Shell',
|
|
86
|
+
'bash': 'Bash',
|
|
87
|
+
'ps1': 'PowerShell',
|
|
88
|
+
'dockerfile': 'Dockerfile',
|
|
89
|
+
};
|
|
90
|
+
return languageMap[ext] || 'Unknown';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Build codebase analysis prompt
|
|
94
|
+
*/
|
|
95
|
+
function buildCodebasePrompt(params, metrics, outputFormat) {
|
|
96
|
+
let prompt = `# Codebase Analysis Request\n\n`;
|
|
97
|
+
prompt += `## Codebase Overview\n`;
|
|
98
|
+
prompt += `- Total Files: ${metrics.totalFiles}\n`;
|
|
99
|
+
prompt += `- Total Lines: ${metrics.totalLines}\n`;
|
|
100
|
+
prompt += `- Languages: ${metrics.languages.join(', ')}\n\n`;
|
|
101
|
+
if (params.focus) {
|
|
102
|
+
prompt += `## Analysis Focus\n`;
|
|
103
|
+
switch (params.focus) {
|
|
104
|
+
case 'architecture':
|
|
105
|
+
prompt += `Focus on system architecture:
|
|
106
|
+
- Identify architectural patterns (MVC, MVVM, Clean Architecture, etc.)
|
|
107
|
+
- Analyze module/component structure
|
|
108
|
+
- Map data flow and dependencies
|
|
109
|
+
- Identify layers and boundaries
|
|
110
|
+
- Create architecture diagram using Mermaid\n\n`;
|
|
111
|
+
break;
|
|
112
|
+
case 'security':
|
|
113
|
+
prompt += `Focus on security analysis:
|
|
114
|
+
- Identify potential vulnerabilities (OWASP Top 10)
|
|
115
|
+
- Check for hardcoded secrets/credentials
|
|
116
|
+
- Analyze authentication/authorization patterns
|
|
117
|
+
- Review input validation and sanitization
|
|
118
|
+
- Check for SQL injection, XSS, CSRF vulnerabilities\n\n`;
|
|
119
|
+
break;
|
|
120
|
+
case 'performance':
|
|
121
|
+
prompt += `Focus on performance analysis:
|
|
122
|
+
- Identify potential bottlenecks
|
|
123
|
+
- Check for N+1 queries, memory leaks
|
|
124
|
+
- Analyze async/await patterns
|
|
125
|
+
- Review caching strategies
|
|
126
|
+
- Check for inefficient algorithms\n\n`;
|
|
127
|
+
break;
|
|
128
|
+
case 'dependencies':
|
|
129
|
+
prompt += `Focus on dependency analysis:
|
|
130
|
+
- Check for outdated dependencies
|
|
131
|
+
- Identify unused dependencies
|
|
132
|
+
- Look for version conflicts
|
|
133
|
+
- Review dependency tree
|
|
134
|
+
- Check for known vulnerabilities in dependencies\n\n`;
|
|
135
|
+
break;
|
|
136
|
+
case 'patterns':
|
|
137
|
+
prompt += `Focus on design patterns:
|
|
138
|
+
- Identify design patterns used
|
|
139
|
+
- Look for anti-patterns
|
|
140
|
+
- Check for code smells
|
|
141
|
+
- Review naming conventions
|
|
142
|
+
- Analyze code organization\n\n`;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
prompt += `## Analysis Focus\nPerform a comprehensive analysis covering architecture, security, performance, and code quality.\n\n`;
|
|
148
|
+
}
|
|
149
|
+
if (params.deepThink) {
|
|
150
|
+
prompt += `## Deep Think Mode\nPerform an extra thorough analysis. Take your time to reason through complex issues. Consider edge cases and subtle problems.\n\n`;
|
|
151
|
+
}
|
|
152
|
+
prompt += `## Output Format\n`;
|
|
153
|
+
if (outputFormat === 'json') {
|
|
154
|
+
prompt += `Provide your response as valid JSON with the following structure:
|
|
155
|
+
{
|
|
156
|
+
"summary": "Overall summary of the codebase",
|
|
157
|
+
"findings": [
|
|
158
|
+
{
|
|
159
|
+
"category": "security|performance|architecture|patterns|dependencies",
|
|
160
|
+
"severity": "high|medium|low",
|
|
161
|
+
"description": "Description of the finding",
|
|
162
|
+
"location": "file path and line numbers if applicable",
|
|
163
|
+
"suggestion": "Recommended fix or improvement"
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
"visualization": "Mermaid diagram code for architecture visualization"
|
|
167
|
+
}\n\n`;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
prompt += `Use Markdown formatting:
|
|
171
|
+
- Start with an executive summary
|
|
172
|
+
- Group findings by category
|
|
173
|
+
- Use severity badges: 🔴 High, 🟡 Medium, 🟢 Low
|
|
174
|
+
- Include code snippets for examples
|
|
175
|
+
- Add a Mermaid diagram for architecture visualization\n\n`;
|
|
176
|
+
}
|
|
177
|
+
prompt += `## Files to Analyze\n\n`;
|
|
178
|
+
// Add all file contents (params.files is guaranteed to have value before this call)
|
|
179
|
+
for (const file of params.files) {
|
|
180
|
+
const language = detectLanguage(file.path);
|
|
181
|
+
prompt += `### ${file.path} (${language})\n`;
|
|
182
|
+
prompt += `\`\`\`${language.toLowerCase().split(' ')[0]}\n`;
|
|
183
|
+
prompt += file.content;
|
|
184
|
+
prompt += `\n\`\`\`\n\n`;
|
|
185
|
+
}
|
|
186
|
+
return prompt;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Convert FileContent array to internal file format
|
|
190
|
+
*/
|
|
191
|
+
function convertFileContents(fileContents) {
|
|
192
|
+
return fileContents.map(fc => ({
|
|
193
|
+
path: fc.path,
|
|
194
|
+
content: fc.content
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Handle gemini_analyze_codebase tool call
|
|
199
|
+
*
|
|
200
|
+
* Supports three input methods (priority: directory > filePaths > files):
|
|
201
|
+
* 1. directory: Pass directory path, automatically read files in directory
|
|
202
|
+
* 2. filePaths: Pass file path list, automatically read these files
|
|
203
|
+
* 3. files: Pass file content array directly (backward compatible)
|
|
204
|
+
*/
|
|
205
|
+
export async function handleAnalyzeCodebase(params, client) {
|
|
206
|
+
try {
|
|
207
|
+
// ===== 1. Parameter validation =====
|
|
208
|
+
const hasDirectory = !!params.directory;
|
|
209
|
+
const hasFilePaths = params.filePaths && params.filePaths.length > 0;
|
|
210
|
+
const hasFiles = params.files && params.files.length > 0;
|
|
211
|
+
// Validate at least one input method is provided
|
|
212
|
+
if (!hasDirectory && !hasFilePaths && !hasFiles) {
|
|
213
|
+
throw new Error('One of directory, filePaths, or files parameter is required. ' +
|
|
214
|
+
'Use directory to pass a directory path, filePaths to pass a file path list, or files to pass a file content array.');
|
|
215
|
+
}
|
|
216
|
+
// Validate optional enum parameters
|
|
217
|
+
const validFocusAreas = ['architecture', 'security', 'performance', 'dependencies', 'patterns'];
|
|
218
|
+
const validFormats = ['markdown', 'json'];
|
|
219
|
+
if (params.focus && !validFocusAreas.includes(params.focus)) {
|
|
220
|
+
throw new Error(`Invalid focus: ${params.focus}. Must be one of: ${validFocusAreas.join(', ')}`);
|
|
221
|
+
}
|
|
222
|
+
if (params.outputFormat && !validFormats.includes(params.outputFormat)) {
|
|
223
|
+
throw new Error(`Invalid outputFormat: ${params.outputFormat}. Must be one of: ${validFormats.join(', ')}`);
|
|
224
|
+
}
|
|
225
|
+
// ===== 2. Get file contents =====
|
|
226
|
+
let filesToAnalyze;
|
|
227
|
+
if (hasDirectory) {
|
|
228
|
+
// Method 1: Read files from directory
|
|
229
|
+
console.log(`[analyze_codebase] Reading directory: ${params.directory}`);
|
|
230
|
+
try {
|
|
231
|
+
const fileContents = await readDirectory(params.directory, {
|
|
232
|
+
include: params.include,
|
|
233
|
+
exclude: params.exclude
|
|
234
|
+
});
|
|
235
|
+
if (fileContents.length === 0) {
|
|
236
|
+
throw new Error(`No matching files found in directory "${params.directory}".` +
|
|
237
|
+
(params.include ? ` Include patterns: ${params.include.join(', ')}` : '') +
|
|
238
|
+
(params.exclude ? ` Exclude patterns: ${params.exclude.join(', ')}` : ''));
|
|
239
|
+
}
|
|
240
|
+
filesToAnalyze = convertFileContents(fileContents);
|
|
241
|
+
console.log(`[analyze_codebase] Successfully read ${filesToAnalyze.length} files`);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
// Handle security errors
|
|
245
|
+
if (error instanceof SecurityError) {
|
|
246
|
+
throw new Error(`Security validation failed: ${error.message}`);
|
|
247
|
+
}
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else if (hasFilePaths) {
|
|
252
|
+
// Method 2: Read from file path list
|
|
253
|
+
console.log(`[analyze_codebase] Reading ${params.filePaths.length} files`);
|
|
254
|
+
try {
|
|
255
|
+
const fileContents = await readFiles(params.filePaths);
|
|
256
|
+
if (fileContents.length === 0) {
|
|
257
|
+
throw new Error('All specified files could not be read. Please check if file paths are correct.');
|
|
258
|
+
}
|
|
259
|
+
filesToAnalyze = convertFileContents(fileContents);
|
|
260
|
+
console.log(`[analyze_codebase] Successfully read ${filesToAnalyze.length} files`);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
if (error instanceof SecurityError) {
|
|
264
|
+
throw new Error(`Security validation failed: ${error.message}`);
|
|
265
|
+
}
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
// Method 3: Use files parameter directly (backward compatible)
|
|
271
|
+
validateRequired(params.files, 'files');
|
|
272
|
+
validateArray(params.files, 'files', 1);
|
|
273
|
+
// Validate each file has path and content
|
|
274
|
+
for (let i = 0; i < params.files.length; i++) {
|
|
275
|
+
const file = params.files[i];
|
|
276
|
+
if (!file.path || typeof file.path !== 'string') {
|
|
277
|
+
throw new Error(`File at index ${i} is missing required 'path' property`);
|
|
278
|
+
}
|
|
279
|
+
if (!file.content || typeof file.content !== 'string') {
|
|
280
|
+
throw new Error(`File at index ${i} is missing required 'content' property`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
filesToAnalyze = params.files;
|
|
284
|
+
}
|
|
285
|
+
// ===== 3. Set defaults and calculate metrics =====
|
|
286
|
+
const outputFormat = params.outputFormat || 'markdown';
|
|
287
|
+
const deepThink = params.deepThink || false;
|
|
288
|
+
// Calculate codebase metrics
|
|
289
|
+
const languages = new Set();
|
|
290
|
+
let totalLines = 0;
|
|
291
|
+
for (const file of filesToAnalyze) {
|
|
292
|
+
languages.add(detectLanguage(file.path));
|
|
293
|
+
totalLines += file.content.split('\n').length;
|
|
294
|
+
}
|
|
295
|
+
const metrics = {
|
|
296
|
+
totalFiles: filesToAnalyze.length,
|
|
297
|
+
totalLines,
|
|
298
|
+
languages: Array.from(languages).filter(l => l !== 'Unknown')
|
|
299
|
+
};
|
|
300
|
+
// ===== 4. Build prompt and call API =====
|
|
301
|
+
// Create temporary params object for building prompt
|
|
302
|
+
const promptParams = {
|
|
303
|
+
...params,
|
|
304
|
+
files: filesToAnalyze
|
|
305
|
+
};
|
|
306
|
+
const prompt = buildCodebasePrompt(promptParams, metrics, outputFormat);
|
|
307
|
+
// Determine thinking level (default high for complex analysis)
|
|
308
|
+
const thinkingLevel = params.thinkingLevel || 'high';
|
|
309
|
+
let response;
|
|
310
|
+
// Always use thinking mode with direct GoogleGenAI call
|
|
311
|
+
const apiKey = process.env.GEMINI_API_KEY;
|
|
312
|
+
if (!apiKey) {
|
|
313
|
+
throw new Error('GEMINI_API_KEY environment variable is not set');
|
|
314
|
+
}
|
|
315
|
+
const ai = new GoogleGenAI({ apiKey });
|
|
316
|
+
const config = {
|
|
317
|
+
thinkingConfig: { thinkingLevel },
|
|
318
|
+
systemInstruction: CODEBASE_ANALYSIS_SYSTEM_PROMPT,
|
|
319
|
+
};
|
|
320
|
+
const contents = [{
|
|
321
|
+
role: 'user',
|
|
322
|
+
parts: [{ text: prompt }]
|
|
323
|
+
}];
|
|
324
|
+
const apiResult = await ai.models.generateContent({
|
|
325
|
+
model: 'gemini-3-pro-preview',
|
|
326
|
+
config,
|
|
327
|
+
contents,
|
|
328
|
+
});
|
|
329
|
+
response = apiResult.text || '';
|
|
330
|
+
// ===== 5. Build return result =====
|
|
331
|
+
const result = {
|
|
332
|
+
summary: '',
|
|
333
|
+
findings: [],
|
|
334
|
+
metrics,
|
|
335
|
+
analysisDepth: deepThink ? 'deep' : 'standard'
|
|
336
|
+
};
|
|
337
|
+
// Parse response
|
|
338
|
+
if (outputFormat === 'json') {
|
|
339
|
+
try {
|
|
340
|
+
// Extract JSON content
|
|
341
|
+
let jsonContent = response;
|
|
342
|
+
const jsonMatch = response.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
343
|
+
if (jsonMatch) {
|
|
344
|
+
jsonContent = jsonMatch[1].trim();
|
|
345
|
+
}
|
|
346
|
+
const parsed = JSON.parse(jsonContent);
|
|
347
|
+
result.summary = parsed.summary || response;
|
|
348
|
+
result.findings = parsed.findings || [];
|
|
349
|
+
if (parsed.visualization) {
|
|
350
|
+
result.visualization = parsed.visualization;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
// JSON parsing failed, use raw response
|
|
355
|
+
result.summary = response;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
result.summary = response;
|
|
360
|
+
// Try to extract Mermaid diagram
|
|
361
|
+
const mermaidMatch = response.match(/```mermaid\s*([\s\S]*?)```/);
|
|
362
|
+
if (mermaidMatch) {
|
|
363
|
+
result.visualization = mermaidMatch[1].trim();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
logError('analyzeCodebase', error);
|
|
370
|
+
throw handleAPIError(error);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=analyze-codebase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-codebase.js","sourceRoot":"","sources":["../../src/tools/analyze-codebase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool 5: gemini_analyze_content
|
|
3
|
+
* General content analysis tool - Analyze code snippets, documents, data
|
|
4
|
+
* Priority: P1 - Phase 3
|
|
5
|
+
*
|
|
6
|
+
* Upgrade notes (v1.1):
|
|
7
|
+
* - Added filePath parameter: Support direct file path input, tool automatically reads content
|
|
8
|
+
* - Retained content parameter: Backward compatible with original calling method
|
|
9
|
+
*/
|
|
10
|
+
import { validateRequired, validateString, validateArray } from '../utils/validators.js';
|
|
11
|
+
import { handleAPIError, logError } from '../utils/error-handler.js';
|
|
12
|
+
import { readFile } from '../utils/file-reader.js';
|
|
13
|
+
import { SecurityError } from '../utils/security.js';
|
|
14
|
+
// Content analysis system prompt
|
|
15
|
+
const ANALYZE_CONTENT_SYSTEM_PROMPT = `You are a versatile code and document analyst with expertise in:
|
|
16
|
+
- Code quality analysis (any programming language)
|
|
17
|
+
- Document summarization and understanding
|
|
18
|
+
- Data structure analysis and optimization
|
|
19
|
+
- Technical writing review
|
|
20
|
+
|
|
21
|
+
Analysis approach:
|
|
22
|
+
1. Auto-detect content type (code, document, data)
|
|
23
|
+
2. Understand the context and purpose
|
|
24
|
+
3. Perform requested task:
|
|
25
|
+
- Summarize: Create concise summary with key points
|
|
26
|
+
- Review: Analyze quality, find issues, suggest improvements
|
|
27
|
+
- Explain: Break down complex content into understandable parts
|
|
28
|
+
- Optimize: Suggest performance and efficiency improvements
|
|
29
|
+
- Debug: Identify potential bugs and logic errors
|
|
30
|
+
|
|
31
|
+
Output requirements:
|
|
32
|
+
- Be clear and actionable
|
|
33
|
+
- Prioritize findings by importance
|
|
34
|
+
- Provide specific examples
|
|
35
|
+
- Use appropriate technical terminology
|
|
36
|
+
- Format output for readability
|
|
37
|
+
|
|
38
|
+
When analyzing code:
|
|
39
|
+
- Identify the language automatically
|
|
40
|
+
- Check for common patterns and anti-patterns
|
|
41
|
+
- Suggest best practices
|
|
42
|
+
- Highlight security concerns
|
|
43
|
+
|
|
44
|
+
When analyzing documents:
|
|
45
|
+
- Extract main themes and ideas
|
|
46
|
+
- Identify structure and organization
|
|
47
|
+
- Suggest improvements for clarity
|
|
48
|
+
- Highlight important points
|
|
49
|
+
|
|
50
|
+
When analyzing data:
|
|
51
|
+
- Understand the structure
|
|
52
|
+
- Identify patterns and anomalies
|
|
53
|
+
- Suggest optimizations
|
|
54
|
+
- Explain relationships`;
|
|
55
|
+
/**
|
|
56
|
+
* Auto-detect content type
|
|
57
|
+
*/
|
|
58
|
+
function detectContentType(content, language) {
|
|
59
|
+
// If programming language is specified, consider it as code
|
|
60
|
+
if (language) {
|
|
61
|
+
return 'code';
|
|
62
|
+
}
|
|
63
|
+
const trimmedContent = content.trim();
|
|
64
|
+
// Check if it's JSON/data
|
|
65
|
+
if (trimmedContent.startsWith('{') || trimmedContent.startsWith('[')) {
|
|
66
|
+
try {
|
|
67
|
+
JSON.parse(trimmedContent);
|
|
68
|
+
return 'data';
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Not valid JSON, continue checking
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Check XML/HTML data
|
|
75
|
+
if (trimmedContent.startsWith('<?xml') || trimmedContent.match(/^<\w+[^>]*>/)) {
|
|
76
|
+
// If it looks like a complete HTML page, it might be code
|
|
77
|
+
if (trimmedContent.includes('<!DOCTYPE html>') || trimmedContent.includes('<script')) {
|
|
78
|
+
return 'code';
|
|
79
|
+
}
|
|
80
|
+
return 'data';
|
|
81
|
+
}
|
|
82
|
+
// Check code characteristics
|
|
83
|
+
const codePatterns = [
|
|
84
|
+
/function\s+\w+\s*\(/, // JavaScript/TypeScript function
|
|
85
|
+
/const\s+\w+\s*=/, // const declaration
|
|
86
|
+
/let\s+\w+\s*=/, // let declaration
|
|
87
|
+
/var\s+\w+\s*=/, // var declaration
|
|
88
|
+
/class\s+\w+/, // class declaration
|
|
89
|
+
/import\s+.*from\s+['"`]/, // ES6 import
|
|
90
|
+
/export\s+(default\s+)?/, // ES6 export
|
|
91
|
+
/def\s+\w+\s*\(/, // Python function
|
|
92
|
+
/class\s+\w+\s*:/, // Python class
|
|
93
|
+
/public\s+(static\s+)?class/, // Java/C# class
|
|
94
|
+
/private\s+\w+/, // Java/C# private
|
|
95
|
+
/<\?php/, // PHP
|
|
96
|
+
/package\s+\w+/, // Go/Java package
|
|
97
|
+
/func\s+\w+\s*\(/, // Go function
|
|
98
|
+
/fn\s+\w+\s*\(/, // Rust function
|
|
99
|
+
/#include\s*<\w+>/, // C/C++ include
|
|
100
|
+
/using\s+namespace/, // C++ using
|
|
101
|
+
/impl\s+\w+/, // Rust impl
|
|
102
|
+
/struct\s+\w+\s*\{/, // Rust/Go/C struct
|
|
103
|
+
/interface\s+\w+\s*\{/, // TypeScript/Go interface
|
|
104
|
+
/=>\s*\{/, // Arrow function
|
|
105
|
+
/async\s+function/, // Async function
|
|
106
|
+
/await\s+\w+/, // Await expression
|
|
107
|
+
];
|
|
108
|
+
if (codePatterns.some(pattern => pattern.test(content))) {
|
|
109
|
+
return 'code';
|
|
110
|
+
}
|
|
111
|
+
// Check if it contains a lot of code-related symbols
|
|
112
|
+
const codeSymbols = (content.match(/[{}\[\]();=><]/g) || []).length;
|
|
113
|
+
const totalChars = content.length;
|
|
114
|
+
if (codeSymbols / totalChars > 0.05) {
|
|
115
|
+
return 'code';
|
|
116
|
+
}
|
|
117
|
+
// Default to document
|
|
118
|
+
return 'document';
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Build analysis prompt
|
|
122
|
+
* @param params Parameter object
|
|
123
|
+
* @param detectedType Detected content type
|
|
124
|
+
* @param task Analysis task
|
|
125
|
+
* @param outputFormat Output format
|
|
126
|
+
* @param contentToAnalyze Content to analyze (provided by caller, read from file or directly passed in)
|
|
127
|
+
*/
|
|
128
|
+
function buildAnalysisPrompt(params, detectedType, task, outputFormat, contentToAnalyze) {
|
|
129
|
+
let prompt = `# Content Analysis Task\n\n`;
|
|
130
|
+
prompt += `## Content Type\n${detectedType}\n\n`;
|
|
131
|
+
if (params.language) {
|
|
132
|
+
prompt += `## Programming Language\n${params.language}\n\n`;
|
|
133
|
+
}
|
|
134
|
+
prompt += `## Analysis Task\n`;
|
|
135
|
+
switch (task) {
|
|
136
|
+
case 'summarize':
|
|
137
|
+
prompt += `Create a concise summary of the content, highlighting key points and main ideas.\n\n`;
|
|
138
|
+
break;
|
|
139
|
+
case 'review':
|
|
140
|
+
prompt += `Perform a thorough review. Identify issues, suggest improvements, and evaluate quality.\n\n`;
|
|
141
|
+
break;
|
|
142
|
+
case 'explain':
|
|
143
|
+
prompt += `Explain the content in detail. Break down complex parts into understandable segments.\n\n`;
|
|
144
|
+
break;
|
|
145
|
+
case 'optimize':
|
|
146
|
+
prompt += `Analyze for optimization opportunities. Focus on performance, efficiency, and best practices.\n\n`;
|
|
147
|
+
break;
|
|
148
|
+
case 'debug':
|
|
149
|
+
prompt += `Identify potential bugs, logic errors, and issues. Suggest fixes for each problem found.\n\n`;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
if (params.focus && params.focus.length > 0) {
|
|
153
|
+
prompt += `## Focus Areas\n`;
|
|
154
|
+
params.focus.forEach(area => {
|
|
155
|
+
prompt += `- ${area}\n`;
|
|
156
|
+
});
|
|
157
|
+
prompt += '\n';
|
|
158
|
+
}
|
|
159
|
+
prompt += `## Output Format\n`;
|
|
160
|
+
if (outputFormat === 'json') {
|
|
161
|
+
prompt += `Provide your response as valid JSON with the following structure:
|
|
162
|
+
{
|
|
163
|
+
"summary": "Brief summary",
|
|
164
|
+
"analysis": "Detailed analysis",
|
|
165
|
+
"issues": [{"severity": "high|medium|low", "description": "...", "location": "..."}],
|
|
166
|
+
"suggestions": ["suggestion1", "suggestion2"]
|
|
167
|
+
}\n\n`;
|
|
168
|
+
}
|
|
169
|
+
else if (outputFormat === 'markdown') {
|
|
170
|
+
prompt += `Use Markdown formatting for better readability. Include headers, lists, and code blocks where appropriate.\n\n`;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
prompt += `Provide plain text output.\n\n`;
|
|
174
|
+
}
|
|
175
|
+
prompt += `## Content to Analyze\n\`\`\`\n${contentToAnalyze}\n\`\`\``;
|
|
176
|
+
return prompt;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Handle gemini_analyze_content tool call
|
|
180
|
+
*
|
|
181
|
+
* Supports two input methods (priority: filePath > content):
|
|
182
|
+
* 1. filePath: Pass file path, automatically read file content
|
|
183
|
+
* 2. content: Direct content input (backward compatible)
|
|
184
|
+
*/
|
|
185
|
+
export async function handleAnalyzeContent(params, client) {
|
|
186
|
+
try {
|
|
187
|
+
// ===== 1. Parameter validation =====
|
|
188
|
+
const hasFilePath = !!params.filePath;
|
|
189
|
+
const hasContent = !!params.content;
|
|
190
|
+
// Validate that at least one input method is provided
|
|
191
|
+
if (!hasFilePath && !hasContent) {
|
|
192
|
+
throw new Error('One of filePath or content parameter is required. ' +
|
|
193
|
+
'Please use filePath to pass a file path, or use content to pass content directly.');
|
|
194
|
+
}
|
|
195
|
+
// Validate optional enum parameters
|
|
196
|
+
const validTypes = ['code', 'document', 'data', 'auto'];
|
|
197
|
+
const validTasks = ['summarize', 'review', 'explain', 'optimize', 'debug'];
|
|
198
|
+
const validFormats = ['text', 'json', 'markdown'];
|
|
199
|
+
if (params.type && !validTypes.includes(params.type)) {
|
|
200
|
+
throw new Error(`Invalid type: ${params.type}. Must be one of: ${validTypes.join(', ')}`);
|
|
201
|
+
}
|
|
202
|
+
if (params.task && !validTasks.includes(params.task)) {
|
|
203
|
+
throw new Error(`Invalid task: ${params.task}. Must be one of: ${validTasks.join(', ')}`);
|
|
204
|
+
}
|
|
205
|
+
if (params.outputFormat && !validFormats.includes(params.outputFormat)) {
|
|
206
|
+
throw new Error(`Invalid outputFormat: ${params.outputFormat}. Must be one of: ${validFormats.join(', ')}`);
|
|
207
|
+
}
|
|
208
|
+
if (params.focus) {
|
|
209
|
+
validateArray(params.focus, 'focus', 1);
|
|
210
|
+
}
|
|
211
|
+
// ===== 2. Get content =====
|
|
212
|
+
let contentToAnalyze;
|
|
213
|
+
let detectedLanguage = params.language;
|
|
214
|
+
if (hasFilePath) {
|
|
215
|
+
// Method 1: Read content from file
|
|
216
|
+
console.log(`[analyze_content] Reading file: ${params.filePath}`);
|
|
217
|
+
try {
|
|
218
|
+
const fileContent = await readFile(params.filePath);
|
|
219
|
+
contentToAnalyze = fileContent.content;
|
|
220
|
+
// If no language specified, use detected language
|
|
221
|
+
if (!detectedLanguage && fileContent.language) {
|
|
222
|
+
detectedLanguage = fileContent.language;
|
|
223
|
+
}
|
|
224
|
+
console.log(`[analyze_content] Successfully read file, size: ${fileContent.size} bytes`);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (error instanceof SecurityError) {
|
|
228
|
+
throw new Error(`Security validation failed: ${error.message}`);
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// Method 2: Direct use of content parameter (backward compatible)
|
|
235
|
+
validateRequired(params.content, 'content');
|
|
236
|
+
validateString(params.content, 'content', 10);
|
|
237
|
+
contentToAnalyze = params.content;
|
|
238
|
+
}
|
|
239
|
+
// ===== 3. Set defaults and detect type =====
|
|
240
|
+
const type = params.type || 'auto';
|
|
241
|
+
const task = params.task || 'summarize';
|
|
242
|
+
const outputFormat = params.outputFormat || 'markdown';
|
|
243
|
+
// Auto-detect content type
|
|
244
|
+
const detectedType = type === 'auto'
|
|
245
|
+
? detectContentType(contentToAnalyze, detectedLanguage)
|
|
246
|
+
: type;
|
|
247
|
+
// ===== 4. Build prompt =====
|
|
248
|
+
// Create temporary parameter object for building prompt
|
|
249
|
+
const promptParams = {
|
|
250
|
+
...params,
|
|
251
|
+
content: contentToAnalyze,
|
|
252
|
+
language: detectedLanguage
|
|
253
|
+
};
|
|
254
|
+
const prompt = buildAnalysisPrompt(promptParams, detectedType, task, outputFormat, contentToAnalyze);
|
|
255
|
+
// Call Gemini API (using default model gemini-3-pro-preview)
|
|
256
|
+
const response = await client.generate(prompt, {
|
|
257
|
+
systemInstruction: ANALYZE_CONTENT_SYSTEM_PROMPT,
|
|
258
|
+
temperature: 0.5,
|
|
259
|
+
maxTokens: 8192
|
|
260
|
+
});
|
|
261
|
+
// Build return result
|
|
262
|
+
const result = {
|
|
263
|
+
analysis: response,
|
|
264
|
+
contentType: detectedType,
|
|
265
|
+
task: task
|
|
266
|
+
};
|
|
267
|
+
// If JSON format, try to parse and extract structured data
|
|
268
|
+
if (outputFormat === 'json') {
|
|
269
|
+
try {
|
|
270
|
+
// Extract JSON content (may be wrapped in markdown code block)
|
|
271
|
+
let jsonContent = response;
|
|
272
|
+
const jsonMatch = response.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
273
|
+
if (jsonMatch) {
|
|
274
|
+
jsonContent = jsonMatch[1].trim();
|
|
275
|
+
}
|
|
276
|
+
const parsed = JSON.parse(jsonContent);
|
|
277
|
+
if (parsed.summary)
|
|
278
|
+
result.summary = parsed.summary;
|
|
279
|
+
if (parsed.suggestions)
|
|
280
|
+
result.suggestions = parsed.suggestions;
|
|
281
|
+
if (parsed.issues)
|
|
282
|
+
result.issues = parsed.issues;
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
// JSON parsing failed, keep original response
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
logError('analyzeContent', error);
|
|
292
|
+
throw handleAPIError(error);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=analyze-content.js.map
|