@kodus/cli 0.0.12 → 0.1.5

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 (131) hide show
  1. package/README.md +380 -0
  2. package/dist/cli.d.ts +4 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +23 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/auth/index.d.ts +3 -0
  7. package/dist/commands/auth/index.d.ts.map +1 -0
  8. package/dist/commands/auth/index.js +36 -0
  9. package/dist/commands/auth/index.js.map +1 -0
  10. package/dist/commands/auth/login.d.ts +7 -0
  11. package/dist/commands/auth/login.d.ts.map +1 -0
  12. package/dist/commands/auth/login.js +80 -0
  13. package/dist/commands/auth/login.js.map +1 -0
  14. package/dist/commands/auth/logout.d.ts +2 -0
  15. package/dist/commands/auth/logout.d.ts.map +1 -0
  16. package/dist/commands/auth/logout.js +24 -0
  17. package/dist/commands/auth/logout.js.map +1 -0
  18. package/dist/commands/auth/signup.d.ts +2 -0
  19. package/dist/commands/auth/signup.d.ts.map +1 -0
  20. package/dist/commands/auth/signup.js +59 -0
  21. package/dist/commands/auth/signup.js.map +1 -0
  22. package/dist/commands/auth/status.d.ts +2 -0
  23. package/dist/commands/auth/status.d.ts.map +1 -0
  24. package/dist/commands/auth/status.js +91 -0
  25. package/dist/commands/auth/status.js.map +1 -0
  26. package/dist/commands/auth/team-key.d.ts +5 -0
  27. package/dist/commands/auth/team-key.d.ts.map +1 -0
  28. package/dist/commands/auth/team-key.js +59 -0
  29. package/dist/commands/auth/team-key.js.map +1 -0
  30. package/dist/commands/auth/token.d.ts +2 -0
  31. package/dist/commands/auth/token.d.ts.map +1 -0
  32. package/dist/commands/auth/token.js +31 -0
  33. package/dist/commands/auth/token.js.map +1 -0
  34. package/dist/commands/pr.d.ts +3 -0
  35. package/dist/commands/pr.d.ts.map +1 -0
  36. package/dist/commands/pr.js +75 -0
  37. package/dist/commands/pr.js.map +1 -0
  38. package/dist/commands/review.d.ts +3 -0
  39. package/dist/commands/review.d.ts.map +1 -0
  40. package/dist/commands/review.js +164 -0
  41. package/dist/commands/review.js.map +1 -0
  42. package/dist/commands/upgrade.d.ts +3 -0
  43. package/dist/commands/upgrade.d.ts.map +1 -0
  44. package/dist/commands/upgrade.js +35 -0
  45. package/dist/commands/upgrade.js.map +1 -0
  46. package/dist/constants.d.ts +3 -0
  47. package/dist/constants.d.ts.map +1 -0
  48. package/dist/constants.js +3 -0
  49. package/dist/constants.js.map +1 -0
  50. package/dist/formatters/json.d.ts +7 -0
  51. package/dist/formatters/json.d.ts.map +1 -0
  52. package/dist/formatters/json.js +7 -0
  53. package/dist/formatters/json.js.map +1 -0
  54. package/dist/formatters/markdown.d.ts +7 -0
  55. package/dist/formatters/markdown.d.ts.map +1 -0
  56. package/dist/formatters/markdown.js +93 -0
  57. package/dist/formatters/markdown.js.map +1 -0
  58. package/dist/formatters/prompt.d.ts +12 -0
  59. package/dist/formatters/prompt.d.ts.map +1 -0
  60. package/dist/formatters/prompt.js +90 -0
  61. package/dist/formatters/prompt.js.map +1 -0
  62. package/dist/formatters/terminal.d.ts +7 -0
  63. package/dist/formatters/terminal.d.ts.map +1 -0
  64. package/dist/formatters/terminal.js +127 -0
  65. package/dist/formatters/terminal.js.map +1 -0
  66. package/dist/index.d.ts +3 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +9 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/services/api/api.interface.d.ts +42 -0
  71. package/dist/services/api/api.interface.d.ts.map +1 -0
  72. package/dist/services/api/api.interface.js +2 -0
  73. package/dist/services/api/api.interface.js.map +1 -0
  74. package/dist/services/api/api.real.d.ts +7 -0
  75. package/dist/services/api/api.real.d.ts.map +1 -0
  76. package/dist/services/api/api.real.js +252 -0
  77. package/dist/services/api/api.real.js.map +1 -0
  78. package/dist/services/api/index.d.ts +4 -0
  79. package/dist/services/api/index.d.ts.map +1 -0
  80. package/dist/services/api/index.js +3 -0
  81. package/dist/services/api/index.js.map +1 -0
  82. package/dist/services/auth.service.d.ts +19 -0
  83. package/dist/services/auth.service.d.ts.map +1 -0
  84. package/dist/services/auth.service.js +90 -0
  85. package/dist/services/auth.service.js.map +1 -0
  86. package/dist/services/context.service.d.ts +22 -0
  87. package/dist/services/context.service.d.ts.map +1 -0
  88. package/dist/services/context.service.js +104 -0
  89. package/dist/services/context.service.js.map +1 -0
  90. package/dist/services/fix.service.d.ts +31 -0
  91. package/dist/services/fix.service.d.ts.map +1 -0
  92. package/dist/services/fix.service.js +120 -0
  93. package/dist/services/fix.service.js.map +1 -0
  94. package/dist/services/git.service.d.ts +32 -0
  95. package/dist/services/git.service.d.ts.map +1 -0
  96. package/dist/services/git.service.js +261 -0
  97. package/dist/services/git.service.js.map +1 -0
  98. package/dist/services/review.service.d.ts +28 -0
  99. package/dist/services/review.service.d.ts.map +1 -0
  100. package/dist/services/review.service.js +111 -0
  101. package/dist/services/review.service.js.map +1 -0
  102. package/dist/types/index.d.ts +161 -0
  103. package/dist/types/index.d.ts.map +1 -0
  104. package/dist/types/index.js +15 -0
  105. package/dist/types/index.js.map +1 -0
  106. package/dist/ui/interactive.d.ts +26 -0
  107. package/dist/ui/interactive.d.ts.map +1 -0
  108. package/dist/ui/interactive.js +371 -0
  109. package/dist/ui/interactive.js.map +1 -0
  110. package/dist/utils/config.d.ts +10 -0
  111. package/dist/utils/config.d.ts.map +1 -0
  112. package/dist/utils/config.js +54 -0
  113. package/dist/utils/config.js.map +1 -0
  114. package/dist/utils/credentials.d.ts +6 -0
  115. package/dist/utils/credentials.d.ts.map +1 -0
  116. package/dist/utils/credentials.js +54 -0
  117. package/dist/utils/credentials.js.map +1 -0
  118. package/dist/utils/rate-limit.d.ts +5 -0
  119. package/dist/utils/rate-limit.d.ts.map +1 -0
  120. package/dist/utils/rate-limit.js +47 -0
  121. package/dist/utils/rate-limit.js.map +1 -0
  122. package/package.json +41 -33
  123. package/index.js +0 -15
  124. package/license.md +0 -21
  125. package/readme.md +0 -128
  126. package/scripts/setup-db.sh +0 -77
  127. package/src/commands/install.js +0 -357
  128. package/src/config/default.js +0 -66
  129. package/src/utils/helpers.js +0 -128
  130. package/templates/.env.example +0 -142
  131. package/templates/docker-compose.yml +0 -139
