@djibrilm/lazy-review 0.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 (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +17 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  8. package/dist/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  9. package/dist/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  10. package/dist/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  11. package/dist/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  12. package/dist/client/assets/index-4oL_AGyI.css +1 -0
  13. package/dist/client/assets/index-CJtKCyBg.js +848 -0
  14. package/dist/client/favicon.png +0 -0
  15. package/dist/client/favicon.svg +1 -0
  16. package/dist/client/icons.svg +24 -0
  17. package/dist/client/index.html +17 -0
  18. package/dist/client/resources/images/logo.png +0 -0
  19. package/dist/client/resources/images/openai.png +0 -0
  20. package/dist/constants.d.ts +3 -0
  21. package/dist/constants.d.ts.map +1 -0
  22. package/dist/constants.js +3 -0
  23. package/dist/constants.js.map +1 -0
  24. package/dist/dev.d.ts +2 -0
  25. package/dist/dev.d.ts.map +1 -0
  26. package/dist/dev.js +10 -0
  27. package/dist/dev.js.map +1 -0
  28. package/dist/modules/ai-agent/agent-context-manager.d.ts +57 -0
  29. package/dist/modules/ai-agent/agent-context-manager.d.ts.map +1 -0
  30. package/dist/modules/ai-agent/agent-context-manager.js +159 -0
  31. package/dist/modules/ai-agent/agent-context-manager.js.map +1 -0
  32. package/dist/modules/ai-agent/ai-agent.module.d.ts +17 -0
  33. package/dist/modules/ai-agent/ai-agent.module.d.ts.map +1 -0
  34. package/dist/modules/ai-agent/ai-agent.module.js +24 -0
  35. package/dist/modules/ai-agent/ai-agent.module.js.map +1 -0
  36. package/dist/modules/ai-agent/ai-agent.utils.d.ts +10 -0
  37. package/dist/modules/ai-agent/ai-agent.utils.d.ts.map +1 -0
  38. package/dist/modules/ai-agent/ai-agent.utils.js +389 -0
  39. package/dist/modules/ai-agent/ai-agent.utils.js.map +1 -0
  40. package/dist/modules/ai-agent/base.agent.d.ts +26 -0
  41. package/dist/modules/ai-agent/base.agent.d.ts.map +1 -0
  42. package/dist/modules/ai-agent/base.agent.js +101 -0
  43. package/dist/modules/ai-agent/base.agent.js.map +1 -0
  44. package/dist/modules/ai-agent/chat.agent.d.ts +35 -0
  45. package/dist/modules/ai-agent/chat.agent.d.ts.map +1 -0
  46. package/dist/modules/ai-agent/chat.agent.js +590 -0
  47. package/dist/modules/ai-agent/chat.agent.js.map +1 -0
  48. package/dist/modules/ai-agent/code-base-indexer.agent.d.ts +13 -0
  49. package/dist/modules/ai-agent/code-base-indexer.agent.d.ts.map +1 -0
  50. package/dist/modules/ai-agent/code-base-indexer.agent.js +506 -0
  51. package/dist/modules/ai-agent/code-base-indexer.agent.js.map +1 -0
  52. package/dist/modules/ai-agent/codebase-scanner.d.ts +37 -0
  53. package/dist/modules/ai-agent/codebase-scanner.d.ts.map +1 -0
  54. package/dist/modules/ai-agent/codebase-scanner.js +260 -0
  55. package/dist/modules/ai-agent/codebase-scanner.js.map +1 -0
  56. package/dist/modules/ai-agent/model-loader.d.ts +7 -0
  57. package/dist/modules/ai-agent/model-loader.d.ts.map +1 -0
  58. package/dist/modules/ai-agent/model-loader.js +129 -0
  59. package/dist/modules/ai-agent/model-loader.js.map +1 -0
  60. package/dist/modules/ai-agent/orientation-loader.d.ts +2 -0
  61. package/dist/modules/ai-agent/orientation-loader.d.ts.map +1 -0
  62. package/dist/modules/ai-agent/orientation-loader.js +70 -0
  63. package/dist/modules/ai-agent/orientation-loader.js.map +1 -0
  64. package/dist/modules/ai-agent/pr-review-session.manager.d.ts +36 -0
  65. package/dist/modules/ai-agent/pr-review-session.manager.d.ts.map +1 -0
  66. package/dist/modules/ai-agent/pr-review-session.manager.js +106 -0
  67. package/dist/modules/ai-agent/pr-review-session.manager.js.map +1 -0
  68. package/dist/modules/ai-agent/pr-review.agent.d.ts +22 -0
  69. package/dist/modules/ai-agent/pr-review.agent.d.ts.map +1 -0
  70. package/dist/modules/ai-agent/pr-review.agent.js +269 -0
  71. package/dist/modules/ai-agent/pr-review.agent.js.map +1 -0
  72. package/dist/modules/ai-agent/research-loop.d.ts +3 -0
  73. package/dist/modules/ai-agent/research-loop.d.ts.map +1 -0
  74. package/dist/modules/ai-agent/research-loop.js +691 -0
  75. package/dist/modules/ai-agent/research-loop.js.map +1 -0
  76. package/dist/modules/ai-agent/review-pipeline/agent-loop.d.ts +36 -0
  77. package/dist/modules/ai-agent/review-pipeline/agent-loop.d.ts.map +1 -0
  78. package/dist/modules/ai-agent/review-pipeline/agent-loop.js +178 -0
  79. package/dist/modules/ai-agent/review-pipeline/agent-loop.js.map +1 -0
  80. package/dist/modules/ai-agent/review-pipeline/change-analyzer.d.ts +8 -0
  81. package/dist/modules/ai-agent/review-pipeline/change-analyzer.d.ts.map +1 -0
  82. package/dist/modules/ai-agent/review-pipeline/change-analyzer.js +93 -0
  83. package/dist/modules/ai-agent/review-pipeline/change-analyzer.js.map +1 -0
  84. package/dist/modules/ai-agent/review-pipeline/finding-ranker.d.ts +47 -0
  85. package/dist/modules/ai-agent/review-pipeline/finding-ranker.d.ts.map +1 -0
  86. package/dist/modules/ai-agent/review-pipeline/finding-ranker.js +91 -0
  87. package/dist/modules/ai-agent/review-pipeline/finding-ranker.js.map +1 -0
  88. package/dist/modules/ai-agent/review-pipeline/finding-verifier.d.ts +29 -0
  89. package/dist/modules/ai-agent/review-pipeline/finding-verifier.d.ts.map +1 -0
  90. package/dist/modules/ai-agent/review-pipeline/finding-verifier.js +130 -0
  91. package/dist/modules/ai-agent/review-pipeline/finding-verifier.js.map +1 -0
  92. package/dist/modules/ai-agent/review-pipeline/repository-explorer.d.ts +21 -0
  93. package/dist/modules/ai-agent/review-pipeline/repository-explorer.d.ts.map +1 -0
  94. package/dist/modules/ai-agent/review-pipeline/repository-explorer.js +247 -0
  95. package/dist/modules/ai-agent/review-pipeline/repository-explorer.js.map +1 -0
  96. package/dist/modules/ai-agent/review-pipeline/review-controller.d.ts +22 -0
  97. package/dist/modules/ai-agent/review-pipeline/review-controller.d.ts.map +1 -0
  98. package/dist/modules/ai-agent/review-pipeline/review-controller.js +102 -0
  99. package/dist/modules/ai-agent/review-pipeline/review-controller.js.map +1 -0
  100. package/dist/modules/ai-agent/review-pipeline/review-writer.d.ts +4 -0
  101. package/dist/modules/ai-agent/review-pipeline/review-writer.d.ts.map +1 -0
  102. package/dist/modules/ai-agent/review-pipeline/review-writer.js +52 -0
  103. package/dist/modules/ai-agent/review-pipeline/review-writer.js.map +1 -0
  104. package/dist/modules/ai-agent/review-pipeline/secret-scanner.d.ts +25 -0
  105. package/dist/modules/ai-agent/review-pipeline/secret-scanner.d.ts.map +1 -0
  106. package/dist/modules/ai-agent/review-pipeline/secret-scanner.js +159 -0
  107. package/dist/modules/ai-agent/review-pipeline/secret-scanner.js.map +1 -0
  108. package/dist/modules/ai-agent/review-pipeline/specialist-reviewer.d.ts +9 -0
  109. package/dist/modules/ai-agent/review-pipeline/specialist-reviewer.d.ts.map +1 -0
  110. package/dist/modules/ai-agent/review-pipeline/specialist-reviewer.js +114 -0
  111. package/dist/modules/ai-agent/review-pipeline/specialist-reviewer.js.map +1 -0
  112. package/dist/modules/ai-agent/review-pipeline/types.d.ts +53 -0
  113. package/dist/modules/ai-agent/review-pipeline/types.d.ts.map +1 -0
  114. package/dist/modules/ai-agent/review-pipeline/types.js +45 -0
  115. package/dist/modules/ai-agent/review-pipeline/types.js.map +1 -0
  116. package/dist/modules/ai-agent/tool-executor.d.ts +37 -0
  117. package/dist/modules/ai-agent/tool-executor.d.ts.map +1 -0
  118. package/dist/modules/ai-agent/tool-executor.js +199 -0
  119. package/dist/modules/ai-agent/tool-executor.js.map +1 -0
  120. package/dist/modules/ai-agent/tool-types.d.ts +72 -0
  121. package/dist/modules/ai-agent/tool-types.d.ts.map +1 -0
  122. package/dist/modules/ai-agent/tool-types.js +2 -0
  123. package/dist/modules/ai-agent/tool-types.js.map +1 -0
  124. package/dist/modules/ai-agent/tools/fs-tools.d.ts +54 -0
  125. package/dist/modules/ai-agent/tools/fs-tools.d.ts.map +1 -0
  126. package/dist/modules/ai-agent/tools/fs-tools.js +237 -0
  127. package/dist/modules/ai-agent/tools/fs-tools.js.map +1 -0
  128. package/dist/modules/ai-agent/tools/git-tools.d.ts +322 -0
  129. package/dist/modules/ai-agent/tools/git-tools.d.ts.map +1 -0
  130. package/dist/modules/ai-agent/tools/git-tools.js +557 -0
  131. package/dist/modules/ai-agent/tools/git-tools.js.map +1 -0
  132. package/dist/modules/ai-agent/tools/pr-chat-tools.d.ts +15 -0
  133. package/dist/modules/ai-agent/tools/pr-chat-tools.d.ts.map +1 -0
  134. package/dist/modules/ai-agent/tools/pr-chat-tools.js +232 -0
  135. package/dist/modules/ai-agent/tools/pr-chat-tools.js.map +1 -0
  136. package/dist/modules/database/database.module.d.ts +10 -0
  137. package/dist/modules/database/database.module.d.ts.map +1 -0
  138. package/dist/modules/database/database.module.js +36 -0
  139. package/dist/modules/database/database.module.js.map +1 -0
  140. package/dist/modules/database/vector-database.service.d.ts +27 -0
  141. package/dist/modules/database/vector-database.service.d.ts.map +1 -0
  142. package/dist/modules/database/vector-database.service.js +170 -0
  143. package/dist/modules/database/vector-database.service.js.map +1 -0
  144. package/dist/modules/github/github.module.d.ts +964 -0
  145. package/dist/modules/github/github.module.d.ts.map +1 -0
  146. package/dist/modules/github/github.module.js +316 -0
  147. package/dist/modules/github/github.module.js.map +1 -0
  148. package/dist/modules/main.module.d.ts +20 -0
  149. package/dist/modules/main.module.d.ts.map +1 -0
  150. package/dist/modules/main.module.js +59 -0
  151. package/dist/modules/main.module.js.map +1 -0
  152. package/dist/modules/qvac/qvac.module.d.ts +28 -0
  153. package/dist/modules/qvac/qvac.module.d.ts.map +1 -0
  154. package/dist/modules/qvac/qvac.module.js +146 -0
  155. package/dist/modules/qvac/qvac.module.js.map +1 -0
  156. package/dist/modules/server/dtos/create-project.dto.d.ts +9 -0
  157. package/dist/modules/server/dtos/create-project.dto.d.ts.map +1 -0
  158. package/dist/modules/server/dtos/create-project.dto.js +2 -0
  159. package/dist/modules/server/dtos/create-project.dto.js.map +1 -0
  160. package/dist/modules/server/entities/agent-task.entity.d.ts +16 -0
  161. package/dist/modules/server/entities/agent-task.entity.d.ts.map +1 -0
  162. package/dist/modules/server/entities/agent-task.entity.js +72 -0
  163. package/dist/modules/server/entities/agent-task.entity.js.map +1 -0
  164. package/dist/modules/server/entities/ai-provider.entity.d.ts +11 -0
  165. package/dist/modules/server/entities/ai-provider.entity.d.ts.map +1 -0
  166. package/dist/modules/server/entities/ai-provider.entity.js +47 -0
  167. package/dist/modules/server/entities/ai-provider.entity.js.map +1 -0
  168. package/dist/modules/server/entities/deployment-plan-approval.entity.d.ts +10 -0
  169. package/dist/modules/server/entities/deployment-plan-approval.entity.d.ts.map +1 -0
  170. package/dist/modules/server/entities/deployment-plan-approval.entity.js +42 -0
  171. package/dist/modules/server/entities/deployment-plan-approval.entity.js.map +1 -0
  172. package/dist/modules/server/entities/deployment-plan-artifact.entity.d.ts +10 -0
  173. package/dist/modules/server/entities/deployment-plan-artifact.entity.d.ts.map +1 -0
  174. package/dist/modules/server/entities/deployment-plan-artifact.entity.js +42 -0
  175. package/dist/modules/server/entities/deployment-plan-artifact.entity.js.map +1 -0
  176. package/dist/modules/server/entities/deployment-plan-feedback.entity.d.ts +9 -0
  177. package/dist/modules/server/entities/deployment-plan-feedback.entity.d.ts.map +1 -0
  178. package/dist/modules/server/entities/deployment-plan-feedback.entity.js +37 -0
  179. package/dist/modules/server/entities/deployment-plan-feedback.entity.js.map +1 -0
  180. package/dist/modules/server/entities/deployment-plan-revision.entity.d.ts +11 -0
  181. package/dist/modules/server/entities/deployment-plan-revision.entity.d.ts.map +1 -0
  182. package/dist/modules/server/entities/deployment-plan-revision.entity.js +47 -0
  183. package/dist/modules/server/entities/deployment-plan-revision.entity.js.map +1 -0
  184. package/dist/modules/server/entities/deployment-plan.entity.d.ts +13 -0
  185. package/dist/modules/server/entities/deployment-plan.entity.d.ts.map +1 -0
  186. package/dist/modules/server/entities/deployment-plan.entity.js +58 -0
  187. package/dist/modules/server/entities/deployment-plan.entity.js.map +1 -0
  188. package/dist/modules/server/entities/project.entity.d.ts +26 -0
  189. package/dist/modules/server/entities/project.entity.d.ts.map +1 -0
  190. package/dist/modules/server/entities/project.entity.js +122 -0
  191. package/dist/modules/server/entities/project.entity.js.map +1 -0
  192. package/dist/modules/server/entities/settings.entity.d.ts +12 -0
  193. package/dist/modules/server/entities/settings.entity.d.ts.map +1 -0
  194. package/dist/modules/server/entities/settings.entity.js +62 -0
  195. package/dist/modules/server/entities/settings.entity.js.map +1 -0
  196. package/dist/modules/server/entities/terminal-log.entity.d.ts +10 -0
  197. package/dist/modules/server/entities/terminal-log.entity.d.ts.map +1 -0
  198. package/dist/modules/server/entities/terminal-log.entity.js +42 -0
  199. package/dist/modules/server/entities/terminal-log.entity.js.map +1 -0
  200. package/dist/modules/server/middleware/auth.middleware.d.ts +8 -0
  201. package/dist/modules/server/middleware/auth.middleware.d.ts.map +1 -0
  202. package/dist/modules/server/middleware/auth.middleware.js +26 -0
  203. package/dist/modules/server/middleware/auth.middleware.js.map +1 -0
  204. package/dist/modules/server/routes/auth.routes.d.ts +13 -0
  205. package/dist/modules/server/routes/auth.routes.d.ts.map +1 -0
  206. package/dist/modules/server/routes/auth.routes.js +59 -0
  207. package/dist/modules/server/routes/auth.routes.js.map +1 -0
  208. package/dist/modules/server/routes/github.routes.d.ts +14 -0
  209. package/dist/modules/server/routes/github.routes.d.ts.map +1 -0
  210. package/dist/modules/server/routes/github.routes.js +124 -0
  211. package/dist/modules/server/routes/github.routes.js.map +1 -0
  212. package/dist/modules/server/routes/project.routes.d.ts +11 -0
  213. package/dist/modules/server/routes/project.routes.d.ts.map +1 -0
  214. package/dist/modules/server/routes/project.routes.js +78 -0
  215. package/dist/modules/server/routes/project.routes.js.map +1 -0
  216. package/dist/modules/server/routes/qvac.routes.d.ts +11 -0
  217. package/dist/modules/server/routes/qvac.routes.d.ts.map +1 -0
  218. package/dist/modules/server/routes/qvac.routes.js +24 -0
  219. package/dist/modules/server/routes/qvac.routes.js.map +1 -0
  220. package/dist/modules/server/routes/routes.d.ts +20 -0
  221. package/dist/modules/server/routes/routes.d.ts.map +1 -0
  222. package/dist/modules/server/routes/routes.js +35 -0
  223. package/dist/modules/server/routes/routes.js.map +1 -0
  224. package/dist/modules/server/routes/settings.controller.d.ts +14 -0
  225. package/dist/modules/server/routes/settings.controller.d.ts.map +1 -0
  226. package/dist/modules/server/routes/settings.controller.js +65 -0
  227. package/dist/modules/server/routes/settings.controller.js.map +1 -0
  228. package/dist/modules/server/server.module.d.ts +19 -0
  229. package/dist/modules/server/server.module.d.ts.map +1 -0
  230. package/dist/modules/server/server.module.js +63 -0
  231. package/dist/modules/server/server.module.js.map +1 -0
  232. package/dist/modules/server/services/auth.services.d.ts +19 -0
  233. package/dist/modules/server/services/auth.services.d.ts.map +1 -0
  234. package/dist/modules/server/services/auth.services.js +87 -0
  235. package/dist/modules/server/services/auth.services.js.map +1 -0
  236. package/dist/modules/server/services/deployment-plan.services.d.ts +6 -0
  237. package/dist/modules/server/services/deployment-plan.services.d.ts.map +1 -0
  238. package/dist/modules/server/services/deployment-plan.services.js +8 -0
  239. package/dist/modules/server/services/deployment-plan.services.js.map +1 -0
  240. package/dist/modules/server/services/github.services.d.ts +939 -0
  241. package/dist/modules/server/services/github.services.d.ts.map +1 -0
  242. package/dist/modules/server/services/github.services.js +46 -0
  243. package/dist/modules/server/services/github.services.js.map +1 -0
  244. package/dist/modules/server/services/project.services.d.ts +41 -0
  245. package/dist/modules/server/services/project.services.d.ts.map +1 -0
  246. package/dist/modules/server/services/project.services.js +360 -0
  247. package/dist/modules/server/services/project.services.js.map +1 -0
  248. package/dist/modules/server/services/qvac.services.d.ts +10 -0
  249. package/dist/modules/server/services/qvac.services.d.ts.map +1 -0
  250. package/dist/modules/server/services/qvac.services.js +58 -0
  251. package/dist/modules/server/services/qvac.services.js.map +1 -0
  252. package/dist/modules/server/services/settings.service.d.ts +60 -0
  253. package/dist/modules/server/services/settings.service.d.ts.map +1 -0
  254. package/dist/modules/server/services/settings.service.js +125 -0
  255. package/dist/modules/server/services/settings.service.js.map +1 -0
  256. package/dist/modules/socket-gateway/interfaces/project-creation-log.interface.d.ts +14 -0
  257. package/dist/modules/socket-gateway/interfaces/project-creation-log.interface.d.ts.map +1 -0
  258. package/dist/modules/socket-gateway/interfaces/project-creation-log.interface.js +2 -0
  259. package/dist/modules/socket-gateway/interfaces/project-creation-log.interface.js.map +1 -0
  260. package/dist/modules/socket-gateway/socket-gateway.module.d.ts +28 -0
  261. package/dist/modules/socket-gateway/socket-gateway.module.d.ts.map +1 -0
  262. package/dist/modules/socket-gateway/socket-gateway.module.js +92 -0
  263. package/dist/modules/socket-gateway/socket-gateway.module.js.map +1 -0
  264. package/package.json +95 -0
@@ -0,0 +1,260 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs/promises';
3
+ import { extractSymbolsWithAST } from './ai-agent.utils.js';
4
+ const IGNORED_DIRS = new Set([
5
+ 'node_modules',
6
+ '.git',
7
+ 'dist',
8
+ 'build',
9
+ '.next',
10
+ '.cache',
11
+ 'coverage',
12
+ '.pnpm',
13
+ ]);
14
+ const IGNORED_FILES = new Set([
15
+ 'pnpm-lock.yaml',
16
+ 'package-lock.json',
17
+ 'yarn.lock',
18
+ '.DS_Store',
19
+ 'prompt_dump.txt',
20
+ ]);
21
+ const SUPPORTED_EXTENSIONS = new Set([
22
+ '.ts',
23
+ '.tsx',
24
+ '.js',
25
+ '.jsx',
26
+ '.py',
27
+ '.rs',
28
+ '.go',
29
+ '.json',
30
+ '.yaml',
31
+ '.yml',
32
+ '.toml',
33
+ '.md',
34
+ '.sql',
35
+ '.graphql',
36
+ '.prisma',
37
+ '.env.example',
38
+ ]);
39
+ const ENTRY_POINT_CANDIDATES = new Set([
40
+ 'src/main.ts',
41
+ 'src/index.ts',
42
+ 'src/app.ts',
43
+ 'src/server.ts',
44
+ 'src/App.tsx',
45
+ 'main.ts',
46
+ 'index.ts',
47
+ 'app.ts',
48
+ 'server.ts',
49
+ 'main.js',
50
+ 'index.js',
51
+ 'src/main.js',
52
+ 'src/index.js',
53
+ 'src/server.js',
54
+ ]);
55
+ const CONFIG_CANDIDATES = [
56
+ 'package.json',
57
+ 'tsconfig.json',
58
+ 'vite.config.ts',
59
+ 'vite.config.js',
60
+ 'next.config.js',
61
+ 'next.config.ts',
62
+ 'docker-compose.yml',
63
+ 'docker-compose.yaml',
64
+ 'Dockerfile',
65
+ 'requirements.txt',
66
+ 'pyproject.toml',
67
+ 'Cargo.toml',
68
+ 'go.mod',
69
+ 'pom.xml',
70
+ 'build.gradle',
71
+ 'Gemfile',
72
+ '.env.example',
73
+ 'prisma/schema.prisma',
74
+ 'schema.graphql',
75
+ 'quasar.conf.js',
76
+ 'nuxt.config.ts',
77
+ 'tailwind.config.ts',
78
+ 'eslint.config.mjs',
79
+ '.prettierrc',
80
+ 'rebar.config',
81
+ 'mix.exs',
82
+ ];
83
+ export async function scanCodebase(absoluteRoot) {
84
+ const files = [];
85
+ let totalSymbols = 0;
86
+ let totalBytes = 0;
87
+ const entryPoints = [];
88
+ const entityFiles = [];
89
+ const routeFiles = [];
90
+ const configFiles = [];
91
+ const topLevelImports = new Map();
92
+ const walkDir = async (dir, relPath) => {
93
+ let entries;
94
+ try {
95
+ entries = await fs.readdir(dir, { withFileTypes: true });
96
+ }
97
+ catch {
98
+ return;
99
+ }
100
+ for (const entry of entries) {
101
+ if (entry.isDirectory()) {
102
+ if (!IGNORED_DIRS.has(entry.name)) {
103
+ await walkDir(path.join(dir, entry.name), path.posix.join(relPath, entry.name));
104
+ }
105
+ continue;
106
+ }
107
+ if (!entry.isFile() || IGNORED_FILES.has(entry.name))
108
+ continue;
109
+ const ext = path.extname(entry.name).toLowerCase();
110
+ if (!SUPPORTED_EXTENSIONS.has(ext))
111
+ continue;
112
+ const fullPath = path.join(dir, entry.name);
113
+ const relFilePath = path.posix.join(relPath, entry.name);
114
+ try {
115
+ const stat = await fs.stat(fullPath);
116
+ if (stat.size > 2 * 1024 * 1024)
117
+ continue;
118
+ totalBytes += stat.size;
119
+ const content = await fs.readFile(fullPath, 'utf-8');
120
+ const filePathLower = relFilePath.toLowerCase();
121
+ const isEntryPoint = ENTRY_POINT_CANDIDATES.has(relFilePath);
122
+ const isConfigFile = CONFIG_CANDIDATES.includes(relFilePath) ||
123
+ CONFIG_CANDIDATES.some((c) => relFilePath.endsWith(c));
124
+ const isEntity = filePathLower.includes('entity') ||
125
+ filePathLower.endsWith('.entity.ts') ||
126
+ filePathLower.endsWith('.entity.js') ||
127
+ filePathLower.endsWith('.model.ts') ||
128
+ filePathLower.endsWith('.model.js');
129
+ const isRoute = filePathLower.includes('route') ||
130
+ filePathLower.includes('routes') ||
131
+ filePathLower.includes('controller') ||
132
+ filePathLower.includes('endpoint');
133
+ let symbols = [];
134
+ const importMatches = content.match(/^import\s+[^;\n]+/gm) || [];
135
+ const requireMatches = content.match(/require\(['"][^'"]+['"]\)/g) || [];
136
+ const imports = [...importMatches, ...requireMatches];
137
+ const importNames = imports
138
+ .map((s) => {
139
+ const m = s.match(/from\s+['"]([^'"]+)['"]/);
140
+ if (m && m[1])
141
+ return m[1].split('/').pop() || m[1];
142
+ const r = s.match(/require\(['"]([^'"]+)['"]\)/);
143
+ if (r && r[1])
144
+ return r[1].split('/').pop() || r[1];
145
+ return '';
146
+ })
147
+ .filter((x) => Boolean(x));
148
+ for (const imp of importNames) {
149
+ if (imp && !imp.startsWith('.') && !imp.startsWith('/')) {
150
+ topLevelImports.set(imp, (topLevelImports.get(imp) || 0) + 1);
151
+ }
152
+ }
153
+ if (ext === '.ts' ||
154
+ ext === '.tsx' ||
155
+ ext === '.js' ||
156
+ ext === '.jsx' ||
157
+ ext === '.py' ||
158
+ ext === '.rs' ||
159
+ ext === '.go') {
160
+ try {
161
+ const astSymbols = await extractSymbolsWithAST(fullPath, content);
162
+ symbols = astSymbols.map((s) => {
163
+ const symbol = s.symbol || {};
164
+ return {
165
+ kind: symbol.kind || 'symbol',
166
+ name: symbol.name || 'anonymous',
167
+ startLine: symbol.startLine || 0,
168
+ endLine: symbol.endLine || 0,
169
+ parent: symbol.parent,
170
+ dependencies: s.dependencies || [],
171
+ content: (s.content || '').substring(0, 1000),
172
+ };
173
+ });
174
+ }
175
+ catch {
176
+ // AST parsing failed
177
+ }
178
+ }
179
+ totalSymbols += symbols.length;
180
+ if (isEntryPoint)
181
+ entryPoints.push(relFilePath);
182
+ if (isEntity)
183
+ entityFiles.push(relFilePath);
184
+ if (isRoute)
185
+ routeFiles.push(relFilePath);
186
+ if (isConfigFile)
187
+ configFiles.push(relFilePath);
188
+ const exportMatches = content.match(/^export\s+(?:default\s+)?(?:class|function|const|let|var|interface|type|enum)\s+(\w+)/gm) || [];
189
+ files.push({
190
+ filePath: relFilePath,
191
+ language: ext.substring(1),
192
+ sizeBytes: stat.size,
193
+ symbols,
194
+ imports: importNames.length > 10 ? importNames.slice(0, 10) : importNames,
195
+ exports: exportMatches
196
+ .map((m) => {
197
+ const match = m.match(/(\w+)\s*$/);
198
+ return match ? match[1] : '';
199
+ })
200
+ .filter((x) => Boolean(x)),
201
+ isConfigFile,
202
+ isEntryPoint,
203
+ isEntity,
204
+ isRoute,
205
+ contentChunks: [],
206
+ dependencyNames: symbols.flatMap((s) => s.dependencies).slice(0, 20),
207
+ });
208
+ }
209
+ catch {
210
+ // Skip unreadable files
211
+ }
212
+ }
213
+ };
214
+ const dirCounts = new Map();
215
+ const collectDirs = async (dir, relPath) => {
216
+ let entries;
217
+ try {
218
+ entries = await fs.readdir(dir, { withFileTypes: true });
219
+ }
220
+ catch {
221
+ return;
222
+ }
223
+ for (const entry of entries) {
224
+ if (entry.isDirectory() && !IGNORED_DIRS.has(entry.name)) {
225
+ const childRel = relPath === '' ? entry.name : `${relPath}/${entry.name}`;
226
+ const fileExts = new Set();
227
+ const subEntries = await fs
228
+ .readdir(path.join(dir, entry.name), { withFileTypes: true })
229
+ .catch(() => []);
230
+ for (const sub of subEntries) {
231
+ if (sub.isFile()) {
232
+ const ext = path.extname(sub.name).toLowerCase();
233
+ if (SUPPORTED_EXTENSIONS.has(ext))
234
+ fileExts.add(ext.substring(1));
235
+ }
236
+ }
237
+ dirCounts.set(childRel, fileExts.size);
238
+ await collectDirs(path.join(dir, entry.name), childRel);
239
+ }
240
+ }
241
+ };
242
+ await walkDir(absoluteRoot, '');
243
+ await collectDirs(absoluteRoot, '');
244
+ const directorySummary = Array.from(dirCounts.entries())
245
+ .map(([dir, count]) => `📁 ${dir}/ (${count} file types)`)
246
+ .join('\n');
247
+ return {
248
+ files,
249
+ totalFiles: files.length,
250
+ totalSymbols,
251
+ totalBytes,
252
+ entryPoints,
253
+ entityFiles,
254
+ routeFiles,
255
+ configFiles,
256
+ topLevelImports,
257
+ directorySummary,
258
+ };
259
+ }
260
+ //# sourceMappingURL=codebase-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-scanner.js","sourceRoot":"","sources":["../../../src/modules/ai-agent/codebase-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { MainModule } from '../main.module.js';
2
+ export declare let currentDeviceConfig: string | null;
3
+ export declare function loadAIModels(mainModule: MainModule, activeRequestIds: Set<string>): Promise<{
4
+ llmModelId: string;
5
+ embeddingModelId: string;
6
+ }>;
7
+ //# sourceMappingURL=model-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-loader.d.ts","sourceRoot":"","sources":["../../../src/modules/ai-agent/model-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAYpD,eAAO,IAAI,mBAAmB,EAAE,MAAM,GAAG,IAAW,CAAC;AA6BrD,wBAAsB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC;gBAtCtD,MAAM;sBAAoB,MAAM;GAsDjE"}
@@ -0,0 +1,129 @@
1
+ import { getModelInfo, loadModel } from '@qvac/sdk';
2
+ import * as qvacModels from '@qvac/sdk';
3
+ import { LLM_MODEL_ID, EMBEDDING_MODEL_ID } from '../../constants.js';
4
+ import SettingsEntity from '../server/entities/settings.entity.js';
5
+ /** Cache loaded model IDs to avoid re-loading on every indexing run */
6
+ let cachedModelIds = null;
7
+ /**
8
+ * In-flight load promise. When boot preload, indexing, and a review page race
9
+ * on their first request, they share ONE load instead of each issuing a
10
+ * redundant `loadModel` for the same 6GB+ model (which would double the wait
11
+ * and the GPU/memory pressure).
12
+ */
13
+ let inFlightLoadPromise = null;
14
+ export let currentDeviceConfig = null;
15
+ /**
16
+ * Forwards QVAC model-load progress (weights → memory) to the socket so the
17
+ * review/chat pages can show a live message instead of an eternal spinner.
18
+ * Tolerates missing sockets and unknown progress shapes.
19
+ */
20
+ function emitModelLoadProgress(mainModule, label, progress) {
21
+ if (!mainModule.socket)
22
+ return;
23
+ const pct = progress?.percentage ??
24
+ (progress?.progress != null ? Math.round(progress.progress * 100) : undefined);
25
+ const message = progress?.message ||
26
+ (pct != null ? `Loading ${label}… ${pct}%` : `Loading ${label} into memory…`);
27
+ try {
28
+ mainModule.socket.emitModelProgress({ message });
29
+ }
30
+ catch {
31
+ // Never let progress reporting break the load itself.
32
+ }
33
+ }
34
+ export async function loadAIModels(mainModule, activeRequestIds) {
35
+ // Return cached IDs if available - loading models is expensive
36
+ if (cachedModelIds) {
37
+ return cachedModelIds;
38
+ }
39
+ // Dedupe concurrent first loads (boot preload + indexing + review page).
40
+ if (inFlightLoadPromise) {
41
+ return inFlightLoadPromise;
42
+ }
43
+ inFlightLoadPromise = doLoadAIModels(mainModule, activeRequestIds).finally(() => {
44
+ inFlightLoadPromise = null;
45
+ });
46
+ return inFlightLoadPromise;
47
+ }
48
+ async function doLoadAIModels(mainModule, activeRequestIds) {
49
+ const LLM_CTX_SIZE = 128000;
50
+ let llmLoadedId = qvacModels[LLM_MODEL_ID]?.modelId ?? LLM_MODEL_ID;
51
+ let embeddingLoadedId = qvacModels[EMBEDDING_MODEL_ID]?.modelId ?? EMBEDDING_MODEL_ID;
52
+ const qvacLlm = qvacModels[LLM_MODEL_ID];
53
+ const qvacEmbedding = qvacModels[EMBEDDING_MODEL_ID];
54
+ const settingsRepo = mainModule.database.appDataSource.getRepository(SettingsEntity);
55
+ let settings = await settingsRepo.findOneBy({ id: 1 });
56
+ if (!settings) {
57
+ settings = settingsRepo.create({ id: 1, useExperimentalGpu: true });
58
+ await settingsRepo.save(settings);
59
+ }
60
+ const useGpu = Boolean(settings.useExperimentalGpu);
61
+ const deviceConfig = useGpu ? undefined : 'cpu';
62
+ currentDeviceConfig = useGpu ? 'GPU' : 'CPU';
63
+ console.log(`Using device: ${useGpu ? 'gpu (Metal/CUDA)' : 'cpu'} (useExperimentalGpu=${useGpu})`);
64
+ const loadGemma4 = async () => {
65
+ if (qvacLlm) {
66
+ let loadPromise;
67
+ try {
68
+ loadPromise = loadModel({
69
+ modelSrc: qvacLlm,
70
+ modelConfig: {
71
+ ctx_size: LLM_CTX_SIZE,
72
+ ...(deviceConfig ? { device: deviceConfig } : {}),
73
+ },
74
+ onProgress: (progress) => emitModelLoadProgress(mainModule, 'Gemma', progress),
75
+ });
76
+ activeRequestIds.add(loadPromise.requestId);
77
+ llmLoadedId = await loadPromise;
78
+ }
79
+ catch (e) {
80
+ if (e?.code !== 52200)
81
+ throw e;
82
+ const info = await getModelInfo(qvacLlm);
83
+ if (info.loadedInstances && info.loadedInstances.length > 0) {
84
+ llmLoadedId = info.loadedInstances[0].registryId;
85
+ }
86
+ else {
87
+ llmLoadedId = qvacLlm.modelId;
88
+ }
89
+ }
90
+ finally {
91
+ if (loadPromise)
92
+ activeRequestIds.delete(loadPromise.requestId);
93
+ }
94
+ }
95
+ };
96
+ const loadGte = async () => {
97
+ if (qvacEmbedding) {
98
+ let loadPromise;
99
+ try {
100
+ loadPromise = loadModel({
101
+ modelSrc: qvacEmbedding,
102
+ modelConfig: { ...(deviceConfig ? { device: deviceConfig } : {}) },
103
+ onProgress: (progress) => emitModelLoadProgress(mainModule, 'Embedding model', progress),
104
+ });
105
+ activeRequestIds.add(loadPromise.requestId);
106
+ embeddingLoadedId = await loadPromise;
107
+ }
108
+ catch (e) {
109
+ if (e?.code !== 52200)
110
+ throw e;
111
+ const info = await getModelInfo(qvacEmbedding);
112
+ if (info.loadedInstances && info.loadedInstances.length > 0) {
113
+ embeddingLoadedId = info.loadedInstances[0].registryId;
114
+ }
115
+ else {
116
+ embeddingLoadedId = qvacEmbedding.modelId;
117
+ }
118
+ }
119
+ finally {
120
+ if (loadPromise)
121
+ activeRequestIds.delete(loadPromise.requestId);
122
+ }
123
+ }
124
+ };
125
+ await Promise.all([loadGemma4(), loadGte()]);
126
+ cachedModelIds = { llmModelId: llmLoadedId, embeddingModelId: embeddingLoadedId };
127
+ return cachedModelIds;
128
+ }
129
+ //# sourceMappingURL=model-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-loader.js","sourceRoot":"","sources":["../../../src/modules/ai-agent/model-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function preLoadOrientationFiles(absoluteRoot: string, indexingVersion: number, progress: (msg: string) => void, embedAndSaveFact: (content: string, filePath: string, metadata?: any) => any): Promise<string[]>;
2
+ //# sourceMappingURL=orientation-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orientation-loader.d.ts","sourceRoot":"","sources":["../../../src/modules/ai-agent/orientation-loader.ts"],"names":[],"mappings":"AAGA,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAC/B,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,KAAK,GAAG,GAC3E,OAAO,CAAC,MAAM,EAAE,CAAC,CAwEnB"}
@@ -0,0 +1,70 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs/promises';
3
+ export async function preLoadOrientationFiles(absoluteRoot, indexingVersion, progress, embedAndSaveFact) {
4
+ progress('📖 Identifying orientation files (README, package.json, entry points)...');
5
+ const orientationFileContents = [];
6
+ try {
7
+ const resolvedPath = path.join(absoluteRoot, 'README.md');
8
+ const stat = await fs.stat(resolvedPath);
9
+ if (stat.isFile()) {
10
+ progress('📄 Pre-loading: README.md');
11
+ const readmeContent = await fs.readFile(resolvedPath, 'utf-8');
12
+ const truncatedReadme = readmeContent.length > 2500
13
+ ? readmeContent.substring(0, 2500) + '\n...[TRUNCATED FOR BREVITY]...'
14
+ : readmeContent;
15
+ orientationFileContents.push(`\n--- README.md ---\n${truncatedReadme}`);
16
+ embedAndSaveFact(readmeContent, 'README.md', {
17
+ source: 'orientation_file',
18
+ version: indexingVersion,
19
+ });
20
+ }
21
+ }
22
+ catch {
23
+ // ignore if README doesn't exist
24
+ }
25
+ const autoReadCandidates = [
26
+ 'package.json',
27
+ 'requirements.txt',
28
+ 'Pipfile',
29
+ 'setup.py',
30
+ 'pom.xml',
31
+ 'build.gradle',
32
+ 'Gemfile',
33
+ 'prisma/schema.prisma',
34
+ 'schema.graphql',
35
+ 'docker-compose.yml',
36
+ 'pyproject.toml',
37
+ 'Cargo.toml',
38
+ 'go.mod',
39
+ '.env.example',
40
+ 'src/main.ts',
41
+ 'src/index.ts',
42
+ 'src/app.ts',
43
+ 'src/server.ts',
44
+ 'src/App.tsx',
45
+ ];
46
+ const readCandidate = async (candidate) => {
47
+ try {
48
+ const resolved = path.join(absoluteRoot, candidate);
49
+ const stat = await fs.stat(resolved);
50
+ if (stat.isFile() && stat.size < 80 * 1024) {
51
+ progress(`📄 Pre-loading: ${candidate}`);
52
+ const content = await fs.readFile(resolved, 'utf-8');
53
+ const truncated = content.length > 2500
54
+ ? content.substring(0, 2500) + '\n...[TRUNCATED FOR BREVITY]...'
55
+ : content;
56
+ orientationFileContents.push(`\n--- ${candidate} ---\n${truncated}`);
57
+ embedAndSaveFact(content, candidate, {
58
+ source: 'orientation_file',
59
+ version: indexingVersion,
60
+ });
61
+ }
62
+ }
63
+ catch {
64
+ // ignore if file doesn't exist
65
+ }
66
+ };
67
+ await Promise.allSettled(autoReadCandidates.map((c) => readCandidate(c)));
68
+ return orientationFileContents;
69
+ }
70
+ //# sourceMappingURL=orientation-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orientation-loader.js","sourceRoot":"","sources":["../../../src/modules/ai-agent/orientation-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAAoB,EACpB,eAAuB,EACvB,QAA+B,EAC/B,gBAA4E;IAE5E,QAAQ,CAAC,0EAA0E,CAAC,CAAC;IACrF,MAAM,uBAAuB,GAAa,EAAE,CAAC;IAE7C,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,QAAQ,CAAC,2BAA2B,CAAC,CAAC;YACtC,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAC/D,MAAM,eAAe,GACnB,aAAa,CAAC,MAAM,GAAG,IAAI;gBACzB,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,iCAAiC;gBACtE,CAAC,CAAC,aAAa,CAAC;YAEpB,uBAAuB,CAAC,IAAI,CAAC,wBAAwB,eAAe,EAAE,CAAC,CAAC;YACxE,gBAAgB,CAAC,aAAa,EAAE,WAAW,EAAE;gBAC3C,MAAM,EAAE,kBAAkB;gBAC1B,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;IAED,MAAM,kBAAkB,GAAG;QACzB,cAAc;QACd,kBAAkB;QAClB,SAAS;QACT,UAAU;QACV,SAAS;QACT,cAAc;QACd,SAAS;QACT,sBAAsB;QACtB,gBAAgB;QAChB,oBAAoB;QACpB,gBAAgB;QAChB,YAAY;QACZ,QAAQ;QACR,cAAc;QACd,aAAa;QACb,cAAc;QACd,YAAY;QACZ,eAAe;QACf,aAAa;KACd,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;gBAC3C,QAAQ,CAAC,mBAAmB,SAAS,EAAE,CAAC,CAAC;gBACzC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACrD,MAAM,SAAS,GACb,OAAO,CAAC,MAAM,GAAG,IAAI;oBACnB,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,iCAAiC;oBAChE,CAAC,CAAC,OAAO,CAAC;gBAEd,uBAAuB,CAAC,IAAI,CAAC,SAAS,SAAS,SAAS,SAAS,EAAE,CAAC,CAAC;gBACrE,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE;oBACnC,MAAM,EAAE,kBAAkB;oBAC1B,OAAO,EAAE,eAAe;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,uBAAuB,CAAC;AACjC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { MainModule } from '../main.module.js';
2
+ import { createGitTools } from './tools/git-tools.js';
3
+ import { createFsTools } from './tools/fs-tools.js';
4
+ export type ParsedDiffFile = {
5
+ file: string;
6
+ diff: string;
7
+ };
8
+ export interface PRReviewSession {
9
+ projectId: string;
10
+ pullNumber: number;
11
+ prDiff: string;
12
+ parsedDiffFiles: ParsedDiffFile[];
13
+ changedFiles: string[];
14
+ llmId: string;
15
+ embeddingId: string;
16
+ gitTools: ReturnType<typeof createGitTools>;
17
+ fsTools: ReturnType<typeof createFsTools>;
18
+ projectOverview: string;
19
+ lastActivityAt: number;
20
+ }
21
+ export declare class PRReviewSessionManager {
22
+ private mainModule;
23
+ private sessions;
24
+ private cleanupInterval;
25
+ private modelAgent;
26
+ constructor(mainModule: MainModule);
27
+ private sessionKey;
28
+ startSession(projectId: string, pullNumber: number, prDiff: string, onProgress?: (message: string) => void): Promise<PRReviewSession>;
29
+ getSession(projectId: string, pullNumber: number): PRReviewSession | undefined;
30
+ stopSession(projectId: string, pullNumber: number): boolean;
31
+ hasSession(projectId: string, pullNumber: number): boolean;
32
+ destroy(): void;
33
+ private emitProgress;
34
+ private cleanupIdleSessions;
35
+ }
36
+ //# sourceMappingURL=pr-review-session.manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-review-session.manager.d.ts","sourceRoot":"","sources":["../../../src/modules/ai-agent/pr-review-session.manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMpD,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC5C,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,sBAAsB;IAKrB,OAAO,CAAC,UAAU;IAJ9B,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,eAAe,CAAiC;IACxD,OAAO,CAAC,UAAU,CAAgB;gBAEd,UAAU,EAAE,UAAU;IAK1C,OAAO,CAAC,UAAU;IAIZ,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACrC,OAAO,CAAC,eAAe,CAAC;IAgE3B,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAQ9E,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAI3D,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAI1D,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,mBAAmB;CAY5B"}
@@ -0,0 +1,106 @@
1
+ import ProjectEntity from '../server/entities/project.entity.js';
2
+ import { parseDiff, createProjectManifestSummary } from './ai-agent.utils.js';
3
+ import { createGitTools } from './tools/git-tools.js';
4
+ import { createFsTools } from './tools/fs-tools.js';
5
+ import { PrReviewAgent } from './pr-review.agent.js';
6
+ const IDLE_SESSION_MS = 30 * 60 * 1000;
7
+ const CLEANUP_INTERVAL_MS = 5 * 60 * 1000;
8
+ export class PRReviewSessionManager {
9
+ mainModule;
10
+ sessions = new Map();
11
+ cleanupInterval;
12
+ modelAgent;
13
+ constructor(mainModule) {
14
+ this.mainModule = mainModule;
15
+ this.modelAgent = new PrReviewAgent(mainModule);
16
+ this.cleanupInterval = setInterval(() => this.cleanupIdleSessions(), CLEANUP_INTERVAL_MS);
17
+ }
18
+ sessionKey(projectId, pullNumber) {
19
+ return `${projectId}:${pullNumber}`;
20
+ }
21
+ async startSession(projectId, pullNumber, prDiff, onProgress) {
22
+ const key = this.sessionKey(projectId, pullNumber);
23
+ const existing = this.sessions.get(key);
24
+ if (existing) {
25
+ existing.lastActivityAt = Date.now();
26
+ existing.prDiff = prDiff;
27
+ existing.parsedDiffFiles = prDiff ? parseDiff(prDiff) : [];
28
+ existing.changedFiles = existing.parsedDiffFiles.map((file) => file.file);
29
+ onProgress?.('Reusing active session…');
30
+ this.emitProgress(projectId, pullNumber, 'Reusing active session…');
31
+ return existing;
32
+ }
33
+ const progress = (message) => {
34
+ onProgress?.(message);
35
+ this.emitProgress(projectId, pullNumber, message);
36
+ };
37
+ progress('Loading AI models…');
38
+ const { llmId, embeddingId } = await this.modelAgent.loadModelsWithIds();
39
+ progress('Parsing pull request diff…');
40
+ const parsedDiffFiles = prDiff ? parseDiff(prDiff) : [];
41
+ const changedFiles = parsedDiffFiles.map((file) => file.file);
42
+ progress('Loading project metadata…');
43
+ const project = await ProjectEntity.findOneBy({ id: projectId });
44
+ if (!project) {
45
+ throw new Error(`Project ${projectId} not found.`);
46
+ }
47
+ if (!project.repository_path) {
48
+ throw new Error(`Project repository path not set.`);
49
+ }
50
+ progress('Initializing repository tools…');
51
+ const gitTools = createGitTools(project.repository_path);
52
+ const fsTools = createFsTools(project.repository_path);
53
+ progress('Loading codebase facts…');
54
+ const projectOverview = project.analysis
55
+ ? createProjectManifestSummary(project.analysis)
56
+ : 'No project overview available.';
57
+ const session = {
58
+ projectId,
59
+ pullNumber,
60
+ prDiff,
61
+ parsedDiffFiles,
62
+ changedFiles,
63
+ llmId,
64
+ embeddingId,
65
+ gitTools,
66
+ fsTools,
67
+ projectOverview,
68
+ lastActivityAt: Date.now(),
69
+ };
70
+ this.sessions.set(key, session);
71
+ progress('Session ready.');
72
+ return session;
73
+ }
74
+ getSession(projectId, pullNumber) {
75
+ const session = this.sessions.get(this.sessionKey(projectId, pullNumber));
76
+ if (session) {
77
+ session.lastActivityAt = Date.now();
78
+ }
79
+ return session;
80
+ }
81
+ stopSession(projectId, pullNumber) {
82
+ return this.sessions.delete(this.sessionKey(projectId, pullNumber));
83
+ }
84
+ hasSession(projectId, pullNumber) {
85
+ return this.sessions.has(this.sessionKey(projectId, pullNumber));
86
+ }
87
+ destroy() {
88
+ clearInterval(this.cleanupInterval);
89
+ this.sessions.clear();
90
+ }
91
+ emitProgress(projectId, pullNumber, message) {
92
+ if (this.mainModule.socket) {
93
+ this.mainModule.socket.emitModelProgress({ projectId, pullNumber, message });
94
+ }
95
+ }
96
+ cleanupIdleSessions() {
97
+ const now = Date.now();
98
+ for (const [key, session] of this.sessions.entries()) {
99
+ if (now - session.lastActivityAt > IDLE_SESSION_MS) {
100
+ this.sessions.delete(key);
101
+ console.log(`[PRReviewSessionManager] Cleaned up idle session for ${session.projectId} PR #${session.pullNumber}`);
102
+ }
103
+ }
104
+ }
105
+ }
106
+ //# sourceMappingURL=pr-review-session.manager.js.map