openwork-agent 1.0.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +436 -0
  3. package/package.json +78 -0
  4. package/src/core/TechDetector.js +351 -0
  5. package/src/generators/ProjectGenerator.js +1241 -0
  6. package/src/generators/ProjectGeneratorExtensions.js +14 -0
  7. package/src/generators/TemplateMethods.js +402 -0
  8. package/src/generators/index.js +5 -0
  9. package/src/index.js +152 -0
  10. package/src/main.js +8 -0
  11. package/src/templates/common/README.md.hbs +358 -0
  12. package/src/templates/docker/index.js +518 -0
  13. package/src/templates/docker.js +58 -0
  14. package/src/templates/go/basic/api/routes/user.go.hbs +138 -0
  15. package/src/templates/go/basic/config/config.go.hbs +54 -0
  16. package/src/templates/go/basic/go.mod.hbs +8 -0
  17. package/src/templates/go/basic/main.go.hbs +70 -0
  18. package/src/templates/go/basic/models/user.go.hbs +69 -0
  19. package/src/templates/go/basic/services/user_service.go.hbs +173 -0
  20. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/controller/UserController.java.hbs +91 -0
  21. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/dto/ApiResponse.java.hbs +40 -0
  22. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/model/User.java.hbs +102 -0
  23. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/repository/UserRepository.java.hbs +20 -0
  24. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/service/UserService.java.hbs +65 -0
  25. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/{{pascalCase projectName}}Application.java.hbs +16 -0
  26. package/src/templates/node/basic/src/config/database.ts.hbs +18 -0
  27. package/src/templates/node/basic/src/controllers/UserController.ts.hbs +98 -0
  28. package/src/templates/node/basic/src/index.ts.hbs +45 -0
  29. package/src/templates/node/basic/src/middleware/errorHandler.ts.hbs +33 -0
  30. package/src/templates/node/basic/src/routes/index.ts.hbs +42 -0
  31. package/src/templates/node/basic/src/types/index.ts.hbs +18 -0
  32. package/src/templates/python/basic/config/database.py.hbs +36 -0
  33. package/src/templates/python/basic/main.py.hbs +58 -0
  34. package/src/templates/python/basic/middleware/error_handler.py.hbs +41 -0
  35. package/src/templates/python/basic/models/user.py.hbs +40 -0
  36. package/src/templates/python/basic/routes/__init__.py.hbs +12 -0
  37. package/src/templates/python/basic/routes/users.py.hbs +64 -0
  38. package/src/templates/rust/basic/Cargo.toml.hbs +39 -0
  39. package/src/templates/rust/basic/src/config/database.rs.hbs +27 -0
  40. package/src/templates/rust/basic/src/handlers/user.rs.hbs +130 -0
  41. package/src/templates/rust/basic/src/handlers/user_routes.rs.hbs +15 -0
  42. package/src/templates/rust/basic/src/main.rs.hbs +53 -0
  43. package/src/templates/rust/basic/src/models/mod.rs.hbs +79 -0
  44. package/src/templates/rust/basic/src/schema.rs.hbs +10 -0
  45. package/src/utils/FileManager.js +186 -0
  46. package/src/utils/Templates.js +231 -0
