mcp-adr-analysis-server 2.0.13 → 2.0.15

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,18 +23,8 @@ 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
- }
37
- // Try multiple possible locations for package.json
26
+ const currentDir = getCurrentDirCompat();
27
+ // Strategy 1: Try multiple possible locations for package.json
38
28
  const possiblePaths = [
39
29
  join(currentDir, 'package.json'),
40
30
  join(currentDir, '..', 'package.json'),
@@ -52,11 +42,17 @@ function getPackageVersion() {
52
42
  // Try next path
53
43
  }
54
44
  }
55
- return '2.0.2'; // fallback version
45
+ // Strategy 2: Use process.env.npm_package_version if available (during npm scripts)
46
+ if (process.env['npm_package_version']) {
47
+ return process.env['npm_package_version'];
48
+ }
49
+ // Final fallback: Use generic version instead of hardcoded specific version
50
+ // This prevents the need to update this code when version changes
51
+ return 'unknown'; // Generic fallback - no longer tied to specific version
56
52
  }
57
53
  catch (error) {
58
54
  console.error('Error reading package.json:', error);
59
- return '2.0.2'; // fallback version
55
+ return 'unknown'; // Generic fallback - no longer tied to specific version
60
56
  }
61
57
  }
62
58
  /**
@@ -330,6 +326,37 @@ export class McpAdrAnalysisServer {
330
326
  description: 'Path to project root for environment analysis',
331
327
  default: '.'
332
328
  },
329
+ environment: {
330
+ type: 'string',
331
+ enum: ['development', 'staging', 'production', 'testing', 'auto-detect'],
332
+ description: 'Target environment context for validation (auto-detect will infer from project structure)',
333
+ default: 'auto-detect'
334
+ },
335
+ environmentConfig: {
336
+ type: 'object',
337
+ description: 'Environment-specific configuration and requirements',
338
+ properties: {
339
+ requiredFiles: {
340
+ type: 'array',
341
+ items: { type: 'string' },
342
+ description: 'Files required for this environment'
343
+ },
344
+ requiredServices: {
345
+ type: 'array',
346
+ items: { type: 'string' },
347
+ description: 'Services that must be implemented for this environment'
348
+ },
349
+ securityLevel: {
350
+ type: 'string',
351
+ enum: ['low', 'medium', 'high', 'critical'],
352
+ description: 'Required security level for this environment'
353
+ },
354
+ performanceRequirements: {
355
+ type: 'object',
356
+ description: 'Performance requirements for this environment'
357
+ }
358
+ }
359
+ },
333
360
  validationType: {
334
361
  type: 'string',
335
362
  enum: ['full', 'todo-only', 'adr-only', 'environment-only'],
@@ -360,6 +387,11 @@ export class McpAdrAnalysisServer {
360
387
  type: 'boolean',
361
388
  description: 'Enable strict validation mode with reality-check mechanisms against overconfident assessments',
362
389
  default: true
390
+ },
391
+ environmentValidation: {
392
+ type: 'boolean',
393
+ description: 'Enable environment-specific validation rules and checks',
394
+ default: true
363
395
  }
364
396
  }
365
397
  }
@@ -1935,6 +1967,208 @@ export class McpAdrAnalysisServer {
1935
1967
  },
1936
1968
  required: ['operation', 'projectPath']
1937
1969
  }
1970
+ },
1971
+ {
1972
+ name: 'mcp_planning',
1973
+ description: 'Enhanced project planning and workflow management tool - phase-based project management, team resource allocation, progress tracking, risk analysis, and executive reporting',
1974
+ inputSchema: {
1975
+ type: 'object',
1976
+ properties: {
1977
+ operation: {
1978
+ type: 'string',
1979
+ enum: ['create_project', 'manage_phases', 'track_progress', 'manage_resources', 'risk_analysis', 'generate_reports'],
1980
+ description: 'Project planning operation to perform'
1981
+ },
1982
+ projectPath: {
1983
+ type: 'string',
1984
+ description: 'Project root path'
1985
+ },
1986
+ projectName: {
1987
+ type: 'string',
1988
+ description: 'Project name (for create_project operation)'
1989
+ },
1990
+ description: {
1991
+ type: 'string',
1992
+ description: 'Project description (for create_project operation)'
1993
+ },
1994
+ phases: {
1995
+ type: 'array',
1996
+ items: {
1997
+ type: 'object',
1998
+ properties: {
1999
+ name: { type: 'string' },
2000
+ duration: { type: 'string' },
2001
+ dependencies: {
2002
+ type: 'array',
2003
+ items: { type: 'string' },
2004
+ default: []
2005
+ },
2006
+ milestones: {
2007
+ type: 'array',
2008
+ items: { type: 'string' },
2009
+ default: []
2010
+ }
2011
+ },
2012
+ required: ['name', 'duration']
2013
+ },
2014
+ description: 'Initial project phases (for create_project operation)'
2015
+ },
2016
+ team: {
2017
+ type: 'array',
2018
+ items: {
2019
+ type: 'object',
2020
+ properties: {
2021
+ name: { type: 'string' },
2022
+ role: { type: 'string' },
2023
+ skills: {
2024
+ type: 'array',
2025
+ items: { type: 'string' },
2026
+ default: []
2027
+ },
2028
+ capacity: { type: 'string' }
2029
+ },
2030
+ required: ['name', 'role', 'capacity']
2031
+ },
2032
+ default: [],
2033
+ description: 'Team structure (for create_project operation)'
2034
+ },
2035
+ importFromAdrs: {
2036
+ type: 'boolean',
2037
+ default: true,
2038
+ description: 'Import phases from existing ADRs (for create_project operation)'
2039
+ },
2040
+ importFromTodos: {
2041
+ type: 'boolean',
2042
+ default: true,
2043
+ description: 'Import tasks from TODO system (for create_project operation)'
2044
+ },
2045
+ action: {
2046
+ type: 'string',
2047
+ enum: ['list', 'create', 'update', 'delete', 'transition', 'add', 'remove', 'allocate', 'optimize'],
2048
+ description: 'Management action (for manage_phases/manage_resources operations)'
2049
+ },
2050
+ phaseId: {
2051
+ type: 'string',
2052
+ description: 'Phase ID for phase operations'
2053
+ },
2054
+ phaseData: {
2055
+ type: 'object',
2056
+ properties: {
2057
+ name: { type: 'string' },
2058
+ description: { type: 'string' },
2059
+ estimatedDuration: { type: 'string' },
2060
+ dependencies: {
2061
+ type: 'array',
2062
+ items: { type: 'string' }
2063
+ },
2064
+ milestones: {
2065
+ type: 'array',
2066
+ items: { type: 'string' }
2067
+ },
2068
+ linkedAdrs: {
2069
+ type: 'array',
2070
+ items: { type: 'string' }
2071
+ }
2072
+ },
2073
+ description: 'Phase data for create/update operations'
2074
+ },
2075
+ targetStatus: {
2076
+ type: 'string',
2077
+ enum: ['planning', 'active', 'completed', 'blocked', 'cancelled'],
2078
+ description: 'Target status for phase transition'
2079
+ },
2080
+ reportType: {
2081
+ type: 'string',
2082
+ enum: ['summary', 'detailed', 'gantt', 'milestones', 'risks', 'executive', 'status', 'health', 'team_performance', 'milestone_tracking'],
2083
+ default: 'summary',
2084
+ description: 'Type of progress report or generated report'
2085
+ },
2086
+ timeframe: {
2087
+ type: 'string',
2088
+ enum: ['current', 'weekly', 'monthly', 'quarterly', 'week', 'month', 'quarter', 'project'],
2089
+ default: 'current',
2090
+ description: 'Time frame for reports and tracking'
2091
+ },
2092
+ includeVisuals: {
2093
+ type: 'boolean',
2094
+ default: true,
2095
+ description: 'Include visual progress indicators'
2096
+ },
2097
+ updateTaskProgress: {
2098
+ type: 'boolean',
2099
+ default: true,
2100
+ description: 'Sync progress from TODO system'
2101
+ },
2102
+ memberId: {
2103
+ type: 'string',
2104
+ description: 'Team member ID for resource operations'
2105
+ },
2106
+ memberData: {
2107
+ type: 'object',
2108
+ properties: {
2109
+ name: { type: 'string' },
2110
+ role: { type: 'string' },
2111
+ skills: {
2112
+ type: 'array',
2113
+ items: { type: 'string' }
2114
+ },
2115
+ capacity: { type: 'string' }
2116
+ },
2117
+ description: 'Team member data for resource operations'
2118
+ },
2119
+ allocationData: {
2120
+ type: 'object',
2121
+ properties: {
2122
+ phaseId: { type: 'string' },
2123
+ allocation: {
2124
+ type: 'number',
2125
+ minimum: 0,
2126
+ maximum: 100
2127
+ }
2128
+ },
2129
+ required: ['phaseId', 'allocation'],
2130
+ description: 'Resource allocation data'
2131
+ },
2132
+ analysisType: {
2133
+ type: 'string',
2134
+ enum: ['automated', 'manual', 'comprehensive'],
2135
+ default: 'comprehensive',
2136
+ description: 'Type of risk analysis'
2137
+ },
2138
+ includeAdrRisks: {
2139
+ type: 'boolean',
2140
+ default: true,
2141
+ description: 'Analyze risks from ADR complexity'
2142
+ },
2143
+ includeDependencyRisks: {
2144
+ type: 'boolean',
2145
+ default: true,
2146
+ description: 'Analyze dependency chain risks'
2147
+ },
2148
+ includeResourceRisks: {
2149
+ type: 'boolean',
2150
+ default: true,
2151
+ description: 'Analyze resource allocation risks'
2152
+ },
2153
+ generateMitigation: {
2154
+ type: 'boolean',
2155
+ default: true,
2156
+ description: 'Generate mitigation strategies'
2157
+ },
2158
+ format: {
2159
+ type: 'string',
2160
+ enum: ['markdown', 'json', 'html'],
2161
+ default: 'markdown',
2162
+ description: 'Report output format'
2163
+ },
2164
+ includeCharts: {
2165
+ type: 'boolean',
2166
+ default: true,
2167
+ description: 'Include progress charts and graphs'
2168
+ }
2169
+ },
2170
+ required: ['operation', 'projectPath']
2171
+ }
1938
2172
  }
1939
2173
  ]
1940
2174
  };
@@ -2053,6 +2287,9 @@ export class McpAdrAnalysisServer {
2053
2287
  case 'smart_score':
2054
2288
  response = await this.smartScore(args);
2055
2289
  break;
2290
+ case 'mcp_planning':
2291
+ response = await this.mcpPlanning(args);
2292
+ break;
2056
2293
  default:
2057
2294
  throw new McpAdrError(`Unknown tool: ${name}`, 'UNKNOWN_TOOL');
2058
2295
  }
@@ -3588,7 +3825,7 @@ ${importResult.content[0].text}
3588
3825
  }
3589
3826
  }
3590
3827
  async compareAdrProgress(args) {
3591
- 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;
3828
+ 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;
3592
3829
  const { getAdrDirectoryPath } = await import('./utils/config.js');
3593
3830
  const path = await import('path');
3594
3831
  // Resolve paths
@@ -3596,7 +3833,21 @@ ${importResult.content[0].text}
3596
3833
  const absoluteAdrPath = adrDirectory ?
3597
3834
  path.resolve(projectPath, adrDirectory) :
3598
3835
  getAdrDirectoryPath(this.config);
3599
- this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath})`);
3836
+ this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath}) [env: ${environment}]`);
3837
+ // Environment validation and auto-detection
3838
+ let detectedEnvironment = environment;
3839
+ let finalEnvironmentConfig = { ...environmentConfig };
3840
+ if (environmentValidation && (validationType === 'full' || validationType === 'environment-only')) {
3841
+ try {
3842
+ const envResult = await this.detectAndValidateEnvironment(projectPath, environment, environmentConfig);
3843
+ detectedEnvironment = envResult.detectedEnvironment;
3844
+ finalEnvironmentConfig = { ...finalEnvironmentConfig, ...envResult.environmentConfig };
3845
+ this.logger.info(`Environment detection result: ${detectedEnvironment}`);
3846
+ }
3847
+ catch (error) {
3848
+ this.logger.warn(`Environment detection failed: ${error instanceof Error ? error.message : String(error)}`);
3849
+ }
3850
+ }
3600
3851
  try {
3601
3852
  // Step 1: Read TODO.md file directly
3602
3853
  let todoContent = '';
@@ -3642,7 +3893,10 @@ ${importResult.content[0].text}
3642
3893
  includeRuleValidation,
3643
3894
  deepCodeAnalysis,
3644
3895
  functionalValidation,
3645
- strictMode
3896
+ strictMode,
3897
+ environment: detectedEnvironment,
3898
+ environmentConfig: finalEnvironmentConfig,
3899
+ environmentValidation
3646
3900
  });
3647
3901
  return {
3648
3902
  content: [
@@ -3657,11 +3911,101 @@ ${importResult.content[0].text}
3657
3911
  throw new McpAdrError(`Failed to compare ADR progress: ${error instanceof Error ? error.message : String(error)}`, 'VALIDATION_ERROR');
3658
3912
  }
3659
3913
  }
3914
+ /**
3915
+ * Detect and validate environment context
3916
+ */
3917
+ async detectAndValidateEnvironment(projectPath, environment, environmentConfig) {
3918
+ const path = await import('path');
3919
+ const fs = await import('fs/promises');
3920
+ let detectedEnvironment = environment;
3921
+ let finalConfig = { ...environmentConfig };
3922
+ if (environment === 'auto-detect') {
3923
+ // Auto-detect environment based on project structure
3924
+ try {
3925
+ // Check for environment indicator files
3926
+ const envFiles = [
3927
+ '.env.development',
3928
+ '.env.staging',
3929
+ '.env.production',
3930
+ '.env.test',
3931
+ 'package.json',
3932
+ 'docker-compose.yml',
3933
+ 'Dockerfile'
3934
+ ];
3935
+ const existingFiles = [];
3936
+ for (const file of envFiles) {
3937
+ try {
3938
+ await fs.access(path.join(projectPath, file));
3939
+ existingFiles.push(file);
3940
+ }
3941
+ catch {
3942
+ // File doesn't exist, continue
3943
+ }
3944
+ }
3945
+ // Environment detection logic
3946
+ if (existingFiles.includes('.env.production') || existingFiles.includes('Dockerfile')) {
3947
+ detectedEnvironment = 'production';
3948
+ }
3949
+ else if (existingFiles.includes('.env.staging')) {
3950
+ detectedEnvironment = 'staging';
3951
+ }
3952
+ else if (existingFiles.includes('.env.test')) {
3953
+ detectedEnvironment = 'testing';
3954
+ }
3955
+ else {
3956
+ detectedEnvironment = 'development';
3957
+ }
3958
+ // Set environment-specific default configurations
3959
+ switch (detectedEnvironment) {
3960
+ case 'production':
3961
+ finalConfig = {
3962
+ securityLevel: 'critical',
3963
+ requiredFiles: ['package.json', 'README.md'],
3964
+ requiredServices: ['monitoring', 'logging'],
3965
+ performanceRequirements: { minUptime: 99.9 },
3966
+ ...finalConfig
3967
+ };
3968
+ break;
3969
+ case 'staging':
3970
+ finalConfig = {
3971
+ securityLevel: 'high',
3972
+ requiredFiles: ['package.json'],
3973
+ requiredServices: ['testing', 'monitoring'],
3974
+ performanceRequirements: { minUptime: 95 },
3975
+ ...finalConfig
3976
+ };
3977
+ break;
3978
+ case 'testing':
3979
+ finalConfig = {
3980
+ securityLevel: 'medium',
3981
+ requiredFiles: ['package.json'],
3982
+ requiredServices: ['testing'],
3983
+ performanceRequirements: {},
3984
+ ...finalConfig
3985
+ };
3986
+ break;
3987
+ default: // development
3988
+ finalConfig = {
3989
+ securityLevel: 'medium',
3990
+ requiredFiles: ['package.json'],
3991
+ requiredServices: [],
3992
+ performanceRequirements: {},
3993
+ ...finalConfig
3994
+ };
3995
+ }
3996
+ }
3997
+ catch (error) {
3998
+ this.logger.warn(`Environment auto-detection failed: ${error instanceof Error ? error.message : String(error)}`);
3999
+ detectedEnvironment = 'development'; // fallback
4000
+ }
4001
+ }
4002
+ return { detectedEnvironment, environmentConfig: finalConfig };
4003
+ }
3660
4004
  /**
3661
4005
  * Perform local ADR progress analysis without relying on AI execution
3662
4006
  */
