sdd-mcp-server 1.3.10 → 1.4.0

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.
@@ -0,0 +1,259 @@
1
+ import { analyzeProject } from './documentGenerator.js';
2
+ export async function generateRequirementsDocument(projectPath, featureName) {
3
+ const analysis = await analyzeProject(projectPath);
4
+ const desc = analysis.description || 'Feature requirements specification';
5
+ const obj = generateCoreObjective(analysis);
6
+ const acceptance = generateAcceptanceCriteria(analysis)
7
+ .map((c, i) => `${i + 1}. ${c}`)
8
+ .join('\n');
9
+ return `# Requirements Document
10
+
11
+ ## Introduction
12
+ ${featureName} - Requirements derived from codebase analysis.
13
+
14
+ **Project**: ${analysis.name}
15
+ **Description**: ${desc}
16
+
17
+ Generated on: ${new Date().toISOString()}
18
+
19
+ ## Functional Requirements
20
+
21
+ ### FR-1: Core Functionality
22
+ **Objective:** ${obj}
23
+
24
+ #### Acceptance Criteria
25
+ ${acceptance}
26
+
27
+ ### FR-2: Technology Integration
28
+ **Objective:** Integrate with the detected technology stack
29
+
30
+ #### Acceptance Criteria
31
+ ${generateTechRequirements(analysis).map((r, i) => `${i + 1}. ${r}`).join('\n')}
32
+
33
+ ### FR-3: Quality Standards
34
+ **Objective:** Meet quality, testing, and review standards
35
+
36
+ #### Acceptance Criteria
37
+ ${generateQualityRequirements(analysis).map((r, i) => `${i + 1}. ${r}`).join('\n')}
38
+
39
+ ## Non-Functional Requirements
40
+
41
+ ### NFR-1: Performance
42
+ - System SHALL respond within acceptable time limits
43
+ - Memory usage SHALL remain within reasonable bounds
44
+
45
+ ### NFR-2: Reliability
46
+ - System SHALL handle errors gracefully
47
+ - System SHALL maintain data integrity
48
+
49
+ ### NFR-3: Maintainability
50
+ - Code SHALL follow established conventions
51
+ - System SHALL be well-documented
52
+ `;
53
+ }
54
+ export async function generateDesignDocument(projectPath, featureName) {
55
+ const analysis = await analyzeProject(projectPath);
56
+ const arch = describeArchitecture(analysis);
57
+ const components = generateComponentList(analysis).map(c => `- **${c.name}**: ${c.description}`).join('\n');
58
+ const dataModels = generateDataModels(analysis).map(m => `- **${m}**: Data structure definition`).join('\n');
59
+ const techStack = generateDetailedTechStack(analysis);
60
+ return `# Technical Design Document
61
+
62
+ ## Project: ${featureName}
63
+
64
+ **Project Name:** ${analysis.name}
65
+ **Architecture:** ${analysis.architecture}
66
+ **Language:** ${analysis.language}
67
+
68
+ Generated on: ${new Date().toISOString()}
69
+
70
+ ## Architecture Overview
71
+
72
+ ### System Architecture
73
+ ${arch}
74
+
75
+ ### Key Components
76
+ ${components}
77
+
78
+ ### Data Models
79
+ ${dataModels}
80
+
81
+ ## Implementation Details
82
+
83
+ ### Technology Stack
84
+ ${techStack}
85
+
86
+ ### Dependencies
87
+ ${generateDependencySummary(analysis)}
88
+
89
+ ## Interface Specifications
90
+
91
+ ### Module Interfaces
92
+ ${generateModuleInterfaces(analysis)}
93
+
94
+ ## Configuration
95
+
96
+ ### Environment Variables
97
+ ${generateEnvVars(analysis)}
98
+
99
+ ### Build Configuration
100
+ ${generateBuildConfig(analysis)}
101
+ `;
102
+ }
103
+ export async function generateTasksDocument(projectPath, featureName) {
104
+ const analysis = await analyzeProject(projectPath);
105
+ const tasks = generateImplementationTasks(analysis);
106
+ const section = (title, list) => list.map((task, idx) => `- [ ] ${idx + 1}. ${task.title}
107
+ ${task.subtasks.map(s => ` - ${s}`).join('\n')}
108
+ - _Requirements: ${task.requirements}_`).join('\n\n');
109
+ return `# Implementation Plan
110
+
111
+ ## Project: ${featureName}
112
+
113
+ **Project Name:** ${analysis.name}
114
+ **Detected Stack:** ${[analysis.language, analysis.framework || '', analysis.buildTool || ''].filter(Boolean).join(' / ')}
115
+
116
+ Generated on: ${new Date().toISOString()}
117
+
118
+ ## Development Phase Tasks
119
+
120
+ ${section('Development', tasks.development)}
121
+
122
+ ## Integration Phase Tasks
123
+
124
+ ${section('Integration', tasks.integration)}
125
+
126
+ ## Quality & Testing Tasks
127
+
128
+ ${section('Quality', tasks.quality)}
129
+ `;
130
+ }
131
+ // Helpers derived from TemplateService, reduced and dependency-free
132
+ function generateCoreObjective(analysis) {
133
+ if (analysis.dependencies?.includes('@modelcontextprotocol/sdk'))
134
+ return 'Provide MCP tools for spec-driven development workflows';
135
+ if (analysis.framework === 'Express.js')
136
+ return 'Expose REST endpoints and middleware for business logic';
137
+ if (analysis.framework === 'React')
138
+ return 'Render interactive UI components with state management';
139
+ return 'Deliver feature-aligned functionality integrated with existing architecture';
140
+ }
141
+ function generateAcceptanceCriteria(analysis) {
142
+ const criteria = [
143
+ 'WHEN invoked THEN it SHALL execute without runtime errors',
144
+ 'IF input is invalid THEN it SHALL return meaningful errors',
145
+ 'WHILE under typical load IT SHALL meet performance targets'
146
+ ];
147
+ if (analysis.testFramework)
148
+ criteria.push('WHERE tests exist THEY SHALL pass with adequate coverage');
149
+ if (analysis.language === 'typescript')
150
+ criteria.push('WHEN type-checking THEN no TypeScript errors SHALL occur');
151
+ return criteria;
152
+ }
153
+ function generateTechRequirements(analysis) {
154
+ const out = ['Integrate with existing build and run scripts'];
155
+ if (analysis.dependencies?.includes('@modelcontextprotocol/sdk'))
156
+ out.push('Expose MCP-compliant tools over stdio');
157
+ if (analysis.buildTool)
158
+ out.push(`Provide build artifacts using ${analysis.buildTool}`);
159
+ return out;
160
+ }
161
+ function generateQualityRequirements(analysis) {
162
+ const out = ['Follow project coding conventions', 'Apply error handling and logging'];
163
+ if (analysis.testFramework)
164
+ out.push(`Include ${analysis.testFramework} tests for new code`);
165
+ return out;
166
+ }
167
+ function describeArchitecture(analysis) {
168
+ if (analysis.architecture === 'Domain-Driven Design (DDD)')
169
+ return 'Layered DDD: Domain, Application, Infrastructure, Presentation';
170
+ if (analysis.architecture.includes('API'))
171
+ return 'REST API with routing, middleware, services, and data access layers';
172
+ if (analysis.framework === 'MCP SDK')
173
+ return 'MCP server exposing development tools via stdio protocol';
174
+ return analysis.architecture || 'Modular architecture with clear separation of concerns';
175
+ }
176
+ function generateComponentList(analysis) {
177
+ const comps = [];
178
+ if (analysis.framework === 'MCP SDK') {
179
+ comps.push({ name: 'MCPServer', description: 'Handles stdio transport and tool registry' });
180
+ comps.push({ name: 'ToolHandlers', description: 'Implement SDD tools (init, requirements, design, tasks, etc.)' });
181
+ }
182
+ if (analysis.architecture.includes('API')) {
183
+ comps.push({ name: 'Controllers', description: 'HTTP route handlers' });
184
+ comps.push({ name: 'Services', description: 'Business logic orchestration' });
185
+ }
186
+ if (comps.length === 0)
187
+ comps.push({ name: 'CoreModule', description: 'Primary feature implementation module' });
188
+ return comps;
189
+ }
190
+ function generateDataModels(analysis) {
191
+ if (analysis.framework === 'MCP SDK')
192
+ return ['Tool', 'Request', 'Response'];
193
+ if (analysis.architecture.includes('API'))
194
+ return ['RequestDTO', 'ResponseDTO'];
195
+ return ['Entity', 'ValueObject'];
196
+ }
197
+ function generateDetailedTechStack(analysis) {
198
+ const parts = [];
199
+ parts.push(`- Runtime: ${analysis.language === 'typescript' ? 'Node.js (TypeScript)' : 'Node.js (JavaScript)'}`);
200
+ if (analysis.framework)
201
+ parts.push(`- Framework: ${analysis.framework}`);
202
+ if (analysis.buildTool)
203
+ parts.push(`- Build: ${analysis.buildTool}`);
204
+ if (analysis.testFramework)
205
+ parts.push(`- Testing: ${analysis.testFramework}`);
206
+ return parts.join('\n');
207
+ }
208
+ function generateDependencySummary(analysis) {
209
+ const deps = (analysis.dependencies || []).slice(0, 10).map((d) => `- ${d}`).join('\n');
210
+ const dev = (analysis.devDependencies || []).slice(0, 10).map((d) => `- ${d}`).join('\n');
211
+ return `#### Production\n${deps || '- (none)'}\n\n#### Development\n${dev || '- (none)'}`;
212
+ }
213
+ function generateModuleInterfaces(analysis) {
214
+ if (analysis.framework === 'MCP SDK') {
215
+ return `- registerTool(name: string, handler: (args) => Promise<unknown>)\n- connect(transport): Promise<void>`;
216
+ }
217
+ if (analysis.architecture.includes('API')) {
218
+ return `- handle(request): Response\n- service.process(input): Result`;
219
+ }
220
+ return `- execute(input): Output`;
221
+ }
222
+ function generateEnvVars(analysis) {
223
+ const envs = ['NODE_ENV', 'LOG_LEVEL'];
224
+ if (analysis.framework === 'MCP SDK')
225
+ envs.push('MCP_MODE');
226
+ return envs.map(e => `- ${e}`).join('\n');
227
+ }
228
+ function generateBuildConfig(analysis) {
229
+ if (analysis.buildTool)
230
+ return `Use ${analysis.buildTool} to emit production artifacts`;
231
+ return 'Use npm scripts (build/test/lint) defined in package.json';
232
+ }
233
+ function generateImplementationTasks(analysis) {
234
+ const dev = [
235
+ { title: 'Set up project scaffolding', subtasks: ['Initialize directories', 'Configure scripts'], requirements: 'FR-1' },
236
+ { title: 'Implement core feature logic', subtasks: ['Add modules', 'Wire integrations'], requirements: 'FR-1' }
237
+ ];
238
+ const integ = [
239
+ { title: 'Integrate with stack', subtasks: ['Validate build', 'Run dev server'], requirements: 'FR-2' }
240
+ ];
241
+ const quality = [
242
+ { title: 'Add tests and quality checks', subtasks: ['Unit tests', 'Lint/typecheck', 'Quality review'], requirements: 'FR-3' }
243
+ ];
244
+ // Tailor tasks if MCP or API
245
+ if (analysis.framework === 'MCP SDK') {
246
+ dev.unshift({ title: 'Expose MCP tools', subtasks: ['Register tools', 'Handle stdio transport'], requirements: 'FR-2' });
247
+ }
248
+ if (analysis.architecture.includes('API')) {
249
+ dev.unshift({ title: 'Add HTTP endpoints', subtasks: ['Define routes', 'Implement handlers'], requirements: 'FR-1' });
250
+ }
251
+ if (analysis.testFramework) {
252
+ quality[0].subtasks.unshift(`Set up ${analysis.testFramework}`);
253
+ }
254
+ if (analysis.language === 'typescript') {
255
+ quality[0].subtasks.push('Ensure type safety (tsc)');
256
+ }
257
+ return { development: dev, integration: integ, quality };
258
+ }
259
+ //# sourceMappingURL=specGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specGenerator.js","sourceRoot":"","sources":["../../src/utils/specGenerator.ts"],"names":[],"mappings":"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"}
@@ -26,13 +26,11 @@ export async function analyzeProject(projectPath) {
26
26
  packageManager: 'npm'
27
27
  };
