Skip to content

Commit 2223b7c

Browse files
Merge pull request #8 from MUGISHA-Pascal/pascal-dev
2 parents 9043fe3 + 0db2fb0 commit 2223b7c

7 files changed

Lines changed: 1070 additions & 26 deletions

File tree

.gitignore

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
node_modules/
2-
dist/
3-
.env
4-
.env.local
5-
*.log
6-
.DS_Store
7-
coverage/
8-
.vscode/
9-
.idea/
10-
.npmrc
1+
node_modules/
2+
dist/
3+
*.log
4+
.DS_Store
5+
coverage/
6+
.vscode/
7+
.idea/
8+
.npmrc
9+
config.bat

README.md

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ A prompt-based CLI tool to scaffold projects for various frameworks and language
55
## Features
66

77
- Interactive prompt-based project setup
8+
- **AI-Powered project generation** with intelligent code generation
9+
- Traditional template-based scaffolding
810
- Support for multiple frameworks:
911
- Go
1012
- Flutter
@@ -14,6 +16,8 @@ A prompt-based CLI tool to scaffold projects for various frameworks and language
1416
- Python
1517
- Beautiful CLI interface with colors and spinners
1618
- Fast project scaffolding
19+
- Context-aware code generation based on project description
20+
- Feature-based file creation (authentication, database, API, etc.)
1721

1822
## Installation
1923

@@ -37,10 +41,44 @@ start-it-cli
3741

3842
Then follow the interactive prompts to:
3943

40-
1. Select your project type (Go, Flutter, React Native, Spring Boot, etc.)
41-
2. Enter your project name
42-
3. Choose additional options based on your framework
43-
4. Watch as your project is scaffolded automatically
44+
1. **Choose generation method**: Traditional (Template-based) or AI-Powered (Smart recommendations)
45+
2. **For Traditional**: Select your project type (Go, Flutter, React Native, Spring Boot, etc.)
46+
3. **For AI-Powered**: Describe your project in natural language
47+
4. Enter your project name
48+
5. Choose additional options based on your framework or AI recommendations
49+
6. Watch as your project is scaffolded automatically
50+
51+
### AI-Powered Generation
52+
53+
The AI feature analyzes your project description and generates:
54+
55+
- **Smart framework recommendations** based on your requirements
56+
- **Contextual code** tailored to your specific use case
57+
- **Feature-based architecture** (authentication, database, API routes, etc.)
58+
- **Production-ready file structure** with actual working code
59+
- **Domain-specific models** (e.g., Patient/Doctor models for hospital systems)
60+
61+
Example AI workflow:
62+
63+
```bash
64+
$ start-it-cli
65+
? Choose project generation method: AI-Powered (Smart recommendations)
66+
? Project name: hospital-management
67+
? Describe your project: A comprehensive hospital management system with patient records
68+
? Project scale: large
69+
? Select features you need: authentication, database, api, frontend, backend, testing
70+
71+
AI Recommendations:
72+
Framework: Node.js
73+
Template: TypeScript Project
74+
Reasoning: Based on your requirements, I recommend Node.js with TypeScript for scalability
75+
76+
Generated Files:
77+
- package.json: Complete with dependencies for auth, database, testing
78+
- src/index.ts: Express server with middleware setup
79+
- src/routes/index.ts: API endpoints for hospital operations
80+
- src/models/index.ts: Patient, Doctor, and User interfaces
81+
```
4482

4583
## Example
4684