@@ -0,0 +1,14 @@
1
+ // Import template methods into ProjectGenerator
2
+ const templateMethods = require('./TemplateMethods');
3
+ const ProjectGenerator = require('./ProjectGenerator');
4
+
5
+ // Add template methods to ProjectGenerator prototype
6
+ Object.assign(ProjectGenerator.prototype, templateMethods);
7
+
8
+ // Import Docker templates
9
+ const dockerTemplates = require('../templates/docker');
10
+
11
+ // Add Docker generation methods to ProjectGenerator
12
+ Object.assign(ProjectGenerator.prototype, dockerTemplates);
13
+
14
+ module.exports = ProjectGenerator;
@@ -0,0 +1,402 @@
1
+ const { generateGitignore, generateEnvExample } = require('../utils/Templates');
2
+
3
+ // Update ProjectGenerator to use the new templates
4
+ const ProjectGenerator = require('./ProjectGenerator');
5
+
6
+ // Extend the ProjectGenerator with template methods
7
+ ProjectGenerator.prototype.generateGitignore = generateGitignore;
8
+ ProjectGenerator.prototype.generateEnvExample = generateEnvExample;
9
+ ProjectGenerator.prototype.generateReadme = function(config) {
10
+ const Handlebars = require('handlebars');
11
+ const fs = require('fs-extra');
12
+ const path = require('path');
13
+
14
+ const templatePath = path.join(__dirname, '../templates/common/README.md.hbs');
15
+ const templateContent = fs.readFileSync(templatePath, 'utf8');
16
+ const template = Handlebars.compile(templateContent);
17
+ return template(config);
18
+ };
19
+
20
+ // Technology-specific configuration methods
21
+ ProjectGenerator.prototype.generateTsConfig = function(config) {
22
+ return JSON.stringify({
23
+ compilerOptions: {
24
+ target: "ES2020",
25
+ module: "commonjs",
26
+ lib: ["ES2020"],
27
+ outDir: "./dist",
28
+ rootDir: "./src",
29
+ strict: true,
30
+ esModuleInterop: true,
31
+ skipLibCheck: true,
32
+ forceConsistentCasingInFileNames: true,
33
+ resolveJsonModule: true,
34
+ declaration: true,
35
+ declarationMap: true,
36
+ sourceMap: true,
37
+ experimentalDecorators: true,
38
+ emitDecoratorMetadata: true
39
+ },
40
+ include: ["src/**/*"],
41
+ exclude: ["node_modules", "dist", "tests"]
42
+ }, null, 2);
43
+ };
44
+
45
+ ProjectGenerator.prototype.generateNodeDevDependencies = function(config) {
46
+ const baseDeps = [
47
+ '@types/node',
48
+ 'typescript',
49
+ 'ts-node',
50
+ 'nodemon',
51
+ 'jest',
52
+ '@types/jest',
53
+ 'ts-jest',
54
+ 'eslint',
55
+ '@typescript-eslint/eslint-plugin',
56
+ '@typescript-eslint/parser'
57
+ ];
58
+
59
+ if (config.framework === 'nestjs') {
60
+ baseDeps.push('@nestjs/cli', '@nestjs/schematics', '@nestjs/testing');
61
+ }
62
+
63
+ return baseDeps;
64
+ };
65
+
66
+ // Python specific methods
67
+ ProjectGenerator.prototype.generateRequirements = function(config) {
68
+ const requirements = [
69
+ 'fastapi==0.104.1',
70
+ 'uvicorn[standard]==0.24.0',
71
+ 'motor==3.3.2',
72
+ 'pydantic==2.5.0',
73
+ 'pydantic-settings==2.1.0',
74
+ 'python-dotenv==1.0.0',
75
+ 'python-multipart==0.0.6',
76
+ 'email-validator==2.1.0'
77
+ ];
78
+
79
+ if (config.database === 'postgresql') {
80
+ requirements.push('psycopg2-binary==2.9.9');
81
+ } else if (config.database === 'mysql') {
82
+ requirements.push('aiomysql==0.2.0');
83
+ } else if (config.database === 'sqlite') {
84
+ requirements.push('aiosqlite==0.19.0');
85
+ }
86
+
87
+ if (config.includeTests) {
88
+ requirements.push('pytest==7.4.3');
89
+ requirements.push('pytest-asyncio==0.21.1');
90
+ requirements.push('httpx==0.25.2');
91
+ }
92
+
93
+ return requirements.join('\n');
94
+ };
95
+
96
+ ProjectGenerator.prototype.generateSetupPy = function(config) {
97
+ return `from setuptools import setup, find_packages
98
+
99
+ setup(
100
+ name="${config.projectName}",
101
+ version="1.0.0",
102
+ description="${config.description}",
103
+ author="${config.author}",
104
+ packages=find_packages(),
105
+ install_requires=[
106
+ # Add your dependencies here
107
+ ],
108
+ classifiers=[
109
+ "Programming Language :: Python :: 3",
110
+ "License :: OSI Approved :: MIT License",
111
+ "Operating System :: OS Independent",
112
+ ],
113
+ python_requires=">=3.8",
114
+ )`;
115
+ };
116
+
117
+ // Java specific methods
118
+ ProjectGenerator.prototype.generatePomXML = function(config) {
119
+ return `<?xml version="1.0" encoding="UTF-8"?>
120
+ <project xmlns="http://maven.apache.org/POM/4.0.0"
121
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
122
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
123
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
124
+ <modelVersion>4.0.0</modelVersion>
125
+
126
+ <groupId>com.${config.projectName}</groupId>
127
+ <artifactId>${config.projectName}</artifactId>
128
+ <version>1.0.0</version>
129
+ <packaging>jar</packaging>
130
+
131
+ <name>${config.pascalCase(config.projectName)}</name>
132
+ <description>${config.description}</description>
133
+
134
+ <parent>
135
+ <groupId>org.springframework.boot</groupId>
136
+ <artifactId>spring-boot-starter-parent</artifactId>
137
+ <version>3.2.0</version>
138
+ <relativePath/>
139
+ </parent>
140
+
141
+ <properties>
142
+ <java.version>17</java.version>
143
+ </properties>
144
+
145
+ <dependencies>
146
+ <dependency>
147
+ <groupId>org.springframework.boot</groupId>
148
+ <artifactId>spring-boot-starter-web</artifactId>
149
+ </dependency>
150
+
151
+ <dependency>
152
+ <groupId>org.springframework.boot</groupId>
153
+ <artifactId>spring-boot-starter-data-mongodb</artifactId>
154
+ </dependency>
155
+
156
+ <dependency>
157
+ <groupId>org.springframework.boot</groupId>
158
+ <artifactId>spring-boot-starter-validation</artifactId>
159
+ </dependency>
160
+
161
+ <dependency>
162
+ <groupId>org.springframework.boot</groupId>
163
+ <artifactId>spring-boot-starter-test</artifactId>
164
+ <scope>test</scope>
165
+ </dependency>
166
+ </dependencies>
167
+
168
+ <build>
169
+ <plugins>
170
+ <plugin>
171
+ <groupId>org.springframework.boot</groupId>
172
+ <artifactId>spring-boot-maven-plugin</artifactId>
173
+ </plugin>
174
+ </plugins>
175
+ </build>
176
+ </project>`;
177
+ };
178
+
179
+ ProjectGenerator.prototype.generateApplicationProperties = function(config) {
180
+ return `# Server Configuration
181
+ server.port=8080
182
+ spring.application.name=${config.projectName}
183
+
184
+ # Database Configuration
185
+ spring.data.mongodb.uri=mongodb://localhost:27017/${config.projectName}
186
+ spring.data.mongodb.database=${config.projectName}
187
+
188
+ # Logging Configuration
189
+ logging.level.com.${config.projectName}=DEBUG
190
+ logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
191
+
192
+ # CORS Configuration
193
+ spring.web.cors.allowed-origins=http://localhost:3000
194
+ spring.web.cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
195
+ spring.web.cors.allowed-headers=*
196
+ spring.web.cors.allow-credentials=true`;
197
+ };
198
+
199
+ // Go specific methods
200
+ ProjectGenerator.prototype.generateGoMod = function(config) {
201
+ return `module ${config.projectName}
202
+
203
+ go 1.21
204
+
205
+ require (
206
+ github.com/gin-gonic/gin v1.9.1
207
+ go.mongodb.org/mongo-driver v1.12.1
208
+ github.com/joho/godotenv v1.4.0
209
+ github.com/google/uuid v1.3.0
210
+ )`;
211
+ };
212
+
213
+ ProjectGenerator.prototype.generateMainGo = function(config) {
214
+ return `package main
215
+
216
+ import (
217
+ "fmt"
218
+ "log"
219
+ "net/http"
220
+
221
+ "github.com/gin-gonic/gin"
222
+ "github.com/joho/godotenv"
223
+ )
224
+
225
+ func main() {
226
+ // Load environment variables
227
+ if err := godotenv.Load(); err != nil {
228
+ log.Println("Warning: Could not load .env file")
229
+ }
230
+
231
+ // Initialize router
232
+ r := gin.Default()
233
+
234
+ // CORS middleware
235
+ r.Use(func(c *gin.Context) {
236
+ c.Header("Access-Control-Allow-Origin", "*")
237
+ c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
238
+ c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
239
+
240
+ if c.Request.Method == "OPTIONS" {
241
+ c.AbortWithStatus(204)
242
+ return
243
+ }
244
+
245
+ c.Next()
246
+ })
247
+
248
+ // Health check
249
+ r.GET("/health", func(c *gin.Context) {
250
+ c.JSON(http.StatusOK, gin.H{
251
+ "status": "OK",
252
+ "message": "${config.projectName} is running",
253
+ })
254
+ })
255
+
256
+ // API routes
257
+ api := r.Group("/api")
258
+ {
259
+ // TODO: Add your API routes here
260
+ api.GET("/users", getUsers)
261
+ }
262
+
263
+ port := os.Getenv("PORT")
264
+ if port == "" {
265
+ port = "8080"
266
+ }
267
+
268
+ fmt.Printf("šŸš€ Server starting on port %s\\n", port)
269
+ log.Fatal(http.ListenAndServe(":"+port, r))
270
+ }
271
+
272
+ func getUsers(c *gin.Context) {
273
+ // TODO: Implement user retrieval logic
274
+ c.JSON(http.StatusOK, gin.H{
275
+ "success": true,
276
+ "data": []interface{}{},
277
+ })
278
+ }`;
279
+ };
280
+
281
+ // Rust specific methods
282
+ ProjectGenerator.prototype.generateCargoToml = function(config) {
283
+ return `[package]
284
+ name = "${config.projectName}"
285
+ version = "0.1.0"
286
+ edition = "2021"
287
+ authors = ["${config.author}"]
288
+ description = "${config.description}"
289
+
290
+ [dependencies]
291
+ actix-web = "4.4"
292
+ actix-cors = "0.7"
293
+ serde = { version = "1.0", features = ["derive"] }
294
+ serde_json = "1.0"
295
+ diesel = { version = "2.1", features = ["postgres", "r2d2"] }
296
+ diesel_migrations = "2.1"
297
+ dotenv = "0.15"
298
+ log = "0.4"
299
+ env_logger = "0.10"
300
+ uuid = { version = "1.5", features = ["v4", "serde"] }
301
+ chrono = { version = "0.4", features = ["serde"] }
302
+ anyhow = "1.0"
303
+ thiserror = "1.0"`;
304
+ };
305
+
306
+ ProjectGenerator.prototype.generateMainRs = function(config) {
307
+ return `use actix_web::{web, App, HttpServer, middleware::Logger};
308
+ use actix_cors::Cors;
309
+ use std::env;
310
+
311
+ #[actix_web::main]
312
+ async fn main() -> std::io::Result<()> {
313
+ env_logger::init();
314
+ dotenv::dotenv().ok();
315
+
316
+ HttpServer::new(|| {
317
+ let cors = Cors::default()
318
+ .allow_any_origin()
319
+ .allow_any_method()
320
+ .allow_any_header()
321
+ .max_age(3600);
322
+
323
+ App::new()
324
+ .wrap(cors)
325
+ .wrap(Logger::default())
326
+ .route("/health", web::get().to(health_check))
327
+ .service(
328
+ web::scope("/api")
329
+ // TODO: Add your API routes here
330
+ .route("/users", web::get().to(get_users))
331
+ )
332
+ })
333
+ .bind("0.0.0.0:8080")?
334
+ .run()
335
+ .await
336
+ }
337
+
338
+ async fn health_check() -> impl actix_web::Responder {
339
+ actix_web::HttpResponse::Ok().json(serde_json::json!({
340
+ "status": "OK",
341
+ "message": "${config.pascalCase(config.projectName)} is running"
342
+ }))
343
+ }
344
+
345
+ async fn get_users() -> impl actix_web::Responder {
346
+ // TODO: Implement user retrieval logic
347
+ actix_web::HttpResponse::Ok().json(serde_json::json!({
348
+ "success": true,
349
+ "data": []
350
+ }))
351
+ }`;
352
+ };
353
+
354
+ // PHP specific methods
355
+ ProjectGenerator.prototype.generateComposerJSON = function(config) {
356
+ return JSON.stringify({
357
+ name: `${config.author}/${config.projectName}`,
358
+ description: config.description,
359
+ type: "project",
360
+ require: {
361
+ php: "^7.4|^8.0",
362
+ "illuminate/database": "^10.0",
363
+ "illuminate/routing": "^10.0",
364
+ "illuminate/http": "^10.0",
365
+ "illuminate/validation": "^10.0",
366
+ "vlucas/phpdotenv": "^5.4"
367
+ },
368
+ requireDev: {
369
+ "phpunit/phpunit": "^9.0",
370
+ "squizlabs/php_codesniffer": "^3.7"
371
+ },
372
+ autoload: {
373
+ psr4: {
374
+ "App\\": "app/"
375
+ }
376
+ },
377
+ scripts: {
378
+ "start": "php -S localhost:8000 -t public",
379
+ "test": "phpunit"
380
+ },
381
+ authors: [
382
+ {
383
+ name: config.author
384
+ }
385
+ ],
386
+ minimumStability: "stable"
387
+ }, null, 2);
388
+ };
389
+
390
+ // Helper method for PascalCase
391
+ ProjectGenerator.prototype.pascalCase = function(str) {
392
+ return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
393
+ return word.toUpperCase();
394
+ }).replace(/\s+/g, '');
395
+ };
396
+
397
+ // Helper method for snakeCase
398
+ ProjectGenerator.prototype.snakeCase = function(str) {
399
+ return str.replace(/([a-z])([A-Z])/g, '$1_$2').replace(/\s+/g, '_').toLowerCase();
400
+ };
401
+
402
+ module.exports = ProjectGenerator;
@@ -0,0 +1,5 @@
1
+ const ProjectGenerator = require('./ProjectGenerator');
2
+ require('./ProjectGeneratorExtensions');
3
+
4
+ // Export main ProjectGenerator with all extensions
5
+ module.exports = ProjectGenerator;
package/src/index.js ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require('commander');
4
+ const inquirer = require('inquirer');
5
+ const chalk = require('chalk');
6
+ const fs = require('fs-extra');
7
+ const path = require('path');
8
+
9
+ const ProjectGenerator = require('./generators');
10
+ const TechDetector = require('./core/TechDetector');
11
+ const FileManager = require('./utils/FileManager');
12
+
13
+ const program = new Command();
14
+
15
+ program
16
+ .name('openwork-agent')
17
+ .description('AI-powered backend code generator for any technology stack')
18
+ .version('1.0.0');
19
+
20
+ program
21
+ .command('create <project-name>')
22
+ .description('Create a new backend project')
23
+ .option('-t, --tech <technology>', 'Specify technology (node, python, java, go, rust, php, etc.)')
24
+ .option('-d, --database <database>', 'Specify database (mongodb, postgresql, mysql, sqlite, etc.)')
25
+ .option('-f, --framework <framework>', 'Specify framework (express, fastapi, spring, gin, etc.)')
26
+ .option('--template <template>', 'Use specific template')
27
+ .option('--no-interactive', 'Skip interactive prompts')
28
+ .option('--docker', 'Include Docker configuration')
29
+ .option('--tests', 'Include test setup')
30
+ .action(async (projectName, options) => {
31
+ try {
32
+ console.log(chalk.blue.bold('\nšŸš€ OpenWork Agent - Backend Code Generator'));
33
+ console.log(chalk.gray('Creating your backend project...\n'));
34
+
35
+ const generator = new ProjectGenerator();
36
+
37
+ let config = {
38
+ projectName,
39
+ technology: options.tech,
40
+ database: options.database,
41
+ framework: options.framework,
42
+ template: options.template,
43
+ interactive: options.interactive,
44
+ includeDocker: options.docker,
45
+ includeTests: options.tests
46
+ };
47
+
48
+ if (config.interactive && !config.technology) {
49
+ config = await generator.promptForConfiguration(config);
50
+ }
51
+
52
+ await generator.createProject(config);
53
+
54
+ console.log(chalk.green.bold('\nāœ… Project created successfully!'));
55
+ console.log(chalk.cyan(`\nNext steps:`));
56
+ console.log(chalk.white(` cd ${projectName}`));
57
+
58
+ // Show setup commands based on technology
59
+ const setupCommands = generator.getSetupCommands(config.technology);
60
+ setupCommands.forEach(cmd => {
61
+ console.log(chalk.white(` ${cmd}`));
62
+ });
63
+
64
+ } catch (error) {
65
+ console.error(chalk.red.bold('\nāŒ Error:'), error.message);
66
+ process.exit(1);
67
+ }
68
+ });
69
+
70
+ program
71
+ .command('analyze')
72
+ .description('Analyze current directory and suggest technology stack')
73
+ .action(async () => {
74
+ try {
75
+ const detector = new TechDetector();
76
+ const analysis = await detector.analyzeCurrentDirectory();
77
+
78
+ console.log(chalk.blue.bold('\nšŸ“Š Technology Analysis'));
79
+
80
+ if (analysis.technologies.length > 0) {
81
+ console.log(chalk.yellow('\nDetected Technologies:'));
82
+ analysis.technologies.forEach(tech => {
83
+ const confidence = Math.round(analysis.confidence[tech] * 100);
84
+ console.log(chalk.white(` ${tech}: ${confidence}% confidence`));
85
+ });
86
+ }
87
+
88
+ if (analysis.frameworks.length > 0) {
89
+ console.log(chalk.yellow('\nDetected Frameworks:'));
90
+ analysis.frameworks.forEach(fw => {
91
+ console.log(chalk.white(` ${fw.technology}: ${fw.framework}`));
92
+ });
93
+ }
94
+
95
+ if (analysis.databases.length > 0) {
96
+ console.log(chalk.yellow('\nDetected Databases:'));
97
+ analysis.databases.forEach(db => {
98
+ console.log(chalk.white(` ${db}`));
99
+ });
100
+ }
101
+
102
+ } catch (error) {
103
+ console.error(chalk.red.bold('\nāŒ Error:'), error.message);
104
+ process.exit(1);
105
+ }
106
+ });
107
+
108
+ program
109
+ .command('templates')
110
+ .description('List available templates')
111
+ .action(() => {
112
+ const templates = [
113
+ { name: 'express-api', tech: 'node', description: 'Express.js REST API with TypeScript' },
114
+ { name: 'fastapi-crud', tech: 'python', description: 'FastAPI CRUD operations with SQLAlchemy' },
115
+ { name: 'spring-boot', tech: 'java', description: 'Spring Boot microservice with JPA' },
116
+ { name: 'go-gin', tech: 'go', description: 'Go Gin web service with GORM' },
117
+ { name: 'rust-actix', tech: 'rust', description: 'Actix-web API with Diesel ORM' },
118
+ { name: 'django-api', tech: 'python', description: 'Django REST API' },
119
+ { name: 'nestjs-api', tech: 'node', description: 'NestJS API with PostgreSQL' },
120
+ { name: 'laravel-api', tech: 'php', description: 'Laravel REST API' }
121
+ ];
122
+
123
+ console.log(chalk.blue.bold('\nšŸ“‹ Available Templates'));
124
+ templates.forEach((template, index) => {
125
+ console.log(chalk.cyan(`${index + 1}. ${template.name}`));
126
+ console.log(chalk.gray(` Tech: ${template.tech} - ${template.description}`));
127
+ });
128
+ });
129
+
130
+ program
131
+ .command('list')
132
+ .description('List supported technologies and frameworks')
133
+ .action(() => {
134
+ const detector = new TechDetector();
135
+ const technologies = detector.getAvailableTechnologies();
136
+
137
+ console.log(chalk.blue.bold('\nšŸ”§ Supported Technologies:'));
138
+ technologies.forEach(tech => {
139
+ const frameworks = detector.getFrameworksForTechnology(tech);
140
+ console.log(chalk.cyan(`\n${tech}:`));
141
+ frameworks.forEach(fw => {
142
+ console.log(chalk.white(` - ${fw}`));
143
+ });
144
+ });
145
+
146
+ console.log(chalk.green.bold('\nšŸ’¾ Supported Databases:'));
147
+ detector.getAvailableDatabases().forEach(db => {
148
+ console.log(chalk.white(` - ${db}`));
149
+ });
150
+ });
151
+
152
+ program.parse();
package/src/main.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Fix the ProjectGenerator import issue
4
+ const ProjectGenerator = require('./generators/ProjectGenerator');
5
+ require('./generators/ProjectGeneratorExtensions');
6
+
7
+ // Re-export the main entry point
8
+ require('./index');