3663
4007
  async performLocalAdrProgressAnalysis(params) {
3664
- const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode } = params;
4008
+ const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode, environment, environmentConfig, environmentValidation } = params;
3665
4009
  const currentDate = new Date().toISOString().split('T')[0];
3666
4010
  // Parse TODO content to extract tasks
3667
4011
  const todoTasks = this.parseTodoTasks(todoContent);
@@ -3669,15 +4013,25 @@ ${importResult.content[0].text}
3669
4013
  const totalAdrs = discoveredAdrs.length;
3670
4014
  const totalTasks = todoTasks.length;
3671
4015
  const completedTasks = todoTasks.filter(task => task.completed).length;
3672
- // Calculate alignment score (simplified)
3673
- const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs);
4016
+ // Calculate alignment score (simplified, now environment-aware)
4017
+ const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs, environment, environmentConfig);
3674
4018
  const alignedTasks = adrTaskMapping.aligned.length;
3675
- const alignmentScore = totalTasks > 0 ? Math.round((alignedTasks / totalTasks) * 100) : 0;
4019
+ let alignmentScore = totalTasks > 0 ? Math.round((alignedTasks / totalTasks) * 100) : 0;
4020
+ // Environment-aware scoring adjustments
4021
+ if (environmentValidation && environmentConfig) {
4022
+ const envScore = this.calculateEnvironmentScore(projectStructure, environment, environmentConfig);
4023
+ alignmentScore = Math.round((alignmentScore + envScore) / 2); // Blend scores
4024
+ }
3676
4025
  // File existence checks