jest.config.js

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ai/generator.ts

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
import { SmartAIProvider } from "./provider";
2+
import { AIProjectRequest, AIRecommendation } from "./types";
3+
import { getTemplate } from "../templates";
4+
import { TemplateConfig } from "../types";
5+
import * as fs from "fs-extra";
6+
import * as path from "path";
7+
import chalk from "chalk";
8+
import ora from "ora";
9+
10+
export class AIProjectGenerator {
11+
private aiProvider: SmartAIProvider;
12+
13+
constructor(apiKey?: string) {
14+
this.aiProvider = new SmartAIProvider(apiKey);
15+
}
16+
17+
async generate(
18+
request: AIProjectRequest & { projectName: string; projectPath: string }
19+
): Promise<void> {
20+
const spinner = ora("Analyzing project requirements...").start();
21+
22+
try {
23+
// Get AI recommendations with generated code
24+
const recommendation = await this.aiProvider.generateProject(request);
25+
26+
spinner.text = "Generating project structure...";
27+
28+
// Create project directory
29+
const projectDir = path.join(request.projectPath, request.projectName);
30+
await fs.ensureDir(projectDir);
31+
32+
// Generate files from AI-generated content
33+
for (const file of recommendation.structure) {
34+
const filePath = path.join(projectDir, file.path);
35+
await fs.ensureDir(path.dirname(filePath));
36+
await fs.writeFile(filePath, file.content);
37+
38+
// Make executable files executable
39+
if (file.isExecutable) {
40+
await fs.chmod(filePath, 0o755);
41+
}
42+
}
43+
44+
spinner.succeed("Project created successfully!");
45+
46+
console.log(chalk.cyan("\nAI Recommendations:"));
47+
console.log(chalk.gray(`Framework: ${recommendation.framework}`));
48+
console.log(chalk.gray(`Template: ${recommendation.template}`));
49+
console.log(chalk.gray(`Reasoning: ${recommendation.reasoning}`));
50+
51+
if (recommendation.dependencies.length > 0) {
52+
console.log(chalk.cyan("\nSuggested Dependencies:"));
53+
recommendation.dependencies.forEach((dep) => {
54+
console.log(
55+
chalk.gray(
56+
`- ${dep.name}@${dep.version || "latest"}: ${dep.purpose}`
57+
)
58+
);
59+
});
60+
}
61+
62+
console.log(chalk.cyan("\nGenerated Files:"));
63+
recommendation.structure.forEach((file) => {
64+
console.log(chalk.gray(`- ${file.path}: ${file.description}`));
65+
});
66+
} catch (error) {
67+
spinner.fail("Failed to generate project");
68+
throw error;
69+
}
70+
}
71+
72+
async generateIntelligentProject(
73+
description: string
74+
): Promise<
75+
Omit<AIRecommendation, "template"> & { template: TemplateConfig }
76+
> {
77+
// Analyze the project description
78+
const features = await this.aiProvider.analyzeRequirements(description);
79+
80+
// Create AI request
81+
const request: AIProjectRequest = {
82+
description,
83+
features,
84+
scale: this.determineScale(description),
85+
deployment: this.determineDeployment(description),
86+
};
87+
88+
// Get AI recommendations
89+
const recommendation = await this.aiProvider.generateProject(request);
90+
91+
// Get the actual template
92+
const template = getTemplate(
93+
recommendation.framework,
94+
recommendation.template
95+
);
96+
97+
// Get smart dependencies
98+
const dependencies = await this.aiProvider.suggestDependencies(
99+
recommendation.framework,
100+
features
101+
);
102+
103+
const { template: _, ...recommendationWithoutTemplate } = recommendation;
104+
105+
return {
106+
...recommendationWithoutTemplate,
107+
dependencies,
108+
template,
109+
};
110+
}
111+
112+
async enhanceTemplate(
113+
template: TemplateConfig,
114+
features: string[]
115+
): Promise<TemplateConfig> {
116+
const enhancedFiles = await Promise.all(
117+
template.files.map(async (file) => {
118+
return {
119+
...file,
120+
content: await this.enhanceFileContent(file.content, features),
121+
};
122+
})
123+
);
124+
125+
return {
126+
...template,
127+
files: enhancedFiles,
128+
};
129+
}
130+
131+
private determineScale(description: string): "small" | "medium" | "large" {
132+
const lowerDesc = description.toLowerCase();
133+
134+
if (
135+
lowerDesc.includes("enterprise") ||
136+
lowerDesc.includes("large") ||
137+
lowerDesc.includes("microservice") ||
138+
lowerDesc.includes("distributed")
139+
) {
140+
return "large";
141+
}
142+
143+
if (
144+
lowerDesc.includes("prototype") ||
145+
lowerDesc.includes("small") ||
146+
lowerDesc.includes("simple") ||
147+
lowerDesc.includes("basic")
148+
) {
149+
return "small";
150+
}
151+
152+
return "medium";
153+
}
154+
155+
private determineDeployment(
156+
description: string
157+
): "local" | "cloud" | "hybrid" {
158+
const lowerDesc = description.toLowerCase();
159+
160+
if (
161+
lowerDesc.includes("cloud") ||
162+
lowerDesc.includes("aws") ||
163+
lowerDesc.includes("azure") ||
164+
lowerDesc.includes("gcp")
165+
) {
166+
return "cloud";
167+
}
168+
169+
if (
170+
lowerDesc.includes("local") ||
171+
lowerDesc.includes("desktop") ||
172+
lowerDesc.includes("offline")
173+
) {
174+
return "local";
175+
}
176+
177+
return "hybrid";
178+
}
179+
180+
private async enhanceFileContent(
181+
content: string,
182+
features: string[]
183+
): Promise<string> {
184+
let enhanced = content;
185+
186+
// Add authentication setup
187+
if (features.includes("authentication")) {
188+
enhanced = this.addAuthenticationBoilerplate(enhanced);
189+
}
190+
191+
// Add database configuration
192+
if (features.includes("database")) {
193+
enhanced = this.addDatabaseConfig(enhanced);
194+
}
195+
196+
// Add API documentation
197+
if (features.includes("api")) {
198+
enhanced = this.addAPIDocumentation(enhanced);
199+
}
200+
201+
// Add testing setup
202+
if (features.includes("testing")) {
203+
enhanced = this.addTestingSetup(enhanced);
204+
}
205+
206+
// Add logging
207+
if (features.includes("logging")) {
208+
enhanced = this.addLoggingSetup(enhanced);
209+
}
210+
211+
return enhanced;
212+
}
213+
214+
private addAuthenticationBoilerplate(content: string): string {
215+
// Add authentication imports and setup based on file type
216+
if (content.includes("package.json")) {
217+
return content.replace(
218+
/"dependencies": {/,
219+
'"dependencies": {\n "passport": "^0.6.0",\n "passport-local": "^1.0.0",\n "bcryptjs": "^2.4.3",\n "jsonwebtoken": "^9.0.0",'
220+
);
221+
}
222+
223+
if (content.includes("import") && content.includes("express")) {
224+
return content.replace(
225+
/import.*express.*/,
226+
`$&\nimport passport from 'passport';\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport jwt from 'jsonwebtoken';`
227+
);
228+
}
229+
230+
return content;
231+
}
232+
233+
private addDatabaseConfig(content: string): string {
234+
if (content.includes("package.json")) {
235+
return content.replace(
236+
/"dependencies": {/,
237+
'"dependencies": {\n "mongoose": "^7.5.0",\n "@types/mongoose": "^5.11.97",'
238+
);
239+
}
240+
241+
if (content.includes("import") && content.includes("express")) {
242+
return content.replace(
243+
/import.*express.*/,
244+
`$&\nimport mongoose from 'mongoose';`
245+
);
246+
}
247+
248+
return content;
249+
}
250+
251+
private addAPIDocumentation(content: string): string {
252+
if (content.includes("package.json")) {
253+
return content.replace(
254+
/"dependencies": {/,
255+
'"dependencies": {\n "swagger-ui-express": "^5.0.0",\n "swagger-jsdoc": "^6.2.8",'
256+
);
257+
}
258+
259+
return content;
260+
}
261+
262+
private addTestingSetup(content: string): string {
263+
if (content.includes("package.json")) {
264+
return content.replace(
265+
/"devDependencies": {/,
266+
'"devDependencies": {\n "jest": "^29.7.0",\n "supertest": "^6.3.3",\n "@types/jest": "^29.5.5",'
267+
);
268+
}
269+
270+
return content;
271+
}
272+
273+
private addLoggingSetup(content: string): string {
274+
if (content.includes("package.json")) {
275+
return content.replace(
276+
/"dependencies": {/,
277+
'"dependencies": {\n "winston": "^3.10.0",'
278+
);
279+
}
280+
281+
if (content.includes("import") && content.includes("express")) {
282+
return content.replace(
283+
/import.*express.*/,
284+
`$&\nimport winston from 'winston';`
285+
);
286+
}
287+
288+
return content;
289+
}
290+
}

0 commit comments

Comments
 (0)