@@ -1,357 +0,0 @@
1
- import inquirer from "inquirer";
2
- import chalk from "chalk";
3
- import ora from "ora";
4
- import fs from "fs-extra";
5
- import path from "path";
6
- import { execSync } from "child_process";
7
- import { DEFAULT_CONFIG, DOCKER_NETWORKS, CRITICAL_ERRORS } from "../config/default.js";
8
- import {
9
- generateBase64Secret,
10
- generateHexSecret,
11
- generateWebhookToken,
12
- generateDbPassword,
13
- copyTemplates,
14
- createDockerNetworks,
15
- updateEnvFile,
16
- } from "../utils/helpers.js";
17
- import { fileURLToPath } from 'url';
18
- import { dirname } from 'path';
19
-
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = dirname(__filename);
22
-
23
- const maxAttempts = 30; // 5 minutes with 10 second intervals
24
-
25
- const waitForService = async (serviceName, successMessage, errorMessage) => {
26
- const spinner = ora(`Waiting for ${serviceName} to be ready`).start();
27
- let isReady = false;
28
- let attempts = 0;
29
-
30
- while (!isReady && attempts < maxAttempts) {
31
- try {
32
- const logs = execSync(`docker-compose logs ${serviceName}`, { stdio: "pipe" }).toString();
33
-
34
- if (logs.includes(successMessage)) {
35
- isReady = true;
36
- spinner.succeed(`${serviceName} is ready`);
37
- } else {
38
- attempts++;
39
- await new Promise(resolve => setTimeout(resolve, 10000));
40
- }
41
- } catch (error) {
42
- attempts++;
43
- await new Promise(resolve => setTimeout(resolve, 10000));
44
- }
45
- }
46
-
47
- if (!isReady) {
48
- spinner.fail(errorMessage);
49
- console.error(chalk.yellow("\nTroubleshooting steps:"));
50
- console.error(chalk.white(`1. Check ${serviceName} logs: docker-compose logs ${serviceName}`));
51
- console.error(chalk.white(`2. Verify ${serviceName} container is running: docker-compose ps ${serviceName}`));
52
- process.exit(1);
53
- }
54
- };
55
-
56
- const copyEnvFile = async () => {
57
- const envExamplePath = path.join(__dirname, '../../templates/.env.example');
58
- const envPath = path.join(process.cwd(), '.env');
59
-
60
- if (!fs.existsSync(envExamplePath)) {
61
- console.error(chalk.red('Error: .env.example file not found in templates directory'));
62
- process.exit(1);
63
- }
64
-
65
- try {
66
- await fs.copy(envExamplePath, envPath);
67
- console.log(chalk.green('.env file created successfully from template'));
68
- } catch (error) {
69
- console.error(chalk.red('Error copying .env file:', error.message));
70
- process.exit(1);
71
- }
72
- };
73
-
74
- export const setupEnvironment = async () => {
75
- try {
76
- // Check prerequisites
77
- console.log(chalk.blue("\n🔍 Checking prerequisites..."));
78
- const spinner = ora("Checking Docker installation").start();
79
-
80
- try {
81
- execSync("docker --version", { stdio: "ignore" });
82
- spinner.succeed("Docker is installed");
83
- } catch (error) {
84
- spinner.fail("Docker is not installed");
85
- console.error(
86
- chalk.red(
87
- "\nPlease install Docker first: https://docs.docker.com/get-docker/"
88
- )
89
- );
90
- process.exit(1);
91
- }
92
-
93
- // Copy template files
94
- const templateSpinner = ora("Copying template files").start();
95
- try {
96
- copyTemplates(process.cwd());
97
- templateSpinner.succeed("Template files copied");
98
- } catch (error) {
99
- templateSpinner.fail("Failed to copy template files");
100
- console.error(chalk.red("\nError details:"));
101
- console.error(chalk.white(error.message));
102
- process.exit(1);
103
- }
104
-
105
- await copyEnvFile();
106
-
107
- // Environment type selection
108
- const { envType } = await inquirer.prompt([
109
- {
110
- type: "list",
111
- name: "envType",
112
- message: "What type of environment are you setting up?",
113
- choices: [
114
- { name: "Local (localhost)", value: "local" },
115
- { name: "External (with public URL)", value: "external" },
116
- ],
117
- default: "local",
118
- },
119
- ]);
120
-
121
- let baseUrl = "http://localhost:3000";
122
- if (envType === "external") {
123
- const { url } = await inquirer.prompt([
124
- {
125
- type: "input",
126
- name: "url",
127
- message: "Enter your public URL (e.g., https://kodus.yourdomain.com):",
128
- validate: (input) => {
129
- try {
130
- const url = new URL(input);
131
- if (!url.protocol.startsWith('http')) {
132
- return "URL must start with http:// or https://";
133
- }
134
- if (!url.hostname.includes('.')) {
135
- return "URL must include a valid domain name";
136
- }
137
- return true;
138
- } catch (e) {
139
- return "Please enter a valid URL (e.g., https://kodus.yourdomain.com)";
140
- }
141
- },
142
- },
143
- ]);
144
- baseUrl = url;
145
- }
146
-
147
- // Git service selection
148
- const { gitService } = await inquirer.prompt([
149
- {
150
- type: "list",
151
- name: "gitService",
152
- message: "Which Git service will you use?",
153
- choices: [
154
- { name: "GitHub", value: "github" },
155
- { name: "GitLab", value: "gitlab" },
156
- { name: "Bitbucket", value: "bitbucket" },
157
- ],
158
- },
159
- ]);
160
-
161
- // Git service configuration
162
- let gitConfig = {};
163
-
164
- if (envType === "local") {
165
- console.log(chalk.yellow("\n⚠️ IMPORTANT: If you're using a cloud Git service (GitHub, GitLab, Bitbucket), you'll need to configure the webhook manually."));
166
- console.log(chalk.yellow("For local or self-hosted Git instances, no additional configuration is needed."));
167
- console.log(chalk.yellow("The webhook URL will be:"));
168
- console.log(chalk.white(`${baseUrl}/api/webhook/${gitService}`));
169
- }
170
-
171
- // Configure webhook URL based on the selected Git service
172
- if (gitService === "github") {
173
- gitConfig = {
174
- API_GITHUB_CODE_MANAGEMENT_WEBHOOK: `${baseUrl}/api/webhook/${gitService}`,
175
- };
176
- } else if (gitService === "gitlab") {
177
- gitConfig = {
178
- API_GITLAB_CODE_MANAGEMENT_WEBHOOK: `${baseUrl}/api/webhook/${gitService}`,
179
- };
180
- } else if (gitService === "bitbucket") {
181
- gitConfig = {
182
- GLOBAL_BITBUCKET_CODE_MANAGEMENT_WEBHOOK: `${baseUrl}/api/webhook/${gitService}`,
183
- };
184
- }
185
-
186
- // Database configuration
187
- const { useDefaultDb } = await inquirer.prompt([
188
- {
189
- type: "confirm",
190
- name: "useDefaultDb",
191
- message: "Would you like to use default database configurations?",
192
- default: true,
193
- },
194
- ]);
195
-
196
- // LLM API Keys configuration
197
- console.log(chalk.blue("\n🔑 Configuring LLM API Keys..."));
198
- const llmKeys = await inquirer.prompt([
199
- {
200
- type: "input",
201
- name: "openAiKey",
202
- message: "Enter your OpenAI API key (optional):",
203
- default: "",
204
- },
205
- {
206
- type: "input",
207
- name: "googleAiKey",
208
- message: "Enter your Google AI API key (optional):",
209
- default: "",
210
- },
211
- {
212
- type: "input",
213
- name: "anthropicKey",
214
- message: "Enter your Anthropic API key (optional):",
215
- default: "",
216
- },
217
- {
218
- type: "input",
219
- name: "novitaKey",
220
- message: "Enter your Novita AI API key (optional):",
221
- default: "",
222
- },
223
- {
224
- type: "input",
225
- name: "vertexKey",
226
- message: "Enter your Vertex AI API key (optional):",
227
- default: "",
228
- },
229
- ]);
230
-
231
- // Update environment variables with generated values
232
- const envUpdates = {
233
- NEXTAUTH_SECRET: generateBase64Secret(),
234
- JWT_SECRET_KEY: generateBase64Secret(),
235
- API_CRYPTO_KEY: generateHexSecret(),
236
- API_JWT_SECRET: generateBase64Secret(),
237
- API_JWT_REFRESHSECRET: generateBase64Secret(),
238
- CODE_MANAGEMENT_SECRET: generateHexSecret(),
239
- CODE_MANAGEMENT_WEBHOOK_TOKEN: generateWebhookToken(),
240
- API_PG_DB_PASSWORD: generateDbPassword(),
241
- API_MG_DB_PASSWORD: generateDbPassword(),
242
- RABBITMQ_DEFAULT_PASS: generateDbPassword(),
243
- GRAFANA_ADMIN_PASSWORD: generateDbPassword(),
244
- API_OPEN_AI_APIKEY: llmKeys.openAiKey,
245
- API_GOOGLE_AI_API_KEY: llmKeys.googleAiKey,
246
- API_ANTHROPIC_API_KEY: llmKeys.anthropicKey,
247
- API_NOVITA_AI_API_KEY: llmKeys.novitaKey,
248
- API_VERTEX_AI_API_KEY: llmKeys.vertexKey,
249
- ...gitConfig,
250
- };
251
-
252
- const envSpinner = ora("Updating environment variables").start();
253
- await updateEnvFile(envUpdates);
254
- envSpinner.succeed("Environment variables updated");
255
-
256
- // Create Docker networks
257
- createDockerNetworks(DOCKER_NETWORKS);
258
-
259
- // Start containers
260
- const dockerSpinner = ora("Starting containers").start();
261
- try {
262
- execSync("docker-compose up -d", { stdio: "pipe" });
263
- dockerSpinner.succeed("Containers started");
264
- } catch (error) {
265
- dockerSpinner.fail("Failed to start containers");
266
- console.error(chalk.red("\nError details:"));
267
- console.error(chalk.white(error.stdout?.toString() || error.message));
268
- process.exit(1);
269
- }
270
-
271
- // Wait for services to be ready
272
- await waitForService(
273
- "db_kodus_postgres",
274
- "database system is ready to accept connections",
275
- "PostgreSQL failed to start"
276
- );
277
-
278
- await waitForService(
279
- "db_kodus_mongodb",
280
- "Waiting for connections",
281
- "MongoDB failed to start"
282
- );
283
-
284
- await waitForService(
285
- "kodus_web",
286
- "✓ Ready in",
287
- "Web service failed to start"
288
- );
289
-
290
- // Setup database
291
- const dbSpinner = ora("Setting up database").start();
292
- try {
293
- const moduleRoot = dirname(dirname(__dirname)); // Sobe 2 níveis: commands -> src -> root
294
- const scriptPath = path.join(moduleRoot, 'scripts', 'setup-db.sh');
295
-
296
- if (!fs.existsSync(scriptPath)) {
297
- dbSpinner.fail('setup-db.sh script not found!');
298
- console.error(chalk.red(`\nScript expected at: ${scriptPath}`));
299
- process.exit(1);
300
- }
301
-
302
- execSync(`sh ${scriptPath}`, { stdio: "pipe" });
303
- dbSpinner.succeed("Database setup completed");
304
- } catch (error) {
305
- dbSpinner.fail("Failed to setup database");
306
- console.error(chalk.red("\nError details:"));
307
- console.error(chalk.white(error.stdout?.toString() || error.message));
308
- process.exit(1);
309
- }
310
-
311
- // Installation complete
312
- console.log(chalk.green("\n✨ Installation completed successfully!"));
313
-
314
- console.log(chalk.blue("\n📝 Installation Summary:"));
315
- console.log(chalk.white(` - Environment: ${envType === "local" ? "Local" : "External"}`));
316
- if (envType === "external") {
317
- console.log(chalk.white(` - Base URL: ${baseUrl}`));
318
- }
319
- console.log(chalk.white(` - Git Service: ${gitService.charAt(0).toUpperCase() + gitService.slice(1)}`));
320
- console.log(chalk.white(` - Database: ${useDefaultDb ? "Default configuration" : "Custom configuration"}`));
321
-
322
- console.log(chalk.blue("\n🔗 Access URLs:"));
323
- console.log(chalk.white(` - Web Interface: ${baseUrl}`));
324
- console.log(chalk.white(" - Grafana Dashboard: http://localhost:3001"));
325
- console.log(chalk.white(" - RabbitMQ Management: http://localhost:15672"));
326
-
327
- console.log(chalk.blue("\n📚 Next Steps:"));
328
- console.log(chalk.white(" 1. Access the web interface"));
329
- console.log(chalk.white(" 2. Set up your first user"));
330
- console.log(chalk.white(" 3. Start using Kodus!"));
331
-
332
- const { startServices } = await inquirer.prompt([
333
- {
334
- type: "confirm",
335
- name: "startServices",
336
- message: "Would you like to start the services now?",
337
- default: true,
338
- },
339
- ]);
340
-
341
- if (startServices) {
342
- execSync("docker-compose up -d", { stdio: "ignore" });
343
-
344
- // Wait for web service to be ready after restart
345
- await waitForService(
346
- "kodus_web",
347
- "✓ Ready in",
348
- "Web service failed to start"
349
- );
350
-
351
- console.log(chalk.green("\nServices started successfully!"));
352
- }
353
- } catch (error) {
354
- console.error(chalk.red("\n❌ Installation failed:"), error.message);
355
- process.exit(1);
356
- }
357
- };
@@ -1,66 +0,0 @@
1
- export const DEFAULT_CONFIG = {
2
- // Base configuration
3
- WEB_NODE_ENV: "development",
4
- WEB_HOSTNAME_API: "localhost",
5
- WEB_PORT_API: "3001",
6
- WEB_PORT: "3000",
7
- WEB_NEXTAUTH_URL: "http://localhost:3000",
8
-
9
- API_NODE_ENV: "development",
10
- API_LOG_LEVEL: "error",
11
- API_LOG_PRETTY: "true",
12
- API_HOST: "0.0.0.0",
13
- API_PORT: "3001",
14
- API_RATE_MAX_REQUEST: "100",
15
- API_RATE_INTERVAL: "1000",
16
- API_JWT_EXPIRES_IN: "365d",
17
- API_JWT_REFRESH_EXPIRES_IN: "7d",
18
-
19
- GLOBAL_API_CONTAINER_NAME: "kodus-orchestrator-prod",
20
-
21
- // Database
22
- API_DATABASE_ENV: "development",
23
- API_PG_DB_USERNAME: "kodusdev",
24
- API_PG_DB_DATABASE: "kodus_db",
25
- API_PG_DB_HOST: "db_kodus_postgres",
26
- API_PG_DB_PORT: "5432",
27
-
28
- API_MG_DB_USERNAME: "kodusdev",
29
- API_MG_DB_DATABASE: "kodus_db",
30
- API_MG_DB_HOST: "db_kodus_mongodb",
31
- API_MG_DB_PORT: "27017",
32
- API_MG_DB_PRODUCTION_CONFIG: "",
33
-
34
- // LLM Models
35
- API_LLM_MODEL_CHATGPT_3_5_TURBO: "gpt-4o-mini",
36
- API_LLM_MODEL_CHATGPT_3_5_TURBO_16K: "gpt-4o-mini",
37
- API_LLM_MODEL_CHATGPT_4: "gpt-4o-mini",
38
- API_LLM_MODEL_CHATGPT_4_TURBO: "gpt-4o-mini",
39
- API_LLM_MODEL_CHATGPT_4_ALL: "gpt-4o",
40
- API_LLM_MODEL_CHATGPT_4_ALL_MINI: "gpt-4o-mini",
41
- API_LLM_MODEL_CLAUDE_3_5_SONNET: "claude-3-5-sonnet-20241022",
42
- API_LLM_MODEL_CLAUDE_3_5_SONNET_20241022: "claude-3-5-sonnet-20241022",
43
- API_LLM_MODEL_GEMINI_1_5_PRO: "gpt-4o-mini",
44
- API_LLM_MODEL_GEMINI_1_5_PRO_EXP: "gpt-4o-mini",
45
-
46
- // Ports
47
- WEB_PORT: "3000",
48
- API_PORT: "3001",
49
-
50
- // RabbitMQ
51
- RABBITMQ_DEFAULT_USER: "kodus",
52
- };
53
-
54
- export const DOCKER_NETWORKS = [
55
- 'shared-network',
56
- 'monitoring-network',
57
- 'kodus-backend-services'
58
- ];
59
-
60
- export const CRITICAL_ERRORS = [
61
- "password authentication failed",
62
- "Unable to connect to the database",
63
- "FATAL:",
64
- "MongoServerError:",
65
- "connection refused"
66
- ];
@@ -1,128 +0,0 @@
1
- import crypto from 'crypto';
2
- import fs from 'fs-extra';
3
- import path from 'path';
4
- import { execSync } from 'child_process';
5
- import ora from 'ora';
6
- import chalk from 'chalk';
7
- import { fileURLToPath } from 'url';
8
- import { dirname } from 'path';
9
-
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = dirname(__filename);
12
-
13
- // Base64 secret key (for JWT and auth)
14
- export const generateBase64Secret = () => crypto.randomBytes(32).toString('base64');
15
-
16
- // Hex secret key (for crypto and management)
17
- export const generateHexSecret = () => crypto.randomBytes(32).toString('hex');
18
-
19
- // URL-safe base64 secret (for webhook tokens)
20
- export const generateWebhookToken = () => {
21
- const base64 = crypto.randomBytes(32).toString('base64');
22
- return base64.replace(/=/g, '').replace(/\+/g, '_').replace(/\//g, '-');
23
- };
24
-
25
- export const generateDbPassword = () =>
26
- crypto
27
- .randomBytes(16)
28
- .toString("base64")
29
- .replace(/[^a-zA-Z0-9]/g, "")
30
- .slice(0, 16);
31
-
32
- export const copyTemplates = (targetDir) => {
33
- try {
34
- const moduleDir = dirname(dirname(dirname(__filename))); // Sobe 3 níveis: utils -> src -> root
35
- const templatesDir = path.join(moduleDir, 'templates');
36
-
37
- if (!fs.existsSync(templatesDir)) {
38
- console.error(chalk.red(`Templates directory not found at: ${templatesDir}`));
39
- console.error(chalk.yellow('Current directory structure:'));
40
- console.error(chalk.white(fs.readdirSync(moduleDir)));
41
- throw new Error('Templates directory not found');
42
- }
43
-
44
- const sourceFile = path.join(templatesDir, 'docker-compose.yml');
45
- const targetFile = path.join(targetDir, 'docker-compose.yml');
46
-
47
- if (!fs.existsSync(sourceFile)) {
48
- console.error(chalk.red(`Template file not found at: ${sourceFile}`));
49
- console.error(chalk.yellow('Files in templates directory:'));
50
- console.error(chalk.white(fs.readdirSync(templatesDir)));
51
- throw new Error('Template file not found');
52
- }
53
-
54
- fs.copySync(sourceFile, targetFile);
55
- } catch (error) {
56
- console.error(chalk.red('Error copying templates:'), error);
57
- throw error;
58
- }
59
- };
60
-
61
- export const backupEnv = () => {
62
- const envPath = path.join(process.cwd(), '.env');
63
- if (fs.existsSync(envPath)) {
64
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
65
- const backupPath = path.join(process.cwd(), `.env.backup.${timestamp}`);
66
- fs.copySync(envPath, backupPath);
67
- return true;
68
- }
69
- return false;
70
- };
71
-
72
- export const restoreEnv = (backupFile) => {
73
- const backupPath = path.join(process.cwd(), backupFile);
74
- if (fs.existsSync(backupPath)) {
75
- const envPath = path.join(process.cwd(), '.env');
76
- fs.copySync(backupPath, envPath);
77
- return true;
78
- }
79
- return false;
80
- };
81
-
82
- export const getLatestVersion = () => {
83
- try {
84
- const result = execSync("git describe --tags --abbrev=0", { stdio: "pipe" })
85
- .toString()
86
- .trim();
87
- return result;
88
- } catch (error) {
89
- return null;
90
- }
91
- };
92
-
93
- export const getCurrentVersion = () => {
94
- try {
95
- const result = execSync("git rev-parse --abbrev-ref HEAD", {
96
- stdio: "pipe",
97
- })
98
- .toString()
99
- .trim();
100
- return result;
101
- } catch (error) {
102
- return null;
103
- }
104
- };
105
-
106
- export const createDockerNetworks = (networks) => {
107
- const networkSpinner = ora("Creating Docker networks").start();
108
-
109
- for (const network of networks) {
110
- try {
111
- // Check if network exists
112
- execSync(`docker network inspect ${network}`, { stdio: 'ignore' });
113
- } catch (error) {
114
- // Network doesn't exist, create it
115
- try {
116
- execSync(`docker network create ${network}`, { stdio: 'pipe' });
117
- console.log(chalk.green(`\nCreated network: ${network}`));
118
- } catch (createError) {
119
- networkSpinner.fail(`Failed to create network: ${network}`);
120
- console.error(chalk.red("\nError details:"));
121
- console.error(chalk.white(createError.stdout?.toString() || createError.message));
122
- process.exit(1);
123
- }
124
- }
125
- }
126
-
127
- networkSpinner.succeed("Docker networks created");
128
- };
@@ -1,142 +0,0 @@
1
- # =============================================
2
- # Environment Configuration Example File
3
- # Copy this file to .env and adjust the values
4
- # =============================================
5
-
6
- ## ---- BASIC SYSTEM CONFIGURATION ----
7
-
8
- # Web Application Settings
9
- WEB_NODE_ENV="self-hosted" # self-hosted, development, production
10
- WEB_HOSTNAME_API="localhost" # API hostname
11
- WEB_PORT_API=3001 # API port
12
- WEB_PORT=3000 # Web application port
13
- GLOBAL_API_CONTAINER_NAME="kodus-orchestrator" # API container name
14
-
15
- # Authentication Settings
16
- NEXTAUTH_URL="http://localhost:3000" # Base URL for authentication
17
- NEXTAUTH_SECRET="" # NextAuth secret key (generate with: openssl rand -base64 32)
18
- JWT_SECRET_KEY="" # JWT secret key (generate with: openssl rand -base64 32)
19
-
20
- ## ---- API CONFIGURATION ----
21
-
22
- # General API Settings
23
- API_NODE_ENV="development" # development, production, test
24
- API_LOG_LEVEL=error # error, warn, info, debug
25
- API_LOG_PRETTY=true # Log formatting
26
- API_HOST=0.0.0.0 # API host
27
- API_PORT=3001 # API port
28
- API_RATE_MAX_REQUEST=100 # Request rate limit
29
- API_RATE_INTERVAL=1000 # Rate limit interval in ms
30
- API_CLOUD_MODE=false # Enable/disable cloud mode
31
- API_CRYPTO_KEY= # Crypto key for encryption/decryption
32
-
33
- # JWT Configuration
34
- API_JWT_EXPIRES_IN=365d # Token expiration time
35
- API_JWT_SECRET=secret # JWT secret key
36
- API_JWT_REFRESHSECRET=refreshSecret # Refresh token secret key
37
- API_JWT_REFRESH_EXPIRES_IN=7d # Refresh token expiration time
38
-
39
- ## ---- DATABASE CONFIGURATION ----
40
-
41
- # PostgreSQL Settings
42
- API_DATABASE_ENV="development" # development, production, test
43
- API_PG_DB_HOST=db_kodus_postgres # PostgreSQL host
44
- API_PG_DB_PORT=5432 # PostgreSQL port
45
- API_PG_DB_USERNAME=kodusdev # Database username
46
- API_PG_DB_PASSWORD= # Database password
47
- API_PG_DB_DATABASE=kodus_db # Database name
48
-
49
- # MongoDB Settings
50
- API_MG_DB_HOST=db_kodus_mongodb # MongoDB host
51
- API_MG_DB_PORT=27017 # MongoDB port
52
- API_MG_DB_USERNAME=kodusdev # Database username
53
- API_MG_DB_PASSWORD= # Database password
54
- API_MG_DB_DATABASE=kodus # Database name
55
- API_MG_DB_PRODUCTION_CONFIG='' # Additional production settings
56
-
57
- ## ---- LLM API KEYS ----
58
-
59
- # API Keys for LLM Providers
60
- API_OPEN_AI_APIKEY= # OpenAI API key
61
- API_GOOGLE_AI_API_KEY= # Google AI API key
62
- API_ANTHROPIC_API_KEY= # Anthropic API key
63
- API_NOVITA_AI_API_KEY= # Novita AI API key
64
- API_VERTEX_AI_API_KEY= # Vertex AI API key
65
-
66
- # Available LLM Models
67
- API_LLM_MODEL_CHATGPT_3_5_TURBO=gpt-4o-mini
68
- API_LLM_MODEL_CHATGPT_3_5_TURBO_16K=gpt-4o-mini
69
- API_LLM_MODEL_CHATGPT_4=gpt-4o-mini
70
- API_LLM_MODEL_CHATGPT_4_TURBO=gpt-4o-mini
71
- API_LLM_MODEL_CHATGPT_4_ALL=gpt-4o
72
- API_LLM_MODEL_CHATGPT_4_ALL_MINI=gpt-4o-mini
73
- API_LLM_MODEL_CLAUDE_3_5_SONNET=claude-3-5-sonnet-20241022
74
- API_LLM_MODEL_CLAUDE_3_5_SONNET_20241022=claude-3-5-sonnet-20241022
75
- API_LLM_MODEL_GEMINI_1_5_PRO=gpt-4o-mini
76
- API_LLM_MODEL_GEMINI_1_5_PRO_EXP=gpt-4o-mini
77
-
78
- ## ---- CRON CONFIGURATION ----
79
- # Format: minute hour day_of_month month day_of_week
80
- # Example: 0 1 * * 5 = Every Friday at 01:00
81
-
82
- API_CRON_AUTOMATION_INTERACTION_MONITOR=0 1 * * 5
83
- API_CRON_AUTOMATION_ISSUES_DETAILS=0 1 * * 5
84
- API_CRON_COMPILE_SPRINT=0 1 * * 5
85
- API_CRON_METRICS=* 5 * * *
86
- API_CRON_AUTOMATION_DAILY_CHECKIN=* 5 * * *
87
- API_CRON_SPRINT_RETRO=* 5 * * *
88
- API_CRON_TEAM_ARTIFACTS_WEEKLY=* 5 * * *
89
- API_CRON_TEAM_ARTIFACTS_DAILY=* 5 * * *
90
- API_CRON_AUTOMATION_TEAM_PROGRESS_TRACKER=* 5 * * *
91
- API_CRON_ORGANIZATION_METRICS=* 5 * * *
92
- API_CRON_AUTOMATION_EXECUTIVE_CHECKIN=* 5 * * *
93
- API_CRON_ORGANIZATION_ARTIFACTS_WEEKLY=* 5 * * *
94
- API_CRON_ORGANIZATION_ARTIFACTS_DAILY=* 5 * * *
95
- API_CRON_ENRICH_TEAM_ARTIFACTS_WEEKLY=* 5 * * *
96
- API_CRON_SYNC_CODE_REVIEW_REACTIONS=* 5 * * *
97
- API_CRON_KODY_LEARNING=0 0 * * 6
98
- API_CRON_CHECK_IF_PR_SHOULD_BE_APPROVED=/2 * * * # A CADA 2 MINUTOS;
99
- ## ---- GIT INTEGRATIONS ----
100
-
101
- CODE_MANAGEMENT_SECRET=
102
- CODE_MANAGEMENT_WEBHOOK_TOKEN=
103
-
104
- # GitHub Settings (Fill only if using GitHub)
105
- API_GITHUB_CODE_MANAGEMENT_WEBHOOK= # GitHub webhook URL
106
- API_GITHUB_APP_ID= # GitHub App ID
107
- API_GITHUB_CLIENT_SECRET= # GitHub App Client Secret
108
- API_GITHUB_PRIVATE_KEY="" # GitHub App Private Key
109
- WEB_GITHUB_INSTALL_URL="" # GitHub App Installation URL
110
- WEB_OAUTH_GITHUB_CLIENT_ID="" # GitHub OAuth Client ID
111
- WEB_OAUTH_GITHUB_CLIENT_SECRET="" # GitHub OAuth Client Secret
112
-
113
- # GitLab Settings (Fill only if using GitLab)
114
- API_GITLAB_TOKEN_URL="https://gitlab.com/oauth/token"
115
- API_GITLAB_CODE_MANAGEMENT_WEBHOOK= # GitLab webhook URL
116
- WEB_GITLAB_SCOPES="read_api read_user read_repository"
117
- WEB_GITLAB_OAUTH_URL="https://gitlab.com/oauth/authorize"
118
- WEB_OAUTH_GITLAB_CLIENT_ID="" # GitLab OAuth Client ID
119
- WEB_OAUTH_GITLAB_CLIENT_SECRET="" # GitLab OAuth Client Secret
120
-
121
- # Bitbucket Settings (Fill only if using Bitbucket)
122
- WEB_BITBUCKET_INSTALL_URL="" # Bitbucket Installation URL
123
- GLOBAL_BITBUCKET_CODE_MANAGEMENT_WEBHOOK= # Bitbucket webhook URL
124
-
125
- ## ---- ADDITIONAL INTEGRATIONS ----
126
-
127
- # Communication Integrations
128
- WEB_CONNECTION_SLACK="" # Slack connection URL
129
- WEB_CONNECTION_DISCORD="" # Discord connection URL
130
-
131
- # JIRA Integration
132
- WEB_JIRA_SCOPES="read%3Aissue-type%3Ajira%20read%3Aproject%3Ajira%20read%3Aproject.property%3Ajira%20read%3Auser%3Ajira%20read%3Aapplication-role%3Ajira%20read%3Aavatar%3Ajira%20read%3Agroup%3Ajira%20read%3Aissue-type-hierarchy%3Ajira%20read%3Aproject-category%3Ajira%20read%3Aproject-version%3Ajira%20read%3Aproject.component%3Ajira%20read%3Aissue-details%3Ajira%20read%3Aaudit-log%3Ajira%20read%3Afield-configuration%3Ajira%20read%3Aissue-meta%3Ajira%20read%3Aissue-security-level%3Ajira%20read%3Aissue.vote%3Ajira%20read%3Aissue.changelog%3Ajira%20read%3Aissue%3Ajira%20read%3Astatus%3Ajira%20read%3Afield%3Ajira%20write%3Awebhook%3Ajira%20read%3Awebhook%3Ajira%20read%3Aissue-status%3Ajira%20read%3Aboard-scope.admin%3Ajira-software%20read%3Ajql%3Ajira%20delete%3Awebhook%3Ajira%20read%3Acomment.property%3Ajira%20read%3Aproject-role%3Ajira%20read%3Aepic%3Ajira-software%20read%3Aboard-scope%3Ajira-software%20read%3Asprint%3Ajira-software%20read%3Afield.default-value%3Ajira%20read%3Afield.option%3Ajira%20read%3Aissue%3Ajira-software%20read%3Acomment%3Ajira%20read%3Aattachment%3Ajira%20read%3Aissue-worklog%3Ajira%20write%3Aissue-link-type%3Ajira%20write%3Afield%3Ajira%20write%3Aworkflow%3Ajira%20write%3Aproject%3Ajira"
133
-
134
- # Support Settings
135
- WEB_ANALYTICS_HOSTNAME="" # Analytics hostname
136
- WEB_SUPPORT_DOCS_URL="https://docs.kodus.io" # Documentation URL
137
- WEB_SUPPORT_DISCORD_INVITE_URL="https://discord.gg/CceCdAke" # Discord invite URL
138
- WEB_SUPPORT_TALK_TO_FOUNDER_URL="https://cal.com/gabrielmalinosqui/30min" # Scheduling URL
139
-
140
- # RabbitMQ Configuration
141
- API_RABBITMQ_URI= # RabbitMQ connection URI
142
- API_RABBITMQ_ENABLED=false # Enable/disable RabbitMQ