/**
* FILE HYGIENE MCP TOOLS
* Accessible through MCP for file system health monitoring
*/
const { spawn } = require('child_process');
const fs = require('fs').promises;
const path = require('path');
class FileHygieneTools {
constructor() {
this.name = 'FileHygieneTools';
this.inventoryPath = 'C:/tools/agent-agency-file-inventory.json';
this.dependencyPath = 'C:/tools/agent-agency-dependency-map.json';
}
/**
* MCP Tool: Check System Health
*/
async checkHealth() {
console.log('[MCP] Running health check...');
return new Promise((resolve, reject) => {
const process = spawn('python', [
'C:/tools/folder_hygiene_agent.py'
], {
input: '2\n' // Select health check option
});
let output = '';
process.stdout.on('data', (data) => {
output += data.toString();
});
process.on('close', (code) => {
if (code === 0) {
// Parse the health report
const report = {
status: output.includes('CRITICAL') ? 'CRITICAL' : 'OK',
brokenDependencies: this.extractNumber(output, 'broken dependencies'),
timestamp: new Date().toISOString(),
reportPath: 'C:/tools/health_report_' +
new Date().toISOString().split('T')[0].replace(/-/g, '') +
'.json'
};
resolve(report);
} else {
reject(new Error('Health check failed'));
}
});
});
}
/**
* MCP Tool: Start Monitoring
*/
async startMonitoring(interval = 60) {
console.log(`[MCP] Starting monitoring (${interval} min intervals)...`);
const process = spawn('python', [
'C:/tools/folder_hygiene_agent.py'
], {
detached: true,
stdio: ['pipe', 'pipe', 'pipe']
});
process.stdin.write('1\n'); // Select monitoring option
process.unref();
return {
status: 'started',
pid: process.pid,
interval: interval,
message: 'Hygiene monitoring started in background'
};
}
/**
* MCP Tool: Rebuild Inventory
*/
async rebuildInventory() {
console.log('[MCP] Rebuilding file inventory...');
return new Promise((resolve, reject) => {
const process = spawn('python', [
'C:/tools/build_inventory.py'
]);
process.on('close', (code) => {
if (code === 0) {
resolve({
status: 'complete',
inventoryPath: this.inventoryPath,
timestamp: new Date().toISOString()
});
} else {
reject(new Error('Inventory rebuild failed'));
}
});
});
}
/**
* MCP Tool: Remap Dependencies
*/
async remapDependencies() {
console.log('[MCP] Remapping dependencies...');
return new Promise((resolve, reject) => {
const process = spawn('python', [
'C:/tools/map_dependencies.py'
]);
process.on('close', (code) => {
if (code === 0) {
resolve({
status: 'complete',
dependencyPath: this.dependencyPath,
timestamp: new Date().toISOString()
});
} else {
reject(new Error('Dependency mapping failed'));
}
});
});
}
/**
* MCP Tool: Safe Reorganize (Dry Run)
*/
async testReorganization() {
console.log('[MCP] Testing safe reorganization...');
return new Promise((resolve, reject) => {
const process = spawn('python', [
'C:/tools/safe_reorganize.py'
]);
let output = '';
process.stdin.write('1\n'); // Select dry run
process.stdout.on('data', (data) => {
output += data.toString();
});
process.on('close', (code) => {
if (code === 0) {
const summary = {
safeToMove: this.extractNumber(output, 'Safe to move'),
riskyFiles: this.extractNumber(output, 'Risky files'),
unmovable: this.extractNumber(output, 'Unmovable'),
wouldMove: this.extractNumber(output, 'Files moved')
};
resolve(summary);
} else {
reject(new Error('Reorganization test failed'));
}
});
});
}
/**
* MCP Tool: Get Broken Dependencies
*/
async getBrokenDependencies() {
console.log('[MCP] Checking broken dependencies...');
try {
const alertFile = await fs.readFile(
'C:/tools/ALERT_BROKEN_DEPENDENCIES.txt',
'utf-8'
);
const lines = alertFile.split('\n');
const broken = [];
for (const line of lines) {
if (line.includes('File:')) {
const match = line.match(/File: (.+)/);
if (match) broken.push(match[1]);
}
}
return {
total: broken.length,
files: broken.slice(0, 20), // First 20
alertPath: 'C:/tools/ALERT_BROKEN_DEPENDENCIES.txt'
};
} catch (error) {
return {
total: 0,
files: [],
error: 'No alert file found'
};
}
}
/**
* MCP Tool: Get Inventory Summary
*/
async getInventorySummary() {
console.log('[MCP] Getting inventory summary...');
try {
const inventory = JSON.parse(
await fs.readFile(this.inventoryPath, 'utf-8')
);
const summary = {
totalFiles: inventory.totalFiles,
categories: {},
lastUpdated: inventory.metadata.created_at
};
// Count by category
for (const item of inventory.inventory) {
const cat = item.category;
summary.categories[cat] = (summary.categories[cat] || 0) + 1;
}
return summary;
} catch (error) {
throw new Error('Could not read inventory');
}
}
// Helper: Extract numbers from output
extractNumber(text, pattern) {
const match = text.match(new RegExp(pattern + '.*?(\\d+)', 'i'));
return match ? parseInt(match[1]) : 0;
}
}
// Export for MCP
module.exports = FileHygieneTools;