mcp-adr-analysis-server
Version:
MCP server for analyzing Architectural Decision Records and project architecture
872 lines (769 loc) • 28 kB
JavaScript
/**
* File system utilities for MCP ADR Analysis Server
* Generates prompts for AI-driven file discovery, reading, and analysis operations
* Enhanced with Chain-of-Thought prompting to reduce LLM confusion
*/
import { dirname } from 'path';
import { FileSystemError } from '../types/index.js';
import { enhancePromptWithCoT, COT_PATTERNS } from './chain-of-thought-template.js';
/**
* Generate prompt for AI-driven project structure analysis
*/
export async function analyzeProjectStructure(projectPath) {
try {
console.error(`[DEBUG] Starting prompt generation for project path: ${projectPath}`);
// Pure prompt-driven approach - delegate all path resolution and validation to AI
const safeProjectPath = projectPath || '.';
console.error(`[DEBUG] Using prompt-driven analysis for path: ${safeProjectPath}`);
// Note: Path validation is delegated to the AI agent that will perform the actual scanning
// Define file patterns for analysis
const filePatterns = [
'**/*',
'!node_modules/**',
'!.git/**',
'!dist/**',
'!build/**',
'!coverage/**',
'!.mcp-adr-cache/**',
'!*.log',
];
console.error(`[DEBUG] Generated prompt for file patterns:`, filePatterns);
console.error(`[DEBUG] Target directory: ${safeProjectPath}`);
// Generate Chain-of-Thought enhanced analysis prompt
const basePrompt = `
# Project Structure Analysis Request
Analyze the project structure at: **${safeProjectPath}**
## Analysis Requirements
**File Discovery**: Scan the directory using the following patterns:
${filePatterns.map(pattern => ` - ${pattern}`).join('\n')}
**Technology Stack Detection**: Identify:
- Programming languages (based on file extensions)
- Frameworks and libraries (from package.json, requirements.txt, etc.)
- Build tools and configuration files
- Testing frameworks and tools
**Architectural Patterns**: Analyze:
- Directory structure and organization
- Code organization patterns (MVC, microservices, etc.)
- Configuration management approaches
- Documentation patterns
**Project Ecosystem**: Examine:
- Dependencies and package management
- Development tools and workflows
- CI/CD configurations
- Documentation and README files
## Expected Output Format
\`\`\`json
{
"rootPath": "<resolved-absolute-path>",
"totalFiles": <number>,
"totalDirectories": <number>,
"technologies": [
{
"name": "technology_name",
"type": "language|framework|tool",
"confidence": 0.95,
"evidence": ["file1.ext", "config.json"]
}
],
"patterns": [
{
"name": "pattern_name",
"type": "architectural|organizational",
"description": "pattern description",
"evidence": ["directory_structure", "file_patterns"]
}
],
"files": [
{
"path": "relative/path/to/file",
"name": "filename.ext",
"extension": ".ext",
"directory": "relative/path/to",
"category": "source|config|documentation|test"
}
],
"directories": ["dir1", "dir2/subdir"],
"summary": "Brief project description and key findings"
}
\`\`\`
`;
// Enhance the base prompt with Chain-of-Thought reasoning
const prompt = enhancePromptWithCoT(basePrompt, COT_PATTERNS.PROJECT_ANALYSIS);
const instructions = `
## Implementation Steps
1. **Directory Scanning**: Use appropriate file system tools to scan the resolved project path
2. **Pattern Filtering**: Apply exclusion patterns: ${filePatterns.filter(p => p.startsWith('!')).join(', ')}
3. **File Analysis**: Examine file extensions, names, and content (for config files)
4. **Technology Detection**: Look for package.json, requirements.txt, Cargo.toml, etc.
5. **Pattern Recognition**: Analyze directory structure and file organization
6. **Result Compilation**: Format findings according to the specified JSON structure
## Safety Checks
- ✅ Path resolution delegated to AI agent with security validation
- ✅ System directory protection enabled
- ✅ File patterns defined for efficient scanning
- ✅ Exclusion patterns prevent scanning large/unnecessary directories
## Context Information
- **Project Path**: ${safeProjectPath}
- **Analysis Type**: Comprehensive project ecosystem analysis
- **Output Format**: Structured JSON with technology stack and architectural patterns
`;
return {
prompt,
instructions,
context: {
projectPath: safeProjectPath,
absoluteProjectPath: 'resolved-by-ai-agent',
filePatterns
}
};
}
catch (error) {
// If it's already a FileSystemError, re-throw it to preserve the specific error message
if (error instanceof FileSystemError) {
throw error;
}
throw new FileSystemError(`Failed to generate project analysis prompt: ${error instanceof Error ? error.message : String(error)}`, { projectPath, absoluteProjectPath: 'resolved-by-ai-agent' });
}
}
/**
* Generate prompt for AI-driven file content reading
*/
export async function readFileContent(filePath) {
try {
console.error(`[DEBUG] Generating file read prompt for: ${filePath}`);
// Pure prompt-driven approach - delegate file reading to AI agent
const safeFilePath = filePath || '';
const prompt = `
# File Content Reading Request
Please read the content of the file: **${safeFilePath}**
## Path Security Validation
The AI agent must:
1. **Validate file path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
2. **Resolve relative paths safely**: Handle relative paths from the current working directory
3. **Prevent unauthorized access**: Reject attempts to read sensitive system files or directories outside the project scope
4. **Validate file existence**: Check if the file exists before attempting to read
## File Reading Requirements
1. **Safe File Access**: Read the file content using appropriate file system tools
2. **Encoding Handling**: Read the file as UTF-8 text content
3. **Error Handling**: Provide clear error messages for:
- File not found
- Permission denied
- Invalid file path
- Binary files or unsupported formats
## Expected Output Format
\`\`\`json
{
"success": true,
"filePath": "${safeFilePath}",
"content": "file content as string",
"metadata": {
"size": <file_size_in_bytes>,
"encoding": "utf-8",
"lastModified": "ISO_timestamp"
},
"security": {
"pathValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
}
}
\`\`\`
## Error Response Format (if file cannot be read)
\`\`\`json
{
"success": false,
"filePath": "${safeFilePath}",
"error": "detailed error message",
"errorType": "FILE_NOT_FOUND|PERMISSION_DENIED|INVALID_PATH|SECURITY_VIOLATION",
"security": {
"pathValidated": boolean,
"accessAuthorized": boolean,
"systemDirectoryCheck": "passed|failed",
"rejectionReason": "specific reason if access denied"
}
}
\`\`\`
`;
const instructions = `
## Implementation Steps
1. **Security Validation**:
- Validate the file path: ${safeFilePath}
- Ensure it's not a system directory or sensitive location
- Check for path traversal attempts (../, .\\, etc.)
2. **File Access**:
- Check if the file exists and is readable
- Verify file permissions allow reading
- Handle symbolic links safely
3. **Content Reading**:
- Read file content as UTF-8 text
- Handle large files appropriately
- Detect and handle binary files
4. **Response Generation**:
- Format response according to the specified JSON structure
- Include comprehensive metadata and security validation results
- Provide detailed error information if reading fails
## Safety Checks
- ✅ Path security validation delegated to AI agent
- ✅ System directory protection enabled
- ✅ File access permission validation required
- ✅ Comprehensive error handling specified
## Context Information
- **File Path**: ${safeFilePath}
- **Operation**: Safe file content reading
- **Security Level**: High (with path validation and access control)
`;
return {
prompt,
instructions,
context: {
filePath: safeFilePath,
operation: 'file_read',
securityLevel: 'high',
expectedFormat: 'json'
}
};
}
catch (error) {
throw new FileSystemError(`Failed to generate file read prompt: ${error instanceof Error ? error.message : String(error)}`, { filePath });
}
}
/**
* Generate prompt for AI-driven file discovery
*/
export async function findFiles(projectPath, patterns, options = {}) {
try {
// Pure prompt-driven approach - delegate all path resolution and validation to AI
const safeProjectPath = projectPath || '.';
const prompt = `
# File Discovery Request
Please find files matching the specified patterns in: **${safeProjectPath}**
## Path Resolution Instructions
1. **Safely resolve the project path**: If path is "." or "./", use the current working directory
2. **Validate path security**: Ensure the path is not a system directory (/, /usr, /bin, etc.)
3. **Handle relative paths**: Resolve relative paths from the current working directory
## Search Patterns
${patterns.map(pattern => `- ${pattern}`).join('\n')}
## Requirements
- Search in the resolved directory (safely resolve ${safeProjectPath})
- Apply patterns to filter files
- ${options.includeContent ? 'Include file content in results' : 'Return file metadata only'}
## Expected Output Format
\`\`\`json
{
"files": [
{
"path": "relative/path/to/file",
"name": "filename.ext",
"extension": ".ext",
"size": 1234,
"directory": "relative/path/to"${options.includeContent ? ',\n "content": "file content here"' : ''}
}
],
"totalFiles": <number>,
"searchPatterns": ${JSON.stringify(patterns)},
"searchPath": "<resolved-absolute-path>"
}
\`\`\`
`;
const instructions = `
## Implementation Steps
1. Scan the resolved directory (safely resolve ${safeProjectPath})
2. Apply patterns: ${patterns.join(', ')}
3. Collect file metadata (name, size, extension, path)
${options.includeContent ? '4. Read and include file content' : '4. Skip file content reading'}
5. Format results as JSON
## Context
- Base directory: ${safeProjectPath}
- Include content: ${options.includeContent || false}
- Pattern count: ${patterns.length}
`;
return {
prompt,
instructions,
context: {
projectPath: safeProjectPath,
absoluteProjectPath: 'resolved-by-ai-agent',
patterns,
includeContent: options.includeContent || false
}
};
}
catch (error) {
throw new FileSystemError(`Failed to generate file discovery prompt: ${error instanceof Error ? error.message : String(error)}`, { projectPath, patterns });
}
}
/**
* Generate prompt for AI-driven file existence check
*/
export async function fileExists(filePath) {
try {
console.error(`[DEBUG] Generating file existence check prompt for: ${filePath}`);
// Pure prompt-driven approach - delegate file existence check to AI agent
const safeFilePath = filePath || '';
const prompt = `
# File Existence Check Request
Please check if the file exists: **${safeFilePath}**
## Path Security Validation
The AI agent must:
1. **Validate file path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
2. **Resolve relative paths safely**: Handle relative paths from the current working directory
3. **Prevent unauthorized access**: Reject attempts to check sensitive system files or directories outside the project scope
4. **Validate path format**: Check for valid file path format and reject malicious patterns
## File Existence Check Requirements
1. **Safe Path Resolution**: Resolve the file path using appropriate file system tools
2. **Access Validation**: Check if the file exists and is accessible
3. **Security Compliance**: Ensure the check doesn't expose sensitive information
4. **Error Handling**: Handle various scenarios:
- File exists and is accessible
- File does not exist
- Path is invalid or malformed
- Permission denied
- Path points to a directory instead of a file
## Expected Output Format
\`\`\`json
{
"success": true,
"filePath": "${safeFilePath}",
"exists": true,
"metadata": {
"type": "file|directory|symlink",
"accessible": true,
"lastChecked": "ISO_timestamp"
},
"security": {
"pathValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
}
}
\`\`\`
## Response Format for Non-Existent File
\`\`\`json
{
"success": true,
"filePath": "${safeFilePath}",
"exists": false,
"metadata": {
"type": null,
"accessible": false,
"lastChecked": "ISO_timestamp"
},
"security": {
"pathValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
}
}
\`\`\`
## Error Response Format (for security violations or invalid paths)
\`\`\`json
{
"success": false,
"filePath": "${safeFilePath}",
"exists": false,
"error": "detailed error message",
"errorType": "INVALID_PATH|SECURITY_VIOLATION|PERMISSION_DENIED|MALFORMED_PATH",
"security": {
"pathValidated": boolean,
"accessAuthorized": boolean,
"systemDirectoryCheck": "passed|failed",
"rejectionReason": "specific reason if access denied"
}
}
\`\`\`
`;
const instructions = `
## Implementation Steps
1. **Security Validation**:
- Validate the file path: ${safeFilePath}
- Ensure it's not a system directory or sensitive location
- Check for path traversal attempts (../, .\\, etc.)
- Validate path format and reject malicious patterns
2. **Path Resolution**:
- Resolve relative paths from the current working directory
- Handle symbolic links appropriately
- Normalize path separators for the operating system
3. **Existence Check**:
- Check if the file exists at the resolved path
- Determine if it's a file, directory, or symbolic link
- Verify accessibility without reading content
4. **Response Generation**:
- Format response according to the specified JSON structure
- Include comprehensive metadata and security validation results
- Provide clear boolean result in the "exists" field
- Include detailed error information if check fails
## Safety Checks
- ✅ Path security validation delegated to AI agent
- ✅ System directory protection enabled
- ✅ File access permission validation required
- ✅ Comprehensive error handling specified
- ✅ Boolean result format clearly defined
## Context Information
- **File Path**: ${safeFilePath}
- **Operation**: Safe file existence check
- **Security Level**: High (with path validation and access control)
- **Expected Result**: Boolean existence status with metadata
`;
return {
prompt,
instructions,
context: {
filePath: safeFilePath,
operation: 'file_exists_check',
securityLevel: 'high',
expectedFormat: 'json',
resultType: 'boolean'
}
};
}
catch (error) {
throw new FileSystemError(`Failed to generate file existence check prompt: ${error instanceof Error ? error.message : String(error)}`, { filePath });
}
}
/**
* Generate prompt for AI-driven directory creation
*/
export async function ensureDirectory(dirPath) {
try {
console.error(`[DEBUG] Generating directory creation prompt for: ${dirPath}`);
// Pure prompt-driven approach - delegate directory creation to AI agent
const safeDirPath = dirPath || '';
const prompt = `
# Directory Creation Request
Please ensure the directory exists: **${safeDirPath}**
## Path Security Validation
The AI agent must:
1. **Validate directory path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
2. **Resolve relative paths safely**: Handle relative paths from the current working directory
3. **Prevent unauthorized access**: Reject attempts to create directories in sensitive system locations
4. **Validate path format**: Check for valid directory path format and reject malicious patterns
## Directory Creation Requirements
1. **Safe Path Resolution**: Resolve the directory path using appropriate file system tools
2. **Recursive Creation**: Create parent directories if they don't exist (recursive: true)
3. **Permission Handling**: Ensure appropriate permissions for directory creation
4. **Error Handling**: Handle various scenarios:
- Directory already exists (success)
- Parent directories don't exist (create them)
- Permission denied
- Invalid path or malformed directory name
- Disk space issues
## Action Confirmation Required
Before creating any directories, confirm the action with the user:
**Action**: Create directory structure
**Target**: ${safeDirPath}
**Type**: Directory creation (recursive)
**Impact**: Creates directory and any missing parent directories
## Expected Output Format
\`\`\`json
{
"success": true,
"dirPath": "${safeDirPath}",
"created": true,
"metadata": {
"type": "directory",
"recursive": true,
"permissions": "755",
"createdAt": "ISO_timestamp"
},
"security": {
"pathValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
},
"confirmation": {
"actionConfirmed": true,
"userApproved": true
}
}
\`\`\`
## Response Format for Existing Directory
\`\`\`json
{
"success": true,
"dirPath": "${safeDirPath}",
"created": false,
"metadata": {
"type": "directory",
"alreadyExists": true,
"permissions": "existing_permissions",
"lastModified": "ISO_timestamp"
},
"security": {
"pathValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
}
}
\`\`\`
## Error Response Format
\`\`\`json
{
"success": false,
"dirPath": "${safeDirPath}",
"created": false,
"error": "detailed error message",
"errorType": "PERMISSION_DENIED|INVALID_PATH|SECURITY_VIOLATION|DISK_FULL",
"security": {
"pathValidated": boolean,
"accessAuthorized": boolean,
"systemDirectoryCheck": "passed|failed",
"rejectionReason": "specific reason if access denied"
}
}
\`\`\`
`;
const instructions = `
## Implementation Steps
1. **Security Validation**:
- Validate the directory path: ${safeDirPath}
- Ensure it's not a system directory or sensitive location
- Check for path traversal attempts (../, .\\, etc.)
- Validate path format and reject malicious patterns
2. **Action Confirmation**:
- Present the directory creation action to the user for confirmation
- Include details about what directories will be created
- Wait for user approval before proceeding
3. **Directory Creation**:
- Check if the directory already exists
- Create parent directories recursively if needed
- Set appropriate permissions (755 or system default)
- Handle symbolic links appropriately
4. **Response Generation**:
- Format response according to the specified JSON structure
- Include comprehensive metadata and security validation results
- Provide detailed error information if creation fails
- Include confirmation status
## Safety Checks
- ✅ Path security validation delegated to AI agent
- ✅ System directory protection enabled
- ✅ Action confirmation required before directory creation
- ✅ Recursive directory creation with permission handling
- ✅ Comprehensive error handling specified
## Context Information
- **Directory Path**: ${safeDirPath}
- **Operation**: Safe directory creation (recursive)
- **Security Level**: High (with path validation and access control)
- **Confirmation Required**: Yes (action confirmation pattern)
`;
return {
prompt,
instructions,
context: {
dirPath: safeDirPath,
operation: 'directory_creation',
securityLevel: 'high',
expectedFormat: 'json',
confirmationRequired: true,
recursive: true
}
};
}
catch (error) {
throw new FileSystemError(`Failed to generate directory creation prompt: ${error instanceof Error ? error.message : String(error)}`, { dirPath });
}
}
/**
* Generate prompt for AI-driven file writing with directory creation
*/
export async function writeFile(filePath, content) {
try {
console.error(`[DEBUG] Generating file write prompt for: ${filePath}`);
// Pure prompt-driven approach - delegate file writing to AI agent
const safeFilePath = filePath || '';
const safeContent = content || '';
const contentPreview = safeContent.length > 200 ? safeContent.substring(0, 200) + '...' : safeContent;
const prompt = `
# File Writing Request
Please write content to the file: **${safeFilePath}**
## Path Security Validation
The AI agent must:
1. **Validate file path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
2. **Resolve relative paths safely**: Handle relative paths from the current working directory
3. **Prevent unauthorized access**: Reject attempts to write to sensitive system files or directories
4. **Validate path format**: Check for valid file path format and reject malicious patterns
## Content Security Validation
The AI agent must:
1. **Content sanitization**: Validate content for security issues (no malicious scripts, etc.)
2. **Encoding validation**: Ensure content is properly encoded as UTF-8
3. **Size validation**: Check content size is reasonable
4. **Format validation**: Verify content format matches file extension expectations
## File Writing Requirements
1. **Directory Creation**: Ensure parent directory exists (create if needed)
2. **Safe File Writing**: Write content using appropriate file system tools
3. **Encoding Handling**: Write the file as UTF-8 text content
4. **Atomic Operations**: Use atomic write operations when possible
5. **Permission Handling**: Set appropriate file permissions
6. **Backup Consideration**: Consider backing up existing files if they exist
## Action Confirmation Required
Before writing any files, confirm the action with the user:
**Action**: Write file content
**Target**: ${safeFilePath}
**Content Size**: ${safeContent.length} characters
**Content Preview**: ${contentPreview}
**Type**: File creation/modification
**Impact**: Creates file and any missing parent directories
## Expected Output Format
\`\`\`json
{
"success": true,
"filePath": "${safeFilePath}",
"written": true,
"metadata": {
"type": "file",
"size": ${safeContent.length},
"encoding": "utf-8",
"permissions": "644",
"createdAt": "ISO_timestamp",
"directoryCreated": boolean
},
"security": {
"pathValidated": true,
"contentValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
},
"confirmation": {
"actionConfirmed": true,
"userApproved": true
}
}
\`\`\`
## Response Format for File Update
\`\`\`json
{
"success": true,
"filePath": "${safeFilePath}",
"written": true,
"metadata": {
"type": "file",
"size": ${safeContent.length},
"encoding": "utf-8",
"permissions": "644",
"updatedAt": "ISO_timestamp",
"previousSize": <previous_file_size>,
"directoryCreated": false
},
"security": {
"pathValidated": true,
"contentValidated": true,
"accessAuthorized": true,
"systemDirectoryCheck": "passed"
},
"confirmation": {
"actionConfirmed": true,
"userApproved": true
}
}
\`\`\`
## Error Response Format
\`\`\`json
{
"success": false,
"filePath": "${safeFilePath}",
"written": false,
"error": "detailed error message",
"errorType": "PERMISSION_DENIED|INVALID_PATH|SECURITY_VIOLATION|CONTENT_INVALID|DISK_FULL",
"security": {
"pathValidated": boolean,
"contentValidated": boolean,
"accessAuthorized": boolean,
"systemDirectoryCheck": "passed|failed",
"rejectionReason": "specific reason if access denied"
}
}
\`\`\`
`;
const instructions = `
## Implementation Steps
1. **Security Validation**:
- Validate the file path: ${safeFilePath}
- Ensure it's not a system directory or sensitive location
- Check for path traversal attempts (../, .\\, etc.)
- Validate content for security issues
2. **Action Confirmation**:
- Present the file writing action to the user for confirmation
- Include details about the file path and content preview
- Show content size and any directories that will be created
- Wait for user approval before proceeding
3. **Directory Preparation**:
- Extract directory path from file path: ${dirname(safeFilePath)}
- Ensure parent directory exists (create recursively if needed)
- Validate directory permissions
4. **File Writing**:
- Check if file already exists (for backup consideration)
- Write content to file using UTF-8 encoding
- Set appropriate file permissions (644 or system default)
- Use atomic write operations when possible
5. **Response Generation**:
- Format response according to the specified JSON structure
- Include comprehensive metadata and security validation results
- Provide detailed error information if writing fails
- Include confirmation status and directory creation details
## Safety Checks
- ✅ Path security validation delegated to AI agent
- ✅ Content security validation required
- ✅ System directory protection enabled
- ✅ Action confirmation required before file writing
- ✅ Directory creation with permission handling
- ✅ Comprehensive error handling specified
## Context Information
- **File Path**: ${safeFilePath}
- **Content Size**: ${safeContent.length} characters
- **Operation**: Safe file writing with directory creation
- **Security Level**: High (with path and content validation)
- **Confirmation Required**: Yes (action confirmation pattern)
`;
return {
prompt,
instructions,
context: {
filePath: safeFilePath,
contentSize: safeContent.length,
operation: 'file_write',
securityLevel: 'high',
expectedFormat: 'json',
confirmationRequired: true,
directoryCreation: true
}
};
}
catch (error) {
throw new FileSystemError(`Failed to generate file write prompt: ${error instanceof Error ? error.message : String(error)}`, { filePath });
}
}
/**
* Get file extension patterns for different file types
*/
export const FILE_PATTERNS = {
// Configuration files
config: [
'package.json',
'tsconfig.json',
'*.config.js',
'*.config.ts',
'.env*',
'Dockerfile',
'docker-compose.yml',
],
// Source code
typescript: ['**/*.ts', '**/*.tsx'],
javascript: ['**/*.js', '**/*.jsx'],
python: ['**/*.py'],
java: ['**/*.java'],
csharp: ['**/*.cs'],
go: ['**/*.go'],
rust: ['**/*.rs'],
// Documentation
documentation: ['**/*.md', '**/*.rst', '**/*.txt', '**/README*'],
// ADRs specifically
adrs: ['docs/adrs/**/*.md', 'adrs/**/*.md', 'decisions/**/*.md'],
// Build and deployment
build: ['Makefile', '*.mk', 'build.gradle', 'pom.xml', 'Cargo.toml'],
ci: [
'.github/workflows/**/*.yml',
'.github/workflows/**/*.yaml',
'.gitlab-ci.yml',
'azure-pipelines.yml',
],
};
//# sourceMappingURL=file-system.js.map