@iservu-inc/adf-cli 0.13.0 ā 0.14.1
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/.context/memory/architecture.md +40 -0
- package/.context/memory/glossary.md +19 -0
- package/.project/docs/VERSIONING-GUIDE.md +127 -0
- package/AGENTS.md +53 -0
- package/CHANGELOG.md +57 -0
- package/README.md +12 -2
- package/bin/adf.js +10 -0
- package/conductor/archive/context_synthesis_20260112/metadata.json +8 -0
- package/conductor/archive/context_synthesis_20260112/plan.md +40 -0
- package/conductor/archive/context_synthesis_20260112/spec.md +43 -0
- package/conductor/archive/verify_opencode_20260111/metadata.json +8 -0
- package/conductor/archive/verify_opencode_20260111/plan.md +34 -0
- package/conductor/archive/verify_opencode_20260111/spec.md +25 -0
- package/conductor/code_styleguides/javascript.md +51 -0
- package/conductor/product-guidelines.md +26 -0
- package/conductor/product.md +25 -0
- package/conductor/setup_state.json +1 -0
- package/conductor/tech-stack.md +28 -0
- package/conductor/tracks/bootstrap_agents_20260111/metadata.json +8 -0
- package/conductor/tracks/bootstrap_agents_20260111/plan.md +17 -0
- package/conductor/tracks/bootstrap_agents_20260111/spec.md +27 -0
- package/conductor/tracks.md +9 -0
- package/conductor/workflow.md +333 -0
- package/lib/analysis/ai-gap-analyzer.js +66 -0
- package/lib/analysis/dynamic-question-generator.js +55 -0
- package/lib/analysis/heuristic-gap-analyzer.js +45 -0
- package/lib/analysis/synthesis-engine.js +142 -0
- package/lib/commands/deploy.js +28 -2
- package/lib/commands/init.js +94 -0
- package/lib/commands/tools.js +38 -0
- package/lib/frameworks/interviewer.js +4 -3
- package/lib/generators/codex-cli-generator.js +41 -0
- package/lib/generators/index.js +33 -0
- package/lib/generators/kiro-generator.js +49 -0
- package/lib/generators/opencode-generator.js +332 -313
- package/lib/generators/trae-generator.js +34 -0
- package/lib/templates/scripts/analyze-framework-updates.js +361 -0
- package/lib/templates/scripts/build.js +608 -0
- package/lib/templates/scripts/check-framework-updates.js +118 -0
- package/lib/templates/scripts/config-helpers.js +1 -1
- package/lib/templates/scripts/deploy.js +13 -28
- package/lib/templates/scripts/init.js +110 -220
- package/lib/templates/scripts/postinstall.js +13 -0
- package/lib/templates/scripts/update-frameworks.js +28 -0
- package/lib/templates/scripts/validate-env.js +428 -0
- package/lib/templates/scripts/validate-mcp.js +471 -0
- package/lib/templates/scripts/validate.js +482 -0
- package/lib/templates/shared/agents/analyst.md +1 -1
- package/lib/templates/shared/agents/architect.md +13 -17
- package/lib/templates/shared/agents/dev.md +2 -2
- package/lib/templates/shared/agents/pm.md +1 -1
- package/lib/templates/shared/agents/qa.md +1 -1
- package/lib/templates/shared/agents/sm.md +2 -2
- package/lib/templates/shared/templates/README.md +2 -2
- package/lib/templates/shared/templates/openspec-proposal.md +2 -2
- package/lib/templates/shared/templates/prd-template.md +1 -1
- package/lib/templates/shared/templates/story-template.md +1 -1
- package/lib/utils/context-extractor.js +157 -0
- package/lib/utils/framework-detector.js +54 -0
- package/lib/utils/tool-feature-registry.js +102 -0
- package/package.json +1 -1
- package/tests/ai-gap-analyzer.test.js +38 -0
- package/tests/codex-cli-generator.test.js +29 -0
- package/tests/context-extractor.test.js +70 -0
- package/tests/deploy-integration.test.js +36 -0
- package/tests/deploy.test.js +57 -0
- package/tests/dynamic-question-generator.test.js +29 -0
- package/tests/framework-detector.test.js +55 -0
- package/tests/heuristic-gap-analyzer.test.js +46 -0
- package/tests/kiro-trae-generators.test.js +43 -0
- package/tests/opencode-generator.test.js +113 -0
- package/tests/synthesis-engine.test.js +52 -0
- package/tests/tool-feature-registry.test.js +23 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AgentDevFramework MCP Configuration Validator
|
|
5
|
+
* Validates MCP server configuration and connectivity
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs-extra');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const chalk = require('chalk');
|
|
11
|
+
const ora = require('ora');
|
|
12
|
+
const dotenv = require('dotenv');
|
|
13
|
+
|
|
14
|
+
const FRAMEWORK_ROOT = path.join(__dirname, '..');
|
|
15
|
+
const ENV_FILE = path.join(FRAMEWORK_ROOT, '.env');
|
|
16
|
+
const MCP_CONFIG = path.join(FRAMEWORK_ROOT, 'shared', 'mcp', 'mcp-config.json');
|
|
17
|
+
|
|
18
|
+
// MCP server requirements
|
|
19
|
+
const MCP_SERVERS = {
|
|
20
|
+
'context7': {
|
|
21
|
+
type: 'http',
|
|
22
|
+
required: false,
|
|
23
|
+
envVars: ['CONTEXT7_API_KEY'],
|
|
24
|
+
description: 'Current framework documentation retrieval',
|
|
25
|
+
url: 'https://context7.com'
|
|
26
|
+
},
|
|
27
|
+
'brave-search': {
|
|
28
|
+
type: 'command',
|
|
29
|
+
required: true,
|
|
30
|
+
envVars: ['BRAVE_API_KEY'],
|
|
31
|
+
description: 'Web search for latest information',
|
|
32
|
+
url: 'https://brave.com/search/api/',
|
|
33
|
+
freeTier: '2,000 queries/month'
|
|
34
|
+
},
|
|
35
|
+
'mem0': {
|
|
36
|
+
type: 'command',
|
|
37
|
+
required: true,
|
|
38
|
+
envVars: ['SMITHERY_KEY', 'SMITHERY_PROFILE', 'OPENAI_API_KEY'],
|
|
39
|
+
description: 'Persistent memory across sessions',
|
|
40
|
+
url: 'https://smithery.ai'
|
|
41
|
+
},
|
|
42
|
+
'clear-thought': {
|
|
43
|
+
type: 'command',
|
|
44
|
+
required: true,
|
|
45
|
+
envVars: ['SMITHERY_KEY', 'OPENAI_API_KEY'],
|
|
46
|
+
description: 'Structured reasoning for complex problems',
|
|
47
|
+
url: 'https://smithery.ai'
|
|
48
|
+
},
|
|
49
|
+
'archon': {
|
|
50
|
+
type: 'http',
|
|
51
|
+
required: false,
|
|
52
|
+
envVars: ['ARCHON_URL', 'SUPABASE_URL', 'SUPABASE_SERVICE_ROLE_KEY', 'OPENAI_API_KEY'],
|
|
53
|
+
description: 'Project knowledge management and task tracking',
|
|
54
|
+
url: 'https://github.com/archon-ai/archon'
|
|
55
|
+
},
|
|
56
|
+
'openmemory': {
|
|
57
|
+
type: 'command',
|
|
58
|
+
required: false,
|
|
59
|
+
envVars: ['OPENMEMORY_API_KEY', 'CLIENT_NAME'],
|
|
60
|
+
description: 'Alternative persistent memory system',
|
|
61
|
+
url: 'https://openmemory.ai',
|
|
62
|
+
note: 'Alternative to mem0 - choose one based on preference'
|
|
63
|
+
},
|
|
64
|
+
'deepwiki': {
|
|
65
|
+
type: 'http',
|
|
66
|
+
required: true,
|
|
67
|
+
envVars: [],
|
|
68
|
+
description: 'GitHub repository documentation and analysis',
|
|
69
|
+
note: 'No API key required'
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
class MCPValidator {
|
|
74
|
+
constructor() {
|
|
75
|
+
this.errors = [];
|
|
76
|
+
this.warnings = [];
|
|
77
|
+
this.passed = 0;
|
|
78
|
+
this.failed = 0;
|
|
79
|
+
this.env = {};
|
|
80
|
+
this.mcpConfig = null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
log(message, type = 'info') {
|
|
84
|
+
const symbols = {
|
|
85
|
+
success: chalk.green('ā'),
|
|
86
|
+
error: chalk.red('ā'),
|
|
87
|
+
warning: chalk.yellow('ā '),
|
|
88
|
+
info: chalk.blue('ā¹')
|
|
89
|
+
};
|
|
90
|
+
console.log(`${symbols[type]} ${message}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
addError(message) {
|
|
94
|
+
this.errors.push(message);
|
|
95
|
+
this.failed++;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
addWarning(message) {
|
|
99
|
+
this.warnings.push(message);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
loadEnvFile() {
|
|
103
|
+
try {
|
|
104
|
+
if (fs.existsSync(ENV_FILE)) {
|
|
105
|
+
const result = dotenv.config({ path: ENV_FILE });
|
|
106
|
+
this.env = result.parsed || {};
|
|
107
|
+
// Also merge process.env
|
|
108
|
+
Object.keys(process.env).forEach(key => {
|
|
109
|
+
if (!this.env[key]) {
|
|
110
|
+
this.env[key] = process.env[key];
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
this.log('Loaded environment variables', 'success');
|
|
114
|
+
this.passed++;
|
|
115
|
+
return true;
|
|
116
|
+
} else {
|
|
117
|
+
this.addError('.env file not found - run validate:env first');
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
} catch (error) {
|
|
121
|
+
this.addError(`Failed to load .env: ${error.message}`);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
checkMCPConfigExists() {
|
|
127
|
+
if (fs.existsSync(MCP_CONFIG)) {
|
|
128
|
+
this.log('MCP configuration file found', 'success');
|
|
129
|
+
this.passed++;
|
|
130
|
+
return true;
|
|
131
|
+
} else {
|
|
132
|
+
this.addError('MCP configuration file not found: shared/mcp/mcp-config.json');
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
loadMCPConfig() {
|
|
138
|
+
try {
|
|
139
|
+
const configContent = fs.readFileSync(MCP_CONFIG, 'utf-8');
|
|
140
|
+
this.mcpConfig = JSON.parse(configContent);
|
|
141
|
+
|
|
142
|
+
if (!this.mcpConfig.mcpServers) {
|
|
143
|
+
this.addError('MCP config missing "mcpServers" section');
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.log(`Loaded MCP configuration with ${Object.keys(this.mcpConfig.mcpServers).length} servers`, 'success');
|
|
148
|
+
this.passed++;
|
|
149
|
+
return true;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
this.addError(`Failed to parse MCP config: ${error.message}`);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
replaceEnvVars(value) {
|
|
157
|
+
if (typeof value !== 'string') return value;
|
|
158
|
+
|
|
159
|
+
return value.replace(/\$\{([^}]+)\}/g, (match, envVar) => {
|
|
160
|
+
return this.env[envVar] || match;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
validateServerConfig(serverName, config) {
|
|
165
|
+
const requirements = MCP_SERVERS[serverName];
|
|
166
|
+
|
|
167
|
+
if (!requirements) {
|
|
168
|
+
this.addWarning(`Unknown MCP server: ${serverName}`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.log(chalk.bold(`\n ${serverName}:`));
|
|
173
|
+
console.log(chalk.gray(` ${requirements.description}`));
|
|
174
|
+
|
|
175
|
+
// Check type
|
|
176
|
+
if (config.type && config.type !== requirements.type) {
|
|
177
|
+
this.addWarning(`${serverName}: Expected type "${requirements.type}", found "${config.type}"`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Check required environment variables
|
|
181
|
+
const missingVars = [];
|
|
182
|
+
requirements.envVars.forEach(envVar => {
|
|
183
|
+
const value = this.env[envVar];
|
|
184
|
+
if (!value || value.trim() === '') {
|
|
185
|
+
missingVars.push(envVar);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (missingVars.length > 0) {
|
|
190
|
+
if (requirements.required) {
|
|
191
|
+
this.addError(`${serverName}: Missing required environment variables: ${missingVars.join(', ')}`);
|
|
192
|
+
console.log(chalk.red(` ā Missing: ${missingVars.join(', ')}`));
|
|
193
|
+
if (requirements.url) {
|
|
194
|
+
console.log(chalk.cyan(` Setup: ${requirements.url}`));
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
this.addWarning(`${serverName}: Missing optional environment variables: ${missingVars.join(', ')}`);
|
|
198
|
+
console.log(chalk.yellow(` ā Missing: ${missingVars.join(', ')}`));
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
this.log(`${serverName}: Configuration valid`, 'success');
|
|
202
|
+
this.passed++;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Display notes
|
|
206
|
+
if (requirements.note) {
|
|
207
|
+
console.log(chalk.gray(` Note: ${requirements.note}`));
|
|
208
|
+
}
|
|
209
|
+
if (requirements.freeTier) {
|
|
210
|
+
console.log(chalk.gray(` Free tier: ${requirements.freeTier}`));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
validateAllServers() {
|
|
215
|
+
console.log(chalk.bold('\nš Validating MCP Servers...'));
|
|
216
|
+
|
|
217
|
+
const configuredServers = Object.keys(this.mcpConfig.mcpServers);
|
|
218
|
+
const expectedServers = Object.keys(MCP_SERVERS);
|
|
219
|
+
|
|
220
|
+
// Check each expected server
|
|
221
|
+
expectedServers.forEach(serverName => {
|
|
222
|
+
if (configuredServers.includes(serverName)) {
|
|
223
|
+
const config = this.mcpConfig.mcpServers[serverName];
|
|
224
|
+
this.validateServerConfig(serverName, config);
|
|
225
|
+
} else {
|
|
226
|
+
const requirements = MCP_SERVERS[serverName];
|
|
227
|
+
if (requirements.required) {
|
|
228
|
+
this.addError(`Missing required MCP server: ${serverName}`);
|
|
229
|
+
console.log(chalk.red(`\n ${serverName}: Not configured`));
|
|
230
|
+
console.log(chalk.gray(` ${requirements.description}`));
|
|
231
|
+
} else {
|
|
232
|
+
this.addWarning(`Missing optional MCP server: ${serverName}`);
|
|
233
|
+
console.log(chalk.yellow(`\n ${serverName}: Not configured (optional)`));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Check for unknown servers
|
|
239
|
+
configuredServers.forEach(serverName => {
|
|
240
|
+
if (!expectedServers.includes(serverName)) {
|
|
241
|
+
this.addWarning(`Unknown MCP server in config: ${serverName}`);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
validateServerConnectivity() {
|
|
247
|
+
console.log(chalk.bold('\nš Checking Server Configuration...'));
|
|
248
|
+
|
|
249
|
+
Object.entries(this.mcpConfig.mcpServers).forEach(([serverName, config]) => {
|
|
250
|
+
// Check command-based servers
|
|
251
|
+
if (config.command) {
|
|
252
|
+
const command = this.replaceEnvVars(config.command);
|
|
253
|
+
console.log(chalk.gray(` ${serverName}: Command-based (${command})`));
|
|
254
|
+
|
|
255
|
+
// Check if npx is available for npx-based servers
|
|
256
|
+
if (command === 'npx') {
|
|
257
|
+
try {
|
|
258
|
+
require('child_process').execSync('npx --version', { stdio: 'ignore' });
|
|
259
|
+
this.log(`${serverName}: npx available`, 'success');
|
|
260
|
+
this.passed++;
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this.addWarning(`${serverName}: npx not available - install Node.js`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Check URL-based servers
|
|
268
|
+
if (config.url) {
|
|
269
|
+
const url = this.replaceEnvVars(config.url);
|
|
270
|
+
console.log(chalk.gray(` ${serverName}: URL-based (${url})`));
|
|
271
|
+
|
|
272
|
+
if (!url.startsWith('http')) {
|
|
273
|
+
this.addWarning(`${serverName}: Invalid URL format: ${url}`);
|
|
274
|
+
} else {
|
|
275
|
+
this.log(`${serverName}: URL configured`, 'success');
|
|
276
|
+
this.passed++;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Check environment variables are properly configured
|
|
281
|
+
if (config.env) {
|
|
282
|
+
const envKeys = Object.keys(config.env);
|
|
283
|
+
const hasPlaceholders = envKeys.some(key => {
|
|
284
|
+
const value = config.env[key];
|
|
285
|
+
return typeof value === 'string' && value.includes('${');
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
if (hasPlaceholders) {
|
|
289
|
+
this.log(`${serverName}: Using environment variables`, 'success');
|
|
290
|
+
this.passed++;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
checkCriticalToolStatus() {
|
|
297
|
+
console.log(chalk.bold('\nšÆ Critical Tool Status...'));
|
|
298
|
+
|
|
299
|
+
const criticalTools = ['brave-search', 'mem0', 'clear-thought', 'deepwiki'];
|
|
300
|
+
const configured = [];
|
|
301
|
+
const missing = [];
|
|
302
|
+
|
|
303
|
+
criticalTools.forEach(tool => {
|
|
304
|
+
const requirements = MCP_SERVERS[tool];
|
|
305
|
+
const isConfigured = this.mcpConfig.mcpServers[tool];
|
|
306
|
+
|
|
307
|
+
if (!isConfigured) {
|
|
308
|
+
missing.push(tool);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const missingVars = requirements.envVars.filter(envVar => {
|
|
313
|
+
const value = this.env[envVar];
|
|
314
|
+
return !value || value.trim() === '';
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (missingVars.length === 0) {
|
|
318
|
+
configured.push(tool);
|
|
319
|
+
} else {
|
|
320
|
+
missing.push(tool);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
if (configured.length > 0) {
|
|
325
|
+
this.log(`${configured.length} critical tools ready: ${configured.join(', ')}`, 'success');
|
|
326
|
+
this.passed++;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (missing.length > 0) {
|
|
330
|
+
this.addError(`${missing.length} critical tools not ready: ${missing.join(', ')}`);
|
|
331
|
+
console.log(chalk.red(` Missing: ${missing.join(', ')}`));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
checkMemorySystemStatus() {
|
|
336
|
+
console.log(chalk.bold('\nš¾ Memory System Status...'));
|
|
337
|
+
|
|
338
|
+
const mem0Ready = this.mcpConfig.mcpServers['mem0'] &&
|
|
339
|
+
this.env['SMITHERY_KEY'] &&
|
|
340
|
+
this.env['OPENAI_API_KEY'];
|
|
341
|
+
|
|
342
|
+
const openmemoryReady = this.mcpConfig.mcpServers['openmemory'] &&
|
|
343
|
+
this.env['OPENMEMORY_API_KEY'];
|
|
344
|
+
|
|
345
|
+
if (mem0Ready && openmemoryReady) {
|
|
346
|
+
this.log('Both memory systems configured (mem0 and openmemory)', 'success');
|
|
347
|
+
console.log(chalk.gray(' Note: You only need one memory system'));
|
|
348
|
+
this.passed++;
|
|
349
|
+
} else if (mem0Ready) {
|
|
350
|
+
this.log('mem0 configured and ready', 'success');
|
|
351
|
+
this.passed++;
|
|
352
|
+
} else if (openmemoryReady) {
|
|
353
|
+
this.log('openmemory configured and ready', 'success');
|
|
354
|
+
this.passed++;
|
|
355
|
+
} else {
|
|
356
|
+
this.addError('No memory system configured - configure either mem0 or openmemory');
|
|
357
|
+
console.log(chalk.red(' Both mem0 and openmemory are unavailable'));
|
|
358
|
+
console.log(chalk.cyan(' Setup mem0: https://smithery.ai'));
|
|
359
|
+
console.log(chalk.cyan(' Setup openmemory: https://openmemory.ai'));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
generateReport() {
|
|
364
|
+
console.log(chalk.bold('\n\nš MCP Configuration Report\n'));
|
|
365
|
+
console.log(chalk.bold('ā'.repeat(50)));
|
|
366
|
+
|
|
367
|
+
// Summary
|
|
368
|
+
console.log(chalk.bold('\nSummary:'));
|
|
369
|
+
console.log(` ${chalk.green('ā')} Configured: ${chalk.bold(this.passed)}`);
|
|
370
|
+
console.log(` ${chalk.red('ā')} Missing: ${chalk.bold(this.failed)}`);
|
|
371
|
+
console.log(` ${chalk.yellow('ā ')} Warnings: ${chalk.bold(this.warnings.length)}`);
|
|
372
|
+
|
|
373
|
+
// Errors
|
|
374
|
+
if (this.errors.length > 0) {
|
|
375
|
+
console.log(chalk.bold('\n\nConfiguration Issues:'));
|
|
376
|
+
this.errors.forEach((error, i) => {
|
|
377
|
+
console.log(` ${i + 1}. ${chalk.red(error)}`);
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Warnings
|
|
382
|
+
if (this.warnings.length > 0) {
|
|
383
|
+
console.log(chalk.bold('\n\nWarnings:'));
|
|
384
|
+
this.warnings.forEach((warning, i) => {
|
|
385
|
+
console.log(` ${i + 1}. ${chalk.yellow(warning)}`);
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
console.log(chalk.bold('\n' + 'ā'.repeat(50)));
|
|
390
|
+
|
|
391
|
+
// Overall status
|
|
392
|
+
console.log(chalk.bold('\nOverall Status:'));
|
|
393
|
+
if (this.failed === 0) {
|
|
394
|
+
console.log(chalk.green(' ā MCP configuration is valid'));
|
|
395
|
+
console.log(chalk.green('\n All critical MCP tools are configured!\n'));
|
|
396
|
+
console.log(chalk.cyan(' Next steps:'));
|
|
397
|
+
console.log(chalk.gray(' 1. Test your MCP tools in Claude Code or other AI tools'));
|
|
398
|
+
console.log(chalk.gray(' 2. Try: @context7 react'));
|
|
399
|
+
console.log(chalk.gray(' 3. Try: /mem0 save "test message"'));
|
|
400
|
+
console.log(chalk.gray(' 4. Try: @deepwiki facebook/react\n'));
|
|
401
|
+
} else {
|
|
402
|
+
console.log(chalk.red(` ā Missing ${this.failed} required configuration(s)`));
|
|
403
|
+
console.log(chalk.yellow('\n Setup Instructions:\n'));
|
|
404
|
+
console.log(chalk.cyan(' 1. Fix environment variables:'));
|
|
405
|
+
console.log(chalk.gray(' npm run validate:env\n'));
|
|
406
|
+
console.log(chalk.cyan(' 2. Add missing API keys to .env\n'));
|
|
407
|
+
console.log(chalk.cyan(' 3. Run MCP validation again:'));
|
|
408
|
+
console.log(chalk.gray(' npm run validate:mcp\n'));
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return this.failed === 0;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async run() {
|
|
415
|
+
console.log(chalk.bold.cyan('\nš AgentDevFramework MCP Configuration Validator\n'));
|
|
416
|
+
|
|
417
|
+
const spinner = ora('Starting validation...').start();
|
|
418
|
+
|
|
419
|
+
try {
|
|
420
|
+
spinner.text = 'Loading environment variables...';
|
|
421
|
+
const envLoaded = this.loadEnvFile();
|
|
422
|
+
|
|
423
|
+
spinner.text = 'Checking MCP configuration file...';
|
|
424
|
+
const configExists = this.checkMCPConfigExists();
|
|
425
|
+
|
|
426
|
+
if (!configExists) {
|
|
427
|
+
spinner.fail('MCP configuration file not found');
|
|
428
|
+
return this.generateReport();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
spinner.text = 'Loading MCP configuration...';
|
|
432
|
+
const configLoaded = this.loadMCPConfig();
|
|
433
|
+
|
|
434
|
+
if (!configLoaded) {
|
|
435
|
+
spinner.fail('Failed to load MCP configuration');
|
|
436
|
+
return this.generateReport();
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
spinner.text = 'Validating MCP servers...';
|
|
440
|
+
this.validateAllServers();
|
|
441
|
+
|
|
442
|
+
spinner.text = 'Checking server connectivity...';
|
|
443
|
+
this.validateServerConnectivity();
|
|
444
|
+
|
|
445
|
+
spinner.text = 'Checking critical tools...';
|
|
446
|
+
this.checkCriticalToolStatus();
|
|
447
|
+
|
|
448
|
+
spinner.text = 'Checking memory systems...';
|
|
449
|
+
this.checkMemorySystemStatus();
|
|
450
|
+
|
|
451
|
+
spinner.succeed('Validation complete');
|
|
452
|
+
|
|
453
|
+
return this.generateReport();
|
|
454
|
+
} catch (error) {
|
|
455
|
+
spinner.fail('Validation failed');
|
|
456
|
+
console.error(chalk.red(`\nError: ${error.message}`));
|
|
457
|
+
console.error(error.stack);
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Run validation if called directly
|
|
464
|
+
if (require.main === module) {
|
|
465
|
+
const validator = new MCPValidator();
|
|
466
|
+
validator.run().then(success => {
|
|
467
|
+
process.exit(success ? 0 : 1);
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
module.exports = MCPValidator;
|