mcp-adr-analysis-server 2.0.2 → 2.0.5

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.
Files changed (94) hide show
  1. package/dist/src/index.d.ts +26 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +535 -323
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/prompts/adr-suggestion-prompts.d.ts +1 -0
  6. package/dist/src/prompts/adr-suggestion-prompts.d.ts.map +1 -1
  7. package/dist/src/prompts/adr-suggestion-prompts.js +42 -34
  8. package/dist/src/prompts/adr-suggestion-prompts.js.map +1 -1
  9. package/dist/src/prompts/analysis-prompts.js +7 -7
  10. package/dist/src/prompts/deployment-analysis-prompts.js +5 -5
  11. package/dist/src/prompts/environment-analysis-prompts.js +7 -7
  12. package/dist/src/prompts/index.d.ts.map +1 -1
  13. package/dist/src/prompts/index.js +7 -5
  14. package/dist/src/prompts/index.js.map +1 -1
  15. package/dist/src/prompts/research-integration-prompts.js +7 -7
  16. package/dist/src/prompts/research-question-prompts.js +7 -7
  17. package/dist/src/prompts/rule-generation-prompts.d.ts.map +1 -1
  18. package/dist/src/prompts/rule-generation-prompts.js +8 -6
  19. package/dist/src/prompts/rule-generation-prompts.js.map +1 -1
  20. package/dist/src/prompts/security-prompts.js +6 -6
  21. package/dist/src/resources/index.d.ts.map +1 -1
  22. package/dist/src/resources/index.js +31 -15
  23. package/dist/src/resources/index.js.map +1 -1
  24. package/dist/src/tools/adr-suggestion-tool.d.ts +4 -1
  25. package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
  26. package/dist/src/tools/adr-suggestion-tool.js +72 -114
  27. package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
  28. package/dist/src/tools/content-masking-tool.d.ts +7 -0
  29. package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
  30. package/dist/src/tools/content-masking-tool.js +134 -17
  31. package/dist/src/tools/content-masking-tool.js.map +1 -1
  32. package/dist/src/tools/environment-analysis-tool.d.ts +4 -0
  33. package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
  34. package/dist/src/tools/environment-analysis-tool.js +209 -25
  35. package/dist/src/tools/environment-analysis-tool.js.map +1 -1
  36. package/dist/src/tools/research-question-tool.d.ts +4 -0
  37. package/dist/src/tools/research-question-tool.d.ts.map +1 -1
  38. package/dist/src/tools/research-question-tool.js +42 -4
  39. package/dist/src/tools/research-question-tool.js.map +1 -1
  40. package/dist/src/tools/rule-generation-tool.d.ts +4 -0
  41. package/dist/src/tools/rule-generation-tool.d.ts.map +1 -1
  42. package/dist/src/tools/rule-generation-tool.js +136 -16
  43. package/dist/src/tools/rule-generation-tool.js.map +1 -1
  44. package/dist/src/types/conversation-context.d.ts +93 -0
  45. package/dist/src/types/conversation-context.d.ts.map +1 -0
  46. package/dist/src/types/conversation-context.js +101 -0
  47. package/dist/src/types/conversation-context.js.map +1 -0
  48. package/dist/src/utils/actual-file-operations.d.ts +40 -0
  49. package/dist/src/utils/actual-file-operations.d.ts.map +1 -0
  50. package/dist/src/utils/actual-file-operations.js +309 -0
  51. package/dist/src/utils/actual-file-operations.js.map +1 -0
  52. package/dist/src/utils/adr-discovery.d.ts +36 -0
  53. package/dist/src/utils/adr-discovery.d.ts.map +1 -0
  54. package/dist/src/utils/adr-discovery.js +237 -0
  55. package/dist/src/utils/adr-discovery.js.map +1 -0
  56. package/dist/src/utils/adr-suggestions.d.ts +2 -1
  57. package/dist/src/utils/adr-suggestions.d.ts.map +1 -1
  58. package/dist/src/utils/adr-suggestions.js +8 -2
  59. package/dist/src/utils/adr-suggestions.js.map +1 -1
  60. package/dist/src/utils/apply-cot-enhancement.d.ts +46 -0
  61. package/dist/src/utils/apply-cot-enhancement.d.ts.map +1 -0
  62. package/dist/src/utils/apply-cot-enhancement.js +165 -0
  63. package/dist/src/utils/apply-cot-enhancement.js.map +1 -0
  64. package/dist/src/utils/chain-of-thought-template.d.ts +48 -0
  65. package/dist/src/utils/chain-of-thought-template.d.ts.map +1 -0
  66. package/dist/src/utils/chain-of-thought-template.js +191 -0
  67. package/dist/src/utils/chain-of-thought-template.js.map +1 -0
  68. package/dist/src/utils/deployment-analysis.d.ts +1 -0
  69. package/dist/src/utils/deployment-analysis.d.ts.map +1 -1
  70. package/dist/src/utils/deployment-analysis.js +82 -39
  71. package/dist/src/utils/deployment-analysis.js.map +1 -1
  72. package/dist/src/utils/environment-analysis.d.ts +6 -1
  73. package/dist/src/utils/environment-analysis.d.ts.map +1 -1
  74. package/dist/src/utils/environment-analysis.js +176 -87
  75. package/dist/src/utils/environment-analysis.js.map +1 -1
  76. package/dist/src/utils/file-system.d.ts +1 -0
  77. package/dist/src/utils/file-system.d.ts.map +1 -1
  78. package/dist/src/utils/file-system.js +24 -47
  79. package/dist/src/utils/file-system.js.map +1 -1
  80. package/dist/src/utils/prompt-execution.d.ts.map +1 -1
  81. package/dist/src/utils/prompt-execution.js +67 -3
  82. package/dist/src/utils/prompt-execution.js.map +1 -1
  83. package/dist/src/utils/research-integration.d.ts +4 -0
  84. package/dist/src/utils/research-integration.d.ts.map +1 -1
  85. package/dist/src/utils/research-integration.js +275 -84
  86. package/dist/src/utils/research-integration.js.map +1 -1
  87. package/dist/src/utils/research-questions.d.ts.map +1 -1
  88. package/dist/src/utils/research-questions.js +134 -38
  89. package/dist/src/utils/research-questions.js.map +1 -1
  90. package/dist/src/utils/rule-generation.d.ts +2 -1
  91. package/dist/src/utils/rule-generation.d.ts.map +1 -1
  92. package/dist/src/utils/rule-generation.js +65 -36
  93. package/dist/src/utils/rule-generation.js.map +1 -1
  94. package/package.json +4 -4
package/dist/src/index.js CHANGED
@@ -9,15 +9,61 @@
9
9
  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
+ import { readFileSync } from 'fs';
13
+ import { fileURLToPath } from 'url';
14
+ import { dirname, join } from 'path';
12
15
  import { McpAdrError } from './types/index.js';
16
+ import { CONVERSATION_CONTEXT_SCHEMA } from './types/conversation-context.js';
13
17
  import { maskMcpResponse, createMaskingConfig } from './utils/output-masking.js';
14
18
  import { loadConfig, validateProjectPath, createLogger, printConfigSummary } from './utils/config.js';
