ai-first-cli 1.3.1 → 1.3.6

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 (514) hide show
  1. package/.ai-dev/index.db +0 -0
  2. package/CHANGELOG.md +241 -0
  3. package/PHASE1_USER_SIMULATION.md +56 -0
  4. package/PHASE2_USER_SIMULATION.md +81 -0
  5. package/PHASE3_USER_SIMULATION.md +176 -0
  6. package/README.es.md +73 -0
  7. package/README.md +119 -15
  8. package/ai/graph/knowledge-graph.json +10 -0
  9. package/ai-context/ai_context.md +130 -0
  10. package/{test-projects/react-app/.ai-dev → ai-context}/ai_rules.md +10 -5
  11. package/ai-context/architecture.md +136 -0
  12. package/ai-context/context/features/src.json +69 -0
  13. package/ai-context/context/features/test-projects.json +69 -0
  14. package/ai-context/context/flows/ai-first.json +9 -0
  15. package/ai-context/context/flows/auth.json +13 -0
  16. package/ai-context/context/flows/doctor.json +9 -0
  17. package/ai-context/context/flows/explore.json +9 -0
  18. package/ai-context/context/flows/routes.json +15 -0
  19. package/ai-context/context/flows/user.json +23 -0
  20. package/ai-context/context/flows/views.json +12 -0
  21. package/{test-projects/react-app/.ai-dev → ai-context}/conventions.md +3 -2
  22. package/ai-context/dependencies.json +3360 -0
  23. package/ai-context/entrypoints.md +45 -0
  24. package/ai-context/index-state.json +196 -0
  25. package/ai-context/modules.json +901 -0
  26. package/ai-context/project.json +33 -0
  27. package/ai-context/repo_map.json +8857 -0
  28. package/ai-context/repo_map.md +2002 -0
  29. package/{test-projects/flask-app/.ai-dev → ai-context}/schema.json +1 -1
  30. package/ai-context/summary.md +46 -0
  31. package/ai-context/symbols.json +82467 -0
  32. package/{test-projects/react-app/.ai-dev → ai-context}/tech_stack.md +15 -7
  33. package/ai-context-evaluation-report-1774223059505.md +206 -0
  34. package/dist/analyzers/architecture.d.ts.map +1 -1
  35. package/dist/analyzers/architecture.js +78 -5
  36. package/dist/analyzers/architecture.js.map +1 -1
  37. package/dist/analyzers/entrypoints.d.ts.map +1 -1
  38. package/dist/analyzers/entrypoints.js +358 -0
  39. package/dist/analyzers/entrypoints.js.map +1 -1
  40. package/dist/analyzers/symbols.d.ts.map +1 -1
  41. package/dist/analyzers/symbols.js +119 -3
  42. package/dist/analyzers/symbols.js.map +1 -1
  43. package/dist/analyzers/techStack.d.ts +8 -0
  44. package/dist/analyzers/techStack.d.ts.map +1 -1
  45. package/dist/analyzers/techStack.js +118 -0
  46. package/dist/analyzers/techStack.js.map +1 -1
  47. package/dist/utils/fileUtils.d.ts.map +1 -1
  48. package/dist/utils/fileUtils.js +5 -0
  49. package/dist/utils/fileUtils.js.map +1 -1
  50. package/package.json +1 -1
  51. package/scripts/ai-context-evaluator.ts +440 -0
  52. package/src/analyzers/architecture.ts +83 -6
  53. package/src/analyzers/entrypoints.ts +400 -0
  54. package/src/analyzers/symbols.ts +129 -3
  55. package/src/analyzers/techStack.ts +137 -0
  56. package/src/utils/fileUtils.ts +5 -0
  57. package/tests/apex-parser.test.ts +193 -0
  58. package/tests/cli-commands-batch1.test.ts +808 -0
  59. package/tests/cli-commands-batch2.test.ts +1113 -0
  60. package/tests/cli-commands-batch3.test.ts +1128 -0
  61. package/tests/cli-index.test.ts +1007 -0
  62. package/tests/cli-init.test.ts +761 -0
  63. package/tests/entrypoints-languages.test.ts +373 -0
  64. package/tests/framework-detection.test.ts +296 -0
  65. package/tests/salesforce-apex-classes.test.ts +713 -0
  66. package/tests/salesforce-apex-triggers.test.ts +871 -0
  67. package/tests/salesforce-custom-objects.test.ts +918 -0
  68. package/tests/salesforce-flows.test.ts +710 -0
  69. package/tests/salesforce-lwc.test.ts +963 -0
  70. package/tests/salesforce-sfdx-integration.test.ts +1125 -0
  71. package/ANALISIS_COMPLETO.md +0 -424
  72. package/ANALISIS_MEJORAS.md +0 -327
  73. package/CONTRIBUTING.md +0 -89
  74. package/FLOW.md +0 -129
  75. package/TEST_RESULTS.md +0 -198
  76. package/TEST_RESULTS_COMPARATIVE.md +0 -159
  77. package/TEST_RESULTS_COMPLETE.md +0 -127
  78. package/TEST_RESULTS_COMPREHENSIVE.md +0 -208
  79. package/install.sh +0 -188
  80. package/run-all-tests.sh +0 -184
  81. package/test-ai-context-understanding.sh +0 -21
  82. package/test-projects/django-app/.ai-dev/ai_context.md +0 -92
  83. package/test-projects/django-app/.ai-dev/ai_rules.md +0 -47
  84. package/test-projects/django-app/.ai-dev/architecture.md +0 -57
  85. package/test-projects/django-app/.ai-dev/cache.json +0 -169
  86. package/test-projects/django-app/.ai-dev/context/flows/views.json +0 -10
  87. package/test-projects/django-app/.ai-dev/conventions.md +0 -51
  88. package/test-projects/django-app/.ai-dev/dependencies.json +0 -312
  89. package/test-projects/django-app/.ai-dev/entrypoints.md +0 -4
  90. package/test-projects/django-app/.ai-dev/files.json +0 -209
  91. package/test-projects/django-app/.ai-dev/graph/knowledge-graph.json +0 -36
  92. package/test-projects/django-app/.ai-dev/graph/module-graph.json +0 -145
  93. package/test-projects/django-app/.ai-dev/graph/symbol-graph.json +0 -1488
  94. package/test-projects/django-app/.ai-dev/graph/symbol-references.json +0 -1
  95. package/test-projects/django-app/.ai-dev/index-state.json +0 -294
  96. package/test-projects/django-app/.ai-dev/modules.json +0 -35
  97. package/test-projects/django-app/.ai-dev/project.json +0 -11
  98. package/test-projects/django-app/.ai-dev/repo_map.json +0 -412
  99. package/test-projects/django-app/.ai-dev/repo_map.md +0 -105
  100. package/test-projects/django-app/.ai-dev/schema.json +0 -5
  101. package/test-projects/django-app/.ai-dev/summary.md +0 -15
  102. package/test-projects/django-app/.ai-dev/symbols.json +0 -1
  103. package/test-projects/django-app/.ai-dev/tech_stack.md +0 -32
  104. package/test-projects/django-app/README.md +0 -91
  105. package/test-projects/django-app/blog/__init__.py +0 -0
  106. package/test-projects/django-app/blog/admin.py +0 -31
  107. package/test-projects/django-app/blog/models.py +0 -55
  108. package/test-projects/django-app/blog/serializers.py +0 -69
  109. package/test-projects/django-app/blog/urls.py +0 -14
  110. package/test-projects/django-app/blog/views.py +0 -96
  111. package/test-projects/django-app/django_app/__init__.py +0 -0
  112. package/test-projects/django-app/django_app/settings.py +0 -90
  113. package/test-projects/django-app/django_app/urls.py +0 -11
  114. package/test-projects/django-app/django_app/wsgi.py +0 -9
  115. package/test-projects/django-app/manage.py +0 -23
  116. package/test-projects/django-app/requirements.txt +0 -3
  117. package/test-projects/django-app/users/__init__.py +0 -0
  118. package/test-projects/django-app/users/admin.py +0 -42
  119. package/test-projects/django-app/users/models.py +0 -54
  120. package/test-projects/django-app/users/serializers.py +0 -113
  121. package/test-projects/django-app/users/urls.py +0 -13
  122. package/test-projects/django-app/users/views.py +0 -135
  123. package/test-projects/express-api/.ai-dev/ai_context.md +0 -112
  124. package/test-projects/express-api/.ai-dev/ai_rules.md +0 -50
  125. package/test-projects/express-api/.ai-dev/architecture.md +0 -62
  126. package/test-projects/express-api/.ai-dev/context/features/controllers.json +0 -13
  127. package/test-projects/express-api/.ai-dev/context/features/services.json +0 -13
  128. package/test-projects/express-api/.ai-dev/context/flows/auth.json +0 -12
  129. package/test-projects/express-api/.ai-dev/context/flows/user.json +0 -13
  130. package/test-projects/express-api/.ai-dev/conventions.md +0 -51
  131. package/test-projects/express-api/.ai-dev/dependencies.json +0 -54
  132. package/test-projects/express-api/.ai-dev/entrypoints.md +0 -17
  133. package/test-projects/express-api/.ai-dev/modules.json +0 -30
  134. package/test-projects/express-api/.ai-dev/project.json +0 -15
  135. package/test-projects/express-api/.ai-dev/repo_map.json +0 -100
  136. package/test-projects/express-api/.ai-dev/repo_map.md +0 -36
  137. package/test-projects/express-api/.ai-dev/schema.json +0 -5
  138. package/test-projects/express-api/.ai-dev/summary.md +0 -14
  139. package/test-projects/express-api/.ai-dev/symbols.json +0 -7
  140. package/test-projects/express-api/.ai-dev/tech_stack.md +0 -38
  141. package/test-projects/express-api/.ai-dev/tools.json +0 -10
  142. package/test-projects/express-api/controllers/authController.js +0 -32
  143. package/test-projects/express-api/controllers/userController.js +0 -51
  144. package/test-projects/express-api/index.js +0 -30
  145. package/test-projects/express-api/middleware/authMiddleware.js +0 -30
  146. package/test-projects/express-api/models/userRepository.js +0 -25
  147. package/test-projects/express-api/package.json +0 -18
  148. package/test-projects/express-api/services/authService.js +0 -17
  149. package/test-projects/express-api/services/userService.js +0 -28
  150. package/test-projects/fastapi-app/.ai-dev/ai_context.md +0 -89
  151. package/test-projects/fastapi-app/.ai-dev/ai_rules.md +0 -47
  152. package/test-projects/fastapi-app/.ai-dev/architecture.md +0 -39
  153. package/test-projects/fastapi-app/.ai-dev/cache.json +0 -125
  154. package/test-projects/fastapi-app/.ai-dev/conventions.md +0 -51
  155. package/test-projects/fastapi-app/.ai-dev/dependencies.json +0 -244
  156. package/test-projects/fastapi-app/.ai-dev/entrypoints.md +0 -4
  157. package/test-projects/fastapi-app/.ai-dev/files.json +0 -154
  158. package/test-projects/fastapi-app/.ai-dev/graph/knowledge-graph.json +0 -15
  159. package/test-projects/fastapi-app/.ai-dev/graph/module-graph.json +0 -78
  160. package/test-projects/fastapi-app/.ai-dev/graph/symbol-graph.json +0 -1724
  161. package/test-projects/fastapi-app/.ai-dev/graph/symbol-references.json +0 -51
  162. package/test-projects/fastapi-app/.ai-dev/index-state.json +0 -217
  163. package/test-projects/fastapi-app/.ai-dev/modules.json +0 -16
  164. package/test-projects/fastapi-app/.ai-dev/project.json +0 -9
  165. package/test-projects/fastapi-app/.ai-dev/repo_map.json +0 -298
  166. package/test-projects/fastapi-app/.ai-dev/repo_map.md +0 -74
  167. package/test-projects/fastapi-app/.ai-dev/schema.json +0 -5
  168. package/test-projects/fastapi-app/.ai-dev/summary.md +0 -12
  169. package/test-projects/fastapi-app/.ai-dev/symbols.json +0 -1
  170. package/test-projects/fastapi-app/.ai-dev/tech_stack.md +0 -32
  171. package/test-projects/fastapi-app/.ai-dev/tools.json +0 -10
  172. package/test-projects/fastapi-app/README.md +0 -118
  173. package/test-projects/fastapi-app/app/database.py +0 -21
  174. package/test-projects/fastapi-app/app/dependencies.py +0 -107
  175. package/test-projects/fastapi-app/app/main.py +0 -47
  176. package/test-projects/fastapi-app/app/models.py +0 -149
  177. package/test-projects/fastapi-app/app/routers/auth.py +0 -117
  178. package/test-projects/fastapi-app/app/routers/posts.py +0 -272
  179. package/test-projects/fastapi-app/app/schemas.py +0 -191
  180. package/test-projects/fastapi-app/requirements.txt +0 -10
  181. package/test-projects/flask-app/.ai-dev/ai_context.md +0 -94
  182. package/test-projects/flask-app/.ai-dev/ai_rules.md +0 -47
  183. package/test-projects/flask-app/.ai-dev/architecture.md +0 -49
  184. package/test-projects/flask-app/.ai-dev/cache.json +0 -157
  185. package/test-projects/flask-app/.ai-dev/context/features/app.json +0 -25
  186. package/test-projects/flask-app/.ai-dev/context/flows/routes.json +0 -14
  187. package/test-projects/flask-app/.ai-dev/conventions.md +0 -51
  188. package/test-projects/flask-app/.ai-dev/dependencies.json +0 -298
  189. package/test-projects/flask-app/.ai-dev/entrypoints.md +0 -4
  190. package/test-projects/flask-app/.ai-dev/files.json +0 -194
  191. package/test-projects/flask-app/.ai-dev/graph/knowledge-graph.json +0 -60
  192. package/test-projects/flask-app/.ai-dev/graph/module-graph.json +0 -95
  193. package/test-projects/flask-app/.ai-dev/graph/symbol-graph.json +0 -1448
  194. package/test-projects/flask-app/.ai-dev/graph/symbol-references.json +0 -45
  195. package/test-projects/flask-app/.ai-dev/index-state.json +0 -273
  196. package/test-projects/flask-app/.ai-dev/modules.json +0 -21
  197. package/test-projects/flask-app/.ai-dev/project.json +0 -13
  198. package/test-projects/flask-app/.ai-dev/repo_map.json +0 -400
  199. package/test-projects/flask-app/.ai-dev/repo_map.md +0 -98
  200. package/test-projects/flask-app/.ai-dev/summary.md +0 -13
  201. package/test-projects/flask-app/.ai-dev/symbols.json +0 -1
  202. package/test-projects/flask-app/.ai-dev/tech_stack.md +0 -32
  203. package/test-projects/flask-app/.ai-dev/tools.json +0 -10
  204. package/test-projects/flask-app/README.md +0 -129
  205. package/test-projects/flask-app/app/__init__.py +0 -46
  206. package/test-projects/flask-app/app/api/__init__.py +0 -7
  207. package/test-projects/flask-app/app/api/routes.py +0 -122
  208. package/test-projects/flask-app/app/auth/__init__.py +0 -7
  209. package/test-projects/flask-app/app/auth/forms.py +0 -52
  210. package/test-projects/flask-app/app/auth/routes.py +0 -68
  211. package/test-projects/flask-app/app/blog/__init__.py +0 -7
  212. package/test-projects/flask-app/app/blog/forms.py +0 -35
  213. package/test-projects/flask-app/app/blog/routes.py +0 -140
  214. package/test-projects/flask-app/app/main/__init__.py +0 -7
  215. package/test-projects/flask-app/app/main/routes.py +0 -88
  216. package/test-projects/flask-app/app/models.py +0 -177
  217. package/test-projects/flask-app/config.py +0 -64
  218. package/test-projects/flask-app/requirements.txt +0 -10
  219. package/test-projects/laravel-app/.ai-dev/ai_context.md +0 -97
  220. package/test-projects/laravel-app/.ai-dev/ai_rules.md +0 -47
  221. package/test-projects/laravel-app/.ai-dev/architecture.md +0 -60
  222. package/test-projects/laravel-app/.ai-dev/cache.json +0 -161
  223. package/test-projects/laravel-app/.ai-dev/context/features/app.json +0 -21
  224. package/test-projects/laravel-app/.ai-dev/context/flows/.json +0 -9
  225. package/test-projects/laravel-app/.ai-dev/context/flows/category.json +0 -12
  226. package/test-projects/laravel-app/.ai-dev/context/flows/comment.json +0 -12
  227. package/test-projects/laravel-app/.ai-dev/context/flows/post.json +0 -12
  228. package/test-projects/laravel-app/.ai-dev/context/flows/unnamed.json +0 -9
  229. package/test-projects/laravel-app/.ai-dev/conventions.md +0 -51
  230. package/test-projects/laravel-app/.ai-dev/dependencies.json +0 -6
  231. package/test-projects/laravel-app/.ai-dev/entrypoints.md +0 -4
  232. package/test-projects/laravel-app/.ai-dev/files.json +0 -199
  233. package/test-projects/laravel-app/.ai-dev/graph/knowledge-graph.json +0 -98
  234. package/test-projects/laravel-app/.ai-dev/graph/module-graph.json +0 -30
  235. package/test-projects/laravel-app/.ai-dev/graph/symbol-graph.json +0 -5
  236. package/test-projects/laravel-app/.ai-dev/graph/symbol-references.json +0 -1
  237. package/test-projects/laravel-app/.ai-dev/index-state.json +0 -280
  238. package/test-projects/laravel-app/.ai-dev/modules.json +0 -29
  239. package/test-projects/laravel-app/.ai-dev/project.json +0 -17
  240. package/test-projects/laravel-app/.ai-dev/repo_map.json +0 -419
  241. package/test-projects/laravel-app/.ai-dev/repo_map.md +0 -106
  242. package/test-projects/laravel-app/.ai-dev/schema.json +0 -5
  243. package/test-projects/laravel-app/.ai-dev/summary.md +0 -15
  244. package/test-projects/laravel-app/.ai-dev/symbols.json +0 -1
  245. package/test-projects/laravel-app/.ai-dev/tech_stack.md +0 -34
  246. package/test-projects/laravel-app/.ai-dev/tools.json +0 -10
  247. package/test-projects/laravel-app/README.md +0 -107
  248. package/test-projects/laravel-app/app/Http/Controllers/Api/CategoryController.php +0 -88
  249. package/test-projects/laravel-app/app/Http/Controllers/Api/CommentController.php +0 -56
  250. package/test-projects/laravel-app/app/Http/Controllers/Api/PostController.php +0 -174
  251. package/test-projects/laravel-app/app/Http/Controllers/Controller.php +0 -12
  252. package/test-projects/laravel-app/app/Models/Category.php +0 -34
  253. package/test-projects/laravel-app/app/Models/Comment.php +0 -51
  254. package/test-projects/laravel-app/app/Models/Post.php +0 -108
  255. package/test-projects/laravel-app/app/Models/User.php +0 -85
  256. package/test-projects/laravel-app/bootstrap/app.php +0 -25
  257. package/test-projects/laravel-app/composer.json +0 -35
  258. package/test-projects/laravel-app/routes/api.php +0 -40
  259. package/test-projects/nestjs-backend/.ai-dev/ai_context.md +0 -111
  260. package/test-projects/nestjs-backend/.ai-dev/ai_rules.md +0 -52
  261. package/test-projects/nestjs-backend/.ai-dev/architecture.md +0 -49
  262. package/test-projects/nestjs-backend/.ai-dev/cache.json +0 -169
  263. package/test-projects/nestjs-backend/.ai-dev/context/features/src.json +0 -23
  264. package/test-projects/nestjs-backend/.ai-dev/context/flows/auth.controller.json +0 -14
  265. package/test-projects/nestjs-backend/.ai-dev/context/flows/auth.json +0 -10
  266. package/test-projects/nestjs-backend/.ai-dev/context/flows/users..json +0 -10
  267. package/test-projects/nestjs-backend/.ai-dev/context/flows/users.controller.json +0 -14
  268. package/test-projects/nestjs-backend/.ai-dev/context/flows/users.json +0 -10
  269. package/test-projects/nestjs-backend/.ai-dev/conventions.md +0 -52
  270. package/test-projects/nestjs-backend/.ai-dev/dependencies.json +0 -152
  271. package/test-projects/nestjs-backend/.ai-dev/entrypoints.md +0 -18
  272. package/test-projects/nestjs-backend/.ai-dev/files.json +0 -209
  273. package/test-projects/nestjs-backend/.ai-dev/graph/knowledge-graph.json +0 -132
  274. package/test-projects/nestjs-backend/.ai-dev/graph/module-graph.json +0 -29
  275. package/test-projects/nestjs-backend/.ai-dev/graph/symbol-graph.json +0 -304
  276. package/test-projects/nestjs-backend/.ai-dev/graph/symbol-references.json +0 -5
  277. package/test-projects/nestjs-backend/.ai-dev/index-state.json +0 -294
  278. package/test-projects/nestjs-backend/.ai-dev/modules.json +0 -19
  279. package/test-projects/nestjs-backend/.ai-dev/project.json +0 -18
  280. package/test-projects/nestjs-backend/.ai-dev/repo_map.json +0 -427
  281. package/test-projects/nestjs-backend/.ai-dev/repo_map.md +0 -104
  282. package/test-projects/nestjs-backend/.ai-dev/schema.json +0 -5
  283. package/test-projects/nestjs-backend/.ai-dev/summary.md +0 -13
  284. package/test-projects/nestjs-backend/.ai-dev/symbols.json +0 -1
  285. package/test-projects/nestjs-backend/.ai-dev/tech_stack.md +0 -38
  286. package/test-projects/nestjs-backend/.ai-dev/tools.json +0 -10
  287. package/test-projects/nestjs-backend/package.json +0 -22
  288. package/test-projects/nestjs-backend/src/app.module.ts +0 -8
  289. package/test-projects/nestjs-backend/src/auth/auth.controller.ts +0 -22
  290. package/test-projects/nestjs-backend/src/auth/auth.module.ts +0 -11
  291. package/test-projects/nestjs-backend/src/auth/auth.service.ts +0 -28
  292. package/test-projects/nestjs-backend/src/auth/dto/login.dto.ts +0 -4
  293. package/test-projects/nestjs-backend/src/auth/strategies/jwt.strategy.ts +0 -18
  294. package/test-projects/nestjs-backend/src/main.ts +0 -9
  295. package/test-projects/nestjs-backend/src/users/users.controller.ts +0 -32
  296. package/test-projects/nestjs-backend/src/users/users.module.ts +0 -10
  297. package/test-projects/nestjs-backend/src/users/users.service.ts +0 -42
  298. package/test-projects/nestjs-backend/tsconfig.json +0 -21
  299. package/test-projects/python-cli/.ai-dev/ai_context.md +0 -95
  300. package/test-projects/python-cli/.ai-dev/ai_rules.md +0 -47
  301. package/test-projects/python-cli/.ai-dev/architecture.md +0 -55
  302. package/test-projects/python-cli/.ai-dev/cache.json +0 -149
  303. package/test-projects/python-cli/.ai-dev/context/features/cli.json +0 -16
  304. package/test-projects/python-cli/.ai-dev/context/flows/list_.json +0 -9
  305. package/test-projects/python-cli/.ai-dev/context/flows/remove_.json +0 -9
  306. package/test-projects/python-cli/.ai-dev/conventions.md +0 -51
  307. package/test-projects/python-cli/.ai-dev/dependencies.json +0 -66
  308. package/test-projects/python-cli/.ai-dev/entrypoints.md +0 -4
  309. package/test-projects/python-cli/.ai-dev/files.json +0 -184
  310. package/test-projects/python-cli/.ai-dev/graph/knowledge-graph.json +0 -83
  311. package/test-projects/python-cli/.ai-dev/graph/module-graph.json +0 -31
  312. package/test-projects/python-cli/.ai-dev/graph/symbol-graph.json +0 -358
  313. package/test-projects/python-cli/.ai-dev/graph/symbol-references.json +0 -11
  314. package/test-projects/python-cli/.ai-dev/index-state.json +0 -259
  315. package/test-projects/python-cli/.ai-dev/modules.json +0 -21
  316. package/test-projects/python-cli/.ai-dev/project.json +0 -15
  317. package/test-projects/python-cli/.ai-dev/repo_map.json +0 -367
  318. package/test-projects/python-cli/.ai-dev/repo_map.md +0 -93
  319. package/test-projects/python-cli/.ai-dev/schema.json +0 -5
  320. package/test-projects/python-cli/.ai-dev/summary.md +0 -14
  321. package/test-projects/python-cli/.ai-dev/symbols.json +0 -1
  322. package/test-projects/python-cli/.ai-dev/tech_stack.md +0 -32
  323. package/test-projects/python-cli/.ai-dev/tools.json +0 -10
  324. package/test-projects/python-cli/__init__.py +0 -1
  325. package/test-projects/python-cli/cli/__init__.py +0 -1
  326. package/test-projects/python-cli/cli/add_command.py +0 -6
  327. package/test-projects/python-cli/cli/list_command.py +0 -7
  328. package/test-projects/python-cli/cli/remove_command.py +0 -6
  329. package/test-projects/python-cli/main.py +0 -34
  330. package/test-projects/python-cli/models/__init__.py +0 -2
  331. package/test-projects/python-cli/models/task.py +0 -19
  332. package/test-projects/python-cli/models/task_repository.py +0 -44
  333. package/test-projects/rails-app/.ai-dev/ai_context.md +0 -94
  334. package/test-projects/rails-app/.ai-dev/ai_rules.md +0 -47
  335. package/test-projects/rails-app/.ai-dev/architecture.md +0 -49
  336. package/test-projects/rails-app/.ai-dev/cache.json +0 -193
  337. package/test-projects/rails-app/.ai-dev/context/features/app.json +0 -24
  338. package/test-projects/rails-app/.ai-dev/context/features/config.json +0 -13
  339. package/test-projects/rails-app/.ai-dev/context/flows/application.json +0 -9
  340. package/test-projects/rails-app/.ai-dev/context/flows/application_.json +0 -9
  341. package/test-projects/rails-app/.ai-dev/context/flows/comments.json +0 -11
  342. package/test-projects/rails-app/.ai-dev/context/flows/comments_.json +0 -11
  343. package/test-projects/rails-app/.ai-dev/context/flows/posts.json +0 -11
  344. package/test-projects/rails-app/.ai-dev/context/flows/posts_.json +0 -11
  345. package/test-projects/rails-app/.ai-dev/context/flows/routes.json +0 -9
  346. package/test-projects/rails-app/.ai-dev/context/flows/users.json +0 -11
  347. package/test-projects/rails-app/.ai-dev/context/flows/users_.json +0 -11
  348. package/test-projects/rails-app/.ai-dev/conventions.md +0 -51
  349. package/test-projects/rails-app/.ai-dev/dependencies.json +0 -6
  350. package/test-projects/rails-app/.ai-dev/entrypoints.md +0 -4
  351. package/test-projects/rails-app/.ai-dev/files.json +0 -239
  352. package/test-projects/rails-app/.ai-dev/graph/knowledge-graph.json +0 -130
  353. package/test-projects/rails-app/.ai-dev/graph/module-graph.json +0 -27
  354. package/test-projects/rails-app/.ai-dev/graph/symbol-graph.json +0 -5
  355. package/test-projects/rails-app/.ai-dev/graph/symbol-references.json +0 -1
  356. package/test-projects/rails-app/.ai-dev/index-state.json +0 -336
  357. package/test-projects/rails-app/.ai-dev/modules.json +0 -26
  358. package/test-projects/rails-app/.ai-dev/project.json +0 -22
  359. package/test-projects/rails-app/.ai-dev/repo_map.json +0 -486
  360. package/test-projects/rails-app/.ai-dev/repo_map.md +0 -117
  361. package/test-projects/rails-app/.ai-dev/schema.json +0 -5
  362. package/test-projects/rails-app/.ai-dev/summary.md +0 -13
  363. package/test-projects/rails-app/.ai-dev/symbols.json +0 -1
  364. package/test-projects/rails-app/.ai-dev/tech_stack.md +0 -32
  365. package/test-projects/rails-app/.ai-dev/tools.json +0 -10
  366. package/test-projects/rails-app/Gemfile +0 -38
  367. package/test-projects/rails-app/README.md +0 -140
  368. package/test-projects/rails-app/Rakefile +0 -8
  369. package/test-projects/rails-app/app/controllers/api/comments_controller.rb +0 -75
  370. package/test-projects/rails-app/app/controllers/api/posts_controller.rb +0 -68
  371. package/test-projects/rails-app/app/controllers/api/users_controller.rb +0 -54
  372. package/test-projects/rails-app/app/controllers/application_controller.rb +0 -31
  373. package/test-projects/rails-app/app/models/comment.rb +0 -34
  374. package/test-projects/rails-app/app/models/post.rb +0 -36
  375. package/test-projects/rails-app/app/models/user.rb +0 -28
  376. package/test-projects/rails-app/app/services/post_service.rb +0 -92
  377. package/test-projects/rails-app/app/services/user_service.rb +0 -76
  378. package/test-projects/rails-app/config/application.rb +0 -27
  379. package/test-projects/rails-app/config/environment.rb +0 -7
  380. package/test-projects/rails-app/config/routes.rb +0 -15
  381. package/test-projects/react-app/.ai-dev/ai_context.md +0 -96
  382. package/test-projects/react-app/.ai-dev/architecture.md +0 -39
  383. package/test-projects/react-app/.ai-dev/cache.json +0 -153
  384. package/test-projects/react-app/.ai-dev/context/features/src.json +0 -18
  385. package/test-projects/react-app/.ai-dev/context/flows/UsersPage.json +0 -14
  386. package/test-projects/react-app/.ai-dev/context/flows/dashboard.json +0 -9
  387. package/test-projects/react-app/.ai-dev/context/flows/login.json +0 -9
  388. package/test-projects/react-app/.ai-dev/context/flows/users.json +0 -9
  389. package/test-projects/react-app/.ai-dev/dependencies.json +0 -128
  390. package/test-projects/react-app/.ai-dev/entrypoints.md +0 -4
  391. package/test-projects/react-app/.ai-dev/files.json +0 -189
  392. package/test-projects/react-app/.ai-dev/graph/knowledge-graph.json +0 -112
  393. package/test-projects/react-app/.ai-dev/graph/module-graph.json +0 -31
  394. package/test-projects/react-app/.ai-dev/graph/symbol-graph.json +0 -868
  395. package/test-projects/react-app/.ai-dev/graph/symbol-references.json +0 -31
  396. package/test-projects/react-app/.ai-dev/index-state.json +0 -266
  397. package/test-projects/react-app/.ai-dev/modules.json +0 -17
  398. package/test-projects/react-app/.ai-dev/project.json +0 -16
  399. package/test-projects/react-app/.ai-dev/repo_map.json +0 -391
  400. package/test-projects/react-app/.ai-dev/repo_map.md +0 -94
  401. package/test-projects/react-app/.ai-dev/schema.json +0 -5
  402. package/test-projects/react-app/.ai-dev/summary.md +0 -13
  403. package/test-projects/react-app/.ai-dev/symbols.json +0 -1
  404. package/test-projects/react-app/.ai-dev/tools.json +0 -10
  405. package/test-projects/react-app/package.json +0 -16
  406. package/test-projects/react-app/src/App.tsx +0 -21
  407. package/test-projects/react-app/src/context/AuthContext.tsx +0 -41
  408. package/test-projects/react-app/src/hooks/useAuth.ts +0 -10
  409. package/test-projects/react-app/src/main.tsx +0 -10
  410. package/test-projects/react-app/src/pages/DashboardPage.tsx +0 -17
  411. package/test-projects/react-app/src/pages/LoginPage.tsx +0 -41
  412. package/test-projects/react-app/src/pages/UsersPage.tsx +0 -36
  413. package/test-projects/react-app/src/services/userService.ts +0 -37
  414. package/test-projects/salesforce-cli/.ai-dev/ai_context.md +0 -89
  415. package/test-projects/salesforce-cli/.ai-dev/ai_rules.md +0 -47
  416. package/test-projects/salesforce-cli/.ai-dev/architecture.md +0 -39
  417. package/test-projects/salesforce-cli/.ai-dev/cache.json +0 -125
  418. package/test-projects/salesforce-cli/.ai-dev/context/features/force-app.json +0 -14
  419. package/test-projects/salesforce-cli/.ai-dev/context/flows/account.json +0 -9
  420. package/test-projects/salesforce-cli/.ai-dev/context/flows/opportunity.json +0 -9
  421. package/test-projects/salesforce-cli/.ai-dev/conventions.md +0 -51
  422. package/test-projects/salesforce-cli/.ai-dev/dependencies.json +0 -6
  423. package/test-projects/salesforce-cli/.ai-dev/entrypoints.md +0 -4
  424. package/test-projects/salesforce-cli/.ai-dev/files.json +0 -154
  425. package/test-projects/salesforce-cli/.ai-dev/graph/knowledge-graph.json +0 -64
  426. package/test-projects/salesforce-cli/.ai-dev/graph/module-graph.json +0 -13
  427. package/test-projects/salesforce-cli/.ai-dev/graph/symbol-graph.json +0 -148
  428. package/test-projects/salesforce-cli/.ai-dev/graph/symbol-references.json +0 -1
  429. package/test-projects/salesforce-cli/.ai-dev/index-state.json +0 -217
  430. package/test-projects/salesforce-cli/.ai-dev/modules.json +0 -12
  431. package/test-projects/salesforce-cli/.ai-dev/project.json +0 -14
  432. package/test-projects/salesforce-cli/.ai-dev/repo_map.json +0 -328
  433. package/test-projects/salesforce-cli/.ai-dev/repo_map.md +0 -80
  434. package/test-projects/salesforce-cli/.ai-dev/schema.json +0 -5
  435. package/test-projects/salesforce-cli/.ai-dev/summary.md +0 -13
  436. package/test-projects/salesforce-cli/.ai-dev/symbols.json +0 -1
  437. package/test-projects/salesforce-cli/.ai-dev/tech_stack.md +0 -31
  438. package/test-projects/salesforce-cli/.ai-dev/tools.json +0 -10
  439. package/test-projects/salesforce-cli/.forceignore +0 -27
  440. package/test-projects/salesforce-cli/force-app/main/default/classes/AccountController.cls +0 -24
  441. package/test-projects/salesforce-cli/force-app/main/default/classes/OpportunityController.cls +0 -25
  442. package/test-projects/salesforce-cli/force-app/main/default/objects/Project__c.object.xml +0 -45
  443. package/test-projects/salesforce-cli/force-app/main/default/triggers/AccountTrigger.trigger +0 -33
  444. package/test-projects/salesforce-cli/sfdx-project.json +0 -11
  445. package/test-projects/spring-boot-app/.ai-dev/ai_context.md +0 -91
  446. package/test-projects/spring-boot-app/.ai-dev/ai_rules.md +0 -48
  447. package/test-projects/spring-boot-app/.ai-dev/architecture.md +0 -39
  448. package/test-projects/spring-boot-app/.ai-dev/cache.json +0 -173
  449. package/test-projects/spring-boot-app/.ai-dev/context/features/src.json +0 -26
  450. package/test-projects/spring-boot-app/.ai-dev/context/flows/PostController.json +0 -19
  451. package/test-projects/spring-boot-app/.ai-dev/context/flows/UserController.json +0 -19
  452. package/test-projects/spring-boot-app/.ai-dev/context/flows/comment.json +0 -11
  453. package/test-projects/spring-boot-app/.ai-dev/context/flows/post.json +0 -14
  454. package/test-projects/spring-boot-app/.ai-dev/context/flows/user.json +0 -14
  455. package/test-projects/spring-boot-app/.ai-dev/conventions.md +0 -52
  456. package/test-projects/spring-boot-app/.ai-dev/dependencies.json +0 -326
  457. package/test-projects/spring-boot-app/.ai-dev/entrypoints.md +0 -4
  458. package/test-projects/spring-boot-app/.ai-dev/files.json +0 -214
  459. package/test-projects/spring-boot-app/.ai-dev/graph/knowledge-graph.json +0 -231
  460. package/test-projects/spring-boot-app/.ai-dev/graph/module-graph.json +0 -22
  461. package/test-projects/spring-boot-app/.ai-dev/graph/symbol-graph.json +0 -794
  462. package/test-projects/spring-boot-app/.ai-dev/graph/symbol-references.json +0 -70
  463. package/test-projects/spring-boot-app/.ai-dev/index-state.json +0 -301
  464. package/test-projects/spring-boot-app/.ai-dev/modules.json +0 -21
  465. package/test-projects/spring-boot-app/.ai-dev/project.json +0 -17
  466. package/test-projects/spring-boot-app/.ai-dev/repo_map.json +0 -461
  467. package/test-projects/spring-boot-app/.ai-dev/repo_map.md +0 -109
  468. package/test-projects/spring-boot-app/.ai-dev/schema.json +0 -5
  469. package/test-projects/spring-boot-app/.ai-dev/summary.md +0 -12
  470. package/test-projects/spring-boot-app/.ai-dev/symbols.json +0 -1
  471. package/test-projects/spring-boot-app/.ai-dev/tech_stack.md +0 -32
  472. package/test-projects/spring-boot-app/.ai-dev/tools.json +0 -10
  473. package/test-projects/spring-boot-app/.classpath +0 -57
  474. package/test-projects/spring-boot-app/.factorypath +0 -69
  475. package/test-projects/spring-boot-app/.project +0 -34
  476. package/test-projects/spring-boot-app/.settings/org.eclipse.core.resources.prefs +0 -4
  477. package/test-projects/spring-boot-app/.settings/org.eclipse.jdt.apt.core.prefs +0 -4
  478. package/test-projects/spring-boot-app/.settings/org.eclipse.jdt.core.prefs +0 -10
  479. package/test-projects/spring-boot-app/.settings/org.eclipse.m2e.core.prefs +0 -4
  480. package/test-projects/spring-boot-app/README.md +0 -122
  481. package/test-projects/spring-boot-app/pom.xml +0 -79
  482. package/test-projects/spring-boot-app/src/main/java/com/example/demo/DemoApplication.java +0 -12
  483. package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/CommentController.java +0 -89
  484. package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/PostController.java +0 -92
  485. package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/UserController.java +0 -84
  486. package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/Comment.java +0 -38
  487. package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/Post.java +0 -56
  488. package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/User.java +0 -44
  489. package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/CommentRepository.java +0 -21
  490. package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/PostRepository.java +0 -18
  491. package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/UserRepository.java +0 -15
  492. package/test-projects/spring-boot-app/src/main/java/com/example/demo/services/PostService.java +0 -83
  493. package/test-projects/spring-boot-app/src/main/java/com/example/demo/services/UserService.java +0 -62
  494. package/test-projects/spring-boot-app/src/main/resources/application.properties +0 -22
  495. package/test-projects/spring-boot-app/target/classes/com/example/demo/DemoApplication.class +0 -0
  496. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController$CommentCreateRequest.class +0 -0
  497. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController$CommentUpdateRequest.class +0 -0
  498. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController.class +0 -0
  499. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController$PostCreateRequest.class +0 -0
  500. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController$PostUpdateRequest.class +0 -0
  501. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController.class +0 -0
  502. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController$UserCreateRequest.class +0 -0
  503. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController$UserUpdateRequest.class +0 -0
  504. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController.class +0 -0
  505. package/test-projects/spring-boot-app/target/classes/com/example/demo/models/Comment.class +0 -0
  506. package/test-projects/spring-boot-app/target/classes/com/example/demo/models/Post.class +0 -0
  507. package/test-projects/spring-boot-app/target/classes/com/example/demo/models/User.class +0 -0
  508. package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/CommentRepository.class +0 -0
  509. package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/PostRepository.class +0 -0
  510. package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/UserRepository.class +0 -0
  511. package/test-projects/spring-boot-app/target/classes/com/example/demo/services/PostService.class +0 -0
  512. package/test-projects/spring-boot-app/target/classes/com/example/demo/services/UserService.class +0 -0
  513. package/tests/e2e/run-e2e.sh +0 -88
  514. /package/{test-projects/django-app/.ai-dev → ai-context}/tools.json +0 -0