28
28
 
29
- console.log(`Analyzing project at: ${projectPath}`);
30
29
 
31
30
  try {
32
31
  // Check for package.json
33
32
  const packageJsonPath = path.join(projectPath, 'package.json');
34
33
  if (fs.existsSync(packageJsonPath)) {
35
- console.log('Found package.json, parsing...');
36
34
  try {
37
35
  const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
38
36
  const packageJson = JSON.parse(packageJsonContent);
@@ -46,9 +44,7 @@ export async function analyzeProject(projectPath) {
46
44
  analysis.devDependencies = Object.keys(packageJson.devDependencies || {});
47
45
  analysis.scripts = packageJson.scripts || {};
48
46
 
49
- console.log(`Extracted: name=${analysis.name}, deps=${analysis.dependencies.length}, devDeps=${analysis.devDependencies.length}`);
50
47
  } catch (parseError) {
51
- console.log('Error parsing package.json:', parseError.message);
52
48
  // Use fallbacks if package.json is malformed
53
49
  analysis.name = getDirectoryBasedName(projectPath);
54
50
  analysis.description = generateSmartDescription(analysis.name);
@@ -103,17 +99,60 @@ export async function analyzeProject(projectPath) {
103
99
  analysis.buildTool = 'Rollup';
104
100
  }
105
101
  } else {
106
- console.log('No package.json found, using directory-based fallbacks');
107
102
  // No package.json found, use directory-based fallbacks
108
103
  analysis.name = getDirectoryBasedName(projectPath);
109
104
  analysis.description = generateSmartDescription(analysis.name);
110
105
  }
111
106
 
112
- // Check for Java/Maven/Gradle projects
107
+
108
+
109
+ // Check for yarn or pnpm
110
+ if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
111
+ analysis.packageManager = 'yarn';
112
+ } else if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
113
+ analysis.packageManager = 'pnpm';
114
+ }
115
+
116
+ // Scan directory structure
117
+ const items = fs.readdirSync(projectPath, { withFileTypes: true });
118
+ for (const item of items) {
119
+ if (item.isDirectory() && !item.name.startsWith('.') && item.name !== 'node_modules') {
120
+ analysis.directories.push(item.name);
121
+
122
+ // Check for test directories
123
+ if (item.name === 'test' || item.name === 'tests' || item.name === '__tests__' || item.name === 'spec') {
124
+ analysis.hasTests = true;
125
+ }
126
+ } else if (item.isFile()) {
127
+ analysis.files.push(item.name);
128
+
129
+ // Check for Docker
130
+ if (item.name === 'Dockerfile' || item.name === 'docker-compose.yml') {
131
+ analysis.hasDocker = true;
132
+ }
133
+
134
+ // Check for CI/CD
135
+ if (item.name === '.gitlab-ci.yml' || item.name === '.travis.yml' || item.name === 'Jenkinsfile') {
136
+ analysis.hasCI = true;
137
+ }
138
+ }
139
+ }
140
+
141
+ // Check for Java/Maven/Gradle projects (including multi-module projects)
113
142
  const pomPath = path.join(projectPath, 'pom.xml');
114
143
  const gradlePath = path.join(projectPath, 'build.gradle');
115
144
  const gradleKtsPath = path.join(projectPath, 'build.gradle.kts');
116
- if (fs.existsSync(pomPath) || fs.existsSync(gradlePath) || fs.existsSync(gradleKtsPath)) {
145
+
146
+ // Also check for Maven/Gradle projects in subdirectories (multi-module projects)
147
+ const hasSubmodulePom = analysis.directories.some(dir =>
148
+ fs.existsSync(path.join(projectPath, dir, 'pom.xml'))
149
+ );
150
+ const hasSubmoduleGradle = analysis.directories.some(dir =>
151
+ fs.existsSync(path.join(projectPath, dir, 'build.gradle')) ||
152
+ fs.existsSync(path.join(projectPath, dir, 'build.gradle.kts'))
153
+ );
154
+
155
+ if (fs.existsSync(pomPath) || fs.existsSync(gradlePath) || fs.existsSync(gradleKtsPath) || hasSubmodulePom || hasSubmoduleGradle) {
117
156
  analysis.language = 'java';
118
157
  if (fs.existsSync(pomPath)) {
119
158
  analysis.packageManager = 'maven';
@@ -134,6 +173,36 @@ export async function analyzeProject(projectPath) {
134
173
  analysis.hasTests = true;
135
174
  }
136
175
  } catch {}
176
+ } else if (hasSubmodulePom) {
177
+ // Analyze submodule pom.xml files for multi-module projects
178
+ analysis.packageManager = 'maven';
179
+ analysis.buildTool = 'Maven';
180
+ let foundSpringBoot = false;
181
+ let foundJUnit = false;
182
+
183
+ for (const dir of analysis.directories) {
184
+ const subPomPath = path.join(projectPath, dir, 'pom.xml');
185
+ if (fs.existsSync(subPomPath)) {
186
+ try {
187
+ const pom = fs.readFileSync(subPomPath, 'utf8');
188
+ if (/spring-boot/i.test(pom) || /org\.springframework\.boot/i.test(pom)) {
189
+ foundSpringBoot = true;
190
+ }
191
+ if (/junit|jupiter/i.test(pom)) {
192
+ foundJUnit = true;
193
+ }
194
+ } catch {}
195
+ }
196
+ }
197
+
198
+ if (foundSpringBoot) {
199
+ analysis.framework = 'Spring Boot';
200
+ analysis.architecture = 'Microservices (Spring Boot)';
201
+ }
202
+ if (foundJUnit) {
203
+ analysis.testFramework = 'JUnit';
204
+ analysis.hasTests = true;
205
+ }
137
206
  } else {
138
207
  analysis.packageManager = 'gradle';
139
208
  analysis.buildTool = 'Gradle';
@@ -159,38 +228,6 @@ export async function analyzeProject(projectPath) {
159
228
  }
160
229
  }
161
230
 
162
- // Check for yarn or pnpm
163
- if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
164
- analysis.packageManager = 'yarn';
165
- } else if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
166
- analysis.packageManager = 'pnpm';
167
- }
168
-
169
- // Scan directory structure
170
- const items = fs.readdirSync(projectPath, { withFileTypes: true });
171
- for (const item of items) {
172
- if (item.isDirectory() && !item.name.startsWith('.') && item.name !== 'node_modules') {
173
- analysis.directories.push(item.name);
174
-
175
- // Check for test directories
176
- if (item.name === 'test' || item.name === 'tests' || item.name === '__tests__' || item.name === 'spec') {
177
- analysis.hasTests = true;
178
- }
179
- } else if (item.isFile()) {
180
- analysis.files.push(item.name);
181
-
182
- // Check for Docker
183
- if (item.name === 'Dockerfile' || item.name === 'docker-compose.yml') {
184
- analysis.hasDocker = true;
185
- }
186
-
187
- // Check for CI/CD
188
- if (item.name === '.gitlab-ci.yml' || item.name === '.travis.yml' || item.name === 'Jenkinsfile') {
189
- analysis.hasCI = true;
190
- }
191
- }
192
- }
193
-
194
231
  // Check for GitHub Actions