3677
4026
  let fileCheckResults = '';
3678
4027
  if (includeFileChecks && projectStructure) {
3679
4028
  fileCheckResults = this.performFileExistenceChecks(todoTasks, projectStructure);
3680
4029
  }
4030
+ // Environment compliance checks
4031
+ let environmentAnalysisResults = '';
4032
+ if (environmentValidation && environmentConfig) {
4033
+ environmentAnalysisResults = this.performEnvironmentComplianceAnalysis(projectStructure, environment, environmentConfig, strictMode);
4034
+ }
3681
4035
  // Mock vs Production analysis
3682
4036
  let mockAnalysisResults = '';
3683
4037
  if (deepCodeAnalysis && projectStructure) {
@@ -3690,6 +4044,7 @@ ${importResult.content[0].text}
3690
4044
  **Project Path**: ${projectPath}
3691
4045
  **TODO Path**: ${todoPath}
3692
4046
  **ADR Directory**: ${adrDirectory}
4047
+ **Environment**: ${environment}${environmentValidation ? ` (validation enabled)` : ''}
3693
4048
 
3694
4049
  ## Summary
3695
4050
  - **Total ADRs**: ${totalAdrs}
@@ -3697,6 +4052,7 @@ ${importResult.content[0].text}
3697
4052
  - **Completed Tasks**: ${completedTasks}
3698
4053
  - **Alignment Score**: ${alignmentScore}%
3699
4054
  - **Compliance Score**: ${Math.max(alignmentScore - 10, 0)}%
4055
+ - **Environment**: ${environment}
3700
4056
 
3701
4057
  ## Configuration
3702
4058
  - **File Checks**: ${includeFileChecks ? 'Enabled' : 'Disabled'}
@@ -3704,6 +4060,13 @@ ${importResult.content[0].text}
3704
4060
  - **Deep Code Analysis**: ${deepCodeAnalysis ? 'Enabled' : 'Disabled'}
3705
4061
  - **Functional Validation**: ${functionalValidation ? 'Enabled' : 'Disabled'}
3706
4062
  - **Strict Mode**: ${strictMode ? 'Enabled - High scrutiny for mock vs production' : 'Disabled'}
4063
+ - **Environment Validation**: ${environmentValidation ? 'Enabled' : 'Disabled'}
4064
+
4065
+ ## Environment Context
4066
+ - **Target Environment**: ${environment}
4067
+ - **Security Level**: ${environmentConfig.securityLevel || 'Not specified'}
4068
+ - **Required Files**: ${environmentConfig.requiredFiles?.length || 0} files
4069
+ - **Required Services**: ${environmentConfig.requiredServices?.length || 0} services
3707
4070
 
3708
4071
  ## ADR Discovery Results
3709
4072
  ${totalAdrs > 0 ?
@@ -3736,6 +4099,8 @@ ${adrTaskMapping.missing.length > 0 ?
3736
4099
 
3737
4100
  ${fileCheckResults || '### File Existence Validation\n- File checks disabled or no project structure available'}
3738
4101
 
4102
+ ${environmentAnalysisResults || ''}
4103
+
3739
4104
  ${mockAnalysisResults || ''}
3740
4105
 
3741
4106
  ## Recommendations
@@ -3746,10 +4111,14 @@ ${alignmentScore < 70 ?
3746
4111
  '1. **Maintain Current Alignment**: Continue following ADR specifications'}
3747
4112
  ${completedTasks < totalTasks * 0.5 ?
3748
4113
  '\n3. **Accelerate Implementation**: Focus on completing pending tasks' : ''}
4114
+ ${environmentValidation && environment === 'production' && alignmentScore < 90 ?
4115
+ '\n4. **⚠️ Production Environment Warning**: Current alignment may not meet production requirements' : ''}
3749
4116
 
3750
4117
  ### Medium Priority Actions
3751
4118
  1. **Review Implementation Quality**: ${strictMode ? 'Strict mode analysis above shows' : 'Consider enabling strict mode for'} detailed quality assessment
3752
4119
  2. **Update Documentation**: Ensure TODO.md reflects current project state
4120
+ ${environmentValidation ?
4121
+ `3. **Environment Compliance**: Ensure ${environment} environment requirements are met` : ''}
3753
4122
 
3754
4123
  ### Low Priority Actions
3755
4124
  1. **Optimize Workflow**: Consider tools for automated ADR-TODO synchronization
@@ -3825,9 +4194,9 @@ To re-run this validation with strict mode:
3825
4194
  return tasks;
3826
4195
  }
3827
4196
  /**
3828
- * Map TODO tasks to ADRs to identify alignment
4197
+ * Map TODO tasks to ADRs to identify alignment (now environment-aware)
3829
4198
  */
3830
- mapTasksToAdrs(tasks, adrs) {
4199
+ mapTasksToAdrs(tasks, adrs, environment, environmentConfig) {
3831
4200
  const aligned = [];
3832
4201
  const misaligned = [];
3833
4202
  const missing = [];
@@ -3837,10 +4206,25 @@ To re-run this validation with strict mode:
3837
4206
  ...(adr.decision || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4),
3838
4207
  ...(adr.context || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4)
3839
4208
  ]);
4209
+ // Environment-specific keywords that should be prioritized
4210
+ const envKeywords = [];
4211
+ if (environment && environmentConfig) {
4212
+ if (environment === 'production') {
4213
+ envKeywords.push('deploy', 'production', 'monitoring', 'security', 'performance');
4214
+ }
4215
+ else if (environment === 'staging') {
4216
+ envKeywords.push('test', 'staging', 'integration', 'validation');
4217
+ }
4218
+ else if (environment === 'development') {
4219
+ envKeywords.push('setup', 'development', 'local', 'debug');
4220
+ }
4221
+ }
3840
4222
  for (const task of tasks) {
3841
4223
  const taskLower = task.title.toLowerCase();
3842
4224
  const hasKeywordMatch = adrKeywords.some(keyword => taskLower.includes(keyword) || keyword.includes(taskLower.split(' ')[0]));
3843
- if (hasKeywordMatch) {
4225
+ // Environment-aware alignment scoring
4226
+ const hasEnvKeywordMatch = envKeywords.some(keyword => taskLower.includes(keyword));
4227
+ if (hasKeywordMatch || hasEnvKeywordMatch) {
3844
4228
  aligned.push(task);
3845
4229
  }
3846
4230
  else {
@@ -3860,6 +4244,25 @@ To re-run this validation with strict mode:
3860
4244
  }
3861
4245
  }
3862
4246
  }
4247
+ // Environment-specific missing tasks
4248
+ if (environment && environmentConfig) {
4249
+ if (environmentConfig.requiredFiles) {
4250
+ for (const file of environmentConfig.requiredFiles) {
4251
+ const hasFileTask = tasks.some(task => task.title.toLowerCase().includes(file.toLowerCase()));
4252
+ if (!hasFileTask) {
4253
+ missing.push(`Create ${file} for ${environment} environment`);
4254
+ }
4255
+ }
4256
+ }
4257
+ if (environmentConfig.requiredServices) {
4258
+ for (const service of environmentConfig.requiredServices) {
4259
+ const hasServiceTask = tasks.some(task => task.title.toLowerCase().includes(service.toLowerCase()));
4260
+ if (!hasServiceTask) {
4261
+ missing.push(`Setup ${service} service for ${environment}`);
4262
+ }
4263
+ }
4264
+ }
4265
+ }
3863
4266
  return { aligned, misaligned, missing };
3864
4267
  }
3865
4268
  /**
@@ -3971,6 +4374,122 @@ To re-run this validation with strict mode:
3971
4374
  }
3972
4375
  return results;
3973
4376
  }
4377
+ /**
4378
+ * Calculate environment-specific compliance score
4379
+ */
4380
+ calculateEnvironmentScore(projectStructure, environment, environmentConfig) {
4381
+ if (!projectStructure || !environmentConfig)
4382
+ return 0;
4383
+ let score = 100; // Start with perfect score
4384
+ // Check required files
4385
+ if (environmentConfig.requiredFiles) {
4386
+ const allFiles = [
4387
+ ...projectStructure.packageFiles || [],
4388
+ ...projectStructure.configFiles || [],
4389
+ ...projectStructure.buildFiles || [],
4390
+ ...projectStructure.dockerFiles || [],
4391
+ ...projectStructure.ciFiles || [],
4392
+ ...projectStructure.scriptFiles || []
4393
+ ];
4394
+ const existingFiles = allFiles.map(f => f.filename);
4395
+ const missingFiles = environmentConfig.requiredFiles.filter((file) => !existingFiles.includes(file));
4396
+ // Deduct 10 points per missing required file
4397
+ score -= missingFiles.length * 10;
4398
+ }
4399
+ // Environment-specific penalties
4400
+ if (environment === 'production') {
4401
+ // Production requires higher standards
4402
+ if (!projectStructure.dockerFiles?.length)
4403
+ score -= 15;
4404
+ if (!projectStructure.ciFiles?.length)
4405
+ score -= 10;
4406
+ }
4407
+ return Math.max(score, 0);
4408
+ }
4409
+ /**
4410
+ * Perform environment compliance analysis
4411
+ */
4412
+ performEnvironmentComplianceAnalysis(projectStructure, environment, environmentConfig, strictMode) {
4413
+ if (!projectStructure || !environmentConfig) {
4414
+ return '\n### Environment Compliance Analysis\n- Environment analysis disabled or no project structure available\n';
4415
+ }
4416
+ let results = '\n### Environment Compliance Analysis\n';
4417
+ // Required files analysis
4418
+ if (environmentConfig.requiredFiles) {
4419
+ results += `#### Required Files for ${environment} Environment\n`;
4420
+ const allFiles = [
4421
+ ...projectStructure.packageFiles || [],
4422
+ ...projectStructure.configFiles || [],
4423
+ ...projectStructure.buildFiles || [],
4424
+ ...projectStructure.dockerFiles || [],
4425
+ ...projectStructure.ciFiles || [],
4426
+ ...projectStructure.scriptFiles || []
4427
+ ];
4428
+ const existingFiles = allFiles.map(f => f.filename);
4429
+ for (const requiredFile of environmentConfig.requiredFiles) {
4430
+ const exists = existingFiles.includes(requiredFile);
4431
+ results += `- ${exists ? '✅' : '❌'} **${requiredFile}**: ${exists ? 'Found' : 'Missing'}\n`;
4432
+ }
4433
+ }
4434
+ // Security level compliance
4435
+ if (environmentConfig.securityLevel) {
4436
+ results += `\n#### Security Level: ${environmentConfig.securityLevel}\n`;
4437
+ const securityIndicators = this.analyzeSecurityCompliance(projectStructure, environmentConfig.securityLevel);
4438
+ results += securityIndicators;
4439
+ }
4440
+ // Environment-specific recommendations
4441
+ results += `\n#### ${environment} Environment Recommendations\n`;
4442
+ switch (environment) {
4443
+ case 'production':
4444
+ results += '- ⚠️ **Production Critical**: Ensure monitoring, logging, and backup strategies are implemented\n';
4445
+ results += '- 🔒 **Security**: Implement comprehensive security measures\n';
4446
+ results += '- 📊 **Performance**: Monitor and optimize for production workloads\n';
4447
+ if (strictMode) {
4448
+ results += '- 🔍 **Strict Mode**: Enhanced validation enabled for production environment\n';
4449
+ }
4450
+ break;
4451
+ case 'staging':
4452
+ results += '- 🧪 **Testing**: Ensure comprehensive test coverage and validation\n';
4453
+ results += '- 📋 **Validation**: Implement environment parity checks\n';
4454
+ break;
4455
+ case 'development':
4456
+ results += '- 🛠️ **Development**: Focus on developer experience and debugging tools\n';
4457
+ results += '- 🔄 **Iteration**: Ensure fast feedback loops\n';
4458
+ break;
4459
+ }
4460
+ return results;
4461
+ }
4462
+ /**
4463
+ * Analyze security compliance based on security level
4464
+ */
4465
+ analyzeSecurityCompliance(projectStructure, securityLevel) {
4466
+ let results = '';
4467
+ const securityFiles = [
4468
+ ...projectStructure.configFiles || [],
4469
+ ...projectStructure.dockerFiles || []
4470
+ ].filter(file => file.filename.includes('security') ||
4471
+ file.filename.includes('auth') ||
4472
+ file.filename.includes('.env') ||
4473
+ file.filename === 'Dockerfile');
4474
+ const hasSecurityConfig = securityFiles.length > 0;
4475
+ switch (securityLevel) {
4476
+ case 'critical':
4477
+ results += `- ${hasSecurityConfig ? '✅' : '❌'} **Critical Security**: ${hasSecurityConfig ? 'Security configuration found' : 'No security configuration detected'}\n`;
4478
+ if (!hasSecurityConfig) {
4479
+ results += ' - **Action Required**: Implement comprehensive security measures\n';
4480
+ }
4481
+ break;
4482
+ case 'high':
4483
+ results += `- ${hasSecurityConfig ? '✅' : '⚠️'} **High Security**: ${hasSecurityConfig ? 'Some security configuration found' : 'Limited security configuration'}\n`;
4484
+ break;
4485
+ case 'medium':
4486
+ results += `- ℹ️ **Medium Security**: Basic security measures recommended\n`;
4487
+ break;
4488
+ default:
4489
+ results += `- ℹ️ **Security Level**: ${securityLevel} (consider increasing for production)\n`;
4490
+ }
4491
+ return results;
4492
+ }
3974
4493
  /**
3975
4494
  * Content masking tool implementations
3976
4495
  */
@@ -4765,6 +5284,15 @@ Please provide:
4765
5284
  throw new McpAdrError(`Smart score analysis failed: ${error instanceof Error ? error.message : String(error)}`, 'SMART_SCORE_ERROR');
4766
5285
  }
4767
5286
  }
5287
+ async mcpPlanning(args) {
5288
+ try {
5289
+ const { mcpPlanning } = await import('./tools/mcp-planning-tool.js');
5290
+ return await mcpPlanning(args);
5291
+ }
5292
+ catch (error) {
5293
+ throw new McpAdrError(`MCP planning failed: ${error instanceof Error ? error.message : String(error)}`, 'MCP_PLANNING_ERROR');
5294
+ }
5295
+ }
4768
5296
  }
4769
5297
  /**
4770
5298
  * Main execution
@@ -4833,4 +5361,5 @@ if (process.argv[1] && (process.argv[1].endsWith('index.js') ||
4833
5361
  process.exit(1);
4834
5362
  });
4835
5363
  }
5364
+ // Test comment for pre-commit hook
4836
5365
  //# sourceMappingURL=index.js.map