sdd-mcp-server 1.3.10 → 1.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  A Model Context Protocol (MCP) server implementing Spec-Driven Development (SDD) workflows for AI-agent CLIs and IDEs like Claude Code, Cursor, and others.
8
8
 
9
- > **✅ v1.3.10 Update**: AI-driven MCP server with language-agnostic workflow tools. Fixed all hardcoded templates, made tools truly universal for any programming language/framework, and added comprehensive AGENTS.md support with complete steering file descriptions and inclusion modes. Perfect for Spring Boot, React, Python, Go, and any other project!
9
+ > **✅ v1.3.11 Update**: AI-driven MCP server with language-agnostic workflow tools. CRITICAL FIX: sdd-steering now generates actual analyzed content instead of instruction templates. Fixed all hardcoded templates, made tools truly universal for any programming language/framework. Perfect for Spring Boot, React, Python, Go, and any other project!
10
10
 
11
11
  ## 🚀 Quick Start
12
12
 
@@ -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);
package/mcp-server.js CHANGED
@@ -859,136 +859,13 @@ server.registerTool("sdd-steering", {
859
859
  updateMode = (productExists || techExists || structureExists) ? 'update' : 'create';
860
860
  }
861
861
 
862
- // Create AI-driven steering documents with project analysis instructions
863
- const productContent = `# Product Overview
862
+ // Generate actual analyzed content using documentGenerator functions
863
+ const analysis = await analyzeProject(currentPath);
864
+ const productContent = generateProductDocument(analysis);
865
+ const techContent = generateTechDocument(analysis);
866
+ const structureContent = generateStructureDocument(analysis);
864
867
 
865
- ## Project Analysis Required
866
-
867
- Please analyze the current project structure and create a comprehensive product overview document. Consider:
868
-
869
- 1. **Project Discovery**: Examine files, directory structure, configuration files, and documentation
870
- 2. **Purpose Identification**: Understand what this project/product does based on code, README, and structure
871
- 3. **Feature Analysis**: Identify key features and capabilities
872
- 4. **User Base**: Determine who uses this product and how
873
- 5. **Business Context**: Understand the value proposition and use cases
874
-
875
- ## Instructions for AI Agent
876
-
877
- Generate a product.md document that includes:
878
-
879
- ### Product Description
880
- - What this project/product does
881
- - Its primary purpose and goals
882
- - Key value propositions
883
-
884
- ### Core Features
885
- - Main features and capabilities
886
- - What makes it unique or valuable
887
-
888
- ### Target Users
889
- - Who uses this product
890
- - Primary user personas
891
- - Use cases and scenarios
892
-
893
- ### Success Metrics
894
- - How success is measured
895
- - Key performance indicators
896
- - Business objectives
897
-
898
- ## Current Project Information
899
- - Project Path: ${currentPath}
900
- - Mode: ${updateMode}
901
- - Analysis Date: ${new Date().toISOString()}
902
-
903
- **Note**: This template will be replaced by AI-generated content specific to your actual project.`;
904
-
905
- const techContent = `# Technology Stack
906
-
907
- ## Project Analysis Required
908
-
909
- Please analyze the current project's technology stack and create a comprehensive technical overview. Consider:
910
-
911
- 1. **Language Detection**: Identify primary programming languages used
912
- 2. **Framework Analysis**: Detect frameworks, libraries, and dependencies
913
- 3. **Architecture Review**: Understand the system architecture and patterns
914
- 4. **Build System**: Identify build tools, package managers, and deployment methods
915
- 5. **Development Environment**: Understand development setup and requirements
916
-
917
- ## Instructions for AI Agent
918
-
919
- Generate a tech.md document that includes:
920
-
921
- ### Technology Stack
922
- - Programming languages used
923
- - Frameworks and libraries
924
- - Key dependencies and their purposes
925
-
926
- ### Architecture
927
- - System architecture (monolith, microservices, etc.)
928
- - Design patterns employed
929
- - Database and storage solutions
930
-
931
- ### Development Environment
932
- - Required tools and versions
933
- - Build and deployment processes
934
- - Development workflows
935
-
936
- ### Dependencies
937
- - Production dependencies and their roles
938
- - Development dependencies and tooling
939
- - Version constraints and compatibility
940
-
941
- ## Current Project Information
942
- - Project Path: ${currentPath}
943
- - Mode: ${updateMode}
944
- - Analysis Date: ${new Date().toISOString()}
945
-
946
- **Note**: This template will be replaced by AI-generated content specific to your actual technology stack.`;
947
-
948
- const structureContent = `# Project Structure
949
-
950
- ## Project Analysis Required
951
-
952
- Please analyze the current project's organization and create a comprehensive structure overview. Consider:
953
-
954
- 1. **Directory Structure**: Examine folder organization and naming conventions
955
- 2. **Code Organization**: Understand how code is structured and modularized
956
- 3. **Configuration**: Identify configuration files and their purposes
957
- 4. **Documentation**: Locate and assess existing documentation
958
- 5. **Patterns**: Identify organizational patterns and conventions
959
-
960
- ## Instructions for AI Agent
961
-
962
- Generate a structure.md document that includes:
963
-
964
- ### File Organization
965
- - Directory structure and purpose of each folder
966
- - Naming conventions and patterns
967
- - Key files and their roles
968
-
969
- ### Code Architecture
970
- - How code is organized and modularized
971
- - Separation of concerns
972
- - Layer structure (if applicable)
973
-
974
- ### Configuration Management
975
- - Configuration files and their purposes
976
- - Environment-specific settings
977
- - Build and deployment configurations
978
-
979
- ### Documentation Structure
980
- - Location of documentation
981
- - Types of documentation available
982
- - Documentation standards and conventions
983
-
984
- ## Current Project Information
985
- - Project Path: ${currentPath}
986
- - Mode: ${updateMode}
987
- - Analysis Date: ${new Date().toISOString()}
988
-
989
- **Note**: This template will be replaced by AI-generated content specific to your actual project structure.`;
990
-
991
- // Write the AI-driven instruction documents
868
+ // Write the analyzed steering documents
992
869
  await fs.writeFile(path.join(steeringPath, 'product.md'), productContent);
993
870
  await fs.writeFile(path.join(steeringPath, 'tech.md'), techContent);
994
871
  await fs.writeFile(path.join(steeringPath, 'structure.md'), structureContent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdd-mcp-server",
3
- "version": "1.3.10",
3
+ "version": "1.3.11",
4
4
  "description": "MCP server for spec-driven development workflows across AI-agent CLIs and IDEs",
5
5
  "main": "dist/index.js",
6
6
  "bin": {