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
package/mcp-server.js
CHANGED
|
@@ -11,6 +11,26 @@ import {
|
|
|
11
11
|
generateStructureDocument
|
|
12
12
|
} from './documentGenerator.js';
|
|
13
13
|
|
|
14
|
+
// Best-effort dynamic loader for spec generators (requirements/design/tasks)
|
|
15
|
+
async function loadSpecGenerator() {
|
|
16
|
+
const tried = [];
|
|
17
|
+
const attempts = [
|
|
18
|
+
'./specGenerator.js', // root-level JS (dev/runtime)
|
|
19
|
+
'./dist/utils/specGenerator.js', // compiled TS output
|
|
20
|
+
'./utils/specGenerator.js' // TS runtime (when transpiled on-the-fly)
|
|
21
|
+
];
|
|
22
|
+
for (const p of attempts) {
|
|
23
|
+
try {
|
|
24
|
+
// eslint-disable-next-line no-await-in-loop
|
|
25
|
+
const mod = await import(p);
|
|
26
|
+
return { mod, path: p };
|
|
27
|
+
} catch (e) {
|
|
28
|
+
tried.push(`${p}: ${(e && e.message) || e}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`Unable to load specGenerator from known paths. Tried: \n- ${tried.join('\n- ')}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
14
34
|
// Resolve version dynamically from package.json when possible
|
|
15
35
|
async function resolveVersion() {
|
|
16
36
|
try {
|
|
@@ -172,39 +192,14 @@ server.registerTool("sdd-requirements", {
|
|
|
172
192
|
const specContent = await fs.readFile(specPath, 'utf8');
|
|
173
193
|
const spec = JSON.parse(specContent);
|
|
174
194
|
|
|
175
|
-
// Generate requirements
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
Please analyze the current project structure and the feature description above to generate comprehensive requirements. Consider:
|
|
185
|
-
|
|
186
|
-
1. **Project Analysis**: Examine the codebase structure, existing files, dependencies, and architecture patterns
|
|
187
|
-
2. **Feature Scope**: Based on the feature description, identify what needs to be built
|
|
188
|
-
3. **User Stories**: Create user stories that capture the value this feature provides
|
|
189
|
-
4. **Technical Requirements**: Identify technical constraints and integration points
|
|
190
|
-
5. **Acceptance Criteria**: Use EARS format (WHEN/IF/WHILE/WHERE) for testable criteria
|
|
191
|
-
|
|
192
|
-
## Requirements Generation Guidelines
|
|
193
|
-
|
|
194
|
-
Generate requirements that:
|
|
195
|
-
- Are specific to this actual project (not generic)
|
|
196
|
-
- Consider the existing codebase architecture
|
|
197
|
-
- Include functional and non-functional requirements
|
|
198
|
-
- Use EARS format for acceptance criteria
|
|
199
|
-
- Are testable and measurable
|
|
200
|
-
- Consider integration with existing features
|
|
201
|
-
|
|
202
|
-
## Current Project Information
|
|
203
|
-
- Project Path: ${process.cwd()}
|
|
204
|
-
- Feature Name: ${spec.feature_name}
|
|
205
|
-
- Initialization Date: ${spec.created_at}
|
|
206
|
-
|
|
207
|
-
**Note**: This template will be replaced by AI-generated requirements specific to your project and feature description.`;
|
|
195
|
+
// Generate requirements using specGenerator with fallback
|
|
196
|
+
let requirementsContent;
|
|
197
|
+
try {
|
|
198
|
+
const { mod } = await loadSpecGenerator();
|
|
199
|
+
requirementsContent = await mod.generateRequirementsDocument(currentPath, featureName);
|
|
200
|
+
} catch (e) {
|
|
201
|
+
requirementsContent = `# Requirements Document\n\n<!-- Warning: Analysis-backed generation failed. Using fallback template. -->\n<!-- Error: ${e && e.message ? e.message : String(e)} -->\n\n## Project Context\n**Feature**: ${spec.feature_name}\n**Description**: ${spec.description || 'Feature to be implemented'}\n`;
|
|
202
|
+
}
|
|
208
203
|
|
|
209
204
|
await fs.writeFile(path.join(featurePath, 'requirements.md'), requirementsContent);
|
|
210
205
|
|
|
@@ -266,8 +261,14 @@ server.registerTool("sdd-design", {
|
|
|
266
261
|
requirementsContext = 'Requirements document not available';
|
|
267
262
|
}
|
|
268
263
|
|
|
269
|
-
// Generate design
|
|
270
|
-
|
|
264
|
+
// Generate design using specGenerator with fallback
|
|
265
|
+
let designContent;
|
|
266
|
+
try {
|
|
267
|
+
const { mod } = await loadSpecGenerator();
|
|
268
|
+
designContent = await mod.generateDesignDocument(currentPath, featureName);
|
|
269
|
+
} catch (e) {
|
|
270
|
+
designContent = `# Technical Design Document\n\n<!-- Warning: Analysis-backed generation failed. Using fallback template. -->\n<!-- Error: ${e && e.message ? e.message : String(e)} -->\n\n## Project Context\n**Feature**: ${spec.feature_name}\n**Phase**: ${spec.phase}`;
|
|
271
|
+
}
|
|
271
272
|
|
|
272
273
|
await fs.writeFile(path.join(featurePath, 'design.md'), designContent);
|
|
273
274
|
|
|
@@ -384,6 +385,14 @@ ${designContext.substring(0, 1000)}${designContext.length > 1000 ? '...\n[Design
|
|
|
384
385
|
- Created: ${spec.created_at}
|
|
385
386
|
|
|
386
387
|
**Note**: This template will be replaced by AI-generated implementation tasks specific to your project requirements and design.`;
|
|
388
|
+
|
|
389
|
+
// Try to replace template with analysis-backed tasks
|
|
390
|
+
try {
|
|
391
|
+
const { mod } = await loadSpecGenerator();
|
|
392
|
+
tasksContent = await mod.generateTasksDocument(currentPath, featureName);
|
|
393
|
+
} catch (e) {
|
|
394
|
+
// Keep template; include debug info in file header already
|
|
395
|
+
}
|
|
387
396
|
|
|
388
397
|
await fs.writeFile(path.join(featurePath, 'tasks.md'), tasksContent);
|
|
389
398
|
|
|
@@ -859,136 +868,13 @@ server.registerTool("sdd-steering", {
|
|
|
859
868
|
updateMode = (productExists || techExists || structureExists) ? 'update' : 'create';
|
|
860
869
|
}
|
|
861
870
|
|
|
862
|
-
//
|
|
863
|
-
const
|
|
864
|
-
|
|
865
|
-
|
|
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.`;
|
|
871
|
+
// Generate actual analyzed content using documentGenerator functions
|
|
872
|
+
const analysis = await analyzeProject(currentPath);
|
|
873
|
+
const productContent = generateProductDocument(analysis);
|
|
874
|
+
const techContent = generateTechDocument(analysis);
|
|
875
|
+
const structureContent = generateStructureDocument(analysis);
|
|
990
876
|
|
|
991
|
-
// Write the
|
|
877
|
+
// Write the analyzed steering documents
|
|
992
878
|
await fs.writeFile(path.join(steeringPath, 'product.md'), productContent);
|
|
993
879
|
await fs.writeFile(path.join(steeringPath, 'tech.md'), techContent);
|
|
994
880
|
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
|
+
"version": "1.4.0",
|
|
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": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"dist/**/*",
|
|
13
13
|
"mcp-server.js",
|
|
14
14
|
"documentGenerator.js",
|
|
15
|
+
"specGenerator.js",
|
|
15
16
|
"README.md",
|
|
16
17
|
"LICENSE",
|
|
17
18
|
"package.json"
|
package/specGenerator.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { analyzeProject } from './documentGenerator.js';
|
|
2
|
+
|
|
3
|
+
export async function generateRequirementsDocument(projectPath, featureName) {
|
|
4
|
+
const analysis = await analyzeProject(projectPath);
|
|
5
|
+
const desc = analysis.description || 'Feature requirements specification';
|
|
6
|
+
const obj = generateCoreObjective(analysis);
|
|
7
|
+
const acceptance = generateAcceptanceCriteria(analysis)
|
|
8
|
+
.map((c, i) => `${i + 1}. ${c}`)
|
|
9
|
+
.join('\n');
|
|
10
|
+
|
|
11
|
+
return `# Requirements Document
|
|
12
|
+
|
|
13
|
+
## Introduction
|
|
14
|
+
${featureName} - Requirements derived from codebase analysis.
|
|
15
|
+
|
|
16
|
+
**Project**: ${analysis.name}
|
|
17
|
+
**Description**: ${desc}
|
|
18
|
+
|
|
19
|
+
Generated on: ${new Date().toISOString()}
|
|
20
|
+
|
|
21
|
+
## Functional Requirements
|
|
22
|
+
|
|
23
|
+
### FR-1: Core Functionality
|
|
24
|
+
**Objective:** ${obj}
|
|
25
|
+
|
|
26
|
+
#### Acceptance Criteria
|
|
27
|
+
${acceptance}
|
|
28
|
+
|
|
29
|
+
### FR-2: Technology Integration
|
|
30
|
+
**Objective:** Integrate with the detected technology stack
|
|
31
|
+
|
|
32
|
+
#### Acceptance Criteria
|
|
33
|
+
${generateTechRequirements(analysis).map((r, i) => `${i + 1}. ${r}`).join('\n')}
|
|
34
|
+
|
|
35
|
+
### FR-3: Quality Standards
|
|
36
|
+
**Objective:** Meet quality, testing, and review standards
|
|
37
|
+
|
|
38
|
+
#### Acceptance Criteria
|
|
39
|
+
${generateQualityRequirements(analysis).map((r, i) => `${i + 1}. ${r}`).join('\n')}
|
|
40
|
+
|
|
41
|
+
## Non-Functional Requirements
|
|
42
|
+
|
|
43
|
+
### NFR-1: Performance
|
|
44
|
+
- System SHALL respond within acceptable time limits
|
|
45
|
+
- Memory usage SHALL remain within reasonable bounds
|
|
46
|
+
|
|
47
|
+
### NFR-2: Reliability
|
|
48
|
+
- System SHALL handle errors gracefully
|
|
49
|
+
- System SHALL maintain data integrity
|
|
50
|
+
|
|
51
|
+
### NFR-3: Maintainability
|
|
52
|
+
- Code SHALL follow established conventions
|
|
53
|
+
- System SHALL be well-documented
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function generateDesignDocument(projectPath, featureName) {
|
|
58
|
+
const analysis = await analyzeProject(projectPath);
|
|
59
|
+
const arch = describeArchitecture(analysis);
|
|
60
|
+
const components = generateComponentList(analysis).map(c => `- **${c.name}**: ${c.description}`).join('\n');
|
|
61
|
+
const dataModels = generateDataModels(analysis).map(m => `- **${m}**: Data structure definition`).join('\n');
|
|
62
|
+
const techStack = generateDetailedTechStack(analysis);
|
|
63
|
+
|
|
64
|
+
return `# Technical Design Document
|
|
65
|
+
|
|
66
|
+
## Project: ${featureName}
|
|
67
|
+
|
|
68
|
+
**Project Name:** ${analysis.name}
|
|
69
|
+
**Architecture:** ${analysis.architecture}
|
|
70
|
+
**Language:** ${analysis.language}
|
|
71
|
+
|
|
72
|
+
Generated on: ${new Date().toISOString()}
|
|
73
|
+
|
|
74
|
+
## Architecture Overview
|
|
75
|
+
|
|
76
|
+
### System Architecture
|
|
77
|
+
${arch}
|
|
78
|
+
|
|
79
|
+
### Key Components
|
|
80
|
+
${components}
|
|
81
|
+
|
|
82
|
+
### Data Models
|
|
83
|
+
${dataModels}
|
|
84
|
+
|
|
85
|
+
## Implementation Details
|
|
86
|
+
|
|
87
|
+
### Technology Stack
|
|
88
|
+
${techStack}
|
|
89
|
+
|
|
90
|
+
### Dependencies
|
|
91
|
+
${generateDependencySummary(analysis)}
|
|
92
|
+
|
|
93
|
+
## Interface Specifications
|
|
94
|
+
|
|
95
|
+
### Module Interfaces
|
|
96
|
+
${generateModuleInterfaces(analysis)}
|
|
97
|
+
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
100
|
+
### Environment Variables
|
|
101
|
+
${generateEnvVars(analysis)}
|
|
102
|
+
|
|
103
|
+
### Build Configuration
|
|
104
|
+
${generateBuildConfig(analysis)}
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export async function generateTasksDocument(projectPath, featureName) {
|
|
109
|
+
const analysis = await analyzeProject(projectPath);
|
|
110
|
+
const tasks = generateImplementationTasks(analysis);
|
|
111
|
+
|
|
112
|
+
const section = (title, list) =>
|
|
113
|
+
list.map((task, idx) => `- [ ] ${idx + 1}. ${task.title}
|
|
114
|
+
${task.subtasks.map(s => ` - ${s}`).join('\n')}
|
|
115
|
+
- _Requirements: ${task.requirements}_`).join('\n\n');
|
|
116
|
+
|
|
117
|
+
return `# Implementation Plan
|
|
118
|
+
|
|
119
|
+
## Project: ${featureName}
|
|
120
|
+
|
|
121
|
+
**Project Name:** ${analysis.name}
|
|
122
|
+
**Detected Stack:** ${[analysis.language, analysis.framework || '', analysis.buildTool || ''].filter(Boolean).join(' / ')}
|
|
123
|
+
|
|
124
|
+
Generated on: ${new Date().toISOString()}
|
|
125
|
+
|
|
126
|
+
## Development Phase Tasks
|
|
127
|
+
|
|
128
|
+
${section('Development', tasks.development)}
|
|
129
|
+
|
|
130
|
+
## Integration Phase Tasks
|
|
131
|
+
|
|
132
|
+
${section('Integration', tasks.integration)}
|
|
133
|
+
|
|
134
|
+
## Quality & Testing Tasks
|
|
135
|
+
|
|
136
|
+
${section('Quality', tasks.quality)}
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Helper functions
|
|
141
|
+
function generateCoreObjective(analysis) {
|
|
142
|
+
if (analysis.dependencies?.includes('@modelcontextprotocol/sdk')) return 'Provide MCP tools for spec-driven development workflows';
|
|
143
|
+
if (analysis.framework === 'Express.js') return 'Expose REST endpoints and middleware for business logic';
|
|
144
|
+
if (analysis.framework === 'React') return 'Render interactive UI components with state management';
|
|
145
|
+
return 'Deliver feature-aligned functionality integrated with existing architecture';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function generateAcceptanceCriteria(analysis) {
|
|
149
|
+
const criteria = [
|
|
150
|
+
'WHEN invoked THEN it SHALL execute without runtime errors',
|
|
151
|
+
'IF input is invalid THEN it SHALL return meaningful errors',
|
|
152
|
+
'WHILE under typical load IT SHALL meet performance targets'
|
|
153
|
+
];
|
|
154
|
+
if (analysis.testFramework) criteria.push('WHERE tests exist THEY SHALL pass with adequate coverage');
|
|
155
|
+
if (analysis.language === 'typescript') criteria.push('WHEN type-checking THEN no TypeScript errors SHALL occur');
|
|
156
|
+
return criteria;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function generateTechRequirements(analysis) {
|
|
160
|
+
const out = ['Integrate with existing build and run scripts'];
|
|
161
|
+
if (analysis.dependencies?.includes('@modelcontextprotocol/sdk')) out.push('Expose MCP-compliant tools over stdio');
|
|
162
|
+
if (analysis.buildTool) out.push(`Provide build artifacts using ${analysis.buildTool}`);
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function generateQualityRequirements(analysis) {
|
|
167
|
+
const out = ['Follow project coding conventions', 'Apply error handling and logging'];
|
|
168
|
+
if (analysis.testFramework) out.push(`Include ${analysis.testFramework} tests for new code`);
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function describeArchitecture(analysis) {
|
|
173
|
+
if (analysis.architecture === 'Domain-Driven Design (DDD)') return 'Layered DDD: Domain, Application, Infrastructure, Presentation';
|
|
174
|
+
if (analysis.architecture.includes('API')) return 'REST API with routing, middleware, services, and data access layers';
|
|
175
|
+
if (analysis.framework === 'MCP SDK') return 'MCP server exposing development tools via stdio protocol';
|
|
176
|
+
return analysis.architecture || 'Modular architecture with clear separation of concerns';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function generateComponentList(analysis) {
|
|
180
|
+
const comps = [];
|
|
181
|
+
if (analysis.framework === 'MCP SDK') {
|
|
182
|
+
comps.push({ name: 'MCPServer', description: 'Handles stdio transport and tool registry' });
|
|
183
|
+
comps.push({ name: 'ToolHandlers', description: 'Implement SDD tools (init, requirements, design, tasks, etc.)' });
|
|
184
|
+
}
|
|
185
|
+
if (analysis.architecture.includes('API')) {
|
|
186
|
+
comps.push({ name: 'Controllers', description: 'HTTP route handlers' });
|
|
187
|
+
comps.push({ name: 'Services', description: 'Business logic orchestration' });
|
|
188
|
+
}
|
|
189
|
+
if (comps.length === 0) comps.push({ name: 'CoreModule', description: 'Primary feature implementation module' });
|
|
190
|
+
return comps;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function generateDataModels(analysis) {
|
|
194
|
+
if (analysis.framework === 'MCP SDK') return ['Tool', 'Request', 'Response'];
|
|
195
|
+
if (analysis.architecture.includes('API')) return ['RequestDTO', 'ResponseDTO'];
|
|
196
|
+
return ['Entity', 'ValueObject'];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function generateDetailedTechStack(analysis) {
|
|
200
|
+
const parts = [];
|
|
201
|
+
parts.push(`- Runtime: ${analysis.language === 'typescript' ? 'Node.js (TypeScript)' : 'Node.js (JavaScript)'}`);
|
|
202
|
+
if (analysis.framework) parts.push(`- Framework: ${analysis.framework}`);
|
|
203
|
+
if (analysis.buildTool) parts.push(`- Build: ${analysis.buildTool}`);
|
|
204
|
+
if (analysis.testFramework) parts.push(`- Testing: ${analysis.testFramework}`);
|
|
205
|
+
return parts.join('\n');
|
|
206
|
+
}
|
|
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
|
+
|
|
214
|
+
function generateModuleInterfaces(analysis) {
|
|
215
|
+
if (analysis.framework === 'MCP SDK') {
|
|
216
|
+
return `- registerTool(name: string, handler: (args) => Promise<unknown>)\n- connect(transport): Promise<void>`;
|
|
217
|
+
}
|
|
218
|
+
if (analysis.architecture.includes('API')) {
|
|
219
|
+
return `- handle(request): Response\n- service.process(input): Result`;
|
|
220
|
+
}
|
|
221
|
+
return `- execute(input): Output`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function generateEnvVars(analysis) {
|
|
225
|
+
const envs = ['NODE_ENV', 'LOG_LEVEL'];
|
|
226
|
+
if (analysis.framework === 'MCP SDK') envs.push('MCP_MODE');
|
|
227
|
+
return envs.map(e => `- ${e}`).join('\n');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function generateBuildConfig(analysis) {
|
|
231
|
+
if (analysis.buildTool) return `Use ${analysis.buildTool} to emit production artifacts`;
|
|
232
|
+
return 'Use npm scripts (build/test/lint) defined in package.json';
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function generateImplementationTasks(analysis) {
|
|
236
|
+
const dev = [
|
|
237
|
+
{ title: 'Set up project scaffolding', subtasks: ['Initialize directories', 'Configure scripts'], requirements: 'FR-1' },
|
|
238
|
+
{ title: 'Implement core feature logic', subtasks: ['Add modules', 'Wire integrations'], requirements: 'FR-1' }
|
|
239
|
+
];
|
|
240
|
+
const integ = [
|
|
241
|
+
{ title: 'Integrate with stack', subtasks: ['Validate build', 'Run dev server'], requirements: 'FR-2' }
|
|
242
|
+
];
|
|
243
|
+
const quality = [
|
|
244
|
+
{ title: 'Add tests and quality checks', subtasks: ['Unit tests', 'Lint/typecheck', 'Quality review'], requirements: 'FR-3' }
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
if (analysis.framework === 'MCP SDK') {
|
|
248
|
+
dev.unshift({ title: 'Expose MCP tools', subtasks: ['Register tools', 'Handle stdio transport'], requirements: 'FR-2' });
|
|
249
|
+
}
|
|
250
|
+
if (analysis.architecture.includes('API')) {
|
|
251
|
+
dev.unshift({ title: 'Add HTTP endpoints', subtasks: ['Define routes', 'Implement handlers'], requirements: 'FR-1' });
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (analysis.testFramework) {
|
|
255
|
+
quality[0].subtasks.unshift(`Set up ${analysis.testFramework}`);
|
|
256
|
+
}
|
|
257
|
+
if (analysis.language === 'typescript') {
|
|
258
|
+
quality[0].subtasks.push('Ensure type safety (tsc)');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return { development: dev, integration: integ, quality };
|
|
262
|
+
}
|
|
263
|
+
|