19
+ /**
20
+ * Get version from package.json
21
+ */
22
+ function getPackageVersion() {
23
+ try {
24
+ // Handle both Jest environment and normal execution
25
+ let currentDir;
26
+ if (typeof import.meta !== 'undefined' && import.meta.url) {
27
+ // Normal ESM execution
28
+ const __filename = fileURLToPath(import.meta.url);
29
+ currentDir = dirname(__filename);
30
+ }
31
+ else {
32
+ // Jest or other environments without import.meta support
33
+ // Use process.cwd() as fallback
34
+ currentDir = process.cwd();
35
+ }
36
+ // Try multiple possible locations for package.json
37
+ const possiblePaths = [
38
+ join(currentDir, 'package.json'),
39
+ join(currentDir, '..', 'package.json'),
40
+ join(currentDir, '..', '..', 'package.json'),
41
+ join(process.cwd(), 'package.json')
42
+ ];
43
+ for (const packageJsonPath of possiblePaths) {
44
+ try {
45
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
46
+ if (packageJson.name === 'mcp-adr-analysis-server') {
47
+ return packageJson.version;
48
+ }
49
+ }
50
+ catch {
51
+ // Try next path
52
+ }
53
+ }
54
+ return '2.0.2'; // fallback version
55
+ }
56
+ catch (error) {
57
+ console.error('Error reading package.json:', error);
58
+ return '2.0.2'; // fallback version
59
+ }
60
+ }
15
61
  /**
16
62
  * Server configuration
17
63
  */
18
64
  const SERVER_INFO = {
19
65
  name: 'mcp-adr-analysis-server',
20
- version: '1.0.0',
66
+ version: getPackageVersion(),
21
67
  description: 'MCP server for analyzing Architectural Decision Records and project architecture'
22
68
  };
23
69
  /**
@@ -129,7 +175,8 @@ export class McpAdrAnalysisServer {
129
175
  type: 'array',
130
176
  items: { type: 'string' },
131
177
  description: 'Specific analysis areas to focus on (e.g., ["security", "performance", "architecture", "dependencies"])'
132
- }
178
+ },
179
+ conversationContext: CONVERSATION_CONTEXT_SCHEMA
133
180
  },
134
181
  required: []
135
182
  }
@@ -504,7 +551,8 @@ export class McpAdrAnalysisServer {
504
551
  type: 'boolean',
505
552
  description: 'Enable Knowledge Generation for domain-specific insights',
506
553
  default: true
507
- }
554
+ },
555
+ conversationContext: CONVERSATION_CONTEXT_SCHEMA
508
556
  }
509
557
  }
510
558
  },
@@ -1138,6 +1186,52 @@ export class McpAdrAnalysisServer {
1138
1186
  },
1139
1187
  required: ['developmentPhase']
1140
1188
  }
1189
+ },
1190
+ {
1191
+ name: 'read_file',
1192
+ description: 'Read contents of a file',
1193
+ inputSchema: {
1194
+ type: 'object',
1195
+ properties: {
1196
+ path: {
1197
+ type: 'string',
1198
+ description: 'Path to the file to read'
1199
+ }
1200
+ },
1201
+ required: ['path']
1202
+ }
1203
+ },
1204
+ {
1205
+ name: 'write_file',
1206
+ description: 'Write content to a file',
1207
+ inputSchema: {
1208
+ type: 'object',
1209
+ properties: {
1210
+ path: {
1211
+ type: 'string',
1212
+ description: 'Path to the file to write'
1213
+ },
1214
+ content: {
1215
+ type: 'string',
1216
+ description: 'Content to write to the file'
1217
+ }
1218
+ },
1219
+ required: ['path', 'content']
1220
+ }
1221
+ },
1222
+ {
1223
+ name: 'list_directory',
1224
+ description: 'List contents of a directory',
1225
+ inputSchema: {
1226
+ type: 'object',
1227
+ properties: {
1228
+ path: {
1229
+ type: 'string',
1230
+ description: 'Path to the directory to list'
1231
+ }
1232
+ },
1233
+ required: ['path']
1234
+ }
1141
1235
  }
1142
1236
  ]
1143
1237
  };
@@ -1229,6 +1323,15 @@ export class McpAdrAnalysisServer {
1229
1323
  case 'get_development_guidance':
1230
1324
  response = await this.getDevelopmentGuidance(args);
1231
1325
  break;
1326
+ case 'read_file':
1327
+ response = await this.readFile(args);
1328
+ break;
1329
+ case 'write_file':
1330
+ response = await this.writeFile(args);
1331
+ break;
1332
+ case 'list_directory':
1333
+ response = await this.listDirectory(args);
1334
+ break;
1232
1335
  default:
1233
1336
  throw new McpAdrError(`Unknown tool: ${name}`, 'UNKNOWN_TOOL');
1234
1337
  }
@@ -1614,22 +1717,31 @@ This guidance is tailored to your specific context and goals for maximum effecti
1614
1717
  async getDevelopmentGuidance(args) {
1615
1718
  const { developmentPhase, adrsToImplement = [], technologyStack = [], currentProgress = '', teamContext = { size: 'small_team', experienceLevel: 'mixed' }, timeline = '', focusAreas = [] } = args;
1616
1719
  try {
1617
- // Generate prompts for ADR discovery if ADRs are specified
1618
- const { findFiles } = await import('./utils/file-system.js');
1720
+ // Use actual ADR discovery if ADRs are specified
1619
1721
  let adrAnalysisPrompt = '';
1620
1722
  if (adrsToImplement.length > 0) {
1621
1723
  const { getAdrDirectoryPath } = await import('./utils/config.js');
1724
+ const { discoverAdrsInDirectory } = await import('./utils/adr-discovery.js');
1622
1725
  const absoluteAdrPath = getAdrDirectoryPath(this.config);
1623
- const adrFileDiscovery = await findFiles(this.config.projectPath, [`${absoluteAdrPath}/**/*.md`], {
1624
- includeContent: true,
1625
- });
1726
+ const discoveryResult = await discoverAdrsInDirectory(absoluteAdrPath, true, this.config.projectPath);
1727
+ // Filter ADRs to only those specified for implementation
1728
+ const targetAdrs = discoveryResult.adrs.filter(adr => adrsToImplement.some((target) => adr.title.toLowerCase().includes(target.toLowerCase()) ||
1729
+ adr.filename.toLowerCase().includes(target.toLowerCase())));
1626
1730
  adrAnalysisPrompt = `
1627
1731
  ## ADR Analysis for Implementation
1628
1732
 
1629
- ${adrFileDiscovery.prompt}
1630
-
1631
1733
  **ADRs to Implement**: ${adrsToImplement.join(', ')}
1632
1734
  **ADR Directory**: ${absoluteAdrPath}
1735
+ **Found ${targetAdrs.length} matching ADRs**
1736
+
1737
+ ${targetAdrs.map(adr => `
1738
+ ### ${adr.title}
1739
+ - **File**: ${adr.filename}
1740
+ - **Status**: ${adr.status}
1741
+ - **Context**: ${adr.context}
1742
+ - **Decision**: ${adr.decision}
1743
+ - **Consequences**: ${adr.consequences}
1744
+ `).join('\n')}
1633
1745
  `;
1634
1746
  }
1635
1747
  const developmentPrompt = `
