imlil 1.0.1

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 (175) hide show
  1. package/.eslintrc.cjs +40 -0
  2. package/DOCS.md +63 -0
  3. package/README.md +160 -0
  4. package/agentTestSandbox/cli-test-zone/README.md +0 -0
  5. package/agentTestSandbox/cli-test-zone/imlil.blueprint.json +5 -0
  6. package/agentTestSandbox/cli-test-zone/notes-warning.md +3 -0
  7. package/agentTestSandbox/cli-test-zone/package.json +0 -0
  8. package/agentTestSandbox/cli-test-zone/public/index.html +0 -0
  9. package/agentTestSandbox/cli-test-zone/src/App.js +0 -0
  10. package/agentTestSandbox/cli-test-zone/src/App.jsx +29 -0
  11. package/agentTestSandbox/cli-test-zone/src/__tests__/App.test.jsx +48 -0
  12. package/agentTestSandbox/cli-test-zone/src/components/AddTodo.js +0 -0
  13. package/agentTestSandbox/cli-test-zone/src/components/Navigation/Navigation.jsx +48 -0
  14. package/agentTestSandbox/cli-test-zone/src/components/Navigation/__tests__/Navigation.module.test.js +45 -0
  15. package/agentTestSandbox/cli-test-zone/src/components/Navigation/__tests__/Navigation.test.jsx +47 -0
  16. package/agentTestSandbox/cli-test-zone/src/components/Navigation.js +0 -0
  17. package/agentTestSandbox/cli-test-zone/src/components/TodoItem/TodoItem.jsx +41 -0
  18. package/agentTestSandbox/cli-test-zone/src/components/TodoItem/__tests__/TodoItem.test.jsx +65 -0
  19. package/agentTestSandbox/cli-test-zone/src/components/TodoItem.js +0 -0
  20. package/agentTestSandbox/cli-test-zone/src/components/TodoList/TodoList.module.css +62 -0
  21. package/agentTestSandbox/cli-test-zone/src/components/TodoList.js +0 -0
  22. package/agentTestSandbox/cli-test-zone/src/index.js +0 -0
  23. package/agentTestSandbox/cli-test-zone/src/pages/About.js +0 -0
  24. package/agentTestSandbox/cli-test-zone/src/pages/Home.js +0 -0
  25. package/agentTestSandbox/cli-test-zone/src/store/TodoContext.js +0 -0
  26. package/agentTestSandbox/cli-test-zone/src/styles/Todo.css +0 -0
  27. package/agentTestSandbox/cli-test-zone/src/styles/index.css +0 -0
  28. package/agentTestSandbox/cli-test-zone/src/utils/__tests__/localStorage.test.js +48 -0
  29. package/agentTestSandbox/cli-test-zone/src/utils/localStorage.js +38 -0
  30. package/agentTestSandbox/parallel-test/.env.example +0 -0
  31. package/agentTestSandbox/parallel-test/.eslintrc.json +0 -0
  32. package/agentTestSandbox/parallel-test/.github/workflows/__tests__/workflows.test.ts +115 -0
  33. package/agentTestSandbox/parallel-test/.github/workflows/cd.yml +0 -0
  34. package/agentTestSandbox/parallel-test/.github/workflows/ci.yml +4 -0
  35. package/agentTestSandbox/parallel-test/.imlil/plan-2026-02-08.md +186 -0
  36. package/agentTestSandbox/parallel-test/.prettierrc +0 -0
  37. package/agentTestSandbox/parallel-test/Dockerfile +0 -0
  38. package/agentTestSandbox/parallel-test/README.md +3 -0
  39. package/agentTestSandbox/parallel-test/ast.json +74 -0
  40. package/agentTestSandbox/parallel-test/docker-compose.yml +4 -0
  41. package/agentTestSandbox/parallel-test/jest.config.js +61 -0
  42. package/agentTestSandbox/parallel-test/k8s/__tests__/deployment.test.ts +168 -0
  43. package/agentTestSandbox/parallel-test/k8s/frontend-deployment.yaml +4 -0
  44. package/agentTestSandbox/parallel-test/nginx/nginx.conf +0 -0
  45. package/agentTestSandbox/parallel-test/package.json +50 -0
  46. package/agentTestSandbox/parallel-test/prisma/__tests__/schema.test.ts +176 -0
  47. package/agentTestSandbox/parallel-test/prisma/schema.prisma +109 -0
  48. package/agentTestSandbox/parallel-test/server/__tests__/controllers/dashboard.controller.test.ts +127 -0
  49. package/agentTestSandbox/parallel-test/server/__tests__/index.test.ts +60 -0
  50. package/agentTestSandbox/parallel-test/server/__tests__/models/user.model.test.ts +111 -0
  51. package/agentTestSandbox/parallel-test/server/config/__tests__/swagger.test.ts +128 -0
  52. package/agentTestSandbox/parallel-test/server/config/database.ts +0 -0
  53. package/agentTestSandbox/parallel-test/server/config/redis.ts +0 -0
  54. package/agentTestSandbox/parallel-test/server/config/swagger.ts +0 -0
  55. package/agentTestSandbox/parallel-test/server/controllers/__tests__/auth.controller.test.ts +178 -0
  56. package/agentTestSandbox/parallel-test/server/controllers/__tests__/user.controller.test.ts +105 -0
  57. package/agentTestSandbox/parallel-test/server/controllers/auth.controller.ts +148 -0
  58. package/agentTestSandbox/parallel-test/server/controllers/dashboard.controller.ts +137 -0
  59. package/agentTestSandbox/parallel-test/server/controllers/user.controller.ts +161 -0
  60. package/agentTestSandbox/parallel-test/server/index.ts +62 -0
  61. package/agentTestSandbox/parallel-test/server/middleware/__tests__/auth.middleware.test.ts +74 -0
  62. package/agentTestSandbox/parallel-test/server/middleware/auth.middleware.ts +55 -0
  63. package/agentTestSandbox/parallel-test/server/middleware/error.middleware.ts +0 -0
  64. package/agentTestSandbox/parallel-test/server/middleware/validation.middleware.ts +0 -0
  65. package/agentTestSandbox/parallel-test/server/models/analytics.model.ts +0 -0
  66. package/agentTestSandbox/parallel-test/server/models/profile.model.ts +0 -0
  67. package/agentTestSandbox/parallel-test/server/models/user.model.ts +78 -0
  68. package/agentTestSandbox/parallel-test/server/routes/auth.routes.ts +0 -0
  69. package/agentTestSandbox/parallel-test/server/routes/dashboard.routes.ts +0 -0
  70. package/agentTestSandbox/parallel-test/server/routes/user.routes.ts +0 -0
  71. package/agentTestSandbox/parallel-test/src/App.tsx +0 -0
  72. package/agentTestSandbox/parallel-test/src/__tests__/config.test.ts +127 -0
  73. package/agentTestSandbox/parallel-test/src/__tests__/index.test.tsx +36 -0
  74. package/agentTestSandbox/parallel-test/src/__tests__/setup.test.ts +34 -0
  75. package/agentTestSandbox/parallel-test/src/__tests__/setupTest.test.ts +44 -0
  76. package/agentTestSandbox/parallel-test/src/components/common/Button/Button.tsx +80 -0
  77. package/agentTestSandbox/parallel-test/src/components/common/Button/__tests__/Button.test.tsx +75 -0
  78. package/agentTestSandbox/parallel-test/src/components/common/Card/Card.tsx +0 -0
  79. package/agentTestSandbox/parallel-test/src/components/common/Input/Input.tsx +0 -0
  80. package/agentTestSandbox/parallel-test/src/components/common/Table/Table.tsx +0 -0
  81. package/agentTestSandbox/parallel-test/src/components/features/Authentication/LoginForm.tsx +75 -0
  82. package/agentTestSandbox/parallel-test/src/components/features/Authentication/RegisterForm.tsx +0 -0
  83. package/agentTestSandbox/parallel-test/src/components/features/Authentication/__tests__/LoginForm.test.tsx +101 -0
  84. package/agentTestSandbox/parallel-test/src/components/features/Dashboard/AnalyticsChart.tsx +0 -0
  85. package/agentTestSandbox/parallel-test/src/components/features/Dashboard/DashboardStats.tsx +81 -0
  86. package/agentTestSandbox/parallel-test/src/components/features/Dashboard/__tests__/DashboardStats.test.tsx +122 -0
  87. package/agentTestSandbox/parallel-test/src/components/layouts/Header.tsx +70 -0
  88. package/agentTestSandbox/parallel-test/src/components/layouts/MainLayout.tsx +0 -0
  89. package/agentTestSandbox/parallel-test/src/components/layouts/Sidebar.tsx +0 -0
  90. package/agentTestSandbox/parallel-test/src/components/layouts/__tests__/MainLayout.test.tsx +65 -0
  91. package/agentTestSandbox/parallel-test/src/hooks/__tests__/useAuth.test.ts +75 -0
  92. package/agentTestSandbox/parallel-test/src/hooks/useApi.ts +0 -0
  93. package/agentTestSandbox/parallel-test/src/hooks/useAuth.ts +54 -0
  94. package/agentTestSandbox/parallel-test/src/hooks/useTheme.ts +0 -0
  95. package/agentTestSandbox/parallel-test/src/index.tsx +0 -0
  96. package/agentTestSandbox/parallel-test/src/services/__tests__/api.service.test.ts +48 -0
  97. package/agentTestSandbox/parallel-test/src/services/analytics.service.ts +0 -0
  98. package/agentTestSandbox/parallel-test/src/services/api.service.ts +59 -0
  99. package/agentTestSandbox/parallel-test/src/services/api.ts +0 -0
  100. package/agentTestSandbox/parallel-test/src/services/auth.service.ts +0 -0
  101. package/agentTestSandbox/parallel-test/src/services/user.service.ts +0 -0
  102. package/agentTestSandbox/parallel-test/src/store/__tests__/store.test.ts +60 -0
  103. package/agentTestSandbox/parallel-test/src/store/index.ts +23 -0
  104. package/agentTestSandbox/parallel-test/src/store/slices/authSlice.ts +0 -0
  105. package/agentTestSandbox/parallel-test/src/store/slices/dashboardSlice.ts +0 -0
  106. package/agentTestSandbox/parallel-test/src/store/slices/userSlice.ts +0 -0
  107. package/agentTestSandbox/parallel-test/src/types/auth.types.ts +0 -0
  108. package/agentTestSandbox/parallel-test/src/types/dashboard.types.ts +0 -0
  109. package/agentTestSandbox/parallel-test/src/types/user.types.ts +0 -0
  110. package/agentTestSandbox/parallel-test/src/utils/constants.ts +0 -0
  111. package/agentTestSandbox/parallel-test/src/utils/formatters.ts +0 -0
  112. package/agentTestSandbox/parallel-test/src/utils/validation.ts +0 -0
  113. package/agentTestSandbox/parallel-test/src/views/Dashboard.tsx +0 -0
  114. package/agentTestSandbox/parallel-test/src/views/Login.tsx +31 -0
  115. package/agentTestSandbox/parallel-test/src/views/Profile.tsx +0 -0
  116. package/agentTestSandbox/parallel-test/src/views/Register.tsx +0 -0
  117. package/agentTestSandbox/parallel-test/src/views/Settings.tsx +0 -0
  118. package/agentTestSandbox/parallel-test/src/views/__tests__/Login.test.tsx +62 -0
  119. package/agentTestSandbox/parallel-test/src/vite-env.d.ts +1 -0
  120. package/agentTestSandbox/parallel-test/tailwind.config.js +0 -0
  121. package/agentTestSandbox/parallel-test/tests/integration/api/auth.test.ts +120 -0
  122. package/agentTestSandbox/parallel-test/tests/unit/components/Button.test.tsx +35 -0
  123. package/agentTestSandbox/parallel-test/tests/unit/config/jest.config.test.js +62 -0
  124. package/agentTestSandbox/parallel-test/tests/unit/config/jest.setup.test.js +52 -0
  125. package/agentTestSandbox/parallel-test/tests/unit/infrastructure/__tests__/docker-config.test.ts +107 -0
  126. package/agentTestSandbox/parallel-test/tsconfig.json +0 -0
  127. package/agentTestSandbox/zone2/Makefile +58 -0
  128. package/agentTestSandbox/zone2/README.md +0 -0
  129. package/agentTestSandbox/zone2/docs/API.md +0 -0
  130. package/agentTestSandbox/zone2/docs/CONTRIBUTING.md +0 -0
  131. package/agentTestSandbox/zone2/imlil.blueprint.json +5 -0
  132. package/agentTestSandbox/zone2/notes-warning.md +3 -0
  133. package/agentTestSandbox/zone2/src/calculator.c +0 -0
  134. package/agentTestSandbox/zone2/src/calculator.h +0 -0
  135. package/agentTestSandbox/zone2/src/core/__tests__/test_memory.c +89 -0
  136. package/agentTestSandbox/zone2/src/core/memory.c +60 -0
  137. package/agentTestSandbox/zone2/src/display.c +0 -0
  138. package/agentTestSandbox/zone2/src/display.h +0 -0
  139. package/agentTestSandbox/zone2/src/input_handler.c +0 -0
  140. package/agentTestSandbox/zone2/src/input_handler.h +0 -0
  141. package/agentTestSandbox/zone2/src/main.c +0 -0
  142. package/agentTestSandbox/zone2/src/utils/error_handling.c +0 -0
  143. package/agentTestSandbox/zone2/src/utils/error_handling.h +0 -0
  144. package/agentTestSandbox/zone2/src/utils/input.c +0 -0
  145. package/agentTestSandbox/zone2/src/utils/input.h +0 -0
  146. package/agentTestSandbox/zone2/src/utils/math_utils.c +0 -0
  147. package/agentTestSandbox/zone2/src/utils/math_utils.h +0 -0
  148. package/agentTestSandbox/zone2/src/utils/stack.c +0 -0
  149. package/agentTestSandbox/zone2/src/utils/stack.h +0 -0
  150. package/agentTestSandbox/zone2/src/utils.c +34 -0
  151. package/agentTestSandbox/zone2/tests/__tests__/test_makefile.c +58 -0
  152. package/agentTestSandbox/zone2/tests/calculator_tests.c +0 -0
  153. package/agentTestSandbox/zone2/tests/input_handler_tests.c +0 -0
  154. package/agentTestSandbox/zone2/tests/math_utils_tests.c +0 -0
  155. package/agentTestSandbox/zone2/tests/test_calculator.c +0 -0
  156. package/agentTestSandbox/zone2/tests/test_input.c +0 -0
  157. package/agentTestSandbox/zone2/tests/test_stack.c +0 -0
  158. package/agentTestSandbox/zone2/tests/test_utils.c +8 -0
  159. package/bin/cli.js +369 -0
  160. package/imlil.config.js +22 -0
  161. package/index.js +0 -0
  162. package/jest.config.js +5 -0
  163. package/package.json +45 -0
  164. package/src/__tests__/cli.test.js +5 -0
  165. package/src/actions/Action.js +125 -0
  166. package/src/agents/Agent.js +64 -0
  167. package/src/agents/Operator.js +147 -0
  168. package/src/agents/ScrumAgent.js +74 -0
  169. package/src/agents/SupervisorAgent.js +198 -0
  170. package/src/agents/ValidatorAgent.js +48 -0
  171. package/src/agents/coder.js +208 -0
  172. package/src/agents/worker.js +52 -0
  173. package/src/utils/db.js +40 -0
  174. package/src/utils/embedapi.js +19 -0
  175. package/test-api.js +24 -0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,34 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include "utils.h"
