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/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 { fileURLToPath } from 'url';
14
- import { dirname, join } from 'path';
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
- let currentDir;
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
- const alignmentScore = totalTasks > 0 ? Math.round((alignedTasks / totalTasks) * 100) : 0;
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
- if (hasKeywordMatch) {
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