sdd-mcp-server 1.3.4 → 1.3.6
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/dist/utils/documentGenerator.d.ts +1 -0
- package/dist/utils/documentGenerator.js +522 -28
- package/dist/utils/documentGenerator.js.map +1 -1
- package/documentGenerator.js +456 -53
- package/mcp-server.js +34 -2
- package/package.json +1 -1
|
@@ -34,3 +34,4 @@ export declare function generateTechDocument(analysis: ProjectAnalysis): string;
|
|
|
34
34
|
* Generates dynamic structure.md content based on project analysis
|
|
35
35
|
*/
|
|
36
36
|
export declare function generateStructureDocument(analysis: ProjectAnalysis): string;
|
|
37
|
+
export declare function extractDevCommands(analysis: ProjectAnalysis): string;
|
|
@@ -93,6 +93,209 @@ export async function analyzeProject(projectPath) {
|
|
|
93
93
|
analysis.buildTool = 'Rollup';
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
// Check for Java/Maven/Gradle projects
|
|
97
|
+
const pomPath = path.join(projectPath, 'pom.xml');
|
|
98
|
+
const gradlePath = path.join(projectPath, 'build.gradle');
|
|
99
|
+
const gradleKtsPath = path.join(projectPath, 'build.gradle.kts');
|
|
100
|
+
if (fs.existsSync(pomPath) || fs.existsSync(gradlePath) || fs.existsSync(gradleKtsPath)) {
|
|
101
|
+
analysis.language = 'java';
|
|
102
|
+
if (fs.existsSync(pomPath)) {
|
|
103
|
+
analysis.packageManager = 'maven';
|
|
104
|
+
analysis.buildTool = 'Maven';
|
|
105
|
+
try {
|
|
106
|
+
const pom = fs.readFileSync(pomPath, 'utf8');
|
|
107
|
+
if (/spring-boot/i.test(pom) || /org\.springframework\.boot/i.test(pom)) {
|
|
108
|
+
analysis.framework = 'Spring Boot';
|
|
109
|
+
analysis.architecture = 'Spring Boot Application';
|
|
110
|
+
}
|
|
111
|
+
const moduleMatches = pom.match(/<module>[^<]+<\/module>/g) || [];
|
|
112
|
+
if (moduleMatches.length > 1) {
|
|
113
|
+
analysis.architecture = 'Microservices (Spring Boot)';
|
|
114
|
+
}
|
|
115
|
+
if (/junit|jupiter/i.test(pom)) {
|
|
116
|
+
analysis.testFramework = 'JUnit';
|
|
117
|
+
analysis.hasTests = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch { }
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
analysis.packageManager = 'gradle';
|
|
124
|
+
analysis.buildTool = 'Gradle';
|
|
125
|
+
try {
|
|
126
|
+
const gradle = fs.readFileSync(fs.existsSync(gradlePath) ? gradlePath : gradleKtsPath, 'utf8');
|
|
127
|
+
if (/org\.springframework\.boot|spring-boot/i.test(gradle)) {
|
|
128
|
+
analysis.framework = 'Spring Boot';
|
|
129
|
+
analysis.architecture = 'Spring Boot Application';
|
|
130
|
+
}
|
|
131
|
+
if (/subprojects\s*\{|include\s+\(/i.test(gradle)) {
|
|
132
|
+
analysis.architecture = 'Microservices (Spring Boot)';
|
|
133
|
+
}
|
|
134
|
+
if (/junit|jupiter|testImplementation\s+['"]org\.junit/i.test(gradle)) {
|
|
135
|
+
analysis.testFramework = 'JUnit';
|
|
136
|
+
analysis.hasTests = true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch { }
|
|
140
|
+
}
|
|
141
|
+
if (fs.existsSync(path.join(projectPath, 'src', 'test', 'java'))) {
|
|
142
|
+
analysis.hasTests = true;
|
|
143
|
+
if (!analysis.testFramework)
|
|
144
|
+
analysis.testFramework = 'JUnit';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Detect Python projects
|
|
148
|
+
const pyproject = path.join(projectPath, 'pyproject.toml');
|
|
149
|
+
const requirements = path.join(projectPath, 'requirements.txt');
|
|
150
|
+
const pipfile = path.join(projectPath, 'Pipfile');
|
|
151
|
+
const setupPy = path.join(projectPath, 'setup.py');
|
|
152
|
+
if (fs.existsSync(pyproject) || fs.existsSync(requirements) || fs.existsSync(pipfile) || fs.existsSync(setupPy)) {
|
|
153
|
+
analysis.language = 'python';
|
|
154
|
+
analysis.packageManager = fs.existsSync(pyproject) ? 'poetry/pip' : (fs.existsSync(pipfile) ? 'pipenv' : 'pip');
|
|
155
|
+
analysis.buildTool = fs.existsSync(pyproject) ? 'Poetry' : 'Pip';
|
|
156
|
+
try {
|
|
157
|
+
const req = fs.existsSync(pyproject) ? fs.readFileSync(pyproject, 'utf8') : (fs.existsSync(requirements) ? fs.readFileSync(requirements, 'utf8') : '');
|
|
158
|
+
if (/django/i.test(req)) {
|
|
159
|
+
analysis.framework = 'Django';
|
|
160
|
+
analysis.architecture = 'Django Web Application';
|
|
161
|
+
}
|
|
162
|
+
else if (/fastapi/i.test(req)) {
|
|
163
|
+
analysis.framework = 'FastAPI';
|
|
164
|
+
analysis.architecture = 'REST API Server';
|
|
165
|
+
}
|
|
166
|
+
else if (/flask/i.test(req)) {
|
|
167
|
+
analysis.framework = 'Flask';
|
|
168
|
+
analysis.architecture = 'REST API Server';
|
|
169
|
+
}
|
|
170
|
+
if (/pytest/i.test(req)) {
|
|
171
|
+
analysis.testFramework = 'pytest';
|
|
172
|
+
analysis.hasTests = true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch { }
|
|
176
|
+
if (fs.existsSync(path.join(projectPath, 'tests')) || fs.existsSync(path.join(projectPath, 'test'))) {
|
|
177
|
+
analysis.hasTests = true;
|
|
178
|
+
if (!analysis.testFramework)
|
|
179
|
+
analysis.testFramework = 'pytest/unittest';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Detect Go projects
|
|
183
|
+
const goMod = path.join(projectPath, 'go.mod');
|
|
184
|
+
if (fs.existsSync(goMod)) {
|
|
185
|
+
analysis.language = 'go';
|
|
186
|
+
analysis.packageManager = 'go';
|
|
187
|
+
analysis.buildTool = 'Go Toolchain';
|
|
188
|
+
try {
|
|
189
|
+
const gomod = fs.readFileSync(goMod, 'utf8');
|
|
190
|
+
if (/github.com\/(gin-gonic\/gin)/i.test(gomod)) {
|
|
191
|
+
analysis.framework = 'Gin';
|
|
192
|
+
analysis.architecture = 'REST API Server';
|
|
193
|
+
}
|
|
194
|
+
else if (/github.com\/(labstack\/echo)/i.test(gomod)) {
|
|
195
|
+
analysis.framework = 'Echo';
|
|
196
|
+
analysis.architecture = 'REST API Server';
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
analysis.architecture = analysis.architecture === 'unknown' ? 'Go Application' : analysis.architecture;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch { }
|
|
203
|
+
analysis.hasTests = analysis.hasTests || false;
|
|
204
|
+
analysis.testFramework = analysis.testFramework || 'go test';
|
|
205
|
+
}
|
|
206
|
+
// Detect Ruby projects
|
|
207
|
+
const gemfile = path.join(projectPath, 'Gemfile');
|
|
208
|
+
if (fs.existsSync(gemfile)) {
|
|
209
|
+
analysis.language = 'ruby';
|
|
210
|
+
analysis.packageManager = 'bundler';
|
|
211
|
+
analysis.buildTool = 'Rake';
|
|
212
|
+
try {
|
|
213
|
+
const gem = fs.readFileSync(gemfile, 'utf8');
|
|
214
|
+
if (/rails/i.test(gem)) {
|
|
215
|
+
analysis.framework = 'Rails';
|
|
216
|
+
analysis.architecture = 'Rails MVC Application';
|
|
217
|
+
}
|
|
218
|
+
else if (/sinatra/i.test(gem)) {
|
|
219
|
+
analysis.framework = 'Sinatra';
|
|
220
|
+
analysis.architecture = 'Web Application';
|
|
221
|
+
}
|
|
222
|
+
if (/rspec/i.test(gem)) {
|
|
223
|
+
analysis.testFramework = 'RSpec';
|
|
224
|
+
analysis.hasTests = true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch { }
|
|
228
|
+
}
|
|
229
|
+
// Detect PHP projects
|
|
230
|
+
const composerJsonPath = path.join(projectPath, 'composer.json');
|
|
231
|
+
if (fs.existsSync(composerJsonPath)) {
|
|
232
|
+
analysis.language = 'php';
|
|
233
|
+
analysis.packageManager = 'composer';
|
|
234
|
+
analysis.buildTool = 'Composer';
|
|
235
|
+
try {
|
|
236
|
+
const composer = JSON.parse(fs.readFileSync(composerJsonPath, 'utf8'));
|
|
237
|
+
const require = composer.require || {};
|
|
238
|
+
if (require['laravel/framework']) {
|
|
239
|
+
analysis.framework = 'Laravel';
|
|
240
|
+
analysis.architecture = 'Laravel MVC Application';
|
|
241
|
+
}
|
|
242
|
+
else if (require['symfony/symfony'] || require['symfony/framework-bundle']) {
|
|
243
|
+
analysis.framework = 'Symfony';
|
|
244
|
+
analysis.architecture = 'Symfony Application';
|
|
245
|
+
}
|
|
246
|
+
if (require['phpunit/phpunit']) {
|
|
247
|
+
analysis.testFramework = 'PHPUnit';
|
|
248
|
+
analysis.hasTests = true;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch { }
|
|
252
|
+
}
|
|
253
|
+
// Detect Rust projects
|
|
254
|
+
const cargoToml = path.join(projectPath, 'Cargo.toml');
|
|
255
|
+
if (fs.existsSync(cargoToml)) {
|
|
256
|
+
analysis.language = 'rust';
|
|
257
|
+
analysis.packageManager = 'cargo';
|
|
258
|
+
analysis.buildTool = 'Cargo';
|
|
259
|
+
try {
|
|
260
|
+
const cargo = fs.readFileSync(cargoToml, 'utf8');
|
|
261
|
+
if (/actix-web/i.test(cargo)) {
|
|
262
|
+
analysis.framework = 'Actix Web';
|
|
263
|
+
analysis.architecture = 'REST API Server';
|
|
264
|
+
}
|
|
265
|
+
else if (/rocket =/i.test(cargo)) {
|
|
266
|
+
analysis.framework = 'Rocket';
|
|
267
|
+
analysis.architecture = 'Web Application';
|
|
268
|
+
}
|
|
269
|
+
else if (/axum/i.test(cargo)) {
|
|
270
|
+
analysis.framework = 'Axum';
|
|
271
|
+
analysis.architecture = 'REST API Server';
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch { }
|
|
275
|
+
analysis.testFramework = 'cargo test';
|
|
276
|
+
}
|
|
277
|
+
// Detect .NET projects
|
|
278
|
+
const entries = fs.readdirSync(projectPath);
|
|
279
|
+
const csproj = entries.find(f => f.endsWith('.csproj')) || null;
|
|
280
|
+
const sln = entries.find(f => f.endsWith('.sln')) || null;
|
|
281
|
+
if (csproj || sln) {
|
|
282
|
+
analysis.language = 'csharp';
|
|
283
|
+
analysis.packageManager = 'dotnet';
|
|
284
|
+
analysis.buildTool = '.NET SDK';
|
|
285
|
+
analysis.framework = 'ASP.NET Core';
|
|
286
|
+
analysis.architecture = analysis.architecture === 'unknown' ? 'ASP.NET Application' : analysis.architecture;
|
|
287
|
+
analysis.testFramework = analysis.testFramework || 'xUnit/NUnit/MSTest';
|
|
288
|
+
}
|
|
289
|
+
// Detect Scala projects
|
|
290
|
+
const sbtBuild = path.join(projectPath, 'build.sbt');
|
|
291
|
+
if (fs.existsSync(sbtBuild)) {
|
|
292
|
+
analysis.language = 'scala';
|
|
293
|
+
analysis.packageManager = 'sbt';
|
|
294
|
+
analysis.buildTool = 'SBT';
|
|
295
|
+
analysis.framework = analysis.framework || 'Play?/Akka?';
|
|
296
|
+
analysis.architecture = analysis.architecture === 'unknown' ? 'Scala Application' : analysis.architecture;
|
|
297
|
+
analysis.testFramework = analysis.testFramework || 'ScalaTest';
|
|
298
|
+
}
|
|
96
299
|
// Check for yarn or pnpm
|
|
97
300
|
if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
|
|
98
301
|
analysis.packageManager = 'yarn';
|
|
@@ -193,8 +396,8 @@ export function generateTechDocument(analysis) {
|
|
|
193
396
|
|
|
194
397
|
## Architecture
|
|
195
398
|
**Type**: ${analysis.architecture}
|
|
196
|
-
**Language**: ${analysis.language === 'typescript' ? 'TypeScript' : 'JavaScript'}
|
|
197
|
-
|
|
399
|
+
**Language**: ${analysis.language === 'typescript' ? 'TypeScript' : analysis.language === 'java' ? 'Java' : analysis.language === 'python' ? 'Python' : analysis.language === 'go' ? 'Go' : analysis.language === 'ruby' ? 'Ruby' : analysis.language === 'php' ? 'PHP' : analysis.language === 'rust' ? 'Rust' : analysis.language === 'csharp' ? 'C#' : analysis.language === 'scala' ? 'Scala' : 'JavaScript'}
|
|
400
|
+
${(analysis.language === 'javascript' || analysis.language === 'typescript') ? `**Module System**: ${analysis.type} ` : ''}
|
|
198
401
|
${analysis.framework ? `**Framework**: ${analysis.framework}` : ''}
|
|
199
402
|
${analysis.buildTool ? `**Build Tool**: ${analysis.buildTool}` : ''}
|
|
200
403
|
|
|
@@ -204,9 +407,8 @@ ${architecture}
|
|
|
204
407
|
${techStack.map(t => `- **${t.name}**: ${t.description}`).join('\n')}
|
|
205
408
|
|
|
206
409
|
## Development Environment
|
|
207
|
-
|
|
208
|
-
- **
|
|
209
|
-
- **Language**: ${analysis.language === 'typescript' ? 'TypeScript with type safety' : 'JavaScript'}
|
|
410
|
+
${analysis.language === 'java' ? `- **JDK**: ${getJavaVersion(projectPathFromCwd())}\n` : analysis.language === 'go' ? `- **Go**: ${getGoVersion(projectPathFromCwd())}\n` : analysis.language === 'python' ? `- **Python**: ${getPythonVersion(projectPathFromCwd())}\n` : analysis.language === 'ruby' ? `- **Ruby**: ${getRubyVersion(projectPathFromCwd())}\n` : analysis.language === 'php' ? `- **PHP**: ${getPhpVersion(projectPathFromCwd())}\n` : analysis.language === 'rust' ? `- **Rust**: ${getRustToolchain(projectPathFromCwd())}\n` : analysis.language === 'csharp' ? `- **.NET SDK**: ${getDotnetTarget(projectPathFromCwd())}\n` : `- **Node Version**: ${getNodeVersion()}\n`}- **Package Manager/Build**: ${analysis.packageManager}
|
|
411
|
+
- **Language**: ${analysis.language === 'typescript' ? 'TypeScript with type safety' : analysis.language ? analysis.language[0].toUpperCase() + analysis.language.slice(1) : 'JavaScript'}
|
|
210
412
|
${analysis.testFramework ? `- **Testing**: ${analysis.testFramework}` : ''}
|
|
211
413
|
|
|
212
414
|
## Dependencies Analysis
|
|
@@ -395,10 +597,33 @@ function generateTechnicalAdvantages(analysis) {
|
|
|
395
597
|
function buildTechStack(analysis) {
|
|
396
598
|
const stack = [];
|
|
397
599
|
// Core runtime
|
|
398
|
-
|
|
399
|
-
name: '
|
|
400
|
-
|
|
401
|
-
|
|
600
|
+
if (analysis.language === 'java') {
|
|
601
|
+
stack.push({ name: 'Java', description: 'JDK runtime for backend services' });
|
|
602
|
+
}
|
|
603
|
+
else if (analysis.language === 'python') {
|
|
604
|
+
stack.push({ name: 'Python', description: 'Python runtime for applications and APIs' });
|
|
605
|
+
}
|
|
606
|
+
else if (analysis.language === 'go') {
|
|
607
|
+
stack.push({ name: 'Go', description: 'Go toolchain for building static binaries' });
|
|
608
|
+
}
|
|
609
|
+
else if (analysis.language === 'ruby') {
|
|
610
|
+
stack.push({ name: 'Ruby', description: 'Ruby runtime for web applications' });
|
|
611
|
+
}
|
|
612
|
+
else if (analysis.language === 'php') {
|
|
613
|
+
stack.push({ name: 'PHP', description: 'PHP runtime for web applications' });
|
|
614
|
+
}
|
|
615
|
+
else if (analysis.language === 'rust') {
|
|
616
|
+
stack.push({ name: 'Rust', description: 'Rust toolchain for systems and APIs' });
|
|
617
|
+
}
|
|
618
|
+
else if (analysis.language === 'csharp') {
|
|
619
|
+
stack.push({ name: 'C#/.NET', description: '.NET runtime and SDK' });
|
|
620
|
+
}
|
|
621
|
+
else if (analysis.language === 'scala') {
|
|
622
|
+
stack.push({ name: 'Scala', description: 'JVM language for backend systems' });
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
stack.push({ name: 'Node.js', description: 'JavaScript runtime for server-side execution' });
|
|
626
|
+
}
|
|
402
627
|
// Language
|
|
403
628
|
if (analysis.language === 'typescript') {
|
|
404
629
|
stack.push({
|
|
@@ -406,6 +631,9 @@ function buildTechStack(analysis) {
|
|
|
406
631
|
description: 'Typed superset of JavaScript for enhanced developer experience'
|
|
407
632
|
});
|
|
408
633
|
}
|
|
634
|
+
else if (analysis.language === 'java') {
|
|
635
|
+
stack.push({ name: 'Spring Boot', description: 'Opinionated framework for building production-ready services' });
|
|
636
|
+
}
|
|
409
637
|
// Framework
|
|
410
638
|
if (analysis.framework) {
|
|
411
639
|
stack.push({
|
|
@@ -438,28 +666,145 @@ function buildTechStack(analysis) {
|
|
|
438
666
|
}
|
|
439
667
|
return stack;
|
|
440
668
|
}
|
|
441
|
-
function extractDevCommands(analysis) {
|
|
442
|
-
if (Object.keys(analysis.scripts).length === 0) {
|
|
443
|
-
return 'No npm scripts defined';
|
|
444
|
-
}
|
|
669
|
+
export function extractDevCommands(analysis) {
|
|
445
670
|
let commands = '```bash\n';
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
671
|
+
switch (analysis.language) {
|
|
672
|
+
case 'java':
|
|
673
|
+
if (analysis.packageManager === 'maven') {
|
|
674
|
+
commands += 'mvn clean install # Build project\n';
|
|
675
|
+
commands += 'mvn test # Run tests\n';
|
|
676
|
+
if (analysis.framework === 'Spring Boot')
|
|
677
|
+
commands += 'mvn spring-boot:run # Run application\n';
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
commands += 'gradle build # Build project\n';
|
|
681
|
+
commands += 'gradle test # Run tests\n';
|
|
682
|
+
if (analysis.framework === 'Spring Boot')
|
|
683
|
+
commands += 'gradle bootRun # Run application\n';
|
|
684
|
+
}
|
|
685
|
+
commands += '```';
|
|
686
|
+
return commands;
|
|
687
|
+
case 'python':
|
|
688
|
+
commands += 'pip install -r requirements.txt # Install deps\n';
|
|
689
|
+
commands += (analysis.framework === 'Django') ? 'python manage.py runserver # Run server\n' :
|
|
690
|
+
(analysis.framework === 'FastAPI' || analysis.framework === 'Flask') ? 'uvicorn app:app --reload # Run dev server\n' : '';
|
|
691
|
+
commands += 'pytest # Run tests\n';
|
|
692
|
+
commands += '```';
|
|
693
|
+
return commands;
|
|
694
|
+
case 'go':
|
|
695
|
+
commands += 'go build ./... # Build\n';
|
|
696
|
+
commands += 'go test ./... # Tests\n';
|
|
697
|
+
commands += 'go run ./cmd/... # Run (example)\n';
|
|
698
|
+
commands += '```';
|
|
699
|
+
return commands;
|
|
700
|
+
case 'ruby':
|
|
701
|
+
commands += 'bundle install # Install deps\n';
|
|
702
|
+
commands += (analysis.framework === 'Rails') ? 'rails server # Run server\n' : '';
|
|
703
|
+
commands += (analysis.testFramework === 'RSpec') ? 'rspec # Run tests\n' : 'rake test # Run tests\n';
|
|
704
|
+
commands += '```';
|
|
705
|
+
return commands;
|
|
706
|
+
case 'php':
|
|
707
|
+
commands += 'composer install # Install deps\n';
|
|
708
|
+
commands += (analysis.framework === 'Laravel') ? 'php artisan serve # Run server\n' : '';
|
|
709
|
+
commands += 'vendor/bin/phpunit # Run tests\n';
|
|
710
|
+
commands += '```';
|
|
711
|
+
return commands;
|
|
712
|
+
case 'rust':
|
|
713
|
+
commands += 'cargo build # Build\n';
|
|
714
|
+
commands += 'cargo test # Tests\n';
|
|
715
|
+
commands += 'cargo run # Run\n';
|
|
716
|
+
commands += '```';
|
|
717
|
+
return commands;
|
|
718
|
+
case 'csharp':
|
|
719
|
+
commands += 'dotnet build # Build\n';
|
|
720
|
+
commands += 'dotnet test # Tests\n';
|
|
721
|
+
commands += 'dotnet run # Run\n';
|
|
722
|
+
commands += '```';
|
|
723
|
+
return commands;
|
|
724
|
+
case 'scala':
|
|
725
|
+
commands += 'sbt compile # Build\n';
|
|
726
|
+
commands += 'sbt test # Tests\n';
|
|
727
|
+
commands += 'sbt run # Run\n';
|
|
728
|
+
commands += '```';
|
|
729
|
+
return commands;
|
|
730
|
+
default:
|
|
731
|
+
if (Object.keys(analysis.scripts).length === 0) {
|
|
732
|
+
return 'No npm scripts defined';
|
|
733
|
+
}
|
|
734
|
+
const commandOrder = ['dev', 'start', 'build', 'test', 'lint', 'typecheck', 'coverage'];
|
|
735
|
+
for (const cmd of commandOrder) {
|
|
736
|
+
if (analysis.scripts[cmd]) {
|
|
737
|
+
commands += `${analysis.packageManager} run ${cmd} # ${describeCommand(cmd, analysis.scripts[cmd])}\n`;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
for (const [cmd, script] of Object.entries(analysis.scripts)) {
|
|
741
|
+
if (!commandOrder.includes(cmd)) {
|
|
742
|
+
commands += `${analysis.packageManager} run ${cmd} # ${script.substring(0, 50)}${script.length > 50 ? '...' : ''}\n`;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
commands += '```';
|
|
746
|
+
return commands;
|
|
458
747
|
}
|
|
459
|
-
commands += '```';
|
|
460
|
-
return commands;
|
|
461
748
|
}
|
|
462
749
|
function describeArchitecture(analysis) {
|
|
750
|
+
if (analysis.architecture.includes('Spring Boot')) {
|
|
751
|
+
return `
|
|
752
|
+
### Spring Boot Service Architecture
|
|
753
|
+
The project uses Spring Boot conventions:
|
|
754
|
+
- **Configuration**: application.yml/properties per service
|
|
755
|
+
- **Layers**: Controller → Service → Repository
|
|
756
|
+
- **Build**: ${analysis.buildTool || 'Maven/Gradle'} with ${analysis.testFramework || 'JUnit'} tests
|
|
757
|
+
${analysis.architecture.includes('Microservices') ? '- **Topology**: Multiple modules/services (microservices)\n' : ''}`;
|
|
758
|
+
}
|
|
759
|
+
if (analysis.framework === 'Django') {
|
|
760
|
+
return `
|
|
761
|
+
### Django MVC Architecture
|
|
762
|
+
- **Apps**: Modular apps with models, views, templates
|
|
763
|
+
- **ORM**: Django ORM for database access
|
|
764
|
+
- **Routing**: URLconf-based routing`;
|
|
765
|
+
}
|
|
766
|
+
if (analysis.framework === 'FastAPI' || analysis.framework === 'Flask') {
|
|
767
|
+
return `
|
|
768
|
+
### Python REST API Architecture
|
|
769
|
+
- **Routing**: Decorator-based route handlers
|
|
770
|
+
- **Middleware**: Request processing chain
|
|
771
|
+
- **Data**: Pydantic/Marshmallow schemas`;
|
|
772
|
+
}
|
|
773
|
+
if (analysis.framework === 'Rails') {
|
|
774
|
+
return `
|
|
775
|
+
### Rails MVC Architecture
|
|
776
|
+
- **Models**: ActiveRecord ORM
|
|
777
|
+
- **Controllers/Views**: Conventional structure with routing
|
|
778
|
+
- **Tasks**: Rake-based automation`;
|
|
779
|
+
}
|
|
780
|
+
if (analysis.framework === 'Laravel' || analysis.framework === 'Symfony') {
|
|
781
|
+
return `
|
|
782
|
+
### PHP Web Architecture
|
|
783
|
+
- **MVC**: Controllers, models, views
|
|
784
|
+
- **Routing**: Framework router
|
|
785
|
+
- **Artisan/Console**: CLI tooling`;
|
|
786
|
+
}
|
|
787
|
+
if (analysis.language === 'go') {
|
|
788
|
+
return `
|
|
789
|
+
### Go Service Architecture
|
|
790
|
+
- **Handlers**: HTTP handlers with router (Gin/Echo/net/http)
|
|
791
|
+
- **Services**: Business logic in packages
|
|
792
|
+
- **Build**: Single binary via go build`;
|
|
793
|
+
}
|
|
794
|
+
if (analysis.language === 'rust') {
|
|
795
|
+
return `
|
|
796
|
+
### Rust Web Service Architecture
|
|
797
|
+
- **Framework**: ${analysis.framework || 'Actix/Axum/Rocket'}
|
|
798
|
+
- **Async**: Tokio runtime
|
|
799
|
+
- **Testing**: cargo test`;
|
|
800
|
+
}
|
|
801
|
+
if (analysis.language === 'csharp') {
|
|
802
|
+
return `
|
|
803
|
+
### ASP.NET Core Architecture
|
|
804
|
+
- **Controllers**: MVC/Web API controllers
|
|
805
|
+
- **Dependency Injection**: Built-in DI
|
|
806
|
+
- **Configuration**: appsettings.json per environment`;
|
|
807
|
+
}
|
|
463
808
|
if (analysis.architecture === 'Domain-Driven Design (DDD)') {
|
|
464
809
|
return `
|
|
465
810
|
### Domain-Driven Design Architecture
|
|
@@ -585,7 +930,39 @@ function buildDirectoryTree(analysis) {
|
|
|
585
930
|
if (analysis.hasDocker) {
|
|
586
931
|
tree += `├── Dockerfile # Container configuration\n`;
|
|
587
932
|
}
|
|
588
|
-
|
|
933
|
+
if (analysis.language === 'java') {
|
|
934
|
+
tree += `├── pom.xml or build.gradle # Build configuration\n`;
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
tree += `├── package.json # Project configuration\n`;
|
|
938
|
+
}
|
|
939
|
+
if (analysis.language === 'java') {
|
|
940
|
+
tree += `├── pom.xml or build.gradle # Build configuration\n`;
|
|
941
|
+
}
|
|
942
|
+
else if (analysis.language === 'python') {
|
|
943
|
+
tree += `├── pyproject.toml / requirements.txt # Python config\n`;
|
|
944
|
+
}
|
|
945
|
+
else if (analysis.language === 'go') {
|
|
946
|
+
tree += `├── go.mod # Go modules\n`;
|
|
947
|
+
}
|
|
948
|
+
else if (analysis.language === 'ruby') {
|
|
949
|
+
tree += `├── Gemfile # Ruby dependencies\n`;
|
|
950
|
+
}
|
|
951
|
+
else if (analysis.language === 'php') {
|
|
952
|
+
tree += `├── composer.json # PHP dependencies\n`;
|
|
953
|
+
}
|
|
954
|
+
else if (analysis.language === 'rust') {
|
|
955
|
+
tree += `├── Cargo.toml # Rust package config\n`;
|
|
956
|
+
}
|
|
957
|
+
else if (analysis.language === 'csharp') {
|
|
958
|
+
tree += `├── *.csproj # .NET project file\n`;
|
|
959
|
+
}
|
|
960
|
+
else if (analysis.language === 'scala') {
|
|
961
|
+
tree += `├── build.sbt # SBT build\n`;
|
|
962
|
+
}
|
|
963
|
+
else {
|
|
964
|
+
tree += `├── package.json # Project configuration\n`;
|
|
965
|
+
}
|
|
589
966
|
if (analysis.language === 'typescript') {
|
|
590
967
|
tree += `├── tsconfig.json # TypeScript configuration\n`;
|
|
591
968
|
}
|
|
@@ -822,4 +1199,121 @@ function getNodeVersion() {
|
|
|
822
1199
|
}
|
|
823
1200
|
return '>= 18.0.0';
|
|
824
1201
|
}
|
|
1202
|
+
function projectPathFromCwd() {
|
|
1203
|
+
try {
|
|
1204
|
+
return process.cwd();
|
|
1205
|
+
}
|
|
1206
|
+
catch {
|
|
1207
|
+
return '.';
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
function getGoVersion(projectPath) {
|
|
1211
|
+
try {
|
|
1212
|
+
const gomod = path.join(projectPath, 'go.mod');
|
|
1213
|
+
if (fs.existsSync(gomod)) {
|
|
1214
|
+
const content = fs.readFileSync(gomod, 'utf8');
|
|
1215
|
+
const m = content.match(/^go\s+([0-9.]+)/m);
|
|
1216
|
+
if (m)
|
|
1217
|
+
return `Go ${m[1]}`;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
catch { }
|
|
1221
|
+
return 'Go (version unknown)';
|
|
1222
|
+
}
|
|
1223
|
+
function getPythonVersion(projectPath) {
|
|
1224
|
+
try {
|
|
1225
|
+
const pyproject = path.join(projectPath, 'pyproject.toml');
|
|
1226
|
+
if (fs.existsSync(pyproject)) {
|
|
1227
|
+
const txt = fs.readFileSync(pyproject, 'utf8');
|
|
1228
|
+
const m = txt.match(/python\s*[=><~!]*\s*['"]([^'"]+)['"]/i);
|
|
1229
|
+
if (m)
|
|
1230
|
+
return `Python ${m[1]}`;
|
|
1231
|
+
}
|
|
1232
|
+
const vfile = path.join(projectPath, '.python-version');
|
|
1233
|
+
if (fs.existsSync(vfile)) {
|
|
1234
|
+
return `Python ${fs.readFileSync(vfile, 'utf8').trim()}`;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
catch { }
|
|
1238
|
+
return 'Python (version unknown)';
|
|
1239
|
+
}
|
|
1240
|
+
function getRubyVersion(projectPath) {
|
|
1241
|
+
try {
|
|
1242
|
+
const rv = path.join(projectPath, '.ruby-version');
|
|
1243
|
+
if (fs.existsSync(rv))
|
|
1244
|
+
return `Ruby ${fs.readFileSync(rv, 'utf8').trim()}`;
|
|
1245
|
+
const gem = path.join(projectPath, 'Gemfile');
|
|
1246
|
+
if (fs.existsSync(gem)) {
|
|
1247
|
+
const txt = fs.readFileSync(gem, 'utf8');
|
|
1248
|
+
const m = txt.match(/ruby\s+['"]([^'"]+)['"]/i);
|
|
1249
|
+
if (m)
|
|
1250
|
+
return `Ruby ${m[1]}`;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
catch { }
|
|
1254
|
+
return 'Ruby (version unknown)';
|
|
1255
|
+
}
|
|
1256
|
+
function getPhpVersion(projectPath) {
|
|
1257
|
+
try {
|
|
1258
|
+
const composer = path.join(projectPath, 'composer.json');
|
|
1259
|
+
if (fs.existsSync(composer)) {
|
|
1260
|
+
const pkg = JSON.parse(fs.readFileSync(composer, 'utf8'));
|
|
1261
|
+
const req = pkg.require || {};
|
|
1262
|
+
if (req.php)
|
|
1263
|
+
return `PHP ${req.php}`;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
catch { }
|
|
1267
|
+
return 'PHP (version unknown)';
|
|
1268
|
+
}
|
|
1269
|
+
function getRustToolchain(projectPath) {
|
|
1270
|
+
try {
|
|
1271
|
+
const tool = path.join(projectPath, 'rust-toolchain');
|
|
1272
|
+
if (fs.existsSync(tool))
|
|
1273
|
+
return `Rust ${fs.readFileSync(tool, 'utf8').trim()}`;
|
|
1274
|
+
const cargo = path.join(projectPath, 'Cargo.toml');
|
|
1275
|
+
if (fs.existsSync(cargo)) {
|
|
1276
|
+
const txt = fs.readFileSync(cargo, 'utf8');
|
|
1277
|
+
const m = txt.match(/edition\s*=\s*"(\d{4})"/);
|
|
1278
|
+
if (m)
|
|
1279
|
+
return `Rust (edition ${m[1]})`;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
catch { }
|
|
1283
|
+
return 'Rust (toolchain unknown)';
|
|
1284
|
+
}
|
|
1285
|
+
function getDotnetTarget(projectPath) {
|
|
1286
|
+
try {
|
|
1287
|
+
const files = fs.readdirSync(projectPath).filter(f => f.endsWith('.csproj'));
|
|
1288
|
+
for (const f of files) {
|
|
1289
|
+
const txt = fs.readFileSync(path.join(projectPath, f), 'utf8');
|
|
1290
|
+
const m = txt.match(/<TargetFramework>([^<]+)<\/TargetFramework>/);
|
|
1291
|
+
if (m)
|
|
1292
|
+
return m[1];
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
catch { }
|
|
1296
|
+
return '.NET (target unknown)';
|
|
1297
|
+
}
|
|
1298
|
+
function getJavaVersion(projectPath) {
|
|
1299
|
+
try {
|
|
1300
|
+
const pomPath = path.join(projectPath, 'pom.xml');
|
|
1301
|
+
if (fs.existsSync(pomPath)) {
|
|
1302
|
+
const pom = fs.readFileSync(pomPath, 'utf8');
|
|
1303
|
+
const m = pom.match(/<maven\.compiler\.source>([^<]+)<\/maven\.compiler\.source>/);
|
|
1304
|
+
const v = m?.[1] || (pom.match(/<java\.version>([^<]+)<\/java\.version>/)?.[1]);
|
|
1305
|
+
if (v)
|
|
1306
|
+
return `JDK ${v}`;
|
|
1307
|
+
}
|
|
1308
|
+
const gradlePath = fs.existsSync(path.join(projectPath, 'build.gradle.kts')) ? path.join(projectPath, 'build.gradle.kts') : path.join(projectPath, 'build.gradle');
|
|
1309
|
+
if (fs.existsSync(gradlePath)) {
|
|
1310
|
+
const gradle = fs.readFileSync(gradlePath, 'utf8');
|
|
1311
|
+
const m = gradle.match(/sourceCompatibility\s*=\s*['"]([^'"]+)['"]/i) || gradle.match(/sourceCompatibility\s+['"]([^'"]+)['"]/i);
|
|
1312
|
+
if (m?.[1])
|
|
1313
|
+
return `JDK ${m[1]}`;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
catch { }
|
|
1317
|
+
return 'JDK (version unknown)';
|
|
1318
|
+
}
|
|
825
1319
|
//# sourceMappingURL=documentGenerator.js.map
|