@@ -0,0 +1,713 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
+ import { extractSymbols } from "../src/analyzers/symbols";
3
+ import { FileInfo } from "../src/core/repoScanner";
4
+ import { detectAdapter } from "../src/core/adapters/index.js";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import os from "os";
8
+
9
+ const SALESFORCE_ENTERPRISE_PATH = path.join(process.cwd(), "test-projects/salesforce-enterprise");
10
+
11
+ describe("Salesforce Apex Classes Detection", () => {
12
+ let tempDir: string;
13
+
14
+ beforeAll(() => {
15
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "apex-classes-test-"));
16
+ });
17
+
18
+ afterAll(() => {
19
+ fs.rmSync(tempDir, { recursive: true, force: true });
20
+ });
21
+
22
+ const createFileInfo = (filePath: string, extension: string, content: string): FileInfo => {
23
+ const fullPath = path.join(tempDir, filePath);
24
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
25
+ fs.writeFileSync(fullPath, content);
26
+
27
+ return {
28
+ path: fullPath,
29
+ relativePath: filePath,
30
+ extension,
31
+ name: filePath.split("/").pop()?.replace(`.${extension}`, "") || "",
32
+ };
33
+ };
34
+
35
+ // =========================================================================
36
+ // INTEGRATION TESTS - Using real Salesforce Enterprise test project
37
+ // =========================================================================
38
+
39
+ describe("Integration: Real Salesforce Enterprise Project", () => {
40
+ it("should detect Salesforce adapter from sfdx-project.json", () => {
41
+ const adapter = detectAdapter(SALESFORCE_ENTERPRISE_PATH);
42
+ expect(adapter.name).toBe("salesforce");
43
+ });
44
+
45
+ it("should detect all 8 Apex classes in the enterprise project", () => {
46
+ const classesDir = path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes");
47
+ const files = fs.readdirSync(classesDir).filter(f => f.endsWith(".cls"));
48
+
49
+ expect(files).toHaveLength(8);
50
+ expect(files).toContain("AccountController.cls");
51
+ expect(files).toContain("AccountControllerTest.cls");
52
+ expect(files).toContain("OpportunityBatch.cls");
53
+ expect(files).toContain("OpportunityBatchTest.cls");
54
+ expect(files).toContain("OpportunityTriggerHandler.cls");
55
+ expect(files).toContain("OpportunityTriggerHelper.cls");
56
+ expect(files).toContain("TriggerManagement.cls");
57
+ expect(files).toContain("Logger.cls");
58
+ });
59
+
60
+ it("should extract symbols from all 8 Apex classes", () => {
61
+ const classesDir = path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes");
62
+ const files = fs.readdirSync(classesDir)
63
+ .filter(f => f.endsWith(".cls"))
64
+ .map(f => {
65
+ const fullPath = path.join(classesDir, f);
66
+ return {
67
+ path: fullPath,
68
+ relativePath: `force-app/main/default/classes/${f}`,
69
+ extension: "cls",
70
+ name: f.replace(".cls", ""),
71
+ } as FileInfo;
72
+ });
73
+
74
+ const result = extractSymbols(files);
75
+
76
+ // All 8 classes should be detected
77
+ const classSymbols = result.symbols.filter(s => s.type === "class");
78
+ expect(classSymbols.length).toBeGreaterThanOrEqual(8);
79
+
80
+ const classNames = classSymbols.map(s => s.name);
81
+ expect(classNames).toContain("AccountController");
82
+ expect(classNames).toContain("AccountControllerTest");
83
+ expect(classNames).toContain("OpportunityBatch");
84
+ expect(classNames).toContain("OpportunityBatchTest");
85
+ expect(classNames).toContain("OpportunityTriggerHandler");
86
+ expect(classNames).toContain("OpportunityTriggerHelper");
87
+ expect(classNames).toContain("TriggerManagement");
88
+ expect(classNames).toContain("Logger");
89
+ });
90
+ });
91
+
92
+ // =========================================================================
93
+ // AccountController - Controller with @AuraEnabled methods
94
+ // =========================================================================
95
+
96
+ describe("AccountController", () => {
97
+ it("should be detected as a class with sharing", () => {
98
+ const content = fs.readFileSync(
99
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountController.cls"),
100
+ "utf-8"
101
+ );
102
+
103
+ const file = createFileInfo("force-app/main/default/classes/AccountController.cls", "cls", content);
104
+ const result = extractSymbols([file]);
105
+
106
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "AccountController");
107
+ expect(classSymbol).toBeDefined();
108
+ expect(classSymbol?.export).toBe(true);
109
+ expect(content).toContain("public with sharing class AccountController");
110
+ });
111
+
112
+ it("should detect @AuraEnabled methods as entrypoints", () => {
113
+ const content = fs.readFileSync(
114
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountController.cls"),
115
+ "utf-8"
116
+ );
117
+
118
+ const file = createFileInfo("force-app/main/default/classes/AccountController.cls", "cls", content);
119
+ const result = extractSymbols([file]);
120
+
121
+ // Find methods that are exported (public)
122
+ const methods = result.symbols.filter(s => s.type === "function" && s.export === true);
123
+
124
+ // Should have @AuraEnabled methods
125
+ expect(content).toContain("@AuraEnabled");
126
+ expect(content).toContain("getAccounts");
127
+ expect(content).toContain("createAccount");
128
+ expect(content).toContain("updateAccount");
129
+ expect(content).toContain("deleteAccount");
130
+ expect(content).toContain("getAccountSummary");
131
+
132
+ // Methods should be detected
133
+ const methodNames = methods.map(m => m.name);
134
+ expect(methodNames).toContain("getAccounts");
135
+ expect(methodNames).toContain("createAccount");
136
+ expect(methodNames).toContain("updateAccount");
137
+ expect(methodNames).toContain("deleteAccount");
138
+ expect(methodNames).toContain("getAccountSummary");
139
+ });
140
+
141
+ it("should detect cacheable @AuraEnabled methods", () => {
142
+ const content = fs.readFileSync(
143
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountController.cls"),
144
+ "utf-8"
145
+ );
146
+
147
+ // Count @AuraEnabled annotations
148
+ const auraEnabledCount = (content.match(/@AuraEnabled/g) || []).length;
149
+ expect(auraEnabledCount).toBeGreaterThanOrEqual(4);
150
+
151
+ // Count cacheable=true annotations
152
+ const cacheableCount = (content.match(/@AuraEnabled\(cacheable=true\)/g) || []).length;
153
+ expect(cacheableCount).toBeGreaterThanOrEqual(2);
154
+ });
155
+
156
+ it("should be identified as a Controller type entrypoint", () => {
157
+ const content = fs.readFileSync(
158
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountController.cls"),
159
+ "utf-8"
160
+ );
161
+
162
+ // Controller classes have specific patterns
163
+ expect(content).toContain("Controller");
164
+ expect(content).toContain("@AuraEnabled");
165
+ });
166
+ });
167
+
168
+ // =========================================================================
169
+ // AccountControllerTest - Test class with @IsTest
170
+ // =========================================================================
171
+
172
+ describe("AccountControllerTest", () => {
173
+ it("should be detected as a test class", () => {
174
+ const content = fs.readFileSync(
175
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountControllerTest.cls"),
176
+ "utf-8"
177
+ );
178
+
179
+ const file = createFileInfo("force-app/main/default/classes/AccountControllerTest.cls", "cls", content);
180
+ const result = extractSymbols([file]);
181
+
182
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "AccountControllerTest");
183
+ expect(classSymbol).toBeDefined();
184
+ expect(classSymbol?.export).toBe(true);
185
+ });
186
+
187
+ it("should have @IsTest annotation", () => {
188
+ const content = fs.readFileSync(
189
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountControllerTest.cls"),
190
+ "utf-8"
191
+ );
192
+
193
+ expect(content).toContain("@IsTest");
194
+ expect(content).toContain("private class AccountControllerTest");
195
+ });
196
+
197
+ it("should have test methods with @isTest annotation", () => {
198
+ const content = fs.readFileSync(
199
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountControllerTest.cls"),
200
+ "utf-8"
201
+ );
202
+
203
+ const isTestCount = (content.match(/@isTest/g) || []).length;
204
+ expect(isTestCount).toBeGreaterThanOrEqual(7); // Multiple test methods
205
+
206
+ expect(content).toContain("testGetAccounts");
207
+ expect(content).toContain("testCreateAccount");
208
+ expect(content).toContain("testUpdateAccount");
209
+ expect(content).toContain("testDeleteAccount");
210
+ });
211
+
212
+ it("should have @testSetup method", () => {
213
+ const content = fs.readFileSync(
214
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountControllerTest.cls"),
215
+ "utf-8"
216
+ );
217
+
218
+ expect(content).toContain("@testSetup");
219
+ expect(content).toContain("setupTestData");
220
+ });
221
+ });
222
+
223
+ // =========================================================================
224
+ // OpportunityBatch - Batchable interface implementation
225
+ // =========================================================================
226
+
227
+ describe("OpportunityBatch", () => {
228
+ it("should be detected as a global class", () => {
229
+ const content = fs.readFileSync(
230
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatch.cls"),
231
+ "utf-8"
232
+ );
233
+
234
+ const file = createFileInfo("force-app/main/default/classes/OpportunityBatch.cls", "cls", content);
235
+ const result = extractSymbols([file]);
236
+
237
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "OpportunityBatch");
238
+ expect(classSymbol).toBeDefined();
239
+ });
240
+
241
+ it("should implement Database.Batchable interface", () => {
242
+ const content = fs.readFileSync(
243
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatch.cls"),
244
+ "utf-8"
245
+ );
246
+
247
+ expect(content).toContain("implements Database.Batchable<SObject>");
248
+ expect(content).toContain("global class OpportunityBatch");
249
+ });
250
+
251
+ it("should implement Database.Stateful for state retention", () => {
252
+ const content = fs.readFileSync(
253
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatch.cls"),
254
+ "utf-8"
255
+ );
256
+
257
+ expect(content).toContain("Database.Stateful");
258
+ });
259
+
260
+ it("should have batch method signatures (start, execute, finish)", () => {
261
+ const content = fs.readFileSync(
262
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatch.cls"),
263
+ "utf-8"
264
+ );
265
+
266
+ expect(content).toContain("global Database.QueryLocator start(Database.BatchableContext BC)");
267
+ expect(content).toContain("global void execute(Database.BatchableContext BC, List<Opportunity> scope)");
268
+ expect(content).toContain("global void finish(Database.BatchableContext BC)");
269
+ });
270
+
271
+ it("should be identified as a Batch entrypoint type", () => {
272
+ const content = fs.readFileSync(
273
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatch.cls"),
274
+ "utf-8"
275
+ );
276
+
277
+ // Batch classes are entrypoints
278
+ expect(content).toContain("Batch");
279
+ expect(content).toContain("implements Database.Batchable");
280
+ });
281
+ });
282
+
283
+ // =========================================================================
284
+ // OpportunityBatchTest - Test class for batch
285
+ // =========================================================================
286
+
287
+ describe("OpportunityBatchTest", () => {
288
+ it("should be detected as a test class with @IsTest", () => {
289
+ const content = fs.readFileSync(
290
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatchTest.cls"),
291
+ "utf-8"
292
+ );
293
+
294
+ const file = createFileInfo("force-app/main/default/classes/OpportunityBatchTest.cls", "cls", content);
295
+ const result = extractSymbols([file]);
296
+
297
+ expect(content).toContain("@IsTest");
298
+ expect(content).toContain("private class OpportunityBatchTest");
299
+
300
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "OpportunityBatchTest");
301
+ expect(classSymbol).toBeDefined();
302
+ });
303
+
304
+ it("should test batch execution", () => {
305
+ const content = fs.readFileSync(
306
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatchTest.cls"),
307
+ "utf-8"
308
+ );
309
+
310
+ expect(content).toContain("Database.executeBatch");
311
+ expect(content).toContain("testBatchExecution");
312
+ expect(content).toContain("testBatchWithCustomQuery");
313
+ expect(content).toContain("testBatchStateRetention");
314
+ });
315
+ });
316
+
317
+ // =========================================================================
318
+ // OpportunityTriggerHandler - Trigger handler class
319
+ // =========================================================================
320
+
321
+ describe("OpportunityTriggerHandler", () => {
322
+ it("should be detected as a class with sharing", () => {
323
+ const content = fs.readFileSync(
324
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityTriggerHandler.cls"),
325
+ "utf-8"
326
+ );
327
+
328
+ const file = createFileInfo("force-app/main/default/classes/OpportunityTriggerHandler.cls", "cls", content);
329
+ const result = extractSymbols([file]);
330
+
331
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "OpportunityTriggerHandler");
332
+ expect(classSymbol).toBeDefined();
333
+ expect(classSymbol?.export).toBe(true);
334
+ });
335
+
336
+ it("should have trigger event handler methods", () => {
337
+ const content = fs.readFileSync(
338
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityTriggerHandler.cls"),
339
+ "utf-8"
340
+ );
341
+
342
+ // Trigger handlers have onBeforeInsert, onBeforeUpdate, etc.
343
+ expect(content).toContain("onBeforeInsert");
344
+ expect(content).toContain("onBeforeUpdate");
345
+ expect(content).toContain("onBeforeDelete");
346
+ expect(content).toContain("onAfterInsert");
347
+ expect(content).toContain("onAfterUpdate");
348
+ expect(content).toContain("onAfterDelete");
349
+ expect(content).toContain("onAfterUndelete");
350
+ });
351
+
352
+ it("should be identified as a Trigger handler entrypoint", () => {
353
+ const content = fs.readFileSync(
354
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityTriggerHandler.cls"),
355
+ "utf-8"
356
+ );
357
+
358
+ expect(content).toContain("Handler");
359
+ expect(content).toContain("Trigger");
360
+ });
361
+ });
362
+
363
+ // =========================================================================
364
+ // OpportunityTriggerHelper - Trigger helper/utility class
365
+ // =========================================================================
366
+
367
+ describe("OpportunityTriggerHelper", () => {
368
+ it("should be detected as a class with sharing", () => {
369
+ const content = fs.readFileSync(
370
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityTriggerHelper.cls"),
371
+ "utf-8"
372
+ );
373
+
374
+ const file = createFileInfo("force-app/main/default/classes/OpportunityTriggerHelper.cls", "cls", content);
375
+ const result = extractSymbols([file]);
376
+
377
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "OpportunityTriggerHelper");
378
+ expect(classSymbol).toBeDefined();
379
+ });
380
+
381
+ it("should have helper methods for triggers", () => {
382
+ const content = fs.readFileSync(
383
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityTriggerHelper.cls"),
384
+ "utf-8"
385
+ );
386
+
387
+ expect(content).toContain("canReopenOpportunity");
388
+ expect(content).toContain("updateAccountTotalRevenue");
389
+ expect(content).toContain("sendWinNotifications");
390
+ expect(content).toContain("getDefaultCloseDate");
391
+ });
392
+ });
393
+
394
+ // =========================================================================
395
+ // TriggerManagement - Utility class (without sharing)
396
+ // =========================================================================
397
+
398
+ describe("TriggerManagement", () => {
399
+ it("should be detected as a class without sharing", () => {
400
+ const content = fs.readFileSync(
401
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/TriggerManagement.cls"),
402
+ "utf-8"
403
+ );
404
+
405
+ const file = createFileInfo("force-app/main/default/classes/TriggerManagement.cls", "cls", content);
406
+ const result = extractSymbols([file]);
407
+
408
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "TriggerManagement");
409
+ expect(classSymbol).toBeDefined();
410
+ expect(content).toContain("public without sharing class TriggerManagement");
411
+ });
412
+
413
+ it("should have trigger bypass management methods", () => {
414
+ const content = fs.readFileSync(
415
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/TriggerManagement.cls"),
416
+ "utf-8"
417
+ );
418
+
419
+ expect(content).toContain("isTriggerBypassed");
420
+ expect(content).toContain("isTriggerBypassedForUser");
421
+ expect(content).toContain("bypassTrigger");
422
+ expect(content).toContain("removeBypass");
423
+ expect(content).toContain("getBypassedTriggers");
424
+ });
425
+
426
+ it("should be identified as a utility class", () => {
427
+ const content = fs.readFileSync(
428
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/TriggerManagement.cls"),
429
+ "utf-8"
430
+ );
431
+
432
+ // Utility classes often use "without sharing" for system-level access
433
+ expect(content).toContain("without sharing");
434
+ expect(content).toContain("Management");
435
+ });
436
+ });
437
+
438
+ // =========================================================================
439
+ // Logger - Service class with logging methods
440
+ // =========================================================================
441
+
442
+ describe("Logger", () => {
443
+ it("should be detected as a class with sharing", () => {
444
+ const content = fs.readFileSync(
445
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/Logger.cls"),
446
+ "utf-8"
447
+ );
448
+
449
+ const file = createFileInfo("force-app/main/default/classes/Logger.cls", "cls", content);
450
+ const result = extractSymbols([file]);
451
+
452
+ const classSymbol = result.symbols.find(s => s.type === "class" && s.name === "Logger");
453
+ expect(classSymbol).toBeDefined();
454
+ expect(classSymbol?.export).toBe(true);
455
+ expect(content).toContain("public with sharing class Logger");
456
+ });
457
+
458
+ it("should have logging severity enum", () => {
459
+ const content = fs.readFileSync(
460
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/Logger.cls"),
461
+ "utf-8"
462
+ );
463
+
464
+ expect(content).toContain("public enum Severity");
465
+ expect(content).toContain("DEBUG");
466
+ expect(content).toContain("INFO");
467
+ expect(content).toContain("WARNING");
468
+ expect(content).toContain("ERROR");
469
+ expect(content).toContain("CRITICAL");
470
+ });
471
+
472
+ it("should have static logging methods", () => {
473
+ const content = fs.readFileSync(
474
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/Logger.cls"),
475
+ "utf-8"
476
+ );
477
+
478
+ expect(content).toContain("public static void log");
479
+ expect(content).toContain("public static void debug");
480
+ expect(content).toContain("public static void info");
481
+ expect(content).toContain("public static void warn");
482
+ expect(content).toContain("public static void error");
483
+ expect(content).toContain("public static void critical");
484
+ expect(content).toContain("public static void logException");
485
+ });
486
+
487
+ it("should be identified as a service class", () => {
488
+ const content = fs.readFileSync(
489
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/Logger.cls"),
490
+ "utf-8"
491
+ );
492
+
493
+ // Service classes often have "with sharing" and contain business logic
494
+ expect(content).toContain("with sharing");
495
+ expect(content).toContain("Logger");
496
+ });
497
+ });
498
+
499
+ // =========================================================================
500
+ // UNIT TESTS - Apex parsing edge cases
501
+ // =========================================================================
502
+
503
+ describe("Unit: Apex parsing edge cases", () => {
504
+ it("should parse class with sharing modes", () => {
505
+ const sharingModes = [
506
+ { code: "public with sharing class TestClass {}", expected: true },
507
+ { code: "public without sharing class TestClass {}", expected: true },
508
+ { code: "public inherited sharing class TestClass {}", expected: true },
509
+ { code: "public class TestClass {}", expected: true },
510
+ ];
511
+
512
+ for (const mode of sharingModes) {
513
+ const file = createFileInfo("TestClass.cls", "cls", mode.code);
514
+ const result = extractSymbols([file]);
515
+ const classSymbol = result.symbols.find(s => s.name === "TestClass");
516
+ expect(classSymbol).toBeDefined();
517
+ expect(classSymbol?.type).toBe("class");
518
+ }
519
+ });
520
+
521
+ it("should parse global class", () => {
522
+ const content = `global class GlobalBatch implements Database.Batchable<SObject> {
523
+ global Database.QueryLocator start(Database.BatchableContext BC) { return null; }
524
+ global void execute(Database.BatchableContext BC, List<SObject> scope) {}
525
+ global void finish(Database.BatchableContext BC) {}
526
+ }`;
527
+
528
+ const file = createFileInfo("GlobalBatch.cls", "cls", content);
529
+ const result = extractSymbols([file]);
530
+
531
+ const classSymbol = result.symbols.find(s => s.name === "GlobalBatch");
532
+ expect(classSymbol).toBeDefined();
533
+ expect(classSymbol?.type).toBe("class");
534
+ });
535
+
536
+ it("should parse @future methods", () => {
537
+ const content = `public class AsyncProcessor {
538
+ @future
539
+ public static void processAsync(String data) {
540
+ // async processing
541
+ }
542
+ }`;
543
+
544
+ const file = createFileInfo("AsyncProcessor.cls", "cls", content);
545
+ const result = extractSymbols([file]);
546
+
547
+ expect(result.symbols.find(s => s.name === "processAsync")).toBeDefined();
548
+ });
549
+
550
+ it("should parse webservice methods", () => {
551
+ const content = `global class WebServiceAPI {
552
+ webservice static String createRecord(String jsonData) {
553
+ return 'created';
554
+ }
555
+ }`;
556
+
557
+ const file = createFileInfo("WebServiceAPI.cls", "cls", content);
558
+ const result = extractSymbols([file]);
559
+
560
+ const methodSymbol = result.symbols.find(s => s.name === "createRecord");
561
+ expect(methodSymbol).toBeDefined();
562
+ expect(methodSymbol?.type).toBe("function");
563
+ });
564
+
565
+ it("should parse interface implementations", () => {
566
+ const content = `public class QueueableImpl implements Queueable {
567
+ public void execute(QueueableContext context) {
568
+ // implementation
569
+ }
570
+ }`;
571
+
572
+ const file = createFileInfo("QueueableImpl.cls", "cls", content);
573
+ const result = extractSymbols([file]);
574
+
575
+ const classSymbol = result.symbols.find(s => s.name === "QueueableImpl");
576
+ expect(classSymbol).toBeDefined();
577
+ expect(result.symbols.find(s => s.name === "execute")).toBeDefined();
578
+ });
579
+
580
+ it("should parse schedulable class", () => {
581
+ const content = `global class ScheduledJob implements Schedulable {
582
+ global void execute(SchedulableContext SC) {
583
+ // scheduled logic
584
+ }
585
+ }`;
586
+
587
+ const file = createFileInfo("ScheduledJob.cls", "cls", content);
588
+ const result = extractSymbols([file]);
589
+
590
+ const classSymbol = result.symbols.find(s => s.name === "ScheduledJob");
591
+ expect(classSymbol).toBeDefined();
592
+ expect(result.symbols.find(s => s.name === "execute")).toBeDefined();
593
+ });
594
+ });
595
+
596
+ // =========================================================================
597
+ // ENTRYPOINT DETECTION TESTS
598
+ // =========================================================================
599
+
600
+ describe("Entrypoint Detection for Salesforce", () => {
601
+ it("should detect AccountController as entrypoint (Controller)", () => {
602
+ const content = fs.readFileSync(
603
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountController.cls"),
604
+ "utf-8"
605
+ );
606
+
607
+ // Controller is an entrypoint pattern per salesforceAdapter
608
+ expect(content).toContain("Controller");
609
+ });
610
+
611
+ it("should detect OpportunityBatch as entrypoint (Batch)", () => {
612
+ const content = fs.readFileSync(
613
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityBatch.cls"),
614
+ "utf-8"
615
+ );
616
+
617
+ // Batch is an entrypoint pattern per salesforceAdapter
618
+ expect(content).toContain("implements Database.Batchable");
619
+ });
620
+
621
+ it("should detect TriggerManagement as utility class", () => {
622
+ const content = fs.readFileSync(
623
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/TriggerManagement.cls"),
624
+ "utf-8"
625
+ );
626
+
627
+ // TriggerManagement uses without sharing and is a utility
628
+ expect(content).toContain("without sharing");
629
+ expect(content).toContain("Management");
630
+ });
631
+
632
+ it("should detect Logger as a service class", () => {
633
+ const content = fs.readFileSync(
634
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/Logger.cls"),
635
+ "utf-8"
636
+ );
637
+
638
+ // Service classes are layer 2 per salesforceAdapter
639
+ expect(content).toContain("with sharing");
640
+ expect(content).toContain("Logger");
641
+ });
642
+ });
643
+
644
+ // =========================================================================
645
+ // SYMBOL EXTRACTION ACCURACY
646
+ // =========================================================================
647
+
648
+ describe("Symbol Extraction Accuracy", () => {
649
+ it("should extract all method symbols from AccountController", () => {
650
+ const content = fs.readFileSync(
651
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/AccountController.cls"),
652
+ "utf-8"
653
+ );
654
+
655
+ const file = createFileInfo("force-app/main/default/classes/AccountController.cls", "cls", content);
656
+ const result = extractSymbols([file]);
657
+
658
+ const methods = result.symbols.filter(s => s.type === "function");
659
+ const methodNames = methods.map(m => m.name);
660
+
661
+ // All public methods should be detected
662
+ expect(methodNames).toContain("getAccounts");
663
+ expect(methodNames).toContain("createAccount");
664
+ expect(methodNames).toContain("updateAccount");
665
+ expect(methodNames).toContain("deleteAccount");
666
+ expect(methodNames).toContain("getAccountSummary");
667
+ });
668
+
669
+ it("should extract all method symbols from OpportunityTriggerHandler", () => {
670
+ const content = fs.readFileSync(
671
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/OpportunityTriggerHandler.cls"),
672
+ "utf-8"
673
+ );
674
+
675
+ const file = createFileInfo("force-app/main/default/classes/OpportunityTriggerHandler.cls", "cls", content);
676
+ const result = extractSymbols([file]);
677
+
678
+ const methods = result.symbols.filter(s => s.type === "function");
679
+ const methodNames = methods.map(m => m.name);
680
+
681
+ // Trigger handler methods
682
+ expect(methodNames).toContain("onBeforeInsert");
683
+ expect(methodNames).toContain("onBeforeUpdate");
684
+ expect(methodNames).toContain("onBeforeDelete");
685
+ expect(methodNames).toContain("onAfterInsert");
686
+ expect(methodNames).toContain("onAfterUpdate");
687
+ expect(methodNames).toContain("onAfterDelete");
688
+ expect(methodNames).toContain("onAfterUndelete");
689
+ });
690
+
691
+ it("should extract all method symbols from Logger", () => {
692
+ const content = fs.readFileSync(
693
+ path.join(SALESFORCE_ENTERPRISE_PATH, "force-app/main/default/classes/Logger.cls"),
694
+ "utf-8"
695
+ );
696
+
697
+ const file = createFileInfo("force-app/main/default/classes/Logger.cls", "cls", content);
698
+ const result = extractSymbols([file]);
699
+
700
+ const methods = result.symbols.filter(s => s.type === "function");
701
+ const methodNames = methods.map(m => m.name);
702
+
703
+ // Logger methods
704
+ expect(methodNames).toContain("log");
705
+ expect(methodNames).toContain("debug");
706
+ expect(methodNames).toContain("info");
707
+ expect(methodNames).toContain("warn");
708
+ expect(methodNames).toContain("error");
709
+ expect(methodNames).toContain("critical");
710
+ expect(methodNames).toContain("logException");
711
+ });
712
+ });
713
+ });