antigravity-flow 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 (115) hide show
  1. package/README.md +182 -0
  2. package/dist/bin/ag-flow.js +127 -0
  3. package/dist/src/adapters/ConsoleLoggerAdapter.js +52 -0
  4. package/dist/src/adapters/EjsTemplateAdapter.js +66 -0
  5. package/dist/src/adapters/JsonLocalizationAdapter.js +81 -0
  6. package/dist/src/adapters/NodeFileSystemAdapter.js +52 -0
  7. package/dist/src/adapters/index.js +20 -0
  8. package/dist/src/commands/guide.js +89 -0
  9. package/dist/src/commands/index.js +19 -0
  10. package/dist/src/commands/init.js +581 -0
  11. package/dist/src/commands/templates.js +143 -0
  12. package/dist/src/core/ConfigService.js +75 -0
  13. package/dist/src/core/ContextGenerator.js +27 -0
  14. package/dist/src/core/DockerfileGenerator.js +151 -0
  15. package/dist/src/core/GitignoreGenerator.js +129 -0
  16. package/dist/src/core/PipelineGenerator.js +68 -0
  17. package/dist/src/core/RulesComposer.js +62 -0
  18. package/dist/src/core/StackDetector.js +115 -0
  19. package/dist/src/core/WorkflowGenerator.js +137 -0
  20. package/dist/src/core/index.js +26 -0
  21. package/dist/src/core/interfaces.js +2 -0
  22. package/dist/src/core/pipelines/PipelineStrategy.js +97 -0
  23. package/dist/src/core/types.js +300 -0
  24. package/dist/src/locales/en.json +293 -0
  25. package/dist/src/locales/fr.json +293 -0
  26. package/dist/src/templates/docker/django.Dockerfile.ejs +21 -0
  27. package/dist/src/templates/docker/dockerignore.ejs +12 -0
  28. package/dist/src/templates/docker/go.Dockerfile.ejs +20 -0
  29. package/dist/src/templates/docker/nestjs.Dockerfile.ejs +25 -0
  30. package/dist/src/templates/docker/node.Dockerfile.ejs +13 -0
  31. package/dist/src/templates/docker/python.Dockerfile.ejs +13 -0
  32. package/dist/src/templates/docker/springboot.Dockerfile.ejs +25 -0
  33. package/dist/src/templates/en/architect.md.ejs +85 -0
  34. package/dist/src/templates/en/ba.md.ejs +88 -0
  35. package/dist/src/templates/en/data.md.ejs +47 -0
  36. package/dist/src/templates/en/dev.md.ejs +77 -0
  37. package/dist/src/templates/en/devops.md.ejs +54 -0
  38. package/dist/src/templates/en/fragments/arch/feature-sliced.md.ejs +12 -0
  39. package/dist/src/templates/en/fragments/arch/hexagonal.md.ejs +14 -0
  40. package/dist/src/templates/en/fragments/arch/mvc.md.ejs +11 -0
  41. package/dist/src/templates/en/fragments/aspnet-core.md.ejs +11 -0
  42. package/dist/src/templates/en/fragments/base-rules.md.ejs +5 -0
  43. package/dist/src/templates/en/fragments/django.md.ejs +12 -0
  44. package/dist/src/templates/en/fragments/fastapi.md.ejs +11 -0
  45. package/dist/src/templates/en/fragments/flutter.md.ejs +11 -0
  46. package/dist/src/templates/en/fragments/nestjs.md.ejs +5 -0
  47. package/dist/src/templates/en/fragments/nextjs.md.ejs +10 -0
  48. package/dist/src/templates/en/fragments/react-native.md.ejs +12 -0
  49. package/dist/src/templates/en/fragments/react.md.ejs +5 -0
  50. package/dist/src/templates/en/fragments/rigor/legacy.md.ejs +6 -0
  51. package/dist/src/templates/en/fragments/rigor/prototype.md.ejs +6 -0
  52. package/dist/src/templates/en/fragments/rigor/strict.md.ejs +7 -0
  53. package/dist/src/templates/en/fragments/rust.md.ejs +11 -0
  54. package/dist/src/templates/en/fragments/scrypto.md.ejs +8 -0
  55. package/dist/src/templates/en/fragments/solidity.md.ejs +20 -0
  56. package/dist/src/templates/en/fragments/spring-boot.md.ejs +13 -0
  57. package/dist/src/templates/en/guide.txt +48 -0
  58. package/dist/src/templates/en/lead.md.ejs +76 -0
  59. package/dist/src/templates/en/pipelines/github-dotnet.yml.ejs +24 -0
  60. package/dist/src/templates/en/pipelines/github-flutter.yml.ejs +24 -0
  61. package/dist/src/templates/en/pipelines/github-nestjs.yml.ejs +26 -0
  62. package/dist/src/templates/en/pipelines/github-react.yml.ejs +26 -0
  63. package/dist/src/templates/en/pipelines/github-rust.yml.ejs +38 -0
  64. package/dist/src/templates/en/pipelines/github-scrypto.yml.ejs +34 -0
  65. package/dist/src/templates/en/po.md.ejs +86 -0
  66. package/dist/src/templates/en/project-context.md.ejs +26 -0
  67. package/dist/src/templates/en/qa.md.ejs +103 -0
  68. package/dist/src/templates/en/rules.md.ejs +30 -0
  69. package/dist/src/templates/en/security.md.ejs +55 -0
  70. package/dist/src/templates/en/techwriter.md.ejs +46 -0
  71. package/dist/src/templates/fr/architect.md.ejs +15 -0
  72. package/dist/src/templates/fr/ba.md.ejs +11 -0
  73. package/dist/src/templates/fr/data.md.ejs +47 -0
  74. package/dist/src/templates/fr/dev.md.ejs +11 -0
  75. package/dist/src/templates/fr/devops.md.ejs +54 -0
  76. package/dist/src/templates/fr/fragments/arch/feature-sliced.md.ejs +12 -0
  77. package/dist/src/templates/fr/fragments/arch/hexagonal.md.ejs +14 -0
  78. package/dist/src/templates/fr/fragments/arch/mvc.md.ejs +11 -0
  79. package/dist/src/templates/fr/fragments/aspnet-core.md.ejs +11 -0
  80. package/dist/src/templates/fr/fragments/flutter.md.ejs +11 -0
  81. package/dist/src/templates/fr/fragments/rigor/legacy.md.ejs +6 -0
  82. package/dist/src/templates/fr/fragments/rigor/prototype.md.ejs +6 -0
  83. package/dist/src/templates/fr/fragments/rigor/strict.md.ejs +7 -0
  84. package/dist/src/templates/fr/fragments/rust.md.ejs +10 -0
  85. package/dist/src/templates/fr/fragments/scrypto.md.ejs +8 -0
  86. package/dist/src/templates/fr/guide.txt +47 -0
  87. package/dist/src/templates/fr/lead.md.ejs +12 -0
  88. package/dist/src/templates/fr/po.md.ejs +11 -0
  89. package/dist/src/templates/fr/project-context.md.ejs +28 -0
  90. package/dist/src/templates/fr/qa.md.ejs +14 -0
  91. package/dist/src/templates/fr/rules.md.ejs +30 -0
  92. package/dist/src/templates/fr/security.md.ejs +55 -0
  93. package/dist/src/templates/fr/techwriter.md.ejs +46 -0
  94. package/dist/src/templates/gitignore/dotnet.txt +6 -0
  95. package/dist/src/templates/gitignore/go.txt +15 -0
  96. package/dist/src/templates/gitignore/java.txt +4 -0
  97. package/dist/src/templates/gitignore/jetbrains.txt +4 -0
  98. package/dist/src/templates/gitignore/linux.txt +5 -0
  99. package/dist/src/templates/gitignore/macos.txt +3 -0
  100. package/dist/src/templates/gitignore/node.txt +11 -0
  101. package/dist/src/templates/gitignore/python.txt +10 -0
  102. package/dist/src/templates/gitignore/rust.txt +3 -0
  103. package/dist/src/templates/gitignore/solidity.txt +19 -0
  104. package/dist/src/templates/gitignore/vscode.txt +6 -0
  105. package/dist/src/templates/gitignore/windows.txt +4 -0
  106. package/dist/tests/commands/InitCommand.spec.js +529 -0
  107. package/dist/tests/commands/InitConfig.spec.js +108 -0
  108. package/dist/tests/core/ConfigService.spec.js +97 -0
  109. package/dist/tests/core/ContextGenerator.spec.js +51 -0
  110. package/dist/tests/core/PipelineGenerator.spec.js +206 -0
  111. package/dist/tests/core/RulesComposer.spec.js +89 -0
  112. package/dist/tests/core/StackDetector.spec.js +69 -0
  113. package/dist/tests/core/Types.spec.js +243 -0
  114. package/dist/tests/core/WorkflowGenerator.spec.js +99 -0
  115. package/package.json +55 -0
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.TemplatesCommand = void 0;
40
+ const inquirer_1 = __importDefault(require("inquirer"));
41
+ const path = __importStar(require("path"));
42
+ const fs = __importStar(require("fs-extra"));
43
+ class TemplatesCommand {
44
+ logger;
45
+ localizationService;
46
+ templatesDir;
47
+ customTemplatesDir;
48
+ constructor(logger, localizationService, templatesDir, customTemplatesDir // .agent/templates
49
+ ) {
50
+ this.logger = logger;
51
+ this.localizationService = localizationService;
52
+ this.templatesDir = templatesDir;
53
+ this.customTemplatesDir = customTemplatesDir;
54
+ }
55
+ async execute(action, templateName) {
56
+ if (action === 'list') {
57
+ await this.listTemplates();
58
+ }
59
+ else if (action === 'update') {
60
+ if (!templateName) {
61
+ // Interactive selection if no name provided
62
+ const files = await this.getAllTemplateFiles();
63
+ const answer = await inquirer_1.default.prompt([
64
+ {
65
+ type: 'list', // or autocomplete if list is huge? list is safer for now.
66
+ name: 'template',
67
+ message: 'Select a template to update:',
68
+ choices: files
69
+ }
70
+ ]);
71
+ templateName = answer.template;
72
+ }
73
+ if (templateName) {
74
+ await this.updateTemplate(templateName);
75
+ }
76
+ }
77
+ else {
78
+ this.logger.error(`Unknown action: ${action}. Use 'list' or 'update'.`);
79
+ }
80
+ }
81
+ async listTemplates() {
82
+ this.logger.info('Available Templates:');
83
+ const files = await this.getAllTemplateFiles();
84
+ files.forEach(f => {
85
+ // Check if customized
86
+ const isCustom = fs.existsSync(path.join(this.customTemplatesDir, f));
87
+ const status = isCustom ? '[Customized]' : '[Default] ';
88
+ console.log(` ${status} ${f}`);
89
+ });
90
+ }
91
+ async updateTemplate(templateName) {
92
+ const defaultPath = path.join(this.templatesDir, templateName);
93
+ const customPath = path.join(this.customTemplatesDir, templateName);
94
+ // 1. Load content (Custom > Default)
95
+ let content = '';
96
+ if (await fs.pathExists(customPath)) {
97
+ content = await fs.readFile(customPath, 'utf8');
98
+ }
99
+ else if (await fs.pathExists(defaultPath)) {
100
+ content = await fs.readFile(defaultPath, 'utf8');
101
+ }
102
+ else {
103
+ this.logger.error(`Template not found: ${templateName}`);
104
+ return;
105
+ }
106
+ // 2. Open Editor
107
+ const answer = await inquirer_1.default.prompt([
108
+ {
109
+ type: 'editor',
110
+ name: 'content',
111
+ message: `Editing template: ${templateName}`,
112
+ default: content,
113
+ },
114
+ ]);
115
+ const newContent = answer.content;
116
+ // 3. Save to custom location
117
+ if (newContent && newContent.trim() !== '') {
118
+ await fs.ensureDir(path.dirname(customPath));
119
+ await fs.writeFile(customPath, newContent);
120
+ this.logger.success(`Template saved to: ${customPath}`);
121
+ }
122
+ else {
123
+ this.logger.warn('Empty content. Update cancelled.');
124
+ }
125
+ }
126
+ async getAllTemplateFiles(dir = this.templatesDir, baseDir = this.templatesDir) {
127
+ let results = [];
128
+ const list = await fs.readdir(dir);
129
+ for (const file of list) {
130
+ const filePath = path.join(dir, file);
131
+ const stat = await fs.stat(filePath);
132
+ if (stat && stat.isDirectory()) {
133
+ results = results.concat(await this.getAllTemplateFiles(filePath, baseDir));
134
+ }
135
+ else {
136
+ // relative path from templates dir
137
+ results.push(path.relative(baseDir, filePath).replace(/\\/g, '/'));
138
+ }
139
+ }
140
+ return results;
141
+ }
142
+ }
143
+ exports.TemplatesCommand = TemplatesCommand;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ConfigService = void 0;
37
+ const path = __importStar(require("path"));
38
+ class ConfigService {
39
+ fileSystem;
40
+ logger;
41
+ configPath = '.agent/antigravity.json';
42
+ constructor(fileSystem, logger) {
43
+ this.fileSystem = fileSystem;
44
+ this.logger = logger;
45
+ }
46
+ async saveConfig(projectDetails) {
47
+ try {
48
+ const fullPath = path.join(projectDetails.rootPath, this.configPath);
49
+ // Ensure directory exists
50
+ const dir = path.dirname(fullPath);
51
+ await this.fileSystem.createDirectory(dir);
52
+ const content = JSON.stringify(projectDetails, null, 2);
53
+ await this.fileSystem.writeFile(fullPath, content);
54
+ this.logger.success(`Configuration saved to ${this.configPath}`);
55
+ }
56
+ catch (error) {
57
+ this.logger.error(`Failed to save configuration: ${error.message}`);
58
+ }
59
+ }
60
+ async loadConfig(rootPath) {
61
+ try {
62
+ const fullPath = path.join(rootPath, this.configPath);
63
+ if (await this.fileSystem.exists(fullPath)) {
64
+ const content = await this.fileSystem.readFile(fullPath);
65
+ return JSON.parse(content);
66
+ }
67
+ return null;
68
+ }
69
+ catch (error) {
70
+ this.logger.warn(`Could not load configuration from ${this.configPath}`);
71
+ return null;
72
+ }
73
+ }
74
+ }
75
+ exports.ConfigService = ConfigService;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextGenerator = void 0;
4
+ class ContextGenerator {
5
+ templateProvider;
6
+ localizationService;
7
+ constructor(templateProvider, localizationService) {
8
+ this.templateProvider = templateProvider;
9
+ this.localizationService = localizationService;
10
+ }
11
+ async generateContext(project) {
12
+ const lang = this.localizationService.getLanguage();
13
+ const templatePath = `${lang}/project-context.md.ejs`;
14
+ const formattedStack = `Frontend: ${project.techStack.frontend}, Backend: ${project.techStack.backend}`;
15
+ const templateContent = await this.templateProvider.getTemplate(templatePath);
16
+ return this.templateProvider.render(templateContent, {
17
+ projectDescription: project.projectDescription || 'N/A',
18
+ techStack: formattedStack,
19
+ architecture: project.architecture,
20
+ buildCommand: project.buildCommand,
21
+ testCommand: project.testCommand,
22
+ isMonorepo: project.isMonorepo || false,
23
+ apps: project.apps || [],
24
+ });
25
+ }
26
+ }
27
+ exports.ContextGenerator = ContextGenerator;
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DockerfileGenerator = void 0;
37
+ const path = __importStar(require("path"));
38
+ const types_1 = require("./types");
39
+ class DockerfileGenerator {
40
+ fileSystem;
41
+ templateProvider;
42
+ logger;
43
+ constructor(fileSystem, templateProvider, logger) {
44
+ this.fileSystem = fileSystem;
45
+ this.templateProvider = templateProvider;
46
+ this.logger = logger;
47
+ }
48
+ async generate(projectRoot, techStack) {
49
+ this.logger.info('Generating Dockerfile...');
50
+ let templateName = '';
51
+ const data = {
52
+ port: 3000,
53
+ packageManager: 'npm',
54
+ installCommand: 'npm install',
55
+ buildCommand: 'npm run build',
56
+ startCommand: 'npm run start:prod',
57
+ };
58
+ switch (techStack.packageManager) {
59
+ case types_1.PackageManager.YARN:
60
+ data.packageManager = 'yarn';
61
+ data.installCommand = 'yarn install --frozen-lockfile';
62
+ data.buildCommand = 'yarn build';
63
+ data.startCommand = 'yarn start:prod';
64
+ break;
65
+ case types_1.PackageManager.PNPM:
66
+ data.packageManager = 'pnpm';
67
+ data.installCommand = 'pnpm install --frozen-lockfile';
68
+ data.buildCommand = 'pnpm build';
69
+ data.startCommand = 'pnpm start:prod';
70
+ break;
71
+ case types_1.PackageManager.BUN:
72
+ data.packageManager = 'bun';
73
+ data.installCommand = 'bun install --frozen-lockfile';
74
+ data.buildCommand = 'bun run build';
75
+ data.startCommand = 'bun run start:prod';
76
+ break;
77
+ }
78
+ switch (techStack.backend) {
79
+ case types_1.BackendFramework.NESTJS:
80
+ templateName = 'docker/nestjs.Dockerfile.ejs';
81
+ break;
82
+ case types_1.BackendFramework.EXPRESS:
83
+ templateName = 'docker/node.Dockerfile.ejs';
84
+ break;
85
+ case types_1.BackendFramework.FASTAPI:
86
+ templateName = 'docker/python.Dockerfile.ejs';
87
+ data.port = 8000;
88
+ data.installCommand = 'pip install -r requirements.txt';
89
+ data.startCommand = 'uvicorn main:app --host 0.0.0.0 --port 8000';
90
+ if (techStack.packageManager === types_1.PackageManager.POETRY) {
91
+ data.installCommand = 'poetry install --no-dev';
92
+ data.startCommand = 'poetry run uvicorn main:app --host 0.0.0.0 --port 8000';
93
+ }
94
+ break;
95
+ case types_1.BackendFramework.DJANGO:
96
+ templateName = 'docker/django.Dockerfile.ejs';
97
+ data.port = 8000;
98
+ data.startCommand = 'python manage.py runserver 0.0.0.0:8000'; // Or gunicorn
99
+ break;
100
+ case types_1.BackendFramework.SPRING_BOOT:
101
+ templateName = 'docker/springboot.Dockerfile.ejs';
102
+ data.port = 8080;
103
+ break;
104
+ case types_1.BackendFramework.GO:
105
+ case types_1.BackendFramework.GIN:
106
+ case types_1.BackendFramework.RUST: // Using Go template for Rust??? No, stick to Go. Wait, RUST has no dockerfile?
107
+ // Ah, Rust was not in original switch. Let's add Go first.
108
+ if (techStack.backend === types_1.BackendFramework.RUST) {
109
+ // TODO: Rust Dockerfile template
110
+ this.logger.warn('Rust Dockerfile template not yet implemented.');
111
+ return;
112
+ }
113
+ templateName = 'docker/go.Dockerfile.ejs';
114
+ data.port = 8080;
115
+ break;
116
+ default:
117
+ this.logger.warn(`No Dockerfile template found for backend: ${techStack.backend}`);
118
+ return;
119
+ }
120
+ try {
121
+ const templateContent = await this.templateProvider.getTemplate(templateName);
122
+ const dockerfileContent = this.templateProvider.render(templateContent, data);
123
+ const outputPath = path.join(projectRoot, 'Dockerfile');
124
+ if (await this.fileSystem.exists(outputPath)) {
125
+ this.logger.warn('Dockerfile already exists. Skipping generation.');
126
+ }
127
+ else {
128
+ await this.fileSystem.writeFile(outputPath, dockerfileContent);
129
+ this.logger.success('Dockerfile generated successfully.');
130
+ // Also generate .dockerignore
131
+ const dockerignorePath = path.join(projectRoot, '.dockerignore');
132
+ if (!await this.fileSystem.exists(dockerignorePath)) {
133
+ try {
134
+ const ignoreTemplate = await this.templateProvider.getTemplate('docker/dockerignore.ejs');
135
+ // No data needed for now, but good to have
136
+ const ignoreContent = this.templateProvider.render(ignoreTemplate, {});
137
+ await this.fileSystem.writeFile(dockerignorePath, ignoreContent);
138
+ this.logger.success('.dockerignore generated successfully.');
139
+ }
140
+ catch (e) {
141
+ this.logger.warn('Failed to generate .dockerignore from template.');
142
+ }
143
+ }
144
+ }
145
+ }
146
+ catch (error) {
147
+ this.logger.error('Failed to generate Dockerfile.');
148
+ }
149
+ }
150
+ }
151
+ exports.DockerfileGenerator = DockerfileGenerator;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.GitignoreGenerator = void 0;
37
+ const path = __importStar(require("path"));
38
+ const types_1 = require("./types");
39
+ class GitignoreGenerator {
40
+ fileSystem;
41
+ logger;
42
+ constructor(fileSystem, logger) {
43
+ this.fileSystem = fileSystem;
44
+ this.logger = logger;
45
+ }
46
+ async generate(projectRoot, techStack) {
47
+ this.logger.info('Generating .gitignore...');
48
+ const fragments = new Set();
49
+ // OS & Editors (Always include)
50
+ fragments.add('macos');
51
+ fragments.add('windows');
52
+ fragments.add('linux');
53
+ fragments.add('vscode');
54
+ fragments.add('jetbrains');
55
+ // Frontend
56
+ if (techStack.frontend !== types_1.FrontendFramework.NONE) {
57
+ fragments.add('node');
58
+ }
59
+ // Backend
60
+ switch (techStack.backend) {
61
+ case types_1.BackendFramework.NESTJS:
62
+ case types_1.BackendFramework.EXPRESS:
63
+ fragments.add('node');
64
+ break;
65
+ case types_1.BackendFramework.FASTAPI:
66
+ case types_1.BackendFramework.DJANGO:
67
+ case types_1.BackendFramework.FLASK:
68
+ fragments.add('python');
69
+ break;
70
+ case types_1.BackendFramework.SPRING_BOOT:
71
+ fragments.add('java');
72
+ fragments.add('maven'); // Assuming Maven for now, possibly Gradle
73
+ break;
74
+ case types_1.BackendFramework.ASPNET_CORE:
75
+ fragments.add('dotnet');
76
+ break;
77
+ case types_1.BackendFramework.RUST:
78
+ fragments.add('rust');
79
+ break;
80
+ case types_1.BackendFramework.GO:
81
+ case types_1.BackendFramework.GIN:
82
+ fragments.add('go');
83
+ break;
84
+ }
85
+ if (techStack.smartContract === 'solidity' || techStack.smartContract === 'scrypto') {
86
+ // Scrypto has no specific gitignore template yet? Rust one covers it mostly.
87
+ if (techStack.smartContract === 'solidity') {
88
+ fragments.add('solidity');
89
+ }
90
+ // If scrypto, maybe just rust is enough
91
+ }
92
+ // Database (if local files)
93
+ // Most DBs don't commit data types, but sqlite does have .db files
94
+ const content = await this.composeContent(Array.from(fragments));
95
+ const outputPath = path.join(projectRoot, '.gitignore');
96
+ if (await this.fileSystem.exists(outputPath)) {
97
+ this.logger.warn('.gitignore already exists. Appending specific rules if missing.');
98
+ const existing = await this.fileSystem.readFile(outputPath);
99
+ // Simple append for now
100
+ await this.fileSystem.writeFile(outputPath, existing + '\n\n' + content);
101
+ }
102
+ else {
103
+ await this.fileSystem.writeFile(outputPath, content);
104
+ }
105
+ this.logger.success('.gitignore generated successfully.');
106
+ }
107
+ async composeContent(fragments) {
108
+ let finalContent = '# Generated by Antigravity Flow\n';
109
+ const templatesDir = path.join(__dirname, '../templates/gitignore');
110
+ for (const fragment of fragments) {
111
+ const fragmentPath = path.join(templatesDir, `${fragment}.txt`);
112
+ try {
113
+ if (await this.fileSystem.exists(fragmentPath)) {
114
+ const content = await this.fileSystem.readFile(fragmentPath);
115
+ finalContent += `\n### ${fragment.toUpperCase()} ###\n${content}\n`;
116
+ }
117
+ else {
118
+ // Silently fail or warn? specific fragments might not exist yet
119
+ // this.logger.warn(`Gitignore fragment not found: ${fragment}`);
120
+ }
121
+ }
122
+ catch (error) {
123
+ this.logger.warn(`Failed to load gitignore fragment: ${fragment}`);
124
+ }
125
+ }
126
+ return finalContent;
127
+ }
128
+ }
129
+ exports.GitignoreGenerator = GitignoreGenerator;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PipelineGenerator = void 0;
37
+ const path = __importStar(require("path"));
38
+ const PipelineStrategy_1 = require("./pipelines/PipelineStrategy");
39
+ class PipelineGenerator {
40
+ fileSystem;
41
+ templateProvider;
42
+ logger;
43
+ strategyFactory = new PipelineStrategy_1.PipelineStrategyFactory();
44
+ constructor(fileSystem, templateProvider, logger) {
45
+ this.fileSystem = fileSystem;
46
+ this.templateProvider = templateProvider;
47
+ this.logger = logger;
48
+ }
49
+ async generatePipeline(projectDetails) {
50
+ const strategy = this.strategyFactory.getStrategy(projectDetails);
51
+ const templateName = strategy.getTemplateName();
52
+ const templatePath = `en/pipelines/${templateName}`; // Hardcoded to EN for config files? Or use local? Config files usually don't need translation but let's stick to structure.
53
+ try {
54
+ const templateContent = await this.templateProvider.getTemplate(templatePath);
55
+ const rendered = this.templateProvider.render(templateContent, {
56
+ project: projectDetails
57
+ });
58
+ await this.fileSystem.createDirectory(projectDetails.workflowDirectory);
59
+ const outputPath = path.join(projectDetails.workflowDirectory, 'ci.yml');
60
+ await this.fileSystem.writeFile(outputPath, rendered);
61
+ this.logger.success(`CI/CD Pipeline generated: ${projectDetails.workflowDirectory}/ci.yml`);
62
+ }
63
+ catch (error) {
64
+ this.logger.error(`Failed to generate pipeline: ${error.message}`);
65
+ }
66
+ }
67
+ }
68
+ exports.PipelineGenerator = PipelineGenerator;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RulesComposer = void 0;
4
+ class RulesComposer {
5
+ templateProvider;
6
+ localizationService;
7
+ constructor(templateProvider, localizationService) {
8
+ this.templateProvider = templateProvider;
9
+ this.localizationService = localizationService;
10
+ }
11
+ async composeRules(stack, rigor) {
12
+ const lang = this.localizationService.getLanguage();
13
+ const fragments = [];
14
+ // Base Rules
15
+ const baseTemplatePath = `${lang}/fragments/base-rules.md.ejs`;
16
+ fragments.push(await this.templateProvider.getTemplate(baseTemplatePath));
17
+ // Rigor Mode Rules
18
+ const rigorTemplatePath = `${lang}/fragments/rigor/${rigor}.md.ejs`;
19
+ try {
20
+ fragments.push(await this.templateProvider.getTemplate(rigorTemplatePath));
21
+ }
22
+ catch (e) {
23
+ console.warn(`Missing rigor fragment: ${rigorTemplatePath}`);
24
+ }
25
+ // Frontend Rules
26
+ if (stack.frontend && stack.frontend !== 'none') {
27
+ const feTemplatePath = `${lang}/fragments/${stack.frontend}.md.ejs`;
28
+ try {
29
+ fragments.push(await this.templateProvider.getTemplate(feTemplatePath));
30
+ }
31
+ catch (e) {
32
+ // Ignore missing fragments for now or log warning
33
+ console.warn(`Missing rule fragment: ${feTemplatePath}`);
34
+ }
35
+ }
36
+ // Backend Rules
37
+ if (stack.backend && stack.backend !== 'none') {
38
+ const beTemplatePath = `${lang}/fragments/${stack.backend}.md.ejs`;
39
+ try {
40
+ fragments.push(await this.templateProvider.getTemplate(beTemplatePath));
41
+ }
42
+ catch (e) {
43
+ console.warn(`Missing rule fragment: ${beTemplatePath}`);
44
+ }
45
+ }
46
+ // Smart Contract Rules
47
+ if (stack.smartContract && stack.smartContract !== 'none') {
48
+ const scTemplatePath = `${lang}/fragments/${stack.smartContract}.md.ejs`;
49
+ try {
50
+ fragments.push(await this.templateProvider.getTemplate(scTemplatePath));
51
+ }
52
+ catch (e) {
53
+ console.warn(`Missing rule fragment: ${scTemplatePath}`);
54
+ }
55
+ }
56
+ // Render all fragments
57
+ // Note: We might want to pass data to fragments if needed
58
+ const renderedFragments = fragments.map(f => this.templateProvider.render(f, {}));
59
+ return renderedFragments.join('\n\n');
60
+ }
61
+ }
62
+ exports.RulesComposer = RulesComposer;