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,19 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./init"), exports);
18
+ __exportStar(require("./guide"), exports);
19
+ __exportStar(require("./templates"), exports);
@@ -0,0 +1,581 @@
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.InitCommand = void 0;
40
+ const inquirer_1 = __importDefault(require("inquirer"));
41
+ const path = __importStar(require("path"));
42
+ const types_1 = require("../core/types");
43
+ class InitCommand {
44
+ workflowGenerator;
45
+ logger;
46
+ localizationService;
47
+ pipelineGenerator;
48
+ configService;
49
+ stackDetector;
50
+ gitignoreGenerator;
51
+ dockerfileGenerator;
52
+ fileSystem;
53
+ constructor(workflowGenerator, logger, localizationService, pipelineGenerator, configService, stackDetector, gitignoreGenerator, dockerfileGenerator, fileSystem) {
54
+ this.workflowGenerator = workflowGenerator;
55
+ this.logger = logger;
56
+ this.localizationService = localizationService;
57
+ this.pipelineGenerator = pipelineGenerator;
58
+ this.configService = configService;
59
+ this.stackDetector = stackDetector;
60
+ this.gitignoreGenerator = gitignoreGenerator;
61
+ this.dockerfileGenerator = dockerfileGenerator;
62
+ this.fileSystem = fileSystem;
63
+ }
64
+ async execute(options = {}) {
65
+ try {
66
+ if (options.config) {
67
+ await this.executeWithConfig(options.config);
68
+ return;
69
+ }
70
+ const language = await this.promptLanguage();
71
+ this.localizationService.setLanguage(language);
72
+ this.showWelcome();
73
+ const projectRoot = process.cwd();
74
+ const detectedStack = await this.detectStack(projectRoot);
75
+ const coreAnswers = await this.promptCoreQuestions(detectedStack);
76
+ const vcsAnswers = await this.promptVersionControlQuestions();
77
+ const toolingAnswers = await this.promptToolingQuestions(coreAnswers.rigor);
78
+ const monorerepoAnswers = await this.promptMonorepoQuestions();
79
+ const deploymentAnswers = await this.promptDeploymentQuestions();
80
+ const commandAnswers = await this.promptCommandQuestions(toolingAnswers.packageManager);
81
+ const strictModeAnswers = await this.promptStrictModeQuestions(coreAnswers.rigor);
82
+ const hexagonalAnswers = await this.promptHexagonalQuestions(coreAnswers.architecture);
83
+ const finalAnswers = await this.promptFinalQuestions();
84
+ if (!finalAnswers.confirm) {
85
+ this.logger.warn(this.localizationService.translate('prompts.cancelled'));
86
+ return;
87
+ }
88
+ const projectDetails = this.buildProjectDetails(projectRoot, language, detectedStack, coreAnswers, vcsAnswers, toolingAnswers, monorerepoAnswers, deploymentAnswers, commandAnswers, strictModeAnswers, hexagonalAnswers, finalAnswers.ideIntegration, finalAnswers.roles);
89
+ await this.generateFiles(projectDetails, finalAnswers.roles);
90
+ await this.integrateWithIde(projectDetails, finalAnswers.ideIntegration, finalAnswers.roles);
91
+ this.logger.success(this.localizationService.translate('prompts.success'));
92
+ }
93
+ catch (error) {
94
+ this.logger.error(this.localizationService.translate('prompts.failed'));
95
+ }
96
+ }
97
+ async promptLanguage() {
98
+ const answer = await inquirer_1.default.prompt([
99
+ {
100
+ type: 'list',
101
+ name: 'language',
102
+ message: 'Select language / Choisissez votre langue',
103
+ choices: ['en', 'fr'],
104
+ default: 'en',
105
+ },
106
+ ]);
107
+ return answer.language;
108
+ }
109
+ showWelcome() {
110
+ this.logger.info(this.localizationService.translate('prompts.welcome'));
111
+ this.logger.info(this.localizationService.translate('prompts.intro'));
112
+ }
113
+ async detectStack(projectRoot) {
114
+ this.logger.info('Auto-detecting project stack...');
115
+ const detectedStack = await this.stackDetector.detectStack(projectRoot);
116
+ if (Object.keys(detectedStack).length > 0) {
117
+ this.logger.success(`Detected: ${JSON.stringify(detectedStack)}`);
118
+ }
119
+ else {
120
+ this.logger.info('No specific stack detected. Falling back to defaults.');
121
+ }
122
+ return detectedStack;
123
+ }
124
+ async promptCoreQuestions(detectedStack) {
125
+ return inquirer_1.default.prompt([
126
+ {
127
+ type: 'input',
128
+ name: 'projectDescription',
129
+ message: this.localizationService.translate('prompts.project_description'),
130
+ default: 'My awesome project',
131
+ },
132
+ {
133
+ type: 'list',
134
+ name: 'frontend',
135
+ message: this.localizationService.translate('prompts.frontend'),
136
+ choices: Object.values(types_1.FrontendFramework),
137
+ default: detectedStack.frontend || types_1.FrontendFramework.NONE,
138
+ },
139
+ {
140
+ type: 'list',
141
+ name: 'backend',
142
+ message: this.localizationService.translate('prompts.backend'),
143
+ choices: Object.values(types_1.BackendFramework),
144
+ default: detectedStack.backend || types_1.BackendFramework.NONE,
145
+ },
146
+ {
147
+ type: 'list',
148
+ name: 'smartContract',
149
+ message: this.localizationService.translate('prompts.smart_contract'),
150
+ choices: Object.values(types_1.SmartContractFramework),
151
+ default: detectedStack.smartContract || types_1.SmartContractFramework.NONE,
152
+ },
153
+ {
154
+ type: 'list',
155
+ name: 'database',
156
+ message: this.localizationService.translate('prompts.database'),
157
+ choices: Object.values(types_1.DatabaseType),
158
+ default: types_1.DatabaseType.NONE,
159
+ },
160
+ {
161
+ type: 'list',
162
+ name: 'orm',
163
+ message: this.localizationService.translate('prompts.orm'),
164
+ choices: Object.values(types_1.OrmType),
165
+ default: types_1.OrmType.NONE,
166
+ when: (answers) => answers.database !== types_1.DatabaseType.NONE,
167
+ },
168
+ {
169
+ type: 'list',
170
+ name: 'architecture',
171
+ message: this.localizationService.translate('prompts.architecture'),
172
+ choices: Object.values(types_1.ArchitectureType),
173
+ default: types_1.ArchitectureType.HEXAGONAL,
174
+ },
175
+ {
176
+ type: 'list',
177
+ name: 'rigor',
178
+ message: this.localizationService.translate('prompts.rigor'),
179
+ choices: Object.values(types_1.RigorMode),
180
+ default: types_1.RigorMode.STRICT,
181
+ },
182
+ ]);
183
+ }
184
+ async promptVersionControlQuestions() {
185
+ return inquirer_1.default.prompt([
186
+ {
187
+ type: 'list',
188
+ name: 'versionControl',
189
+ message: this.localizationService.translate('prompts.version_control'),
190
+ choices: Object.values(types_1.VersionControlPlatform),
191
+ default: types_1.VersionControlPlatform.GITHUB,
192
+ },
193
+ {
194
+ type: 'list',
195
+ name: 'branchingStrategy',
196
+ message: this.localizationService.translate('prompts.branching_strategy'),
197
+ choices: Object.values(types_1.BranchingStrategy),
198
+ default: types_1.BranchingStrategy.GITHUB_FLOW,
199
+ when: (answers) => answers.versionControl !== types_1.VersionControlPlatform.NONE,
200
+ },
201
+ {
202
+ type: 'list',
203
+ name: 'commitConvention',
204
+ message: this.localizationService.translate('prompts.commit_convention'),
205
+ choices: Object.values(types_1.CommitConvention),
206
+ default: types_1.CommitConvention.CONVENTIONAL,
207
+ when: (answers) => answers.versionControl !== types_1.VersionControlPlatform.NONE,
208
+ },
209
+ ]);
210
+ }
211
+ async promptToolingQuestions(rigor) {
212
+ return inquirer_1.default.prompt([
213
+ {
214
+ type: 'list',
215
+ name: 'packageManager',
216
+ message: this.localizationService.translate('prompts.package_manager'),
217
+ choices: Object.values(types_1.PackageManager),
218
+ default: types_1.PackageManager.NPM,
219
+ },
220
+ {
221
+ type: 'list',
222
+ name: 'testingFramework',
223
+ message: this.localizationService.translate('prompts.testing_framework'),
224
+ choices: Object.values(types_1.TestingFramework),
225
+ default: types_1.TestingFramework.JEST,
226
+ },
227
+ {
228
+ type: 'list',
229
+ name: 'coverageTarget',
230
+ message: this.localizationService.translate('prompts.coverage_target'),
231
+ choices: Object.values(types_1.CoverageTarget),
232
+ default: rigor === types_1.RigorMode.STRICT ? types_1.CoverageTarget.FULL : types_1.CoverageTarget.HIGH,
233
+ },
234
+ ]);
235
+ }
236
+ async promptMonorepoQuestions() {
237
+ return inquirer_1.default.prompt([
238
+ {
239
+ type: 'confirm',
240
+ name: 'isMonorepo',
241
+ message: this.localizationService.translate('prompts.is_monorepo'),
242
+ default: false,
243
+ },
244
+ {
245
+ type: 'list',
246
+ name: 'monorepoTool',
247
+ message: this.localizationService.translate('prompts.monorepo_tool'),
248
+ choices: Object.values(types_1.MonorepoTool),
249
+ default: types_1.MonorepoTool.TURBOREPO,
250
+ when: (answers) => answers.isMonorepo,
251
+ },
252
+ {
253
+ type: 'input',
254
+ name: 'apps',
255
+ message: this.localizationService.translate('prompts.monorepo_apps'),
256
+ when: (answers) => answers.isMonorepo,
257
+ filter: (input) => input
258
+ .split(',')
259
+ .map((s) => s.trim())
260
+ .filter((s) => s.length > 0),
261
+ },
262
+ ]);
263
+ }
264
+ async promptDeploymentQuestions() {
265
+ return inquirer_1.default.prompt([
266
+ {
267
+ type: 'list',
268
+ name: 'deploymentPlatform',
269
+ message: this.localizationService.translate('prompts.deployment_platform'),
270
+ choices: Object.values(types_1.DeploymentPlatform),
271
+ default: types_1.DeploymentPlatform.NONE,
272
+ },
273
+ {
274
+ type: 'list',
275
+ name: 'containerization',
276
+ message: this.localizationService.translate('prompts.containerization'),
277
+ choices: Object.values(types_1.Containerization),
278
+ default: types_1.Containerization.DOCKER,
279
+ when: (answers) => answers.deploymentPlatform !== types_1.DeploymentPlatform.VERCEL &&
280
+ answers.deploymentPlatform !== types_1.DeploymentPlatform.NETLIFY &&
281
+ answers.deploymentPlatform !== types_1.DeploymentPlatform.NONE,
282
+ },
283
+ {
284
+ type: 'checkbox',
285
+ name: 'securityScanning',
286
+ message: this.localizationService.translate('prompts.security_scanning'),
287
+ choices: Object.values(types_1.SecurityScanningTool).filter((s) => s !== types_1.SecurityScanningTool.NONE),
288
+ default: [types_1.SecurityScanningTool.DEPENDABOT],
289
+ },
290
+ ]);
291
+ }
292
+ async promptCommandQuestions(packageManager) {
293
+ return inquirer_1.default.prompt([
294
+ {
295
+ type: 'input',
296
+ name: 'buildCommand',
297
+ message: this.localizationService.translate('prompts.build_command'),
298
+ default: this.getDefaultBuildCommand(packageManager),
299
+ },
300
+ {
301
+ type: 'input',
302
+ name: 'testCommand',
303
+ message: this.localizationService.translate('prompts.test_command'),
304
+ default: this.getDefaultTestCommand(packageManager),
305
+ },
306
+ ]);
307
+ }
308
+ async promptStrictModeQuestions(rigor) {
309
+ if (rigor !== types_1.RigorMode.STRICT)
310
+ return {};
311
+ return inquirer_1.default.prompt([
312
+ {
313
+ type: 'number',
314
+ name: 'prApprovalsRequired',
315
+ message: this.localizationService.translate('prompts.pr_approvals'),
316
+ default: 2,
317
+ },
318
+ {
319
+ type: 'confirm',
320
+ name: 'preCommitHooks',
321
+ message: this.localizationService.translate('prompts.pre_commit_hooks'),
322
+ default: true,
323
+ },
324
+ {
325
+ type: 'confirm',
326
+ name: 'blockMergeOnFailingChecks',
327
+ message: this.localizationService.translate('prompts.block_merge_failing'),
328
+ default: true,
329
+ },
330
+ ]);
331
+ }
332
+ async promptHexagonalQuestions(architecture) {
333
+ if (architecture !== types_1.ArchitectureType.HEXAGONAL && architecture !== types_1.ArchitectureType.CLEAN)
334
+ return {};
335
+ return inquirer_1.default.prompt([
336
+ {
337
+ type: 'input',
338
+ name: 'interfacePrefix',
339
+ message: this.localizationService.translate('prompts.interface_prefix'),
340
+ default: 'I',
341
+ },
342
+ {
343
+ type: 'list',
344
+ name: 'repositoryPattern',
345
+ message: this.localizationService.translate('prompts.repository_pattern'),
346
+ choices: ['repository', 'dao', 'active-record'],
347
+ default: 'repository',
348
+ },
349
+ ]);
350
+ }
351
+ async promptFinalQuestions() {
352
+ return inquirer_1.default.prompt([
353
+ {
354
+ type: 'checkbox',
355
+ name: 'roles',
356
+ message: this.localizationService.translate('prompts.workflows_selection'),
357
+ choices: Object.values(types_1.WorkflowRole).map((role) => ({
358
+ name: this.localizationService.translate(`roles.${role}`),
359
+ value: role,
360
+ })),
361
+ default: [types_1.WorkflowRole.DEVELOPER, types_1.WorkflowRole.QA, types_1.WorkflowRole.LEAD_DEV],
362
+ },
363
+ {
364
+ type: 'checkbox',
365
+ name: 'ideIntegration',
366
+ message: this.localizationService.translate('prompts.ide_integration'),
367
+ choices: [
368
+ { name: 'Cursor (.cursor/rules)', value: types_1.IdeIntegration.CURSOR },
369
+ { name: 'Windsurf (.windsurfrules)', value: types_1.IdeIntegration.WINDSURF },
370
+ { name: 'Gemini Code Assist (.gemini)', value: types_1.IdeIntegration.GEMINI },
371
+ { name: 'GitHub Copilot', value: types_1.IdeIntegration.COPILOT },
372
+ ],
373
+ default: [],
374
+ },
375
+ {
376
+ type: 'confirm',
377
+ name: 'confirm',
378
+ message: this.localizationService.translate('prompts.confirm'),
379
+ default: true,
380
+ },
381
+ ]);
382
+ }
383
+ buildProjectDetails(projectRoot, language, detectedStack, coreAnswers, vcsAnswers, toolingAnswers, monorepoAnswers, deploymentAnswers, commandAnswers, strictModeAnswers, hexagonalAnswers, ideIntegrations, roles) {
384
+ return {
385
+ rootPath: projectRoot,
386
+ workflowDirectory: '.agent/workflows',
387
+ rulesDirectory: '.agent/rules',
388
+ buildCommand: commandAnswers.buildCommand,
389
+ testCommand: commandAnswers.testCommand,
390
+ techStack: {
391
+ frontend: coreAnswers.frontend,
392
+ backend: coreAnswers.backend,
393
+ smartContract: coreAnswers.smartContract,
394
+ database: coreAnswers.database,
395
+ orm: coreAnswers.orm,
396
+ testingFramework: toolingAnswers.testingFramework,
397
+ packageManager: toolingAnswers.packageManager,
398
+ },
399
+ architecture: coreAnswers.architecture,
400
+ rigor: coreAnswers.rigor,
401
+ projectDescription: coreAnswers.projectDescription,
402
+ isMonorepo: monorepoAnswers.isMonorepo,
403
+ apps: monorepoAnswers.apps,
404
+ monorepoTool: monorepoAnswers.monorepoTool,
405
+ language: language,
406
+ versionControl: vcsAnswers.versionControl,
407
+ branchingStrategy: vcsAnswers.branchingStrategy,
408
+ commitConvention: vcsAnswers.commitConvention,
409
+ packageManager: toolingAnswers.packageManager,
410
+ coverageTarget: toolingAnswers.coverageTarget,
411
+ deploymentPlatform: deploymentAnswers.deploymentPlatform,
412
+ containerization: deploymentAnswers.containerization,
413
+ securityScanning: deploymentAnswers.securityScanning,
414
+ ideIntegrations: ideIntegrations,
415
+ roles: roles,
416
+ ...strictModeAnswers,
417
+ ...hexagonalAnswers,
418
+ };
419
+ }
420
+ async generateFiles(projectDetails, roles) {
421
+ await this.workflowGenerator.generateWorkflows(projectDetails, roles);
422
+ await this.workflowGenerator.generateProjectContext(projectDetails);
423
+ await this.pipelineGenerator.generatePipeline(projectDetails);
424
+ await this.gitignoreGenerator.generate(projectDetails.rootPath, projectDetails.techStack);
425
+ await this.dockerfileGenerator.generate(projectDetails.rootPath, projectDetails.techStack);
426
+ await this.configService.saveConfig(projectDetails);
427
+ }
428
+ async integrateWithIde(projectDetails, ideIntegrations, roles) {
429
+ const rulesPath = path.join(projectDetails.rootPath, '.agent/rules/coding-standards.md');
430
+ const rulesContent = await this.fileSystem.readFile(rulesPath);
431
+ if (ideIntegrations.includes(types_1.IdeIntegration.CURSOR)) {
432
+ await this.integrateCursor(projectDetails, rulesContent, roles);
433
+ }
434
+ if (ideIntegrations.includes(types_1.IdeIntegration.WINDSURF)) {
435
+ await this.integrateWindsurf(projectDetails, rulesContent, roles);
436
+ }
437
+ if (ideIntegrations.includes(types_1.IdeIntegration.GEMINI)) {
438
+ await this.integrateGemini(projectDetails, rulesContent);
439
+ }
440
+ // Future: Copilot, Cody integrations
441
+ }
442
+ async integrateCursor(projectDetails, rulesContent, roles) {
443
+ // 1. Base Rules
444
+ const cursorPath = path.join(projectDetails.rootPath, '.cursor/rules/antigravity.mdc');
445
+ await this.fileSystem.createDirectory(path.dirname(cursorPath));
446
+ await this.fileSystem.writeFile(cursorPath, rulesContent);
447
+ this.logger.success('Integrated with Cursor (.cursor/rules/antigravity.mdc)');
448
+ // 2. Roles
449
+ for (const role of roles) {
450
+ const roleFileName = `${role.toLowerCase()}.md`;
451
+ const sourcePath = path.join(projectDetails.rootPath, projectDetails.workflowDirectory, roleFileName);
452
+ if (await this.fileSystem.exists(sourcePath)) {
453
+ const ruleContent = await this.fileSystem.readFile(sourcePath);
454
+ const mdcContent = `---
455
+ description: Act as a ${role}
456
+ globs: **/*
457
+ ---
458
+ ${ruleContent}`;
459
+ const rolePath = path.join(projectDetails.rootPath, '.cursor/rules', `${role.toLowerCase()}.mdc`);
460
+ await this.fileSystem.writeFile(rolePath, mdcContent);
461
+ }
462
+ }
463
+ this.logger.success('Integrated Roles with Cursor (.cursor/rules/*.mdc)');
464
+ }
465
+ async integrateWindsurf(projectDetails, rulesContent, roles) {
466
+ // 1. Base Rules (.windsurfrules)
467
+ const windsurfPath = path.join(projectDetails.rootPath, '.windsurfrules');
468
+ let currentContent = '';
469
+ if (await this.fileSystem.exists(windsurfPath)) {
470
+ currentContent = await this.fileSystem.readFile(windsurfPath);
471
+ }
472
+ const separator = '\n\n# Antigravity Rules\n\n';
473
+ if (!currentContent.includes('# Antigravity Rules')) {
474
+ await this.fileSystem.writeFile(windsurfPath, currentContent + separator + rulesContent);
475
+ this.logger.success('Integrated with Windsurf (.windsurfrules)');
476
+ }
477
+ else {
478
+ this.logger.info('Windsurf already configured, skipping append.');
479
+ }
480
+ // 2. Roles (.windsurf/rules/)
481
+ for (const role of roles) {
482
+ const roleFileName = `${role.toLowerCase()}.md`;
483
+ const sourcePath = path.join(projectDetails.rootPath, projectDetails.workflowDirectory, roleFileName);
484
+ if (await this.fileSystem.exists(sourcePath)) {
485
+ const ruleContent = await this.fileSystem.readFile(sourcePath);
486
+ const rolePath = path.join(projectDetails.rootPath, '.windsurf/rules', roleFileName);
487
+ await this.fileSystem.createDirectory(path.dirname(rolePath));
488
+ await this.fileSystem.writeFile(rolePath, ruleContent);
489
+ }
490
+ }
491
+ this.logger.success('Integrated Roles with Windsurf (.windsurf/rules/*.md)');
492
+ }
493
+ async integrateGemini(projectDetails, rulesContent) {
494
+ const geminiPath = path.join(projectDetails.rootPath, '.gemini/settings.json');
495
+ await this.fileSystem.createDirectory(path.dirname(geminiPath));
496
+ const geminiConfig = {
497
+ codeAssist: {
498
+ customInstructions: rulesContent.substring(0, 2000),
499
+ },
500
+ };
501
+ await this.fileSystem.writeFile(geminiPath, JSON.stringify(geminiConfig, null, 2));
502
+ this.logger.success('Integrated with Gemini Code Assist (.gemini/settings.json)');
503
+ }
504
+ getDefaultBuildCommand(packageManager) {
505
+ switch (packageManager) {
506
+ case types_1.PackageManager.YARN:
507
+ return 'yarn build';
508
+ case types_1.PackageManager.PNPM:
509
+ return 'pnpm build';
510
+ case types_1.PackageManager.BUN:
511
+ return 'bun run build';
512
+ case types_1.PackageManager.CARGO:
513
+ return 'cargo build';
514
+ case types_1.PackageManager.POETRY:
515
+ return 'poetry build';
516
+ case types_1.PackageManager.GO_MODULES:
517
+ return 'go build';
518
+ case types_1.PackageManager.MAVEN:
519
+ return 'mvn package';
520
+ case types_1.PackageManager.GRADLE:
521
+ return 'gradle build';
522
+ case types_1.PackageManager.NUGET:
523
+ return 'dotnet build';
524
+ default:
525
+ return 'npm run build';
526
+ }
527
+ }
528
+ getDefaultTestCommand(packageManager) {
529
+ switch (packageManager) {
530
+ case types_1.PackageManager.YARN:
531
+ return 'yarn test';
532
+ case types_1.PackageManager.PNPM:
533
+ return 'pnpm test';
534
+ case types_1.PackageManager.BUN:
535
+ return 'bun test';
536
+ case types_1.PackageManager.CARGO:
537
+ return 'cargo test';
538
+ case types_1.PackageManager.POETRY:
539
+ return 'poetry run pytest';
540
+ case types_1.PackageManager.GO_MODULES:
541
+ return 'go test ./...';
542
+ case types_1.PackageManager.MAVEN:
543
+ return 'mvn test';
544
+ case types_1.PackageManager.GRADLE:
545
+ return 'gradle test';
546
+ case types_1.PackageManager.NUGET:
547
+ return 'dotnet test';
548
+ default:
549
+ return 'npm run test';
550
+ }
551
+ }
552
+ async executeWithConfig(configPath) {
553
+ const projectRoot = process.cwd();
554
+ const fullConfigPath = path.isAbsolute(configPath) ? configPath : path.join(projectRoot, configPath);
555
+ if (!await this.fileSystem.exists(fullConfigPath)) {
556
+ this.logger.error(`Configuration file not found: ${fullConfigPath}`);
557
+ return;
558
+ }
559
+ this.logger.info(`Loading configuration from ${fullConfigPath}...`);
560
+ const content = await this.fileSystem.readFile(fullConfigPath);
561
+ try {
562
+ const projectDetails = JSON.parse(content);
563
+ // Override paths to current context
564
+ projectDetails.rootPath = projectRoot;
565
+ if (projectDetails.language) {
566
+ this.localizationService.setLanguage(projectDetails.language);
567
+ }
568
+ this.logger.info('Using configuration to skip prompts.');
569
+ const roles = projectDetails.roles || [types_1.WorkflowRole.DEVELOPER]; // Default if missing
570
+ await this.generateFiles(projectDetails, roles);
571
+ if (projectDetails.ideIntegrations) {
572
+ await this.integrateWithIde(projectDetails, projectDetails.ideIntegrations, roles);
573
+ }
574
+ this.logger.success('Project initialized from configuration successfully.');
575
+ }
576
+ catch (e) {
577
+ this.logger.error(`Failed to parse configuration: ${e.message}`);
578
+ }
579
+ }
580
+ }
581
+ exports.InitCommand = InitCommand;