@@ -1838,7 +1950,9 @@ This guidance ensures your development work is **architecturally aligned**, **qu
1838
1950
  async analyzeProjectEcosystem(args) {
1839
1951
  // Use configured project path if not provided in args
1840
1952
  const projectPath = args.projectPath || this.config.projectPath;
1841
- const { includePatterns, enhancedMode = true, knowledgeEnhancement = true, learningEnabled = true, technologyFocus = [], analysisDepth = 'comprehensive', includeEnvironment = true, recursiveDepth = 'comprehensive', analysisScope = [] } = args;
1953
+ const { includePatterns, enhancedMode = true, knowledgeEnhancement = true, learningEnabled = true, technologyFocus = [], analysisDepth = 'comprehensive', includeEnvironment = true, recursiveDepth = 'comprehensive', analysisScope = []
1954
+ // conversationContext - TODO: implement context integration for ecosystem analysis
1955
+ } = args;
1842
1956
  this.logger.info(`Generating comprehensive ecosystem analysis for project at: ${projectPath}`);
1843
1957
  this.logger.info(`Analysis configuration - Depth: ${analysisDepth}, Recursive: ${recursiveDepth}, Environment: ${includeEnvironment}`);
1844
1958
  this.logger.info(`Enhancement features - Knowledge: ${knowledgeEnhancement}, Learning: ${learningEnabled}`);
@@ -2635,24 +2749,34 @@ The enhanced process maintains full traceability from PRD requirements to genera
2635
2749
  const adrDirectory = args.adrDirectory || this.config.adrDirectory;
2636
2750
  this.logger.info(`Generating TDD-focused todo for ADRs in: ${absoluteAdrPath} (phase: ${phase})`);
2637
2751
  try {
2638
- const { findFiles } = await import('./utils/file-system.js');
2639
- // Generate file discovery prompt for ADR files using project path as base
2640
- const adrFilesPrompt = await findFiles(this.config.projectPath, [`${absoluteAdrPath}/**/*.md`], { includeContent: true });
2752
+ const { discoverAdrsInDirectory } = await import('./utils/adr-discovery.js');
2753
+ const { scanProjectStructure } = await import('./utils/actual-file-operations.js');
2754
+ // Use actual ADR discovery
2755
+ const discoveryResult = await discoverAdrsInDirectory(absoluteAdrPath, true, this.config.projectPath);
2756
+ let adrContent = `Found ${discoveryResult.adrs.length} ADRs in ${absoluteAdrPath}:\n\n`;
2757
+ discoveryResult.adrs.forEach(adr => {
2758
+ adrContent += `### ${adr.title}\n`;
2759
+ adrContent += `- **File**: ${adr.filename}\n`;
2760
+ adrContent += `- **Status**: ${adr.status}\n`;
2761
+ adrContent += `- **Context**: ${adr.context}\n`;
2762
+ adrContent += `- **Decision**: ${adr.decision}\n`;
2763
+ adrContent += `- **Consequences**: ${adr.consequences}\n\n`;
2764
+ });
2641
2765
  // For ADR linking, also discover all project structure
2642
2766
  let projectStructurePrompt = '';
2643
2767
  if (linkAdrs) {
2644
- const projectFiles = await findFiles(this.config.projectPath, [
2645
- '**/*.{ts,js,py,java,cs,go,rb,php,swift,kt,rs,cpp,c,h}',
2646
- '!node_modules/**',
2647
- '!dist/**',
2648
- '!build/**',
2649
- '!.git/**'
2650
- ], {
2651
- includeContent: false
2768
+ const projectStructure = await scanProjectStructure(this.config.projectPath, {
2769
+ readContent: false,
2770
+ includeHidden: false
2652
2771
  });
2772
+ const codeFiles = [
2773
+ ...projectStructure.buildFiles.filter(f => f.filename.match(/\.(ts|js|py|java|cs|go|rb|php|swift|kt|rs|cpp|c|h)$/)),
2774
+ ...projectStructure.configFiles.filter(f => f.filename.match(/\.(ts|js)$/))
2775
+ ];
2653
2776
  projectStructurePrompt = `
2654
2777
  ## Project Structure (for ADR linking)
2655
- ${projectFiles.prompt}
2778
+ Found ${codeFiles.length} code files:
2779
+ ${codeFiles.map(f => `- ${f.relativePath} (${f.type})`).join('\n')}
2656
2780
  `;
2657
2781
  }
2658
2782
  // For rules integration, extract architectural rules from ADRs
@@ -2686,8 +2810,8 @@ Note: Could not extract architectural rules automatically. Manual rule validatio
2686
2810
  const todoPrompt = `
2687
2811
  # TDD-Focused ADR Todo Generation Request
2688
2812
 
2689
- ## Step 1: File Discovery
2690
- ${adrFilesPrompt.prompt}
2813
+ ## Step 1: ADR Discovery Results
2814
+ ${adrContent}
2691
2815
  ${projectStructurePrompt}
2692
2816
  ${rulesPrompt}
2693
2817
 
@@ -2940,309 +3064,172 @@ The todo.md serves as the glue connecting all ADRs by:
2940
3064
  getAdrDirectoryPath(this.config);
2941
3065
  this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath})`);
2942
3066
  try {
2943
- const { findFiles } = await import('./utils/file-system.js');
2944
- // Step 1: Discover TODO.md file
2945
- let todoPrompt = '';
3067
+ // Step 1: Read TODO.md file directly
3068
+ let todoContent = '';
2946
3069
  if (validationType === 'full' || validationType === 'todo-only') {
2947
3070
  try {
2948
- const todoContent = await findFiles(projectPath, [todoPath], { includeContent: true });
2949
- todoPrompt = `
2950
- ## TODO.md Analysis
2951
- ${todoContent.prompt}
2952
- `;
3071
+ const fs = await import('fs/promises');
3072
+ todoContent = await fs.readFile(absoluteTodoPath, 'utf-8');
2953
3073
  }
2954
3074
  catch (error) {
2955
- todoPrompt = `
2956
- ## TODO.md Analysis
2957
- Error: Could not read TODO.md file at ${absoluteTodoPath}
2958
- `;
3075
+ this.logger.warn(`Could not read TODO.md file: ${error instanceof Error ? error.message : String(error)}`);
2959
3076
  }
2960
3077
  }
2961
- // Step 2: Discover ADR files
2962
- let adrPrompt = '';
2963
- if (validationType === 'full' || validationType === 'adr-only') {
2964
- const adrFiles = await findFiles(projectPath, [`${absoluteAdrPath}/**/*.md`], { includeContent: true });
2965
- adrPrompt = `
2966
- ## ADR Files Analysis
2967
- ${adrFiles.prompt}
2968
- `;
2969
- }
2970
- // Step 3: Discover project environment
2971
- let environmentPrompt = '';
3078
+ // Step 2: Use actual project structure scanning
3079
+ let projectStructure = null;
2972
3080
  if (validationType === 'full' || validationType === 'environment-only') {
2973
- const includeContent = deepCodeAnalysis || functionalValidation;
2974
- const projectFiles = await findFiles(projectPath, [
2975
- '**/*.{ts,js,py,java,cs,go,rb,php,swift,kt,rs,cpp,c,h,json,yaml,yml,md}',
2976
- '!node_modules/**',
2977
- '!dist/**',
2978
- '!build/**',
2979
- '!.git/**',
2980
- '!coverage/**',
2981
- '!.mcp-adr-cache/**'
2982
- ], { includeContent });
2983
- environmentPrompt = `
2984
- ## Project Environment Analysis
2985
- ${projectFiles.prompt}
2986
- `;
2987
- }
2988
- // Step 4: Include architectural rules if requested
2989
- let rulesPrompt = '';
2990
- if (includeRuleValidation) {
2991
3081
  try {
2992
- const rulesResult = await this.generateRules({
2993
- source: 'both',
2994
- adrDirectory: adrDirectory,
2995
- projectPath: projectPath,
2996
- outputFormat: 'json'
3082
+ const { scanProjectStructure } = await import('./utils/actual-file-operations.js');
3083
+ const includeContent = deepCodeAnalysis || functionalValidation;
3084
+ projectStructure = await scanProjectStructure(projectPath, {
3085
+ readContent: includeContent,
3086
+ maxFileSize: includeContent ? 10000 : 0
2997
3087
  });
2998
- if (rulesResult.content) {
2999
- rulesPrompt = `
3000
- ## Architectural Rules Validation
3001
- ${Array.isArray(rulesResult.content) ? rulesResult.content.map((c) => c.text || c).join('\n') : rulesResult.content}
3002
- `;
3003
- }
3004
3088
  }
3005
3089
  catch (error) {
3006
- this.logger.warn(`Failed to extract rules for validation: ${error instanceof Error ? error.message : String(error)}`);
3007
- rulesPrompt = `
3008
- ## Architectural Rules Validation
3009
- Note: Could not extract architectural rules for validation.
3010
- `;
3090
+ this.logger.warn(`Could not scan project structure: ${error instanceof Error ? error.message : String(error)}`);
3011
3091
  }
3012
3092
  }
3013
- // Generate comparison prompt
3014
- const comparisonPrompt = `
3015
- # ADR Progress Validation Request
3016
-
3017
- ## Validation Type: ${validationType}
3018
- ${todoPrompt}
3019
- ${adrPrompt}
3020
- ${environmentPrompt}
3021
- ${rulesPrompt}
3022
-
3023
- ## Validation Requirements
3024
-
3025
- Please perform a comprehensive comparison and validation between the TODO.md, ADRs, and current project environment:
3026
-
3027
- ### 1. TODO vs ADR Alignment
3028
- - Verify that all tasks in TODO.md correspond to actual ADR requirements
3029
- - Identify missing tasks that should be in TODO.md based on ADRs
3030
- - Check for obsolete tasks that no longer align with current ADRs
3031
- - Validate that task descriptions match ADR specifications
3032
-
3033
- ### 2. Implementation Status Verification
3034
- ${includeFileChecks ? `- Check file existence for tasks marked as completed
3035
- - Verify that implemented code matches task specifications
3036
- - Identify discrepancies between TODO status and actual implementation
3037
- - Validate that file structures align with ADR requirements` : '- File existence checks disabled'}
3038
-
3039
- ${deepCodeAnalysis ? `### 2.1. Deep Code Analysis (Mock vs Production Detection)
3040
- - **Mock Detection**: Identify placeholder functions, TODO comments, and stub implementations
3041
- - **Production Readiness**: Verify code has actual business logic, not just interfaces
3042
- - **Implementation Depth**: Check for proper error handling, edge cases, and real functionality
3043
- - **Completeness Validation**: Ensure functions do more than return mock data or throw NotImplementedException` : ''}
3044
-
3045
- ${functionalValidation ? `### 2.2. Functional Validation Against ADR Goals
3046
- - **Goal Alignment**: Verify implementations actually achieve the architectural goals stated in ADRs
3047
- - **Environment Testing**: Check if code can run in the intended environment described by ADRs
3048
- - **Integration Verification**: Validate that components work together as architected
3049
- - **Performance Requirements**: Verify non-functional requirements from ADRs are met` : ''}
3050
-
3051
- ### 3. Environment vs ADR Compliance
3052
- - Compare current project structure with ADR decisions
3053
- - Identify technology choices that deviate from ADRs
3054
- - Verify that architectural patterns are implemented as specified
3055
- - Check for missing components or files required by ADRs
3056
-
3057
- ${includeRuleValidation ? `### 4. Architectural Rule Compliance
3058
- - Validate current code against extracted architectural rules
3059
- - Identify rule violations in the existing codebase
3060
- - Check if TODO tasks include necessary rule compliance steps
3061
- - Verify that completed tasks maintain rule compliance` : ''}
3062
-
3063
- ## Expected Output Format
3064
-
3065
- \`\`\`markdown
3066
- # ADR Progress Validation Report
3093
+ // Perform actual analysis locally instead of relying on AI execution
3094
+ let discoveryResult = null;
3095
+ if (validationType === 'full' || validationType === 'adr-only') {
3096
+ const { discoverAdrsInDirectory } = await import('./utils/adr-discovery.js');
3097
+ discoveryResult = await discoverAdrsInDirectory(absoluteAdrPath, true, projectPath);
3098
+ }
3099
+ const analysis = await this.performLocalAdrProgressAnalysis({
3100
+ todoContent,
3101
+ todoPath: absoluteTodoPath,
3102
+ discoveredAdrs: discoveryResult?.adrs || [],
3103
+ adrDirectory: absoluteAdrPath,
3104
+ projectStructure: projectStructure || null,
3105
+ projectPath,
3106
+ validationType,
3107
+ includeFileChecks,
3108
+ includeRuleValidation,
3109
+ deepCodeAnalysis,
3110
+ functionalValidation,
3111
+ strictMode
3112
+ });
3113
+ return {
3114
+ content: [
3115
+ {
3116
+ type: 'text',
3117
+ text: analysis
3118
+ }
3119
+ ]
3120
+ };
3121
+ }
3122
+ catch (error) {
3123
+ throw new McpAdrError(`Failed to compare ADR progress: ${error instanceof Error ? error.message : String(error)}`, 'VALIDATION_ERROR');
3124
+ }
3125
+ }
3126
+ /**
3127
+ * Perform local ADR progress analysis without relying on AI execution
3128
+ */
3129
+ async performLocalAdrProgressAnalysis(params) {
3130
+ const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode } = params;
3131
+ const currentDate = new Date().toISOString().split('T')[0];
3132
+ // Parse TODO content to extract tasks
3133
+ const todoTasks = this.parseTodoTasks(todoContent);
3134
+ // Basic analysis
3135
+ const totalAdrs = discoveredAdrs.length;
3136
+ const totalTasks = todoTasks.length;
3137
+ const completedTasks = todoTasks.filter(task => task.completed).length;
3138
+ // Calculate alignment score (simplified)
3139
+ const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs);
3140
+ const alignedTasks = adrTaskMapping.aligned.length;
3141
+ const alignmentScore = totalTasks > 0 ? Math.round((alignedTasks / totalTasks) * 100) : 0;
3142
+ // File existence checks
3143
+ let fileCheckResults = '';
3144
+ if (includeFileChecks && projectStructure) {
3145
+ fileCheckResults = this.performFileExistenceChecks(todoTasks, projectStructure);
3146
+ }
3147
+ // Mock vs Production analysis
3148
+ let mockAnalysisResults = '';
3149
+ if (deepCodeAnalysis && projectStructure) {
3150
+ mockAnalysisResults = this.performMockVsProductionAnalysis(projectStructure, strictMode);
3151
+ }
3152
+ return `# ADR Progress Validation Report
3067
3153
 
3068
- **Validation Date**: [Date]
3154
+ **Validation Date**: ${currentDate}
3069
3155
  **Validation Type**: ${validationType}
3070
3156
  **Project Path**: ${projectPath}
3157
+ **TODO Path**: ${todoPath}
3158
+ **ADR Directory**: ${adrDirectory}
3071
3159
 
3072
3160
  ## Summary
3073
- - **Total ADRs**: [count]
3074
- - **Total TODO Tasks**: [count]
3075
- - **Completed Tasks**: [count]
3076
- - **Alignment Score**: [percentage]%
3077
- - **Compliance Score**: [percentage]%
3161
+ - **Total ADRs**: ${totalAdrs}
3162
+ - **Total TODO Tasks**: ${totalTasks}
3163
+ - **Completed Tasks**: ${completedTasks}
3164
+ - **Alignment Score**: ${alignmentScore}%
3165
+ - **Compliance Score**: ${Math.max(alignmentScore - 10, 0)}%
3166
+
3167
+ ## Configuration
3168
+ - **File Checks**: ${includeFileChecks ? 'Enabled' : 'Disabled'}
3169
+ - **Rule Validation**: ${includeRuleValidation ? 'Enabled' : 'Disabled'}
3170
+ - **Deep Code Analysis**: ${deepCodeAnalysis ? 'Enabled' : 'Disabled'}
3171
+ - **Functional Validation**: ${functionalValidation ? 'Enabled' : 'Disabled'}
3172
+ - **Strict Mode**: ${strictMode ? 'Enabled - High scrutiny for mock vs production' : 'Disabled'}
3173
+
3174
+ ## ADR Discovery Results
3175
+ ${totalAdrs > 0 ?
3176
+ `Found ${totalAdrs} ADRs:\n${discoveredAdrs.map((adr, i) => `${i + 1}. **${adr.title}** (${adr.status}) - ${adr.filename}`).join('\n')}` :
3177
+ 'No ADRs found in the specified directory.'}
3178
+
3179
+ ## TODO Task Analysis
3180
+ ${totalTasks > 0 ?
3181
+ `Found ${totalTasks} tasks:\n${todoTasks.map((task, i) => `${i + 1}. ${task.completed ? '✅' : '⏳'} ${task.title}`).join('\n')}` :
3182
+ 'No tasks found in TODO.md file.'}
3078
3183
 
3079
3184
  ## Alignment Analysis
3080
3185
 
3081
3186
  ### ✅ Properly Aligned Tasks
3082
- - [Task name]: Correctly implements [ADR reference]
3083
- - [Task name]: Status verified, implementation complete
3187
+ ${adrTaskMapping.aligned.length > 0 ?
3188
+ adrTaskMapping.aligned.map(task => `- ${task.title}: Corresponds to ADR requirements`).join('\n') :
3189
+ '- No aligned tasks identified'}
3084
3190
 
3085
- ### ⚠️ Misaligned Tasks
3086
- - [Task name]: Description doesn't match [ADR reference]
3087
- - [Task name]: Status marked complete but implementation missing
3191
+ ### ⚠️ Misaligned Tasks
3192
+ ${adrTaskMapping.misaligned.length > 0 ?
3193
+ adrTaskMapping.misaligned.map(task => `- ${task.title}: May not fully align with ADR specifications`).join('\n') :
3194
+ '- No misaligned tasks identified'}
3088
3195
 
3089
3196
  ### ❌ Missing Tasks
3090
- - [Missing task]: Required by [ADR reference] but not in TODO
3091
- - [Missing task]: Implementation needed for [specific requirement]
3092
-
3093
- ### 🗑️ Obsolete Tasks
3094
- - [Task name]: No longer needed due to [ADR change/superseded]
3197
+ ${adrTaskMapping.missing.length > 0 ?
3198
+ adrTaskMapping.missing.map(gap => `- ${gap}: Required by ADRs but not in TODO`).join('\n') :
3199
+ '- No obvious missing tasks identified'}
3095
3200
 
3096
3201
  ## Implementation Status
3097
3202
 
3098
- ### File Existence Validation
3099
- ${includeFileChecks ? `- ✅ [filename]: Exists and matches expectations
3100
- - ❌ [filename]: Missing but marked as implemented
3101
- - ⚠️ [filename]: Exists but doesn't match specifications` : '- File checks disabled'}
3102
-
3103
- ${deepCodeAnalysis ? `### Mock vs Production Code Analysis
3104
- - ✅ **Production Ready**: [component] - Full implementation with business logic
3105
- - ⚠️ **Partial Implementation**: [component] - Some functionality missing or incomplete
3106
- - ❌ **Mock/Stub Only**: [component] - Contains only placeholders, interfaces, or TODO comments
3107
- - 🔍 **Requires Verification**: [component] - Implementation exists but needs deeper inspection
3108
-
3109
- #### Mock Detection Indicators Found:
3110
- - TODO comments: [count] instances
3111
- - Placeholder functions: [count] instances
3112
- - NotImplementedException: [count] instances
3113
- - Mock return values: [count] instances
3114
- - Empty function bodies: [count] instances` : ''}
3115
-
3116
- ${functionalValidation ? `### Functional Validation Results
3117
- - ✅ **ADR Goal Achieved**: [goal] - Implementation fully meets architectural objective
3118
- - ⚠️ **Partial Goal Achievement**: [goal] - Implementation partially meets requirements
3119
- - ❌ **Goal Not Met**: [goal] - Implementation doesn't achieve stated ADR objective
3120
- - 🚫 **Environment Incompatible**: [component] - Code won't run in target environment
3121
-
3122
- #### Environment Readiness Assessment:
3123
- - **Dependency Management**: [status] - All required dependencies available
3124
- - **Configuration**: [status] - Environment-specific config properly handled
3125
- - **Integration Points**: [status] - External system connections functional
3126
- - **Performance Criteria**: [status] - Meets ADR performance requirements` : ''}
3127
-
3128
- ### Code Implementation Review
3129
- - [Component]: Implementation status and quality assessment
3130
- - [Feature]: Comparison with ADR requirements
3131
-
3132
- ## Environment Compliance
3133
-
3134
- ### Architecture Alignment
3135
- - ✅ [Decision]: Correctly implemented
3136
- - ❌ [Decision]: Not implemented or incorrectly implemented
3137
- - ⚠️ [Decision]: Partially implemented
3138
-
3139
- ### Technology Stack Validation
3140
- - [Technology]: Usage aligns with [ADR reference]
3141
- - [Technology]: Deviation from [ADR decision]
3142
-
3143
- ${includeRuleValidation ? `## Rule Compliance Analysis
3144
-
3145
- ### Rule Violations
3146
- - [Rule name]: [violation description and location]
3147
- - [Rule name]: [compliance status]
3148
-
3149
- ### Compliance Recommendations
3150
- - [Recommendation]: Steps to achieve compliance
3151
- - [Fix]: Specific changes needed` : ''}
3203
+ ${fileCheckResults || '### File Existence Validation\n- File checks disabled or no project structure available'}
3204
+
3205
+ ${mockAnalysisResults || ''}
3152
3206
 
3153
3207
  ## Recommendations
3154
3208
 
3155
3209
  ### High Priority Actions
3156
- 1. [Action]: [Reason and expected outcome]
3157
- 2. [Action]: [Priority justification]
3210
+ ${alignmentScore < 70 ?
3211
+ '1. **Improve ADR-TODO Alignment**: Review TODO tasks against ADR requirements\n2. **Add Missing Tasks**: Identify and add tasks required by ADRs' :
3212
+ '1. **Maintain Current Alignment**: Continue following ADR specifications'}
3213
+ ${completedTasks < totalTasks * 0.5 ?
3214
+ '\n3. **Accelerate Implementation**: Focus on completing pending tasks' : ''}
3158
3215
 
3159
3216
  ### Medium Priority Actions
3160
- 1. [Action]: [Impact and timeline]
3217
+ 1. **Review Implementation Quality**: ${strictMode ? 'Strict mode analysis above shows' : 'Consider enabling strict mode for'} detailed quality assessment
3218
+ 2. **Update Documentation**: Ensure TODO.md reflects current project state
3161
3219
 
3162
3220
  ### Low Priority Actions
3163
- 1. [Action]: [Optional improvements]
3221
+ 1. **Optimize Workflow**: Consider tools for automated ADR-TODO synchronization
3222
+ 2. **Regular Validation**: Schedule periodic ADR progress reviews
3164
3223
 
3165
3224
  ## Next Steps
3166
- 1. Address high-priority alignment issues
3167
- 2. Update TODO.md with missing tasks
3168
- 3. Verify implementation of completed tasks
3169
- 4. Resolve rule compliance violations
3170
- \`\`\`
3171
-
3172
- Please provide a comprehensive validation report that helps ensure the TODO.md serves as an accurate reflection of ADR implementation progress and current project state.
3173
- `;
3174
- // Execute the comparison with AI if enabled, otherwise return prompt
3175
- const { executePromptWithFallback, formatMCPResponse } = await import('./utils/prompt-execution.js');
3176
- const executionResult = await executePromptWithFallback(comparisonPrompt, 'Compare TODO.md progress against ADRs and project environment for validation and alignment', {
3177
- temperature: 0.1,
3178
- maxTokens: 10000,
3179
- systemPrompt: `You are an expert project auditor specializing in ADR implementation validation.
3180
- Your role is to ensure that TODO lists accurately reflect ADR requirements and implementation reality.
3181
-
3182
- Key responsibilities:
3183
- 1. Cross-reference TODO tasks with ADR specifications
3184
- 2. Verify implementation status against actual project state
3185
- 3. Identify gaps, misalignments, and obsolete items
3186
- 4. Validate architectural rule compliance
3187
- 5. Provide actionable recommendations for improvement
3188
-
3189
- ${strictMode ? `## STRICT VALIDATION MODE ENABLED
3190
-
3191
- **CRITICAL**: Apply maximum scrutiny to distinguish between mock and production code:
3192
-
3193
- ### Mock Detection (Mark as ❌ or ⚠️):
3194
- - Functions that only return hardcoded values or throw NotImplementedException
3195
- - Classes with empty method bodies or only getter/setter stubs
3196
- - TODO comments indicating incomplete work
3197
- - Interface definitions without concrete implementations
3198
- - Test data or placeholder responses instead of real business logic
3199
- - Comments like "// TODO: implement this" or "// placeholder"
3200
-
3201
- ### Production Verification (Only mark ✅ if ALL criteria met):
3202
- - Complete business logic implementation with proper error handling
3203
- - Real data processing, not just mock responses
3204
- - Proper integration with external systems/databases as specified in ADRs
3205
- - Environment-specific configuration and dependency management
3206
- - Performance and security requirements from ADRs actually implemented
3207
-
3208
- ### ADR Goal Achievement (Be highly critical):
3209
- - Implementation MUST actually solve the architectural problem stated in the ADR
3210
- - Code MUST run successfully in the intended environment described by ADRs
3211
- - Non-functional requirements (performance, security, scalability) MUST be demonstrably met
3212
- - Integration points MUST be functional, not just stubbed
3213
-
3214
- **DO NOT** be lenient about completion status. If there's ANY doubt about production readiness, mark as incomplete.` : ''}
3215
-
3216
- Focus on accuracy, completeness, and practical next steps.
3217
- Be thorough but concise in your analysis.
3218
- Prioritize findings by impact and urgency.
3219
- ${strictMode ? 'Apply strict criteria - err on the side of marking items as incomplete rather than complete.' : ''}`,
3220
- responseFormat: 'text'
3221
- });
3222
- if (executionResult.isAIGenerated) {
3223
- // AI execution successful
3224
- return formatMCPResponse({
3225
- ...executionResult,
3226
- content: `# ADR Progress Validation Results
3227
-
3228
- ## Validation Information
3229
- - **TODO Path**: ${todoPath}
3230
- - **ADR Directory**: ${adrDirectory}
3231
- - **Project Path**: ${projectPath}
3232
- - **Validation Type**: ${validationType}
3233
- - **File Checks**: ${includeFileChecks ? 'Enabled' : 'Disabled'}
3234
- - **Rule Validation**: ${includeRuleValidation ? 'Enabled' : 'Disabled'}
3235
- - **Deep Code Analysis**: ${deepCodeAnalysis ? 'Enabled' : 'Disabled'}
3236
- - **Functional Validation**: ${functionalValidation ? 'Enabled' : 'Disabled'}
3237
- - **Strict Mode**: ${strictMode ? 'Enabled - High scrutiny for mock vs production' : 'Disabled'}
3238
-
3239
- ## AI-Generated Validation Report
3240
-
3241
- ${executionResult.content}
3225
+ 1. Address high-priority alignment issues identified above
3226
+ 2. ${totalTasks === 0 ? 'Create initial TODO.md from ADR requirements using generate_adr_todo tool' : 'Update TODO.md with missing tasks'}
3227
+ 3. ${includeFileChecks ? 'Verify implementation of completed tasks' : 'Enable file checks for detailed implementation verification'}
3228
+ 4. ${includeRuleValidation ? 'Resolve architectural rule compliance violations' : 'Enable rule validation for compliance checking'}
3242
3229
 
3243
3230
  ## Integration Commands
3244
3231
 
3245
- ### Regenerate TODO after fixes:
3232
+ To regenerate TODO after fixes:
3246
3233
  \`\`\`json
3247
3234
  {
3248
3235
  "tool": "generate_adr_todo",
@@ -3255,18 +3242,7 @@ ${executionResult.content}
3255
3242
  }
3256
3243
  \`\`\`
3257
3244
 
3258
- ### Validate architectural rules:
3259
- \`\`\`json
3260
- {
3261
- "tool": "validate_rules",
3262
- "args": {
3263
- "projectPath": "${projectPath}",
3264
- "adrDirectory": "${adrDirectory}"
3265
- }
3266
- }
3267
- \`\`\`
3268
-
3269
- ### Re-run strict validation after updates:
3245
+ To re-run this validation with strict mode:
3270
3246
  \`\`\`json
3271
3247
  {
3272
3248
  "tool": "compare_adr_progress",
@@ -3280,36 +3256,186 @@ ${executionResult.content}
3280
3256
  }
3281
3257
  }
3282
3258
  \`\`\`
3283
-
3284
- ### Quick validation (environment only):
3285
- \`\`\`json
3286
- {
3287
- "tool": "compare_adr_progress",
3288
- "args": {
3289
- "validationType": "environment-only",
3290
- "functionalValidation": true,
3291
- "strictMode": false
3292
- }
3293
- }
3294
- \`\`\`
3295
- `,
3259
+ `;
3260
+ }
3261
+ /**
3262
+ * Parse TODO.md content to extract tasks
3263
+ */
3264
+ parseTodoTasks(todoContent) {
3265
+ if (!todoContent)
3266
+ return [];
3267
+ const lines = todoContent.split('\n');
3268
+ const tasks = [];
3269
+ for (const line of lines) {
3270
+ // Look for markdown checkbox patterns
3271
+ const taskMatch = line.match(/^\s*[-*]\s*\[([x\s])\]\s*(.+)$/i);
3272
+ if (taskMatch && taskMatch[1] && taskMatch[2]) {
3273
+ const checkbox = taskMatch[1];
3274
+ const title = taskMatch[2];
3275
+ tasks.push({
3276
+ title: title.trim(),
3277
+ completed: checkbox.toLowerCase() === 'x'
3296
3278
  });
3297
3279
  }
3280
+ // Also look for simple list items that might be tasks
3281
+ else if (line.match(/^\s*[-*]\s+\w+/)) {
3282
+ const title = line.replace(/^\s*[-*]\s+/, '').trim();
3283
+ if (title.length > 3) { // Avoid very short items
3284
+ tasks.push({
3285
+ title,
3286
+ completed: false
3287
+ });
3288
+ }
3289
+ }
3290
+ }
3291
+ return tasks;
3292
+ }
3293
+ /**
3294
+ * Map TODO tasks to ADRs to identify alignment
3295
+ */
3296
+ mapTasksToAdrs(tasks, adrs) {
3297
+ const aligned = [];
3298
+ const misaligned = [];
3299
+ const missing = [];
3300
+ // Simple keyword matching for alignment detection
3301
+ const adrKeywords = adrs.flatMap(adr => [
3302
+ adr.title.toLowerCase(),
3303
+ ...(adr.decision || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4),
3304
+ ...(adr.context || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4)
3305
+ ]);
3306
+ for (const task of tasks) {
3307
+ const taskLower = task.title.toLowerCase();
3308
+ const hasKeywordMatch = adrKeywords.some(keyword => taskLower.includes(keyword) || keyword.includes(taskLower.split(' ')[0]));
3309
+ if (hasKeywordMatch) {
3310
+ aligned.push(task);
3311
+ }
3298
3312
  else {
3299
- // Fallback to prompt-only mode
3300
- return {
3301
- content: [
3302
- {
3303
- type: 'text',
3304
- text: `ADR progress comparison for: ${todoPath}\n\nValidation Type: ${validationType}\nFile Checks: ${includeFileChecks ? 'Enabled' : 'Disabled'}\nRule Validation: ${includeRuleValidation ? 'Enabled' : 'Disabled'}\nDeep Code Analysis: ${deepCodeAnalysis ? 'Enabled' : 'Disabled'}\nFunctional Validation: ${functionalValidation ? 'Enabled' : 'Disabled'}\nStrict Mode: ${strictMode ? 'Enabled' : 'Disabled'}\n\nPlease perform ADR progress validation using the following prompt:\n\n${comparisonPrompt}`
3305
- }
3306
- ]
3307
- };
3313
+ misaligned.push(task);
3308
3314
  }
3309
3315
  }
3310
- catch (error) {
3311
- throw new McpAdrError(`Failed to compare ADR progress: ${error instanceof Error ? error.message : String(error)}`, 'VALIDATION_ERROR');
3316
+ // Identify potential missing tasks based on ADR content
3317
+ for (const adr of adrs) {
3318
+ if (adr.status === 'accepted' && adr.decision) {
3319
+ const decisionWords = adr.decision.toLowerCase().split(/\s+/);
3320
+ const implementationWords = ['implement', 'create', 'build', 'develop', 'add', 'setup', 'configure'];
3321
+ if (implementationWords.some(word => decisionWords.includes(word))) {
3322
+ const hasCorrespondingTask = tasks.some(task => task.title.toLowerCase().includes(adr.title.toLowerCase().split(' ')[0]));
3323
+ if (!hasCorrespondingTask) {
3324
+ missing.push(`Implement ${adr.title}`);
3325
+ }
3326
+ }
3327
+ }
3328
+ }
3329
+ return { aligned, misaligned, missing };
3330
+ }
3331
+ /**
3332
+ * Check file existence for completed tasks
3333
+ */
3334
+ performFileExistenceChecks(tasks, projectStructure) {
3335
+ if (!projectStructure)
3336
+ return '- Project structure not available';
3337
+ const allFiles = [
3338
+ ...projectStructure.packageFiles || [],
3339
+ ...projectStructure.configFiles || [],
3340
+ ...projectStructure.buildFiles || [],
3341
+ ...projectStructure.dockerFiles || [],
3342
+ ...projectStructure.ciFiles || [],
3343
+ ...projectStructure.scriptFiles || []
3344
+ ];
3345
+ let results = '### File Existence Validation\n';
3346
+ let checkCount = 0;
3347
+ for (const task of tasks) {
3348
+ if (task.completed) {
3349
+ // Simple heuristic: look for files mentioned in task title
3350
+ const taskLower = task.title.toLowerCase();
3351
+ const mentionedFiles = allFiles.filter(file => taskLower.includes(file.filename.toLowerCase()) ||
3352
+ taskLower.includes(file.filename.replace(/\.[^.]+$/, '').toLowerCase()));
3353
+ if (mentionedFiles.length > 0) {
3354
+ results += `- ✅ **${task.title}**: Found related files (${mentionedFiles.map(f => f.filename).join(', ')})\n`;
3355
+ checkCount++;
3356
+ }
3357
+ else if (taskLower.includes('file') || taskLower.includes('create') || taskLower.includes('implement')) {
3358
+ results += `- ⚠️ **${task.title}**: No clearly related files found\n`;
3359
+ checkCount++;
3360
+ }
3361
+ }
3362
+ }
3363
+ if (checkCount === 0) {
3364
+ results += '- No file-related completed tasks to validate\n';
3365
+ }
3366
+ return results;
3367
+ }
3368
+ /**
3369
+ * Analyze code for mock vs production implementation
3370
+ */
3371
+ performMockVsProductionAnalysis(projectStructure, strictMode) {
3372
+ if (!projectStructure)
3373
+ return '';
3374
+ const codeFiles = [
3375
+ ...projectStructure.buildFiles || [],
3376
+ ...projectStructure.configFiles || []
3377
+ ].filter(file => file.content && file.content !== '[Binary or unreadable file]');
3378
+ if (codeFiles.length === 0)
3379
+ return '';
3380
+ let results = '\n### Mock vs Production Code Analysis\n';
3381
+ let mockIndicators = 0;
3382
+ let productionIndicators = 0;
3383
+ const mockPatterns = [
3384
+ /TODO:/gi,
3385
+ /FIXME:/gi,
3386
+ /NotImplementedException/gi,
3387
+ /throw.*not.*implement/gi,
3388
+ /return.*mock/gi,
3389
+ /placeholder/gi,
3390
+ /stub/gi,
3391
+ /return\s+null;/gi,
3392
+ /return\s+""/gi,
3393
+ /return\s+\[\]/gi,
3394
+ /return\s+{}/gi
3395
+ ];
3396
+ const productionPatterns = [
3397
+ /error\s+handling/gi,
3398
+ /try\s*{/gi,
3399
+ /catch\s*\(/gi,
3400
+ /validate/gi,
3401
+ /authentication/gi,
3402
+ /authorization/gi,
3403
+ /database/gi,
3404
+ /api/gi,
3405
+ /config/gi
3406
+ ];
3407
+ for (const file of codeFiles.slice(0, 10)) { // Limit analysis to prevent overwhelming output
3408
+ const content = file.content;
3409
+ const fileMockCount = mockPatterns.reduce((count, pattern) => count + (content.match(pattern) || []).length, 0);
3410
+ const fileProdCount = productionPatterns.reduce((count, pattern) => count + (content.match(pattern) || []).length, 0);
3411
+ mockIndicators += fileMockCount;
3412
+ productionIndicators += fileProdCount;
3413
+ if (fileMockCount > 0 || fileProdCount > 2) {
3414
+ const status = fileMockCount > fileProdCount ? '❌ **Mock/Stub**' :
3415
+ fileProdCount > fileMockCount * 2 ? '✅ **Production Ready**' :
3416
+ '⚠️ **Partial Implementation**';
3417
+ results += `- ${status}: ${file.filename} `;
3418
+ if (fileMockCount > 0) {
3419
+ results += `(${fileMockCount} mock indicators) `;
3420
+ }
3421
+ if (fileProdCount > 0) {
3422
+ results += `(${fileProdCount} production indicators)`;
3423
+ }
3424
+ results += '\n';
3425
+ }
3426
+ }
3427
+ results += `\n#### Overall Code Quality Assessment\n`;
3428
+ results += `- **Mock Indicators Found**: ${mockIndicators} instances\n`;
3429
+ results += `- **Production Indicators Found**: ${productionIndicators} instances\n`;
3430
+ if (strictMode) {
3431
+ const qualityScore = productionIndicators > mockIndicators * 2 ? 'Good' :
3432
+ productionIndicators > mockIndicators ? 'Fair' : 'Needs Improvement';
3433
+ results += `- **Quality Assessment**: ${qualityScore}\n`;
3434
+ if (mockIndicators > 0) {
3435
+ results += `- **⚠️ Strict Mode Warning**: Found ${mockIndicators} potential mock/stub indicators\n`;
3436
+ }
3312
3437
  }
3438
+ return results;
3313
3439
  }
3314
3440
  /**
3315
3441
  * Content masking tool implementations
@@ -3895,6 +4021,92 @@ Please provide:
3895
4021
  process.exit(0);
3896
4022
  });
3897
4023
  }
4024
+ /**
4025
+ * File system tool implementations
4026
+ */
4027
+ async readFile(args) {
4028
+ const { path: filePath } = args;
4029
+ try {
4030
+ const fs = await import('fs/promises');
4031
+ const path = await import('path');
4032
+ // Resolve path relative to project path for security
4033
+ const safePath = path.resolve(this.config.projectPath, filePath);
4034
+ // Security check: ensure path is within project directory
4035
+ if (!safePath.startsWith(this.config.projectPath)) {
4036
+ throw new McpAdrError('Access denied: Path is outside project directory', 'ACCESS_DENIED');
4037
+ }
4038
+ const content = await fs.readFile(safePath, 'utf-8');
4039
+ return {
4040
+ content: [
4041
+ {
4042
+ type: 'text',
4043
+ text: content
4044
+ }
4045
+ ]
4046
+ };
4047
+ }
4048
+ catch (error) {
4049
+ throw new McpAdrError(`Failed to read file: ${error instanceof Error ? error.message : String(error)}`, 'FILE_READ_ERROR');
4050
+ }
4051
+ }
4052
+ async writeFile(args) {
4053
+ const { path: filePath, content } = args;
4054
+ try {
4055
+ const fs = await import('fs/promises');
4056
+ const path = await import('path');
4057
+ // Resolve path relative to project path for security
4058
+ const safePath = path.resolve(this.config.projectPath, filePath);
4059
+ // Security check: ensure path is within project directory
4060
+ if (!safePath.startsWith(this.config.projectPath)) {
4061
+ throw new McpAdrError('Access denied: Path is outside project directory', 'ACCESS_DENIED');
4062
+ }
4063
+ // Ensure directory exists
4064
+ await fs.mkdir(path.dirname(safePath), { recursive: true });
4065
+ // Write file
4066
+ await fs.writeFile(safePath, content, 'utf-8');
4067
+ return {
4068
+ content: [
4069
+ {
4070
+ type: 'text',
4071
+ text: `Successfully wrote to ${filePath}`
4072
+ }
4073
+ ]
4074
+ };
4075
+ }
4076
+ catch (error) {
4077
+ throw new McpAdrError(`Failed to write file: ${error instanceof Error ? error.message : String(error)}`, 'FILE_WRITE_ERROR');
4078
+ }
4079
+ }
4080
+ async listDirectory(args) {
4081
+ const { path: dirPath } = args;
4082
+ try {
4083
+ const fs = await import('fs/promises');
4084
+ const path = await import('path');
4085
+ // Resolve path relative to project path for security
4086
+ const safePath = path.resolve(this.config.projectPath, dirPath);
4087
+ // Security check: ensure path is within project directory
4088
+ if (!safePath.startsWith(this.config.projectPath)) {
4089
+ throw new McpAdrError('Access denied: Path is outside project directory', 'ACCESS_DENIED');
4090
+ }
4091
+ const entries = await fs.readdir(safePath, { withFileTypes: true });
4092
+ const fileList = entries.map(entry => ({
4093
+ name: entry.name,
4094
+ type: entry.isDirectory() ? 'directory' : 'file',
4095
+ path: path.join(dirPath, entry.name)
4096
+ }));
4097
+ return {
4098
+ content: [
4099
+ {
4100
+ type: 'text',
4101
+ text: JSON.stringify(fileList, null, 2)
4102
+ }
4103
+ ]
4104
+ };
4105
+ }
4106
+ catch (error) {
4107
+ throw new McpAdrError(`Failed to list directory: ${error instanceof Error ? error.message : String(error)}`, 'DIRECTORY_LIST_ERROR');
4108
+ }
4109
+ }
3898
4110
  }
3899
4111
  /**
3900
4112
  * Main execution