mcp-adr-analysis-server 2.0.12 → 2.0.14
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/README.md +132 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/src/index.d.ts +18 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +464 -23
- package/dist/src/index.js.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.d.ts +23 -0
- package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -0
- package/dist/src/tools/deployment-readiness-tool.js +696 -0
- package/dist/src/tools/deployment-readiness-tool.js.map +1 -0
- package/dist/src/tools/smart-git-push-tool-v2.d.ts +14 -0
- package/dist/src/tools/smart-git-push-tool-v2.d.ts.map +1 -1
- package/dist/src/tools/smart-git-push-tool-v2.js +415 -20
- package/dist/src/tools/smart-git-push-tool-v2.js.map +1 -1
- package/dist/src/tools/todo-management-tool-v2.d.ts +39 -0
- package/dist/src/tools/todo-management-tool-v2.d.ts.map +1 -1
- package/dist/src/tools/todo-management-tool-v2.js +229 -5
- package/dist/src/tools/todo-management-tool-v2.js.map +1 -1
- package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +4 -4
- package/dist/src/utils/directory-compat.d.ts +8 -0
- package/dist/src/utils/directory-compat.d.ts.map +1 -0
- package/dist/src/utils/directory-compat.js +27 -0
- package/dist/src/utils/directory-compat.js.map +1 -0
- package/package.json +13 -12
package/dist/src/index.js
CHANGED
|
@@ -10,8 +10,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
10
10
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
11
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
12
12
|
import { readFileSync } from 'fs';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
import { getCurrentDirCompat } from './utils/directory-compat.js';
|
|
15
15
|
import { McpAdrError } from './types/index.js';
|
|
16
16
|
import { CONVERSATION_CONTEXT_SCHEMA } from './types/conversation-context.js';
|
|
17
17
|
import { maskMcpResponse, createMaskingConfig } from './utils/output-masking.js';
|
|
@@ -23,17 +23,7 @@ import { KnowledgeGraphManager } from './utils/knowledge-graph-manager.js';
|
|
|
23
23
|
function getPackageVersion() {
|
|
24
24
|
try {
|
|
25
25
|
// Handle both Jest environment and normal execution
|
|
26
|
-
|
|
27
|
-
if (typeof import.meta !== 'undefined' && import.meta.url) {
|
|
28
|
-
// Normal ESM execution
|
|
29
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
30
|
-
currentDir = dirname(__filename);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
// Jest or other environments without import.meta support
|
|
34
|
-
// Use process.cwd() as fallback
|
|
35
|
-
currentDir = process.cwd();
|
|
36
|
-
}
|
|
26
|
+
const currentDir = getCurrentDirCompat();
|
|
37
27
|
// Try multiple possible locations for package.json
|
|
38
28
|
const possiblePaths = [
|
|
39
29
|
join(currentDir, 'package.json'),
|
|
@@ -330,6 +320,37 @@ export class McpAdrAnalysisServer {
|
|
|
330
320
|
description: 'Path to project root for environment analysis',
|
|
331
321
|
default: '.'
|
|
332
322
|
},
|
|
323
|
+
environment: {
|
|
324
|
+
type: 'string',
|
|
325
|
+
enum: ['development', 'staging', 'production', 'testing', 'auto-detect'],
|
|
326
|
+
description: 'Target environment context for validation (auto-detect will infer from project structure)',
|
|
327
|
+
default: 'auto-detect'
|
|
328
|
+
},
|
|
329
|
+
environmentConfig: {
|
|
330
|
+
type: 'object',
|
|
331
|
+
description: 'Environment-specific configuration and requirements',
|
|
332
|
+
properties: {
|
|
333
|
+
requiredFiles: {
|
|
334
|
+
type: 'array',
|
|
335
|
+
items: { type: 'string' },
|
|
336
|
+
description: 'Files required for this environment'
|
|
337
|
+
},
|
|
338
|
+
requiredServices: {
|
|
339
|
+
type: 'array',
|
|
340
|
+
items: { type: 'string' },
|
|
341
|
+
description: 'Services that must be implemented for this environment'
|
|
342
|
+
},
|
|
343
|
+
securityLevel: {
|
|
344
|
+
type: 'string',
|
|
345
|
+
enum: ['low', 'medium', 'high', 'critical'],
|
|
346
|
+
description: 'Required security level for this environment'
|
|
347
|
+
},
|
|
348
|
+
performanceRequirements: {
|
|
349
|
+
type: 'object',
|
|
350
|
+
description: 'Performance requirements for this environment'
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
},
|
|
333
354
|
validationType: {
|
|
334
355
|
type: 'string',
|
|
335
356
|
enum: ['full', 'todo-only', 'adr-only', 'environment-only'],
|
|
@@ -360,6 +381,11 @@ export class McpAdrAnalysisServer {
|
|
|
360
381
|
type: 'boolean',
|
|
361
382
|
description: 'Enable strict validation mode with reality-check mechanisms against overconfident assessments',
|
|
362
383
|
default: true
|
|
384
|
+
},
|
|
385
|
+
environmentValidation: {
|
|
386
|
+
type: 'boolean',
|
|
387
|
+
description: 'Enable environment-specific validation rules and checks',
|
|
388
|
+
default: true
|
|
363
389
|
}
|
|
364
390
|
}
|
|
365
391
|
}
|
|
@@ -1598,6 +1624,126 @@ export class McpAdrAnalysisServer {
|
|
|
1598
1624
|
}
|
|
1599
1625
|
}
|
|
1600
1626
|
},
|
|
1627
|
+
{
|
|
1628
|
+
name: 'deployment_readiness',
|
|
1629
|
+
description: 'Comprehensive deployment readiness validation with test failure tracking, deployment history analysis, and hard blocking for unsafe deployments. Integrates with smart_git_push for deployment gating.',
|
|
1630
|
+
inputSchema: {
|
|
1631
|
+
type: 'object',
|
|
1632
|
+
properties: {
|
|
1633
|
+
operation: {
|
|
1634
|
+
type: 'string',
|
|
1635
|
+
enum: ['check_readiness', 'validate_production', 'test_validation', 'deployment_history', 'full_audit', 'emergency_override'],
|
|
1636
|
+
description: 'Type of deployment readiness check to perform'
|
|
1637
|
+
},
|
|
1638
|
+
projectPath: {
|
|
1639
|
+
type: 'string',
|
|
1640
|
+
description: 'Path to project directory (defaults to current working directory)'
|
|
1641
|
+
},
|
|
1642
|
+
targetEnvironment: {
|
|
1643
|
+
type: 'string',
|
|
1644
|
+
enum: ['staging', 'production', 'integration'],
|
|
1645
|
+
default: 'production',
|
|
1646
|
+
description: 'Target deployment environment'
|
|
1647
|
+
},
|
|
1648
|
+
strictMode: {
|
|
1649
|
+
type: 'boolean',
|
|
1650
|
+
default: true,
|
|
1651
|
+
description: 'Enable strict validation (recommended for production)'
|
|
1652
|
+
},
|
|
1653
|
+
allowMockCode: {
|
|
1654
|
+
type: 'boolean',
|
|
1655
|
+
default: false,
|
|
1656
|
+
description: 'Allow mock code in deployment (NOT RECOMMENDED)'
|
|
1657
|
+
},
|
|
1658
|
+
productionCodeThreshold: {
|
|
1659
|
+
type: 'number',
|
|
1660
|
+
default: 85,
|
|
1661
|
+
description: 'Minimum production code quality score (0-100)'
|
|
1662
|
+
},
|
|
1663
|
+
mockCodeMaxAllowed: {
|
|
1664
|
+
type: 'number',
|
|
1665
|
+
default: 0,
|
|
1666
|
+
description: 'Maximum mock code indicators allowed'
|
|
1667
|
+
},
|
|
1668
|
+
maxTestFailures: {
|
|
1669
|
+
type: 'number',
|
|
1670
|
+
default: 0,
|
|
1671
|
+
description: 'Maximum test failures allowed (0 = zero tolerance)'
|
|
1672
|
+
},
|
|
1673
|
+
requireTestCoverage: {
|
|
1674
|
+
type: 'number',
|
|
1675
|
+
default: 80,
|
|
1676
|
+
description: 'Minimum test coverage percentage required'
|
|
1677
|
+
},
|
|
1678
|
+
blockOnFailingTests: {
|
|
1679
|
+
type: 'boolean',
|
|
1680
|
+
default: true,
|
|
1681
|
+
description: 'Block deployment if tests are failing'
|
|
1682
|
+
},
|
|
1683
|
+
testSuiteRequired: {
|
|
1684
|
+
type: 'array',
|
|
1685
|
+
items: { type: 'string' },
|
|
1686
|
+
default: [],
|
|
1687
|
+
description: 'Required test suites that must pass'
|
|
1688
|
+
},
|
|
1689
|
+
maxRecentFailures: {
|
|
1690
|
+
type: 'number',
|
|
1691
|
+
default: 2,
|
|
1692
|
+
description: 'Maximum recent deployment failures allowed'
|
|
1693
|
+
},
|
|
1694
|
+
deploymentSuccessThreshold: {
|
|
1695
|
+
type: 'number',
|
|
1696
|
+
default: 80,
|
|
1697
|
+
description: 'Minimum deployment success rate required (%)'
|
|
1698
|
+
},
|
|
1699
|
+
blockOnRecentFailures: {
|
|
1700
|
+
type: 'boolean',
|
|
1701
|
+
default: true,
|
|
1702
|
+
description: 'Block if recent deployments failed'
|
|
1703
|
+
},
|
|
1704
|
+
rollbackFrequencyThreshold: {
|
|
1705
|
+
type: 'number',
|
|
1706
|
+
default: 20,
|
|
1707
|
+
description: 'Maximum rollback frequency allowed (%)'
|
|
1708
|
+
},
|
|
1709
|
+
requireAdrCompliance: {
|
|
1710
|
+
type: 'boolean',
|
|
1711
|
+
default: true,
|
|
1712
|
+
description: 'Require ADR compliance validation'
|
|
1713
|
+
},
|
|
1714
|
+
integrateTodoTasks: {
|
|
1715
|
+
type: 'boolean',
|
|
1716
|
+
default: true,
|
|
1717
|
+
description: 'Auto-create blocking tasks for issues'
|
|
1718
|
+
},
|
|
1719
|
+
updateHealthScoring: {
|
|
1720
|
+
type: 'boolean',
|
|
1721
|
+
default: true,
|
|
1722
|
+
description: 'Update project health scores'
|
|
1723
|
+
},
|
|
1724
|
+
triggerSmartGitPush: {
|
|
1725
|
+
type: 'boolean',
|
|
1726
|
+
default: false,
|
|
1727
|
+
description: 'Trigger smart git push validation'
|
|
1728
|
+
},
|
|
1729
|
+
emergencyBypass: {
|
|
1730
|
+
type: 'boolean',
|
|
1731
|
+
default: false,
|
|
1732
|
+
description: 'Emergency bypass for critical fixes'
|
|
1733
|
+
},
|
|
1734
|
+
businessJustification: {
|
|
1735
|
+
type: 'string',
|
|
1736
|
+
description: 'Business justification for overrides (required for emergency_override)'
|
|
1737
|
+
},
|
|
1738
|
+
approvalRequired: {
|
|
1739
|
+
type: 'boolean',
|
|
1740
|
+
default: true,
|
|
1741
|
+
description: 'Require approval for overrides'
|
|
1742
|
+
}
|
|
1743
|
+
},
|
|
1744
|
+
required: ['operation']
|
|
1745
|
+
}
|
|
1746
|
+
},
|
|
1601
1747
|
{
|
|
1602
1748
|
name: 'troubleshoot_guided_workflow',
|
|
1603
1749
|
description: 'Structured failure analysis and test plan generation - provide JSON failure info to get specific test commands',
|
|
@@ -1924,6 +2070,9 @@ export class McpAdrAnalysisServer {
|
|
|
1924
2070
|
case 'smart_git_push':
|
|
1925
2071
|
response = await this.smartGitPush(args);
|
|
1926
2072
|
break;
|
|
2073
|
+
case 'deployment_readiness':
|
|
2074
|
+
response = await this.deploymentReadiness(args);
|
|
2075
|
+
break;
|
|
1927
2076
|
case 'troubleshoot_guided_workflow':
|
|
1928
2077
|
response = await this.troubleshootGuidedWorkflow(args);
|
|
1929
2078
|
break;
|
|
@@ -3465,7 +3614,7 @@ ${importResult.content[0].text}
|
|
|
3465
3614
|
}
|
|
3466
3615
|
}
|
|
3467
3616
|
async compareAdrProgress(args) {
|
|
3468
|
-
const { todoPath = 'TODO.md', adrDirectory = this.config.adrDirectory, projectPath = this.config.projectPath, validationType = 'full', includeFileChecks = true, includeRuleValidation = true, deepCodeAnalysis = true, functionalValidation = true, strictMode = true } = args;
|
|
3617
|
+
const { todoPath = 'TODO.md', adrDirectory = this.config.adrDirectory, projectPath = this.config.projectPath, environment = 'auto-detect', environmentConfig = {}, validationType = 'full', includeFileChecks = true, includeRuleValidation = true, deepCodeAnalysis = true, functionalValidation = true, strictMode = true, environmentValidation = true } = args;
|
|
3469
3618
|
const { getAdrDirectoryPath } = await import('./utils/config.js');
|
|
3470
3619
|
const path = await import('path');
|
|
3471
3620
|
// Resolve paths
|
|
@@ -3473,7 +3622,21 @@ ${importResult.content[0].text}
|
|
|
3473
3622
|
const absoluteAdrPath = adrDirectory ?
|
|
3474
3623
|
path.resolve(projectPath, adrDirectory) :
|
|
3475
3624
|
getAdrDirectoryPath(this.config);
|
|
3476
|
-
this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath})`);
|
|
3625
|
+
this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath}) [env: ${environment}]`);
|
|
3626
|
+
// Environment validation and auto-detection
|
|
3627
|
+
let detectedEnvironment = environment;
|
|
3628
|
+
let finalEnvironmentConfig = { ...environmentConfig };
|
|
3629
|
+
if (environmentValidation && (validationType === 'full' || validationType === 'environment-only')) {
|
|
3630
|
+
try {
|
|
3631
|
+
const envResult = await this.detectAndValidateEnvironment(projectPath, environment, environmentConfig);
|
|
3632
|
+
detectedEnvironment = envResult.detectedEnvironment;
|
|
3633
|
+
finalEnvironmentConfig = { ...finalEnvironmentConfig, ...envResult.environmentConfig };
|
|
3634
|
+
this.logger.info(`Environment detection result: ${detectedEnvironment}`);
|
|
3635
|
+
}
|
|
3636
|
+
catch (error) {
|
|
3637
|
+
this.logger.warn(`Environment detection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3477
3640
|
try {
|
|
3478
3641
|
// Step 1: Read TODO.md file directly
|
|
3479
3642
|
let todoContent = '';
|
|
@@ -3519,7 +3682,10 @@ ${importResult.content[0].text}
|
|
|
3519
3682
|
includeRuleValidation,
|
|
3520
3683
|
deepCodeAnalysis,
|
|
3521
3684
|
functionalValidation,
|
|
3522
|
-
strictMode
|
|
3685
|
+
strictMode,
|
|
3686
|
+
environment: detectedEnvironment,
|
|
3687
|
+
environmentConfig: finalEnvironmentConfig,
|
|
3688
|
+
environmentValidation
|
|
3523
3689
|
});
|
|
3524
3690
|
return {
|
|
3525
3691
|
content: [
|
|
@@ -3534,11 +3700,101 @@ ${importResult.content[0].text}
|
|
|
3534
3700
|
throw new McpAdrError(`Failed to compare ADR progress: ${error instanceof Error ? error.message : String(error)}`, 'VALIDATION_ERROR');
|
|
3535
3701
|
}
|
|
3536
3702
|
}
|
|
3703
|
+
/**
|
|
3704
|
+
* Detect and validate environment context
|
|
3705
|
+
*/
|
|
3706
|
+
async detectAndValidateEnvironment(projectPath, environment, environmentConfig) {
|
|
3707
|
+
const path = await import('path');
|
|
3708
|
+
const fs = await import('fs/promises');
|
|
3709
|
+
let detectedEnvironment = environment;
|
|
3710
|
+
let finalConfig = { ...environmentConfig };
|
|
3711
|
+
if (environment === 'auto-detect') {
|
|
3712
|
+
// Auto-detect environment based on project structure
|
|
3713
|
+
try {
|
|
3714
|
+
// Check for environment indicator files
|
|
3715
|
+
const envFiles = [
|
|
3716
|
+
'.env.development',
|
|
3717
|
+
'.env.staging',
|
|
3718
|
+
'.env.production',
|
|
3719
|
+
'.env.test',
|
|
3720
|
+
'package.json',
|
|
3721
|
+
'docker-compose.yml',
|
|
3722
|
+
'Dockerfile'
|
|
3723
|
+
];
|
|
3724
|
+
const existingFiles = [];
|
|
3725
|
+
for (const file of envFiles) {
|
|
3726
|
+
try {
|
|
3727
|
+
await fs.access(path.join(projectPath, file));
|
|
3728
|
+
existingFiles.push(file);
|
|
3729
|
+
}
|
|
3730
|
+
catch {
|
|
3731
|
+
// File doesn't exist, continue
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
// Environment detection logic
|
|
3735
|
+
if (existingFiles.includes('.env.production') || existingFiles.includes('Dockerfile')) {
|
|
3736
|
+
detectedEnvironment = 'production';
|
|
3737
|
+
}
|
|
3738
|
+
else if (existingFiles.includes('.env.staging')) {
|
|
3739
|
+
detectedEnvironment = 'staging';
|
|
3740
|
+
}
|
|
3741
|
+
else if (existingFiles.includes('.env.test')) {
|
|
3742
|
+
detectedEnvironment = 'testing';
|
|
3743
|
+
}
|
|
3744
|
+
else {
|
|
3745
|
+
detectedEnvironment = 'development';
|
|
3746
|
+
}
|
|
3747
|
+
// Set environment-specific default configurations
|
|
3748
|
+
switch (detectedEnvironment) {
|
|
3749
|
+
case 'production':
|
|
3750
|
+
finalConfig = {
|
|
3751
|
+
securityLevel: 'critical',
|
|
3752
|
+
requiredFiles: ['package.json', 'README.md'],
|
|
3753
|
+
requiredServices: ['monitoring', 'logging'],
|
|
3754
|
+
performanceRequirements: { minUptime: 99.9 },
|
|
3755
|
+
...finalConfig
|
|
3756
|
+
};
|
|
3757
|
+
break;
|
|
3758
|
+
case 'staging':
|
|
3759
|
+
finalConfig = {
|
|
3760
|
+
securityLevel: 'high',
|
|
3761
|
+
requiredFiles: ['package.json'],
|
|
3762
|
+
requiredServices: ['testing', 'monitoring'],
|
|
3763
|
+
performanceRequirements: { minUptime: 95 },
|
|
3764
|
+
...finalConfig
|
|
3765
|
+
};
|
|
3766
|
+
break;
|
|
3767
|
+
case 'testing':
|
|
3768
|
+
finalConfig = {
|
|
3769
|
+
securityLevel: 'medium',
|
|
3770
|
+
requiredFiles: ['package.json'],
|
|
3771
|
+
requiredServices: ['testing'],
|
|
3772
|
+
performanceRequirements: {},
|
|
3773
|
+
...finalConfig
|
|
3774
|
+
};
|
|
3775
|
+
break;
|
|
3776
|
+
default: // development
|
|
3777
|
+
finalConfig = {
|
|
3778
|
+
securityLevel: 'medium',
|
|
3779
|
+
requiredFiles: ['package.json'],
|
|
3780
|
+
requiredServices: [],
|
|
3781
|
+
performanceRequirements: {},
|
|
3782
|
+
...finalConfig
|
|
3783
|
+
};
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
catch (error) {
|
|
3787
|
+
this.logger.warn(`Environment auto-detection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3788
|
+
detectedEnvironment = 'development'; // fallback
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
return { detectedEnvironment, environmentConfig: finalConfig };
|
|
3792
|
+
}
|
|
3537
3793
|
/**
|
|
3538
3794
|
* Perform local ADR progress analysis without relying on AI execution
|
|
3539
3795
|
*/
|
|
3540
3796
|
async performLocalAdrProgressAnalysis(params) {
|
|
3541
|
-
const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode } = params;
|
|
3797
|
+
const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode, environment, environmentConfig, environmentValidation } = params;
|
|
3542
3798
|
const currentDate = new Date().toISOString().split('T')[0];
|
|
3543
3799
|
// Parse TODO content to extract tasks
|
|
3544
3800
|
const todoTasks = this.parseTodoTasks(todoContent);
|
|
@@ -3546,15 +3802,25 @@ ${importResult.content[0].text}
|
|
|
3546
3802
|
const totalAdrs = discoveredAdrs.length;
|
|
3547
3803
|
const totalTasks = todoTasks.length;
|
|
3548
3804
|
const completedTasks = todoTasks.filter(task => task.completed).length;
|
|
3549
|
-
// Calculate alignment score (simplified)
|
|
3550
|
-
const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs);
|
|
3805
|
+
// Calculate alignment score (simplified, now environment-aware)
|
|
3806
|
+
const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs, environment, environmentConfig);
|
|
3551
3807
|
const alignedTasks = adrTaskMapping.aligned.length;
|
|
3552
|
-
|
|
3808
|
+
let alignmentScore = totalTasks > 0 ? Math.round((alignedTasks / totalTasks) * 100) : 0;
|
|
3809
|
+
// Environment-aware scoring adjustments
|
|
3810
|
+
if (environmentValidation && environmentConfig) {
|
|
3811
|
+
const envScore = this.calculateEnvironmentScore(projectStructure, environment, environmentConfig);
|
|
3812
|
+
alignmentScore = Math.round((alignmentScore + envScore) / 2); // Blend scores
|
|
3813
|
+
}
|
|
3553
3814
|
// File existence checks
|
|
3554
3815
|
let fileCheckResults = '';
|
|
3555
3816
|
if (includeFileChecks && projectStructure) {
|
|
3556
3817
|
fileCheckResults = this.performFileExistenceChecks(todoTasks, projectStructure);
|
|
3557
3818
|
}
|
|
3819
|
+
// Environment compliance checks
|
|
3820
|
+
let environmentAnalysisResults = '';
|
|
3821
|
+
if (environmentValidation && environmentConfig) {
|
|
3822
|
+
environmentAnalysisResults = this.performEnvironmentComplianceAnalysis(projectStructure, environment, environmentConfig, strictMode);
|
|
3823
|
+
}
|
|
3558
3824
|
// Mock vs Production analysis
|
|
3559
3825
|
let mockAnalysisResults = '';
|
|
3560
3826
|
if (deepCodeAnalysis && projectStructure) {
|
|
@@ -3567,6 +3833,7 @@ ${importResult.content[0].text}
|
|
|
3567
3833
|
**Project Path**: ${projectPath}
|
|
3568
3834
|
**TODO Path**: ${todoPath}
|
|
3569
3835
|
**ADR Directory**: ${adrDirectory}
|
|
3836
|
+
**Environment**: ${environment}${environmentValidation ? ` (validation enabled)` : ''}
|
|
3570
3837
|
|
|
3571
3838
|
## Summary
|
|
3572
3839
|
- **Total ADRs**: ${totalAdrs}
|
|
@@ -3574,6 +3841,7 @@ ${importResult.content[0].text}
|
|
|
3574
3841
|
- **Completed Tasks**: ${completedTasks}
|
|
3575
3842
|
- **Alignment Score**: ${alignmentScore}%
|
|
3576
3843
|
- **Compliance Score**: ${Math.max(alignmentScore - 10, 0)}%
|
|
3844
|
+
- **Environment**: ${environment}
|
|
3577
3845
|
|
|
3578
3846
|
## Configuration
|
|
3579
3847
|
- **File Checks**: ${includeFileChecks ? 'Enabled' : 'Disabled'}
|
|
@@ -3581,6 +3849,13 @@ ${importResult.content[0].text}
|
|
|
3581
3849
|
- **Deep Code Analysis**: ${deepCodeAnalysis ? 'Enabled' : 'Disabled'}
|
|
3582
3850
|
- **Functional Validation**: ${functionalValidation ? 'Enabled' : 'Disabled'}
|
|
3583
3851
|
- **Strict Mode**: ${strictMode ? 'Enabled - High scrutiny for mock vs production' : 'Disabled'}
|
|
3852
|
+
- **Environment Validation**: ${environmentValidation ? 'Enabled' : 'Disabled'}
|
|
3853
|
+
|
|
3854
|
+
## Environment Context
|
|
3855
|
+
- **Target Environment**: ${environment}
|
|
3856
|
+
- **Security Level**: ${environmentConfig.securityLevel || 'Not specified'}
|
|
3857
|
+
- **Required Files**: ${environmentConfig.requiredFiles?.length || 0} files
|
|
3858
|
+
- **Required Services**: ${environmentConfig.requiredServices?.length || 0} services
|
|
3584
3859
|
|
|
3585
3860
|
## ADR Discovery Results
|
|
3586
3861
|
${totalAdrs > 0 ?
|
|
@@ -3613,6 +3888,8 @@ ${adrTaskMapping.missing.length > 0 ?
|
|
|
3613
3888
|
|
|
3614
3889
|
${fileCheckResults || '### File Existence Validation\n- File checks disabled or no project structure available'}
|
|
3615
3890
|
|
|
3891
|
+
${environmentAnalysisResults || ''}
|
|
3892
|
+
|
|
3616
3893
|
${mockAnalysisResults || ''}
|
|
3617
3894
|
|
|
3618
3895
|
## Recommendations
|
|
@@ -3623,10 +3900,14 @@ ${alignmentScore < 70 ?
|
|
|
3623
3900
|
'1. **Maintain Current Alignment**: Continue following ADR specifications'}
|
|
3624
3901
|
${completedTasks < totalTasks * 0.5 ?
|
|
3625
3902
|
'\n3. **Accelerate Implementation**: Focus on completing pending tasks' : ''}
|
|
3903
|
+
${environmentValidation && environment === 'production' && alignmentScore < 90 ?
|
|
3904
|
+
'\n4. **⚠️ Production Environment Warning**: Current alignment may not meet production requirements' : ''}
|
|
3626
3905
|
|
|
3627
3906
|
### Medium Priority Actions
|
|
3628
3907
|
1. **Review Implementation Quality**: ${strictMode ? 'Strict mode analysis above shows' : 'Consider enabling strict mode for'} detailed quality assessment
|
|
3629
3908
|
2. **Update Documentation**: Ensure TODO.md reflects current project state
|
|
3909
|
+
${environmentValidation ?
|
|
3910
|
+
`3. **Environment Compliance**: Ensure ${environment} environment requirements are met` : ''}
|
|
3630
3911
|
|
|
3631
3912
|
### Low Priority Actions
|
|
3632
3913
|
1. **Optimize Workflow**: Consider tools for automated ADR-TODO synchronization
|
|
@@ -3702,9 +3983,9 @@ To re-run this validation with strict mode:
|
|
|
3702
3983
|
return tasks;
|
|
3703
3984
|
}
|
|
3704
3985
|
/**
|
|
3705
|
-
* Map TODO tasks to ADRs to identify alignment
|
|
3986
|
+
* Map TODO tasks to ADRs to identify alignment (now environment-aware)
|
|
3706
3987
|
*/
|
|
3707
|
-
mapTasksToAdrs(tasks, adrs) {
|
|
3988
|
+
mapTasksToAdrs(tasks, adrs, environment, environmentConfig) {
|
|
3708
3989
|
const aligned = [];
|
|
3709
3990
|
const misaligned = [];
|
|
3710
3991
|
const missing = [];
|
|
@@ -3714,10 +3995,25 @@ To re-run this validation with strict mode:
|
|
|
3714
3995
|
...(adr.decision || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4),
|
|
3715
3996
|
...(adr.context || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4)
|
|
3716
3997
|
]);
|
|
3998
|
+
// Environment-specific keywords that should be prioritized
|
|
3999
|
+
const envKeywords = [];
|
|
4000
|
+
if (environment && environmentConfig) {
|
|
4001
|
+
if (environment === 'production') {
|
|
4002
|
+
envKeywords.push('deploy', 'production', 'monitoring', 'security', 'performance');
|
|
4003
|
+
}
|
|
4004
|
+
else if (environment === 'staging') {
|
|
4005
|
+
envKeywords.push('test', 'staging', 'integration', 'validation');
|
|
4006
|
+
}
|
|
4007
|
+
else if (environment === 'development') {
|
|
4008
|
+
envKeywords.push('setup', 'development', 'local', 'debug');
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
3717
4011
|
for (const task of tasks) {
|
|
3718
4012
|
const taskLower = task.title.toLowerCase();
|
|
3719
4013
|
const hasKeywordMatch = adrKeywords.some(keyword => taskLower.includes(keyword) || keyword.includes(taskLower.split(' ')[0]));
|
|
3720
|
-
|
|
4014
|
+
// Environment-aware alignment scoring
|
|
4015
|
+
const hasEnvKeywordMatch = envKeywords.some(keyword => taskLower.includes(keyword));
|
|
4016
|
+
if (hasKeywordMatch || hasEnvKeywordMatch) {
|
|
3721
4017
|
aligned.push(task);
|
|
3722
4018
|
}
|
|
3723
4019
|
else {
|
|
@@ -3737,6 +4033,25 @@ To re-run this validation with strict mode:
|
|
|
3737
4033
|
}
|
|
3738
4034
|
}
|
|
3739
4035
|
}
|
|
4036
|
+
// Environment-specific missing tasks
|
|
4037
|
+
if (environment && environmentConfig) {
|
|
4038
|
+
if (environmentConfig.requiredFiles) {
|
|
4039
|
+
for (const file of environmentConfig.requiredFiles) {
|
|
4040
|
+
const hasFileTask = tasks.some(task => task.title.toLowerCase().includes(file.toLowerCase()));
|
|
4041
|
+
if (!hasFileTask) {
|
|
4042
|
+
missing.push(`Create ${file} for ${environment} environment`);
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
}
|
|
4046
|
+
if (environmentConfig.requiredServices) {
|
|
4047
|
+
for (const service of environmentConfig.requiredServices) {
|
|
4048
|
+
const hasServiceTask = tasks.some(task => task.title.toLowerCase().includes(service.toLowerCase()));
|
|
4049
|
+
if (!hasServiceTask) {
|
|
4050
|
+
missing.push(`Setup ${service} service for ${environment}`);
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
3740
4055
|
return { aligned, misaligned, missing };
|
|
3741
4056
|
}
|
|
3742
4057
|
/**
|
|
@@ -3848,6 +4163,122 @@ To re-run this validation with strict mode:
|
|
|
3848
4163
|
}
|
|
3849
4164
|
return results;
|
|
3850
4165
|
}
|
|
4166
|
+
/**
|
|
4167
|
+
* Calculate environment-specific compliance score
|
|
4168
|
+
*/
|
|
4169
|
+
calculateEnvironmentScore(projectStructure, environment, environmentConfig) {
|
|
4170
|
+
if (!projectStructure || !environmentConfig)
|
|
4171
|
+
return 0;
|
|
4172
|
+
let score = 100; // Start with perfect score
|
|
4173
|
+
// Check required files
|
|
4174
|
+
if (environmentConfig.requiredFiles) {
|
|
4175
|
+
const allFiles = [
|
|
4176
|
+
...projectStructure.packageFiles || [],
|
|
4177
|
+
...projectStructure.configFiles || [],
|
|
4178
|
+
...projectStructure.buildFiles || [],
|
|
4179
|
+
...projectStructure.dockerFiles || [],
|
|
4180
|
+
...projectStructure.ciFiles || [],
|
|
4181
|
+
...projectStructure.scriptFiles || []
|
|
4182
|
+
];
|
|
4183
|
+
const existingFiles = allFiles.map(f => f.filename);
|
|
4184
|
+
const missingFiles = environmentConfig.requiredFiles.filter((file) => !existingFiles.includes(file));
|
|
4185
|
+
// Deduct 10 points per missing required file
|
|
4186
|
+
score -= missingFiles.length * 10;
|
|
4187
|
+
}
|
|
4188
|
+
// Environment-specific penalties
|
|
4189
|
+
if (environment === 'production') {
|
|
4190
|
+
// Production requires higher standards
|
|
4191
|
+
if (!projectStructure.dockerFiles?.length)
|
|
4192
|
+
score -= 15;
|
|
4193
|
+
if (!projectStructure.ciFiles?.length)
|
|
4194
|
+
score -= 10;
|
|
4195
|
+
}
|
|
4196
|
+
return Math.max(score, 0);
|
|
4197
|
+
}
|
|
4198
|
+
/**
|
|
4199
|
+
* Perform environment compliance analysis
|
|
4200
|
+
*/
|
|
4201
|
+
performEnvironmentComplianceAnalysis(projectStructure, environment, environmentConfig, strictMode) {
|
|
4202
|
+
if (!projectStructure || !environmentConfig) {
|
|
4203
|
+
return '\n### Environment Compliance Analysis\n- Environment analysis disabled or no project structure available\n';
|
|
4204
|
+
}
|
|
4205
|
+
let results = '\n### Environment Compliance Analysis\n';
|
|
4206
|
+
// Required files analysis
|
|
4207
|
+
if (environmentConfig.requiredFiles) {
|
|
4208
|
+
results += `#### Required Files for ${environment} Environment\n`;
|
|
4209
|
+
const allFiles = [
|
|
4210
|
+
...projectStructure.packageFiles || [],
|
|
4211
|
+
...projectStructure.configFiles || [],
|
|
4212
|
+
...projectStructure.buildFiles || [],
|
|
4213
|
+
...projectStructure.dockerFiles || [],
|
|
4214
|
+
...projectStructure.ciFiles || [],
|
|
4215
|
+
...projectStructure.scriptFiles || []
|
|
4216
|
+
];
|
|
4217
|
+
const existingFiles = allFiles.map(f => f.filename);
|
|
4218
|
+
for (const requiredFile of environmentConfig.requiredFiles) {
|
|
4219
|
+
const exists = existingFiles.includes(requiredFile);
|
|
4220
|
+
results += `- ${exists ? '✅' : '❌'} **${requiredFile}**: ${exists ? 'Found' : 'Missing'}\n`;
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
// Security level compliance
|
|
4224
|
+
if (environmentConfig.securityLevel) {
|
|
4225
|
+
results += `\n#### Security Level: ${environmentConfig.securityLevel}\n`;
|
|
4226
|
+
const securityIndicators = this.analyzeSecurityCompliance(projectStructure, environmentConfig.securityLevel);
|
|
4227
|
+
results += securityIndicators;
|
|
4228
|
+
}
|
|
4229
|
+
// Environment-specific recommendations
|
|
4230
|
+
results += `\n#### ${environment} Environment Recommendations\n`;
|
|
4231
|
+
switch (environment) {
|
|
4232
|
+
case 'production':
|
|
4233
|
+
results += '- ⚠️ **Production Critical**: Ensure monitoring, logging, and backup strategies are implemented\n';
|
|
4234
|
+
results += '- 🔒 **Security**: Implement comprehensive security measures\n';
|
|
4235
|
+
results += '- 📊 **Performance**: Monitor and optimize for production workloads\n';
|
|
4236
|
+
if (strictMode) {
|
|
4237
|
+
results += '- 🔍 **Strict Mode**: Enhanced validation enabled for production environment\n';
|
|
4238
|
+
}
|
|
4239
|
+
break;
|
|
4240
|
+
case 'staging':
|
|
4241
|
+
results += '- 🧪 **Testing**: Ensure comprehensive test coverage and validation\n';
|
|
4242
|
+
results += '- 📋 **Validation**: Implement environment parity checks\n';
|
|
4243
|
+
break;
|
|
4244
|
+
case 'development':
|
|
4245
|
+
results += '- 🛠️ **Development**: Focus on developer experience and debugging tools\n';
|
|
4246
|
+
results += '- 🔄 **Iteration**: Ensure fast feedback loops\n';
|
|
4247
|
+
break;
|
|
4248
|
+
}
|
|
4249
|
+
return results;
|
|
4250
|
+
}
|
|
4251
|
+
/**
|
|
4252
|
+
* Analyze security compliance based on security level
|
|
4253
|
+
*/
|
|
4254
|
+
analyzeSecurityCompliance(projectStructure, securityLevel) {
|
|
4255
|
+
let results = '';
|
|
4256
|
+
const securityFiles = [
|
|
4257
|
+
...projectStructure.configFiles || [],
|
|
4258
|
+
...projectStructure.dockerFiles || []
|
|
4259
|
+
].filter(file => file.filename.includes('security') ||
|
|
4260
|
+
file.filename.includes('auth') ||
|
|
4261
|
+
file.filename.includes('.env') ||
|
|
4262
|
+
file.filename === 'Dockerfile');
|
|
4263
|
+
const hasSecurityConfig = securityFiles.length > 0;
|
|
4264
|
+
switch (securityLevel) {
|
|
4265
|
+
case 'critical':
|
|
4266
|
+
results += `- ${hasSecurityConfig ? '✅' : '❌'} **Critical Security**: ${hasSecurityConfig ? 'Security configuration found' : 'No security configuration detected'}\n`;
|
|
4267
|
+
if (!hasSecurityConfig) {
|
|
4268
|
+
results += ' - **Action Required**: Implement comprehensive security measures\n';
|
|
4269
|
+
}
|
|
4270
|
+
break;
|
|
4271
|
+
case 'high':
|
|
4272
|
+
results += `- ${hasSecurityConfig ? '✅' : '⚠️'} **High Security**: ${hasSecurityConfig ? 'Some security configuration found' : 'Limited security configuration'}\n`;
|
|
4273
|
+
break;
|
|
4274
|
+
case 'medium':
|
|
4275
|
+
results += `- ℹ️ **Medium Security**: Basic security measures recommended\n`;
|
|
4276
|
+
break;
|
|
4277
|
+
default:
|
|
4278
|
+
results += `- ℹ️ **Security Level**: ${securityLevel} (consider increasing for production)\n`;
|
|
4279
|
+
}
|
|
4280
|
+
return results;
|
|
4281
|
+
}
|
|
3851
4282
|
/**
|
|
3852
4283
|
* Content masking tool implementations
|
|
3853
4284
|
*/
|
|
@@ -4615,6 +5046,15 @@ Please provide:
|
|
|
4615
5046
|
throw new McpAdrError(`Smart git push failed: ${error instanceof Error ? error.message : String(error)}`, 'SMART_GIT_PUSH_ERROR');
|
|
4616
5047
|
}
|
|
4617
5048
|
}
|
|
5049
|
+
async deploymentReadiness(args) {
|
|
5050
|
+
try {
|
|
5051
|
+
const { deploymentReadiness } = await import('./tools/deployment-readiness-tool.js');
|
|
5052
|
+
return await deploymentReadiness(args);
|
|
5053
|
+
}
|
|
5054
|
+
catch (error) {
|
|
5055
|
+
throw new McpAdrError(`Deployment readiness check failed: ${error instanceof Error ? error.message : String(error)}`, 'DEPLOYMENT_READINESS_ERROR');
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
4618
5058
|
async troubleshootGuidedWorkflow(args) {
|
|
4619
5059
|
try {
|
|
4620
5060
|
const { troubleshootGuidedWorkflow } = await import('./tools/troubleshoot-guided-workflow-tool.js');
|
|
@@ -4701,4 +5141,5 @@ if (process.argv[1] && (process.argv[1].endsWith('index.js') ||
|
|
|
4701
5141
|
process.exit(1);
|
|
4702
5142
|
});
|
|
4703
5143
|
}
|
|
5144
|
+
// Test comment for pre-commit hook
|
|
4704
5145
|
//# sourceMappingURL=index.js.map
|