195
232
  if (fs.existsSync(path.join(projectPath, '.github', 'workflows'))) {
196
233
  analysis.hasCI = true;
@@ -220,8 +257,7 @@ export async function analyzeProject(projectPath) {
220
257
 
221
258
  // Validate and improve analysis results before returning
222
259
  const finalAnalysis = validateAndImproveAnalysis(analysis, projectPath);
223
- console.log(`Final analysis: ${finalAnalysis.name} - ${finalAnalysis.architecture}`);
224
-
260
+
225
261
  return finalAnalysis;
226
262
  }
227
263
 
@@ -243,7 +279,16 @@ function getDirectoryBasedName(projectPath) {
243
279
  */
244
280
  function generateSmartDescription(projectName) {
245
281
  const name = projectName.toLowerCase();
246
-
282
+
283
+ if (name.includes('microservices') && name.includes('spring')) {
284
+ return 'Spring Boot microservices application demonstrating distributed architecture patterns and service communication';
285
+ }
286
+ if (name.includes('microservices')) {
287
+ return 'Microservices architecture demonstration with multiple independent services';
288
+ }
289
+ if (name.includes('spring') && name.includes('boot')) {
290
+ return 'Spring Boot application built with modern Java frameworks and best practices';
291
+ }
247
292
  if (name.includes('api')) {
248
293
  return `RESTful API service for ${projectName.replace(/api/i, '').trim()} application`;
249
294
  }
@@ -265,7 +310,7 @@ function generateSmartDescription(projectName) {
265
310
  if (name.includes('tool')) {
266
311
  return `Development tool for ${projectName.replace(/tool/i, '').trim()} workflows`;
267
312
  }
268
-
313
+
269
314
  return `${projectName} application providing core functionality and services`;
270
315
  }
271
316
 
@@ -309,8 +354,7 @@ function validateAndImproveAnalysis(analysis, projectPath) {
309
354
  export function generateProductDocument(analysis) {
310
355
  // Validate analysis has meaningful content
311
356
  if (isAnalysisGeneric(analysis)) {
312
- console.log('Analysis appears generic, enhancing with intelligent defaults');
313
- analysis = enhanceGenericAnalysis(analysis);
357
+ analysis = enhanceGenericAnalysis(analysis);
314
358
  }
315
359
 
316
360
  const features = extractFeatures(analysis);