5
+
6
+ /**
7
+ * Handles division by zero errors
8
+ * @return ERROR_DIV_ZERO error code
9
+ */
10
+ int handle_division_by_zero(void) {
11
+ print_error("Error: Division by zero attempted");
12
+ return ERROR_DIV_ZERO;
13
+ }
14
+
15
+ /**
16
+ * Handles invalid input errors
17
+ * @param msg Custom error message
18
+ * @return ERROR_INVALID_INPUT error code
19
+ */
20
+ int handle_invalid_input(const char* msg) {
21
+ char error_msg[MAX_ERROR_MSG_LEN];
22
+
23
+ snprintf(error_msg, MAX_ERROR_MSG_LEN, "Invalid input: %s", msg);
24
+ print_error(error_msg);
25
+ return ERROR_INVALID_INPUT;
26
+ }
27
+
28
+ /**
29
+ * Prints error message to stderr
30
+ * @param msg Error message to print
31
+ */
32
+ void print_error(const char* msg) {
33
+ fprintf(stderr, "[ERROR] %s\n", msg);
34
+ }
@@ -0,0 +1,58 @@
1
+ #include "unity.h"
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <unistd.h>
5
+
6
+ /* Mock system command for testing */
7
+ int mock_system_return = 0;
8
+ int system(const char* command) {
9
+ return mock_system_return;
10
+ }
11
+
12
+ void setUp(void) {
13
+ /* Reset mock system return value before each test */
14
+ mock_system_return = 0;
15
+ }
16
+
17
+ void tearDown(void) {
18
+ /* Cleanup after each test */
19
+ }
20
+
21
+ void test_makefile_build_targets(int*) {
22
+ FILE* result = fopen("Makefile", "r");
23
+ TEST_ASSERT_NOT_NULL(result);
24
+ fclose(result);
25
+
26
+ /* Test make all command */
27
+ mock_system_return = 0;
28
+ TEST_ASSERT_EQUAL_INT(0, system("make all"));
29
+
30
+ /* Test make build command */
31
+ TEST_ASSERT_EQUAL_INT(0, system("make build"));
32
+ }
33
+
34
+ void test_makefile_test_targets(int*) {
35
+ /* Test make test command */
36
+ mock_system_return = 0;
37
+ TEST_ASSERT_EQUAL_INT(0, system("make test"));
38
+
39
+ /* Test make check command */
40
+ TEST_ASSERT_EQUAL_INT(0, system("make check"));
41
+ }
42
+
43
+ void test_makefile_clean_commands(int*) {
44
+ /* Test make clean command */
45
+ mock_system_return = 0;
46
+ TEST_ASSERT_EQUAL_INT(0, system("make clean"));
47
+
48
+ /* Test make distclean command */
49
+ TEST_ASSERT_EQUAL_INT(0, system("make distclean"));
50
+ }
51
+
52
+ int main(void) {
53
+ UNITY_BEGIN();
54
+ RUN_TEST(test_makefile_build_targets);
55
+ RUN_TEST(test_makefile_test_targets);
56
+ RUN_TEST(test_makefile_clean_commands);
57
+ return UNITY_END();
58
+ }
File without changes
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ #include "unity.h"
2
+ #include "../include/utils.h"
3
+ #include <stdio.h>
4
+
5
+ void setUp(void) {
6
+ }
7
+
8
+ void tearDown(void) x)�((���Q��Ё������}��٥ͥ��}��}�ɼ���)ٽ���ѕ��}������}��٥ͥ��}��}�ɼ�ٽ�����(�������Q��Ёѡ�Ё�Ёɕ��ɹ́ѡ�������ѕ����ɽȁ����(������Ёɕ�ձЀ􁡅����}��٥ͥ��}��}�ɼ���(����QMQ}MMIQ}EU0�ɕ�ձа��Ĥ�)�()ٽ���ѕ��}������}��م���}����Сٽ�����(�������Q��ЁݥѠ�9U10������(������Ёɕ�ձ�Ā􁡅����}��م���}����С9U10��(����QMQ}MMIQ}EU1}%9P�ɕ�ձ�İ��Ĥ�((�������Q��ЁݥѠ�م���������(�������ȁم���}�����mt����̈�(������Ёɕ�ձ�Ȁ􁡅����}��م���}����Сم���}����Ф�(����QMQ}MMIQ}EU0�ɕ�ձ�Ȱ����)�()ٽ���ѕ��}�ɥ��}��ɽȡٽ�����(�������Q��Ёѡ�Ё�ɥ��}��ɽȁ���͸�Ё�Ʌ͠(�������M�����ݔ�����Ё��ɕ�ѱ�ѕ�Ё�ё��а�ݔ����Ёٕɥ�䁥Ё�չ�(�����ɥ��}��ɽȠ�Q��Ё��ɽȁ���ͅ�����(����QMQ}AML��쀼��%��ݔ���Ё��ɔ��ѡ���չ�ѥ��������Ё�Ʌ͠)�()��Ё�����ٽ�����(����U9%Qe} %8���(����IU9}QMP�ѕ��}������}��٥ͥ��}��}�ɼ��(����IU9}QMP�ѕ��}������}��م���}����Ф�(����IU9}QMP�ѕ��}�ɥ��}��ɽȤ�(����ɕ��ɸ�U9%Qe}9���)�(
package/bin/cli.js ADDED
@@ -0,0 +1,369 @@
1
+ #!/usr/bin/env node
2
+
3
+ import path from 'path';
4
+ import fs from 'fs/promises';
5
+ import { fileURLToPath } from 'url';
6
+ import { program } from 'commander';
7
+ import { findUp } from 'find-up';
8
+ import { initializeDatabase, getDb } from '../src/utils/db.js';
9
+ import SupervisorAgent from '../src/agents/SupervisorAgent.js';
10
+ import ScrumAgent from '../src/agents/ScrumAgent.js';
11
+ import ValidatorAgent from '../src/agents/ValidatorAgent.js';
12
+ import { callEmbedApi } from '../src/utils/embedapi.js';
13
+ import os from 'os';
14
+ import inquirer from 'inquirer';
15
+ import blessed from 'blessed';
16
+ import contrib from 'blessed-contrib';
17
+ import Piscina from 'piscina';
18
+
19
+ // --- API Key Management ---
20
+
21
+ async function getApiKey() {
22
+ if (process.env.IMLIL_API_KEY) {
23
+ return process.env.IMLIL_API_KEY;
24
+ }
25
+
26
+ const configPath = path.join(os.homedir(), '.imlil');
27
+ try {
28
+ const apiKey = await fs.readFile(configPath, 'utf8');
29
+ return apiKey.trim();
30
+ } catch (error) {
31
+ const { apiKey } = await inquirer.prompt([
32
+ {
33
+ type: 'password',
34
+ name: 'apiKey',
35
+ message: 'Please enter your EmbedAPI key:',
36
+ },
37
+ ]);
38
+ await fs.writeFile(configPath, apiKey);
39
+ return apiKey;
40
+ }
41
+ }
42
+
43
+ // --- Main Application ---
44
+
45
+ program
46
+ .command('make <project_description>')
47
+ .description('Create a new project by orchestrating agents')
48
+ .option('--debug', 'Enable debug mode to see raw AI responses.')
49
+ .option('--max-agents <num>', 'Set the maximum number of parallel agents.')
50
+ .action(async (project_description, options) => {
51
+ const isTTY = process.stdout.isTTY;
52
+ let screen, grid, logBox, agentStatusBox, statsBox, progressBar;
53
+
54
+ if (isTTY) {
55
+ screen = blessed.screen({
56
+ smartCSR: true,
57
+ title: 'imlil - NASA Control Room'
58
+ });
59
+
60
+ grid = new contrib.grid({rows: 12, cols: 12, screen: screen});
61
+
62
+ logBox = grid.set(0, 0, 10, 8, blessed.log, {
63
+ label: 'Mission Log',
64
+ tags: true,
65
+ border: { type: 'line' },
66
+ style: { border: { fg: 'cyan' } }
67
+ });
68
+
69
+ agentStatusBox = grid.set(0, 8, 7, 4, blessed.box, {
70
+ label: 'Agent Status',
71
+ tags: true,
72
+ border: { type: 'line' },
73
+ style: { border: { fg: 'green' } }
74
+ });
75
+
76
+ statsBox = grid.set(7, 8, 3, 4, blessed.box, {
77
+ label: 'Mission Stats',
78
+ tags: true,
79
+ border: { type: 'line' },
80
+ style: { border: { fg: 'magenta' } }
81
+ });
82
+
83
+ progressBar = grid.set(10, 0, 2, 12, blessed.progressbar, {
84
+ label: 'Overall Progress',
85
+ border: { type: 'line' },
86
+ style: { border: { fg: 'yellow' }, bar: { bg: 'yellow' } },
87
+ filled: 0
88
+ });
89
+
90
+ screen.render();
91
+ } else {
92
+ // No UI components for non-TTY mode
93
+ logBox = null;
94
+ agentStatusBox = null;
95
+ statsBox = null;
96
+ progressBar = null;
97
+ screen = null;
98
+ }
99
+
100
+ const logStream = await fs.open('imlil.log', 'w');
101
+
102
+ console.log = (...args) => {
103
+ const message = args.join(' ');
104
+ if (logBox) logBox.log(message);
105
+ else process.stdout.write(message + '\n');
106
+ logStream.write(`${new Date().toISOString()} - ${message}\n`);
107
+ if (screen) screen.render();
108
+ };
109
+
110
+ console.error = (...args) => {
111
+ const message = args.join(' ');
112
+ if (logBox) logBox.log(`{red-fg}ERROR: ${message}{/red-fg}`);
113
+ else process.stderr.write(`ERROR: ${message}\n`);
114
+ logStream.write(`${new Date().toISOString()} - ERROR: ${message}\n`);
115
+ };
116
+
117
+ setTimeout(() => {
118
+ if (logBox) logBox.log('{red-fg}MISSION ABORTED: Time limit exceeded (10m).{/red-fg}');
119
+ else console.log('MISSION ABORTED: Time limit exceeded (10m).');
120
+ logStream.write(`${new Date().toISOString()} - MISSION ABORTED: Time limit exceeded.\n`);
121
+ if (screen) screen.render();
122
+ setTimeout(() => {
123
+ if (screen) screen.destroy();
124
+ process.exit(1);
125
+ }, 3000);
126
+ }, 600000);
127
+
128
+ const apiKey = await getApiKey();
129
+ const __filename = fileURLToPath(import.meta.url);
130
+ const __dirname = path.dirname(__filename);
131
+ const packageJsonPath = await findUp('package.json', { cwd: __dirname });
132
+ const projectRoot = path.dirname(packageJsonPath);
133
+
134
+ let config = {
135
+ mode: 'yolo',
136
+ maxAgents: 20,
137
+ cliPersonality: `You are a sick bro, a funny, over-motivated guru developer.`,
138
+ debug: !!options.debug
139
+ };
140
+
141
+ try {
142
+ const configPath = path.resolve(projectRoot, 'imlil.config.js');
143
+ const configModule = await import(configPath);
144
+ Object.assign(config, configModule.default);
145
+ } catch (error) {}
146
+
147
+ if (options.maxAgents) {
148
+ config.maxAgents = parseInt(options.maxAgents, 10);
149
+ }
150
+
151
+ const aiModel = {
152
+ generateText: async (params) => {
153
+ const { messages } = params;
154
+ const lastMessage = messages[messages.length - 1];
155
+ const fullPrompt = `${config.cliPersonality}\n\n${lastMessage.content}`;
156
+ const response = await callEmbedApi(fullPrompt, apiKey);
157
+ return { completion: [{ text: response }] };
158
+ }
159
+ };
160
+
161
+ await initializeDatabase();
162
+ const supervisor = new SupervisorAgent('Supervisor', 'Orchestrates the project', aiModel, apiKey, config);
163
+ await supervisor.run(project_description);
164
+ await orchestrator(config, apiKey, projectRoot, screen, logBox, agentStatusBox, statsBox, progressBar);
165
+ });
166
+
167
+ async function orchestrator(config, apiKey, projectRoot, screen, logBox, agentStatusBox, statsBox, progressBar) {
168
+ const db = getDb();
169
+ const scrumMaster = new ScrumAgent('Scrum Master', 'Manages the task backlog', null, apiKey, config);
170
+ const validator = new ValidatorAgent('Validator', 'Validates completed tasks', null, apiKey, config);
171
+
172
+ logBox.log('{bold}Orchestrator: Agent army, ATTENTION! MISSION START!{/bold}');
173
+
174
+ const piscina = new Piscina({
175
+ filename: path.resolve(projectRoot, 'src/agents/worker.js'),
176
+ minThreads: 1,
177
+ maxThreads: config.maxAgents
178
+ });
179
+
180
+ const activeTasks = new Map();
181
+ const validationQueue = [];
182
+
183
+ const updateAgentStatus = async () => {
184
+ let content = '{bold}ACTIVE OPERATORS:{/bold}\n';
185
+ let i = 1;
186
+ activeTasks.forEach((task) => {
187
+ const status = task.currentActivity || 'Initializing...';
188
+ // Truncate status if too long
189
+ const displayStatus = status.length > 40 ? status.substring(0, 37) + '...' : status;
190
+ content += `{yellow-fg}Operator ${i++}: ${displayStatus} | ${task.title}{/yellow-fg}\n`;
191
+ });
192
+ if (validationQueue.length > 0) {
193
+ content += '\n{bold}VALIDATION QUEUE:{/bold}\n';
194
+ validationQueue.forEach((item) => {
195
+ content += `{magenta-fg}Validator 1: CHECKING - ${item.task.title}{/magenta-fg}\n`;
196
+ });
197
+ }
198
+ agentStatusBox.setContent(content);
199
+
200
+ // Update Stats Box
201
+ const pendingCount = (await db.all('SELECT count(*) as count FROM tasks WHERE status = ?', 'pending'))[0].count;
202
+ const completedCount = (await db.all('SELECT count(*) as count FROM tasks WHERE status = ?', 'completed'))[0].count;
203
+ const totalCount = (await db.all('SELECT count(*) as count FROM tasks'))[0].count;
204
+
205
+ let statsContent = '';
206
+ statsContent += `{blue-fg}Operators Active: {/blue-fg}${activeTasks.size}/${config.maxAgents}\n`;
207
+ statsContent += `{blue-fg}Validators Active: {/blue-fg}${validationQueue.length > 0 ? 1 : 0}\n`;
208
+ statsContent += `{blue-fg}Tasks: {/blue-fg}${completedCount}/${totalCount} (${pendingCount} pending)\n`;
209
+ statsContent += `{blue-fg}Total Agents: {/blue-fg}${activeTasks.size + (validationQueue.length > 0 ? 1 : 0) + 1}\n`;
210
+ statsBox.setContent(statsContent);
211
+
212
+ screen.render();
213
+ };
214
+
215
+ const processTasks = async () => {
216
+ const totalTasks = (await db.all('SELECT * FROM tasks')).length;
217
+ let isProcessing = false;
218
+ let qaDone = false;
219
+
220
+ const scheduler = async () => {
221
+ if (isProcessing) return;
222
+ isProcessing = true;
223
+
224
+ try {
225
+ // Refresh counts
226
+ let currentTotalTasks = (await db.all('SELECT count(*) as count FROM tasks'))[0].count;
227
+ let completedTasksCount = (await db.all('SELECT count(*) as count FROM tasks WHERE status = ?', 'completed'))[0].count;
228
+ let failedTasksCount = (await db.all('SELECT count(*) as count FROM tasks WHERE status = ?', 'failed'))[0].count;
229
+
230
+ progressBar.filled = (completedTasksCount / currentTotalTasks) * 100;
231
+ await updateAgentStatus();
232
+
233
+ if (completedTasksCount + failedTasksCount >= currentTotalTasks) {
234
+ if (!qaDone) {
235
+ qaDone = true;
236
+ logBox.log('\n{magenta-fg}{bold}Phase 4: QA & Self-Healing...{/bold}{/magenta-fg}');
237
+ screen.render();
238
+
239
+ try {
240
+ const { exec } = await import('child_process');
241
+ const util = await import('util');
242
+ const execPromise = util.promisify(exec);
243
+
244
+ logBox.log('Running tests (npm test)...');
245
+ screen.render();
246
+ // Run tests with CI=true to avoid watch mode
247
+ await execPromise('npm test -- --watchAll=false', {
248
+ cwd: process.cwd(),
249
+ env: { ...process.env, CI: 'true' }
250
+ });
251
+ logBox.log('{green-fg}Tests Passed!{/green-fg}');
252
+
253
+ logBox.log('Running build (npm run build)...');
254
+ screen.render();
255
+ await execPromise('npm run build', { cwd: process.cwd() });
256
+ logBox.log('{green-fg}Build Successful!{/green-fg}');
257
+
258
+ } catch (error) {
259
+ const errorOutput = (error.stdout || '') + '\n' + (error.stderr || '') + '\n' + error.message;
260
+ logBox.log(`{red-fg}QA Failed! Generating fix task...{/red-fg}`);
261
+
262
+ // Truncate error if too massive, but keep tail
263
+ const lastErrors = errorOutput.slice(-2000);
264
+
265
+ await scrumMaster.addTask(
266
+ 'Fix QA Failure',
267
+ `The application failed validation.\nError Log:\n${lastErrors}\n\nAnalyze the error and fix the code.`,
268
+ []
269
+ );
270
+
271
+ qaDone = false; // Reset to allow re-testing after fix
272
+ screen.render();
273
+ return; // Continue scheduler loop to pick up new task
274
+ }
275
+ }
276
+
277
+ progressBar.filled = 100;
278
+ logBox.log('\n{blue-fg}{bold}MISSION COMPLETE! ALL TASKS PROCESSED & VERIFIED!{/bold}{/blue-fg}');
279
+ screen.render();
280
+ setTimeout(() => {
281
+ screen.destroy();
282
+ process.exit(0);
283
+ }, 3000);
284
+ return;
285
+ }
286
+
287
+ while (activeTasks.size < config.maxAgents) {
288
+ const nextTask = await scrumMaster.getNextTask();
289
+ if (!nextTask) break;
290
+
291
+ logBox.log(`{blue-fg}ScrumMaster: Dispatching task "${nextTask.title}" to Operator...{/blue-fg}`);
292
+ nextTask.currentActivity = 'Receiving instructions...'; // Init status
293
+ activeTasks.set(nextTask.id, nextTask);
294
+ await updateAgentStatus();
295
+
296
+ piscina.run({ task: nextTask, apiKey, config }).then(async (result) => {
297
+ activeTasks.delete(nextTask.id);
298
+ validationQueue.push(result);
299
+ await updateAgentStatus();
300
+ handleValidation();
301
+ }).catch(err => {
302
+ console.error(`CRITICAL ERROR in Worker for task "${nextTask.title}": ${err.message}`);
303
+ activeTasks.delete(nextTask.id);
304
+ updateAgentStatus();
305
+ });
306
+ }
307
+ } finally {
308
+ isProcessing = false;
309
+ }
310
+ };
311
+
312
+ // Run scheduler immediately and set a heartbeat
313
+ await scheduler();
314
+ setInterval(scheduler, 200);
315
+ };
316
+
317
+ const handleValidation = async () => {
318
+ if (validationQueue.length === 0) return;
319
+
320
+ const item = validationQueue.shift();
321
+
322
+ if (item.status !== 'completed') {
323
+ logBox.log(`{red-fg}Worker failed task "${item.task.title}": ${item.error || 'Unknown error'}. Re-queuing...{/red-fg}`);
324
+ await scrumMaster.requeueTask(item.task);
325
+ await updateAgentStatus();
326
+ return;
327
+ }
328
+
329
+ logBox.log(`{magenta-fg}Validator 1: Scrutinizing result for "${item.task.title}"...{/magenta-fg}`);
330
+ await updateAgentStatus();
331
+
332
+ const { isValid, error } = await validator.validate(item.task, item.testPath);
333
+
334
+ if (isValid) {
335
+ await scrumMaster.markTaskAsCompleted(item.task);
336
+ logBox.log(`{green-fg}Validator 1: Task "${item.task.title}" passes!{/green-fg}`);
337
+ } else {
338
+ await scrumMaster.requeueTask(item.task);
339
+ logBox.log(`{red-fg}Validator 1: REJECTED! Task "${item.task.title}" failed: ${error}. Retrying...{/red-fg}`);
340
+ }
341
+ await updateAgentStatus();
342
+ };
343
+
344
+ piscina.on('message', (msg) => {
345
+ if (msg && msg.type === 'log') {
346
+ if (msg.level === 'error') {
347
+ console.error(`[Worker] ${msg.message}`);
348
+ } else {
349
+ console.log(`[Worker] ${msg.message}`);
350
+ }
351
+ } else if (msg && msg.type === 'activity') {
352
+ const task = activeTasks.get(msg.taskId);
353
+ if (task) {
354
+ task.currentActivity = msg.action;
355
+ // We could call updateAgentStatus here, but it might be too frequent.
356
+ // The scheduler calls it every 200ms anyway.
357
+ // But for "live" feel, let's call it.
358
+ // Optimization: Debounce or throttle this if it flickers too much.
359
+ // For now, raw update.
360
+ updateAgentStatus();
361
+ }
362
+ }
363
+ });
364
+
365
+ await processTasks();
366
+ screen.key(['escape', 'q', 'C-c'], () => process.exit(0));
367
+ }
368
+
369
+ program.parse(process.argv);
@@ -0,0 +1,22 @@
1
+ // imlil.config.js
2
+ // This is the central configuration file for imlil.
3
+
4
+ export default {
5
+ // Mode can be 'yolo' or 'safe'.
6
+ // 'yolo' mode runs with more autonomy and may experiment more.
7
+ // 'safe' mode will be more cautious.
8
+ mode: 'yolo',
9
+
10
+ // The maximum number of agents to run concurrently.
11
+ // Go crazy, but be mindful of your API limits.
12
+ maxAgents: 20,
13
+
14
+ // The personality of the CLI.
15
+ // It's a system prompt that guides the AI's tone and style.
16
+ cliPersonality: `
17
+ You are a sick bro, a funny, over-motivated guru developer.
18
+ Your tone is enthusiastic, slightly chaotic, and always encouraging.
19
+ You use slang, jokes, and metaphors from the world of extreme sports, hacking, and gaming.
20
+ Your goal is to make the user feel like they're on an epic coding adventure.
21
+ `,
22
+ };
package/index.js ADDED
File without changes
package/jest.config.js ADDED
@@ -0,0 +1,5 @@
1
+ export default {
2
+ testEnvironment: 'node',
3
+ transform: {},
4
+ roots: ['<rootDir>/src'],
5
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "imlil",
3
+ "version": "1.0.1",
4
+ "description": "Your CTO in a box. One CLI. One API Key. Infinite Staff. Spawn a high-velocity, autonomous AI engineering team to build software in seconds.",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "imlil": "bin/cli.js"
9
+ },
10
+ "scripts": {
11
+ "test": "jest",
12
+ "lint": "eslint src/"
13
+ },
14
+ "keywords": [],
15
+ "author": "",
16
+ "license": "ISC",
17
+ "dependencies": {
18
+ "@embedapi/core": "^1.0.11",
19
+ "blessed": "^0.1.81",
20
+ "blessed-contrib": "^4.11.0",
21
+ "cli-progress": "^3.12.0",
22
+ "commander": "^12.0.0",
23
+ "dotenv": "^16.4.5",
24
+ "esprima": "^4.0.1",
25
+ "fast-glob": "^3.3.3",
26
+ "find-up": "^8.0.0",
27
+ "firebase-admin": "^12.2.0",
28
+ "inquirer": "^13.2.2",
29
+ "jscodeshift": "^17.3.0",
30
+ "piscina": "^5.1.4",
31
+ "recast": "^0.23.11",
32
+ "simple-git": "^3.30.0",
33
+ "sqlite": "^5.1.1",
34
+ "sqlite3": "^5.1.7",
35
+ "tree-sitter": "^0.25.0",
36
+ "tree-sitter-javascript": "^0.25.0",
37
+ "uuid": "^9.0.1"
38
+ },
39
+ "devDependencies": {
40
+ "eslint": "^8.57.1",
41
+ "eslint-config-airbnb-base": "^15.0.0",
42
+ "eslint-plugin-import": "^2.32.0",
43
+ "jest": "^30.2.0"
44
+ }
45
+ }
@@ -0,0 +1,5 @@
1
+ describe('imlil CLI', () => {
2
+ it('should be true', () => {
3
+ expect(true).toBe(true);
4
+ });
5
+ });