@light-merlin-dark/vssh
Version:
MCP-native SSH proxy for AI agents. CLI & MCP Server, plugin system, AI safety guards.
87 lines • 3.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DependencyChecker = void 0;
class DependencyChecker {
constructor(sshService, proxyService, isLocalExecution) {
this.sshService = sshService;
this.proxyService = proxyService;
this.isLocalExecution = isLocalExecution;
this.cache = new Map();
this.cacheTTL = 5 * 60 * 1000; // 5 minutes
}
async checkPluginDependencies(plugin) {
if (!plugin.runtimeDependencies || plugin.runtimeDependencies.length === 0) {
return [];
}
const results = await Promise.all(plugin.runtimeDependencies.map(dep => this.checkDependency(dep)));
return results;
}
async checkDependency(dependency) {
const cacheKey = `${dependency.command}-${this.isLocalExecution ? 'local' : 'remote'}`;
// Check cache
const cached = this.cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
return cached.result;
}
// Perform check
const result = await this.performCheck(dependency);
// Cache result
this.cache.set(cacheKey, {
result,
timestamp: Date.now()
});
return result;
}
async performCheck(dependency) {
try {
// Use the checkCommand if provided, otherwise default to 'which'
const checkCommand = dependency.checkCommand || `which ${dependency.command}`;
const output = await this.executeCommand(checkCommand);
// If command executed successfully and has output, dependency is available
const isAvailable = output.trim().length > 0;
return {
dependency,
isAvailable,
error: isAvailable ? undefined : this.getErrorMessage(dependency)
};
}
catch (error) {
return {
dependency,
isAvailable: false,
error: this.getErrorMessage(dependency)
};
}
}
async executeCommand(command) {
if (this.isLocalExecution) {
// Execute locally
return await this.sshService.executeCommand(command);
}
else {
// Execute on remote server via proxy
const result = await this.proxyService.executeCommand(command, { skipLogging: true });
return result.output;
}
}
getErrorMessage(dependency) {
const location = this.isLocalExecution ? 'locally' : 'on the server';
const baseMessage = `${dependency.displayName} is not installed ${location}.`;
if (dependency.installHint) {
return `${baseMessage} ${dependency.installHint}`;
}
return `${baseMessage} Please install ${dependency.displayName} to use this functionality.`;
}
clearCache() {
this.cache.clear();
}
assertAllDependenciesAvailable(results) {
const missing = results.filter(r => !r.isAvailable && !r.dependency.optional);
if (missing.length > 0) {
const errors = missing.map(r => `• ${r.error}`).join('\n');
throw new Error(`Missing required dependencies:\n${errors}`);
}
}
}
exports.DependencyChecker = DependencyChecker;
//# sourceMappingURL=dependency-checker.js.map