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.
- package/README.md +30 -5
- package/dist/index.js +41 -161
- package/dist/index.js.map +1 -1
- package/dist/utils/specGenerator.d.ts +3 -0
- package/dist/utils/specGenerator.js +259 -0
- package/dist/utils/specGenerator.js.map +1 -0
- package/documentGenerator.js +89 -45
- package/mcp-server.js +50 -164
- package/package.json +2 -1
- package/specGenerator.js +263 -0
|
@@ -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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"}
|
package/documentGenerator.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
313
|
-
analysis = enhanceGenericAnalysis(analysis);
|
|
357
|
+
analysis = enhanceGenericAnalysis(analysis);
|
|
314
358
|
}
|
|
315
359
|
|
|
316
360
|
const features = extractFeatures(analysis);
|