bc-code-intelligence-mcp
Version:
BC Code Intelligence MCP Server - Complete Specialist Bundle with AI-driven expert consultation, seamless handoffs, and context-preserving workflows
887 lines • 38.5 kB
JavaScript
/**
* Configuration Diagnostic Tools
*
* Tools for Chris Config to diagnose configuration and layer issues,
* particularly git authentication and Azure DevOps connectivity.
*/
import simpleGit from 'simple-git';
import { existsSync, accessSync, constants as fsConstants } from 'fs';
import { stat, readdir } from 'fs/promises';
import { join } from 'path';
export class ConfigDiagnosticTools {
layerService;
configLoader;
constructor(layerService, configLoader) {
this.layerService = layerService;
this.configLoader = configLoader;
}
getToolDefinitions() {
return [
{
name: 'diagnose_git_layer',
description: 'Diagnose git layer authentication and connectivity issues. Use this when git layers fail to load or Azure DevOps PAT authentication is not working.',
inputSchema: {
type: 'object',
properties: {
git_url: {
type: 'string',
description: 'Git repository URL to test (e.g., https://dev.azure.com/org/project/_git/repo)'
},
auth_type: {
type: 'string',
enum: ['token', 'basic', 'ssh'],
description: 'Authentication type being used'
},
token_env_var: {
type: 'string',
description: 'Environment variable name containing the PAT/token (if using token auth)'
},
branch: {
type: 'string',
description: 'Branch to test (defaults to main)',
default: 'main'
},
test_type: {
type: 'string',
enum: ['connectivity', 'authentication', 'clone', 'full'],
description: 'Type of diagnostic test to run',
default: 'full'
}
},
required: ['git_url', 'auth_type']
}
},
{
name: 'validate_layer_config',
description: 'Validate layer configuration before attempting to load. Checks paths, permissions, and configuration syntax.',
inputSchema: {
type: 'object',
properties: {
config_path: {
type: 'string',
description: 'Path to configuration file to validate'
},
check_type: {
type: 'string',
enum: ['syntax', 'paths', 'permissions', 'full'],
description: 'Type of validation to perform',
default: 'full'
}
},
required: ['config_path']
}
},
{
name: 'test_azure_devops_pat',
description: 'Test Azure DevOps Personal Access Token (PAT) validity and permissions. Helps diagnose PAT-related authentication failures.',
inputSchema: {
type: 'object',
properties: {
organization: {
type: 'string',
description: 'Azure DevOps organization name'
},
project: {
type: 'string',
description: 'Azure DevOps project name'
},
repository: {
type: 'string',
description: 'Repository name'
},
pat_env_var: {
type: 'string',
description: 'Environment variable containing the PAT'
}
},
required: ['organization', 'project', 'repository', 'pat_env_var']
}
},
{
name: 'get_layer_diagnostics',
description: 'Get detailed diagnostics for all configured layers including load status, errors, and performance metrics.',
inputSchema: {
type: 'object',
properties: {
layer_name: {
type: 'string',
description: 'Specific layer name to diagnose (optional - omit for all layers)'
},
include_metrics: {
type: 'boolean',
description: 'Include performance metrics',
default: true
}
},
required: []
}
},
{
name: 'diagnose_local_layer',
description: 'Diagnose local layer (project overrides) path and content issues. Use when local layers fail to load or have 0 topics.',
inputSchema: {
type: 'object',
properties: {
layer_path: {
type: 'string',
description: 'Path to local layer directory (e.g., ./bc-code-intel-overrides)',
default: './bc-code-intel-overrides'
}
},
required: []
}
},
{
name: 'reload_layers',
description: 'Reload layers after configuration changes without restarting MCP server. Useful for testing configuration changes.',
inputSchema: {
type: 'object',
properties: {
layer_name: {
type: 'string',
description: 'Specific layer to reload (optional - omit to reload all layers)'
},
reload_config: {
type: 'boolean',
description: 'Reload configuration file before reloading layers',
default: true
}
},
required: []
}
}
];
}
async handleToolCall(request) {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'diagnose_git_layer':
return await this.diagnoseGitLayer(args);
case 'validate_layer_config':
return await this.validateLayerConfig(args);
case 'test_azure_devops_pat':
return await this.testAzureDevOpsPAT(args);
case 'get_layer_diagnostics':
return await this.getLayerDiagnostics(args);
case 'diagnose_local_layer':
return await this.diagnoseLocalLayer(args);
case 'reload_layers':
return await this.reloadLayers(args);
default:
return {
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
isError: true
};
}
}
catch (error) {
return {
content: [{
type: 'text',
text: `Error executing ${name}: ${error instanceof Error ? error.message : String(error)}`
}],
isError: true
};
}
}
async diagnoseGitLayer(args) {
const { git_url, auth_type, token_env_var, branch = 'main', test_type = 'full' } = args;
const diagnostics = {
timestamp: new Date().toISOString(),
url: git_url,
auth_type,
tests: []
};
// Test 1: URL Format Validation
if (test_type === 'connectivity' || test_type === 'full') {
const urlTest = this.validateGitUrl(git_url);
diagnostics.tests.push(urlTest);
}
// Test 2: Authentication Configuration
if (test_type === 'authentication' || test_type === 'full') {
const authTest = await this.testAuthConfiguration(git_url, auth_type, token_env_var);
diagnostics.tests.push(authTest);
}
// Test 3: Network Connectivity (if full test)
if (test_type === 'connectivity' || test_type === 'full') {
const connectivityTest = await this.testGitConnectivity(git_url, auth_type, token_env_var);
diagnostics.tests.push(connectivityTest);
}
// Test 4: Clone Test (if full or clone test)
if (test_type === 'clone' || test_type === 'full') {
const cloneTest = await this.testGitClone(git_url, auth_type, token_env_var, branch);
diagnostics.tests.push(cloneTest);
}
// Generate recommendations based on failures
const recommendations = this.generateRecommendations(diagnostics.tests, auth_type);
return {
content: [{
type: 'text',
text: JSON.stringify({
...diagnostics,
summary: this.generateDiagnosticSummary(diagnostics.tests),
recommendations
}, null, 2)
}]
};
}
validateGitUrl(url) {
const test = {
name: 'URL Format Validation',
passed: false,
details: {}
};
// Check URL format
try {
const urlObj = new URL(url);
test.details.protocol = urlObj.protocol;
test.details.hostname = urlObj.hostname;
test.details.pathname = urlObj.pathname;
// Azure DevOps specific validation
if (url.includes('dev.azure.com') || url.includes('visualstudio.com')) {
test.details.provider = 'Azure DevOps';
// Parse Azure DevOps URL components
const azureMatch = url.match(/dev\.azure\.com\/([^\/]+)\/([^\/]+)\/_git\/(.+?)(?:\.git)?$/);
if (azureMatch) {
test.details.organization = azureMatch[1];
test.details.project = azureMatch[2];
test.details.repository = azureMatch[3];
test.passed = true;
test.details.message = 'Valid Azure DevOps URL format';
}
else {
test.details.message = 'Invalid Azure DevOps URL format. Expected: https://dev.azure.com/{org}/{project}/_git/{repo}';
test.details.recommendation = 'Verify your Azure DevOps repository URL format';
}
}
else if (url.includes('github.com')) {
test.details.provider = 'GitHub';
test.passed = true;
}
else if (url.includes('gitlab.com')) {
test.details.provider = 'GitLab';
test.passed = true;
}
else {
test.details.provider = 'Unknown';
test.passed = true; // Generic git URL
}
}
catch (error) {
test.details.message = `Invalid URL: ${error instanceof Error ? error.message : String(error)}`;
test.details.recommendation = 'Provide a valid HTTP(S) or SSH URL';
}
return test;
}
async testAuthConfiguration(url, authType, tokenEnvVar) {
const test = {
name: 'Authentication Configuration',
passed: false,
details: {}
};
test.details.auth_type = authType;
if (authType === 'token') {
if (!tokenEnvVar) {
test.details.message = 'Token environment variable not specified';
test.details.recommendation = 'Specify token_env_var parameter';
return test;
}
test.details.token_env_var = tokenEnvVar;
const tokenValue = process.env[tokenEnvVar];
if (!tokenValue) {
test.details.message = `Environment variable ${tokenEnvVar} not set or empty`;
test.details.recommendation = `Set ${tokenEnvVar} environment variable with your PAT`;
test.details.check_instructions = [
`Run: echo $env:${tokenEnvVar} (PowerShell) or echo $${tokenEnvVar} (Bash)`,
'Verify the PAT is not expired',
'Ensure the PAT has "Code (Read)" permission for Azure DevOps'
];
return test;
}
test.details.token_length = tokenValue.length;
test.details.token_prefix = tokenValue.substring(0, 4) + '...';
// Azure DevOps PAT validation
if (url.includes('dev.azure.com')) {
// Azure DevOps PATs are typically 52 characters
if (tokenValue.length === 52) {
test.passed = true;
test.details.message = 'PAT format appears valid for Azure DevOps';
}
else {
test.details.message = `PAT length (${tokenValue.length}) unusual for Azure DevOps (expected 52 characters)`;
test.details.recommendation = 'Verify this is a valid Azure DevOps Personal Access Token';
}
}
else {
test.passed = true;
test.details.message = 'Token configuration present';
}
}
else if (authType === 'ssh') {
test.details.message = 'SSH authentication configured';
test.passed = true;
}
else {
test.details.message = `Unsupported auth type: ${authType}`;
test.details.recommendation = 'Use "token", "basic", or "ssh" for auth_type';
}
return test;
}
async testGitConnectivity(url, authType, tokenEnvVar) {
const test = {
name: 'Git Connectivity Test',
passed: false,
details: {}
};
try {
const git = simpleGit();
// Prepare URL with auth for ls-remote test
let testUrl = url;
if (authType === 'token' && tokenEnvVar) {
const token = process.env[tokenEnvVar];
if (token && testUrl.startsWith('https://')) {
// For Azure DevOps, use empty username with PAT
testUrl = testUrl.replace('https://', `https://:${token}@`);
}
}
// Try ls-remote to test connectivity without cloning
const result = await git.listRemote(['--heads', testUrl]);
test.passed = true;
test.details.message = 'Successfully connected to repository';
test.details.branches_found = result.split('\n').filter(Boolean).length;
}
catch (error) {
test.details.message = 'Failed to connect to repository';
test.details.error = error.message;
// Parse common error scenarios
if (error.message.includes('Authentication failed') || error.message.includes('403')) {
test.details.issue = 'Authentication failure';
test.details.recommendation = 'Verify PAT is valid and has Code (Read) permission';
}
else if (error.message.includes('Could not resolve host')) {
test.details.issue = 'Network/DNS issue';
test.details.recommendation = 'Check network connection and URL hostname';
}
else if (error.message.includes('Repository not found') || error.message.includes('404')) {
test.details.issue = 'Repository not found';
test.details.recommendation = 'Verify repository URL and access permissions';
}
else {
test.details.issue = 'Unknown error';
test.details.recommendation = 'Check error message for details';
}
}
return test;
}
async testGitClone(url, authType, tokenEnvVar, branch) {
const test = {
name: 'Git Clone Test',
passed: false,
details: {}
};
const tempDir = join(process.cwd(), '.bckb-diagnostic-temp', Date.now().toString());
try {
const git = simpleGit();
// Prepare URL with auth
let cloneUrl = url;
if (authType === 'token' && tokenEnvVar) {
const token = process.env[tokenEnvVar];
if (token && cloneUrl.startsWith('https://')) {
// For Azure DevOps, use empty username with PAT as password
cloneUrl = cloneUrl.replace('https://', `https://:${token}@`);
}
}
test.details.clone_url_format = cloneUrl.replace(/:([^@]+)@/, ':***@'); // Mask token in output
await git.clone(cloneUrl, tempDir, [
'--depth', '1',
'--single-branch',
'--branch', branch
]);
test.passed = true;
test.details.message = `Successfully cloned repository (branch: ${branch})`;
test.details.temp_location = tempDir;
}
catch (error) {
test.details.message = 'Clone failed';
test.details.error = error.message;
// Detailed error analysis
if (error.message.includes('authentication failed') || error.message.includes('invalid credentials')) {
test.details.issue = 'Authentication failed during clone';
test.details.recommendation = [
'Verify PAT is valid and not expired',
'Ensure PAT has "Code (Read)" scope in Azure DevOps',
'Check that the PAT belongs to a user with repository access',
'Try regenerating the PAT in Azure DevOps'
];
}
else if (error.message.includes(`Couldn't find remote ref ${branch}`)) {
test.details.issue = `Branch '${branch}' not found`;
test.details.recommendation = `Verify branch name - try 'main' or 'master'`;
}
else {
test.details.issue = 'Clone operation failed';
test.details.recommendation = 'Review error message for specific cause';
}
}
return test;
}
generateDiagnosticSummary(tests) {
const passed = tests.filter(t => t.passed).length;
const failed = tests.filter(t => !t.passed).length;
return {
total_tests: tests.length,
passed,
failed,
overall_status: failed === 0 ? 'PASS' : 'FAIL',
failed_tests: tests.filter(t => !t.passed).map(t => t.name)
};
}
generateRecommendations(tests, authType) {
const recommendations = [];
const failedTests = tests.filter(t => !t.passed);
if (failedTests.length === 0) {
return ['All tests passed! Git layer should work with this configuration.'];
}
// URL format issues
if (failedTests.some(t => t.name === 'URL Format Validation')) {
recommendations.push('Fix the repository URL format before proceeding');
}
// Auth configuration issues
if (failedTests.some(t => t.name === 'Authentication Configuration')) {
recommendations.push('Configure authentication properly (set environment variable with valid PAT)');
if (authType === 'token') {
recommendations.push('For Azure DevOps: Create a PAT with "Code (Read)" scope at https://dev.azure.com/{org}/_usersSettings/tokens');
}
}
// Connectivity issues
if (failedTests.some(t => t.name === 'Git Connectivity Test')) {
recommendations.push('Test network connectivity and verify repository URL');
recommendations.push('Ensure firewall/proxy allows git protocol access');
}
// Clone issues
if (failedTests.some(t => t.name === 'Git Clone Test')) {
recommendations.push('Review clone test error details for specific issue');
recommendations.push('Verify PAT permissions include repository access');
}
return recommendations;
}
async testAzureDevOpsPAT(args) {
const { organization, project, repository, pat_env_var } = args;
const url = `https://dev.azure.com/${organization}/${project}/_git/${repository}`;
// Reuse git layer diagnostics
return this.diagnoseGitLayer({
git_url: url,
auth_type: 'token',
token_env_var: pat_env_var,
test_type: 'full'
});
}
async validateLayerConfig(args) {
const { config_path, check_type = 'full' } = args;
// TODO: Implement config validation
return {
content: [{
type: 'text',
text: JSON.stringify({
message: 'Configuration validation not yet implemented',
config_path,
check_type
}, null, 2)
}]
};
}
async getLayerDiagnostics(args) {
const { layer_name, include_metrics = true } = args;
const diagnostics = {
timestamp: new Date().toISOString(),
layers: []
};
const stats = this.layerService.getStatistics();
for (const layerStat of stats) {
if (layer_name && layerStat.name !== layer_name) {
continue;
}
const layerDiag = {
name: layerStat.name,
priority: layerStat.priority,
enabled: layerStat.enabled,
topic_count: layerStat.topicCount,
index_count: layerStat.indexCount,
load_status: layerStat.topicCount > 0 ? 'SUCCESS' : 'EMPTY_OR_FAILED'
};
if (include_metrics) {
layerDiag.metrics = {
load_time_ms: layerStat.loadTimeMs || 0,
memory_usage: layerStat.memoryUsage
};
}
diagnostics.layers.push(layerDiag);
}
if (diagnostics.layers.length === 0 && layer_name) {
return {
content: [{
type: 'text',
text: `Layer '${layer_name}' not found. Available layers: ${stats.map(s => s.name).join(', ')}`
}],
isError: true
};
}
return {
content: [{
type: 'text',
text: JSON.stringify(diagnostics, null, 2)
}]
};
}
async diagnoseLocalLayer(args) {
const { layer_path = './bc-code-intel-overrides' } = args;
const diagnostics = {
timestamp: new Date().toISOString(),
layer_path,
tests: []
};
// Test 1: Path Existence
const pathTest = {
name: 'Path Existence Check',
passed: false,
details: {}
};
pathTest.details.absolute_path = join(process.cwd(), layer_path);
pathTest.details.exists = existsSync(pathTest.details.absolute_path);
if (pathTest.details.exists) {
pathTest.passed = true;
pathTest.details.message = 'Directory exists';
}
else {
pathTest.details.message = 'Directory does not exist';
pathTest.details.recommendation = `Create directory: mkdir ${layer_path}`;
}
diagnostics.tests.push(pathTest);
// Test 2: Permissions Check
if (pathTest.details.exists) {
const permTest = {
name: 'Path Permissions Check',
passed: false,
details: {}
};
try {
accessSync(pathTest.details.absolute_path, fsConstants.R_OK);
permTest.details.readable = true;
}
catch {
permTest.details.readable = false;
}
try {
accessSync(pathTest.details.absolute_path, fsConstants.W_OK);
permTest.details.writable = true;
}
catch {
permTest.details.writable = false;
}
if (permTest.details.readable) {
permTest.passed = true;
permTest.details.message = 'Directory is accessible';
}
else {
permTest.details.message = 'Directory is not readable';
permTest.details.recommendation = 'Check file permissions on the directory';
}
diagnostics.tests.push(permTest);
}
// Test 3: Content Discovery
if (pathTest.details.exists) {
const contentTest = {
name: 'Content Discovery',
passed: false,
details: {}
};
try {
const files = await readdir(pathTest.details.absolute_path);
contentTest.details.total_files = files.length;
// Check for markdown files
const mdFiles = files.filter(f => f.endsWith('.md'));
contentTest.details.markdown_files = mdFiles.length;
// Check for expected directories
const expectedDirs = ['domains', 'topics', 'overrides', 'specialists'];
const foundDirs = files.filter(f => expectedDirs.includes(f));
contentTest.details.expected_directories_found = foundDirs;
// Recursively count markdown files
let totalMdFiles = mdFiles.length;
for (const item of files) {
const itemPath = join(pathTest.details.absolute_path, item);
try {
const stats = await stat(itemPath);
if (stats.isDirectory()) {
const subFiles = await this.countMarkdownFiles(itemPath);
totalMdFiles += subFiles;
}
}
catch {
// Skip inaccessible items
}
}
contentTest.details.total_markdown_files = totalMdFiles;
if (totalMdFiles > 0) {
contentTest.passed = true;
contentTest.details.message = `Found ${totalMdFiles} markdown file(s)`;
}
else {
contentTest.details.message = 'No markdown files found';
contentTest.details.recommendation = 'Add .md files to the directory or subdirectories (domains/, topics/, overrides/)';
contentTest.details.example_structure = [
`${layer_path}/domains/performance/my-optimization.md`,
`${layer_path}/topics/company-specific-pattern.md`,
`${layer_path}/overrides/existing-topic-override.md`
];
}
}
catch (error) {
contentTest.details.message = 'Failed to read directory contents';
contentTest.details.error = error.message;
}
diagnostics.tests.push(contentTest);
}
// Test 4: Markdown File Validation (sample)
if (pathTest.details.exists) {
const validationTest = {
name: 'Markdown File Validation',
passed: false,
details: {}
};
try {
const sampleMdFiles = await this.findSampleMarkdownFiles(pathTest.details.absolute_path, 3);
validationTest.details.files_checked = sampleMdFiles.length;
if (sampleMdFiles.length > 0) {
const validFiles = [];
const invalidFiles = [];
for (const file of sampleMdFiles) {
const isValid = await this.validateMarkdownFile(file);
if (isValid) {
validFiles.push(file);
}
else {
invalidFiles.push(file);
}
}
validationTest.details.valid_files = validFiles.length;
validationTest.details.invalid_files = invalidFiles.length;
if (validFiles.length > 0) {
validationTest.passed = true;
validationTest.details.message = `${validFiles.length} of ${sampleMdFiles.length} files have valid frontmatter`;
}
else {
validationTest.details.message = 'No valid markdown files with frontmatter found';
validationTest.details.recommendation = 'Ensure markdown files have YAML frontmatter with title, domain, etc.';
}
if (invalidFiles.length > 0) {
validationTest.details.invalid_file_examples = invalidFiles.slice(0, 2);
validationTest.details.issue = 'Some files missing or have invalid YAML frontmatter';
}
}
}
catch (error) {
validationTest.details.message = 'Failed to validate markdown files';
validationTest.details.error = error.message;
}
diagnostics.tests.push(validationTest);
}
// Generate recommendations
const recommendations = this.generateLocalLayerRecommendations(diagnostics.tests);
return {
content: [{
type: 'text',
text: JSON.stringify({
...diagnostics,
summary: this.generateDiagnosticSummary(diagnostics.tests),
recommendations
}, null, 2)
}]
};
}
async countMarkdownFiles(dir) {
let count = 0;
try {
const files = await readdir(dir);
for (const file of files) {
const filePath = join(dir, file);
try {
const stats = await stat(filePath);
if (stats.isDirectory()) {
count += await this.countMarkdownFiles(filePath);
}
else if (file.endsWith('.md')) {
count++;
}
}
catch {
// Skip inaccessible files
}
}
}
catch {
// Skip inaccessible directories
}
return count;
}
async findSampleMarkdownFiles(dir, limit) {
const files = [];
const findInDir = async (currentDir) => {
if (files.length >= limit)
return;
try {
const items = await readdir(currentDir);
for (const item of items) {
if (files.length >= limit)
break;
const itemPath = join(currentDir, item);
try {
const stats = await stat(itemPath);
if (stats.isDirectory()) {
await findInDir(itemPath);
}
else if (item.endsWith('.md')) {
files.push(itemPath);
}
}
catch {
// Skip inaccessible items
}
}
}
catch {
// Skip inaccessible directories
}
};
await findInDir(dir);
return files;
}
async validateMarkdownFile(filePath) {
try {
const { readFile } = await import('fs/promises');
const content = await readFile(filePath, 'utf-8');
// Check for YAML frontmatter
const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
if (!frontmatterMatch) {
return false;
}
// Basic validation - has some required fields
const frontmatter = frontmatterMatch[1];
return frontmatter.includes('title:') || frontmatter.includes('domain:');
}
catch {
return false;
}
}
generateLocalLayerRecommendations(tests) {
const recommendations = [];
const failedTests = tests.filter(t => !t.passed);
if (failedTests.length === 0) {
return ['All local layer checks passed! Layer should be loading correctly.'];
}
// Path doesn't exist
if (failedTests.some(t => t.name === 'Path Existence Check')) {
recommendations.push('Create the local layer directory before adding content');
recommendations.push('Use: mkdir -p ./bc-code-intel-overrides/domains');
}
// Permission issues
if (failedTests.some(t => t.name === 'Path Permissions Check')) {
recommendations.push('Fix directory permissions to allow read access');
recommendations.push('Check ownership and group permissions');
}
// No content
if (failedTests.some(t => t.name === 'Content Discovery')) {
recommendations.push('Add markdown files with BC knowledge to the directory');
recommendations.push('Organize in subdirectories: domains/, topics/, or overrides/');
recommendations.push('Each .md file should have YAML frontmatter with title, domain, tags, etc.');
}
// Invalid files
if (failedTests.some(t => t.name === 'Markdown File Validation')) {
recommendations.push('Ensure markdown files have proper YAML frontmatter (---...---)');
recommendations.push('Required frontmatter fields: title, domain');
recommendations.push('See embedded knowledge files for examples');
}
return recommendations;
}
async reloadLayers(args) {
const { layer_name, reload_config = true } = args;
const results = {
timestamp: new Date().toISOString(),
config_reloaded: false,
layers_reloaded: [],
errors: []
};
try {
// Step 1: Reload configuration if requested
if (reload_config && this.configLoader) {
try {
const configResult = await this.configLoader.loadConfiguration();
results.config_reloaded = true;
if (configResult.validation_errors.length > 0) {
results.errors.push(`Configuration has ${configResult.validation_errors.length} validation errors`);
for (const error of configResult.validation_errors) {
results.errors.push(` ${error.field}: ${error.message}`);
}
}
}
catch (error) {
results.errors.push(`Failed to reload configuration: ${error.message}`);
results.config_reloaded = false;
}
}
// Step 2: Refresh layer cache
try {
await this.layerService.refreshCache();
// Get updated layer statistics
const stats = this.layerService.getStatistics();
for (const stat of stats) {
if (layer_name && stat.name !== layer_name) {
continue;
}
results.layers_reloaded.push({
name: stat.name,
priority: stat.priority,
topic_count: stat.topicCount,
index_count: stat.indexCount,
load_time_ms: stat.loadTimeMs || 0,
status: stat.topicCount > 0 ? 'SUCCESS' : 'EMPTY_OR_FAILED'
});
}
if (layer_name && results.layers_reloaded.length === 0) {
results.errors.push(`Layer '${layer_name}' not found`);
}
}
catch (error) {
results.errors.push(`Failed to reload layers: ${error.message}`);
}
const success = results.errors.length === 0;
const message = success
? `Successfully reloaded ${results.layers_reloaded.length} layer(s)`
: `Reload completed with ${results.errors.length} error(s)`;
return {
content: [{
type: 'text',
text: JSON.stringify({
...results,
success,
message
}, null, 2)
}],
isError: !success
};
}
catch (error) {
return {
content: [{
type: 'text',
text: JSON.stringify({
error: `Fatal error during reload: ${error.message}`,
results
}, null, 2)
}],
isError: true
};
}
}
}
//# sourceMappingURL=config-diagnostic-tools.js.map