ai-first-cli 1.3.1 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (532) hide show
  1. package/.ai-dev/index.db +0 -0
  2. package/BETA_EVALUATION_REPORT.md +151 -0
  3. package/CHANGELOG.md +178 -0
  4. package/PHASE1_USER_SIMULATION.md +56 -0
  5. package/PHASE2_USER_SIMULATION.md +81 -0
  6. package/PHASE3_USER_SIMULATION.md +176 -0
  7. package/README.es.md +18 -0
  8. package/README.md +80 -1
  9. package/ai/graph/knowledge-graph.json +10 -0
  10. package/ai-context/ai_context.md +130 -0
  11. package/{test-projects/react-app/.ai-dev → ai-context}/ai_rules.md +10 -5
  12. package/ai-context/architecture.md +136 -0
  13. package/ai-context/context/features/src.json +69 -0
  14. package/ai-context/context/features/test-projects.json +69 -0
  15. package/ai-context/context/flows/App.json +17 -0
  16. package/ai-context/context/flows/DashboardPage.json +14 -0
  17. package/ai-context/context/flows/LoginPage.json +14 -0
  18. package/ai-context/context/flows/admin.json +10 -0
  19. package/ai-context/context/flows/ai-first.json +9 -0
  20. package/ai-context/context/flows/androidresources.json +11 -0
  21. package/ai-context/context/flows/auth.json +13 -0
  22. package/ai-context/context/flows/authController.json +14 -0
  23. package/ai-context/context/flows/doctor.json +9 -0
  24. package/ai-context/context/flows/entrypoints.json +9 -0
  25. package/ai-context/context/flows/explore.json +9 -0
  26. package/ai-context/context/flows/fastapiAdapter.json +14 -0
  27. package/ai-context/context/flows/fastapiadapter.json +11 -0
  28. package/ai-context/context/flows/index.json +19 -0
  29. package/ai-context/context/flows/indexer.json +9 -0
  30. package/ai-context/context/flows/indexstate.json +9 -0
  31. package/ai-context/context/flows/init.json +22 -0
  32. package/ai-context/context/flows/main.json +18 -0
  33. package/ai-context/context/flows/mainactivity.json +9 -0
  34. package/ai-context/context/flows/models.json +15 -0
  35. package/ai-context/context/flows/posts.json +15 -0
  36. package/ai-context/context/flows/repoMapper.json +20 -0
  37. package/ai-context/context/flows/repomapper.json +11 -0
  38. package/ai-context/context/flows/routes.json +15 -0
  39. package/ai-context/context/flows/serializers.json +10 -0
  40. package/ai-context/context/flows/user.json +23 -0
  41. package/ai-context/context/flows/views.json +12 -0
  42. package/{test-projects/react-app/.ai-dev → ai-context}/conventions.md +3 -2
  43. package/ai-context/dependencies.json +3360 -0
  44. package/ai-context/entrypoints.md +45 -0
  45. package/ai-context/index-state.json +196 -0
  46. package/ai-context/modules.json +901 -0
  47. package/ai-context/project.json +33 -0
  48. package/ai-context/repo_map.json +8857 -0
  49. package/ai-context/repo_map.md +2002 -0
  50. package/{test-projects/flask-app/.ai-dev → ai-context}/schema.json +1 -1
  51. package/ai-context/summary.md +46 -0
  52. package/ai-context/symbols.json +82467 -0
  53. package/{test-projects/react-app/.ai-dev → ai-context}/tech_stack.md +15 -7
  54. package/ai-context-evaluation-report-1774223059505.md +206 -0
  55. package/dist/analyzers/architecture.d.ts.map +1 -1
  56. package/dist/analyzers/architecture.js +6 -0
  57. package/dist/analyzers/architecture.js.map +1 -1
  58. package/dist/analyzers/entrypoints.d.ts.map +1 -1
  59. package/dist/analyzers/entrypoints.js +105 -0
  60. package/dist/analyzers/entrypoints.js.map +1 -1
  61. package/dist/analyzers/symbols.d.ts.map +1 -1
  62. package/dist/analyzers/symbols.js +72 -1
  63. package/dist/analyzers/symbols.js.map +1 -1
  64. package/dist/analyzers/techStack.d.ts +8 -0
  65. package/dist/analyzers/techStack.d.ts.map +1 -1
  66. package/dist/analyzers/techStack.js +75 -0
  67. package/dist/analyzers/techStack.js.map +1 -1
  68. package/dist/scripts/ai-context-evaluator.js +367 -0
  69. package/package.json +1 -1
  70. package/quick-evaluation-report-1774396002305.md +64 -0
  71. package/quick-evaluator.ts +200 -0
  72. package/scripts/ai-context-evaluator.ts +440 -0
  73. package/src/analyzers/architecture.ts +8 -0
  74. package/src/analyzers/entrypoints.ts +115 -0
  75. package/src/analyzers/symbols.ts +77 -1
  76. package/src/analyzers/techStack.ts +93 -0
  77. package/tests/apex-parser.test.ts +193 -0
  78. package/tests/cli-commands-batch1.test.ts +808 -0
  79. package/tests/cli-commands-batch2.test.ts +1113 -0
  80. package/tests/cli-commands-batch3.test.ts +1128 -0
  81. package/tests/cli-index.test.ts +1007 -0
  82. package/tests/cli-init.test.ts +761 -0
  83. package/tests/salesforce-apex-classes.test.ts +713 -0
  84. package/tests/salesforce-apex-triggers.test.ts +871 -0
  85. package/tests/salesforce-custom-objects.test.ts +918 -0
  86. package/tests/salesforce-flows.test.ts +710 -0
  87. package/tests/salesforce-lwc.test.ts +963 -0
  88. package/tests/salesforce-sfdx-integration.test.ts +1125 -0
  89. package/ANALISIS_COMPLETO.md +0 -424
  90. package/ANALISIS_MEJORAS.md +0 -327
  91. package/CONTRIBUTING.md +0 -89
  92. package/FLOW.md +0 -129
  93. package/TEST_RESULTS.md +0 -198
  94. package/TEST_RESULTS_COMPARATIVE.md +0 -159
  95. package/TEST_RESULTS_COMPLETE.md +0 -127
  96. package/TEST_RESULTS_COMPREHENSIVE.md +0 -208
  97. package/install.sh +0 -188
  98. package/run-all-tests.sh +0 -184
  99. package/test-ai-context-understanding.sh +0 -21
  100. package/test-projects/django-app/.ai-dev/ai_context.md +0 -92
  101. package/test-projects/django-app/.ai-dev/ai_rules.md +0 -47
  102. package/test-projects/django-app/.ai-dev/architecture.md +0 -57
  103. package/test-projects/django-app/.ai-dev/cache.json +0 -169
  104. package/test-projects/django-app/.ai-dev/context/flows/views.json +0 -10
  105. package/test-projects/django-app/.ai-dev/conventions.md +0 -51
  106. package/test-projects/django-app/.ai-dev/dependencies.json +0 -312
  107. package/test-projects/django-app/.ai-dev/entrypoints.md +0 -4
  108. package/test-projects/django-app/.ai-dev/files.json +0 -209
  109. package/test-projects/django-app/.ai-dev/graph/knowledge-graph.json +0 -36
  110. package/test-projects/django-app/.ai-dev/graph/module-graph.json +0 -145
  111. package/test-projects/django-app/.ai-dev/graph/symbol-graph.json +0 -1488
  112. package/test-projects/django-app/.ai-dev/graph/symbol-references.json +0 -1
  113. package/test-projects/django-app/.ai-dev/index-state.json +0 -294
  114. package/test-projects/django-app/.ai-dev/modules.json +0 -35
  115. package/test-projects/django-app/.ai-dev/project.json +0 -11
  116. package/test-projects/django-app/.ai-dev/repo_map.json +0 -412
  117. package/test-projects/django-app/.ai-dev/repo_map.md +0 -105
  118. package/test-projects/django-app/.ai-dev/schema.json +0 -5
  119. package/test-projects/django-app/.ai-dev/summary.md +0 -15
  120. package/test-projects/django-app/.ai-dev/symbols.json +0 -1
  121. package/test-projects/django-app/.ai-dev/tech_stack.md +0 -32
  122. package/test-projects/django-app/README.md +0 -91
  123. package/test-projects/django-app/blog/__init__.py +0 -0
  124. package/test-projects/django-app/blog/admin.py +0 -31
  125. package/test-projects/django-app/blog/models.py +0 -55
  126. package/test-projects/django-app/blog/serializers.py +0 -69
  127. package/test-projects/django-app/blog/urls.py +0 -14
  128. package/test-projects/django-app/blog/views.py +0 -96
  129. package/test-projects/django-app/django_app/__init__.py +0 -0
  130. package/test-projects/django-app/django_app/settings.py +0 -90
  131. package/test-projects/django-app/django_app/urls.py +0 -11
  132. package/test-projects/django-app/django_app/wsgi.py +0 -9
  133. package/test-projects/django-app/manage.py +0 -23
  134. package/test-projects/django-app/requirements.txt +0 -3
  135. package/test-projects/django-app/users/__init__.py +0 -0
  136. package/test-projects/django-app/users/admin.py +0 -42
  137. package/test-projects/django-app/users/models.py +0 -54
  138. package/test-projects/django-app/users/serializers.py +0 -113
  139. package/test-projects/django-app/users/urls.py +0 -13
  140. package/test-projects/django-app/users/views.py +0 -135
  141. package/test-projects/express-api/.ai-dev/ai_context.md +0 -112
  142. package/test-projects/express-api/.ai-dev/ai_rules.md +0 -50
  143. package/test-projects/express-api/.ai-dev/architecture.md +0 -62
  144. package/test-projects/express-api/.ai-dev/context/features/controllers.json +0 -13
  145. package/test-projects/express-api/.ai-dev/context/features/services.json +0 -13
  146. package/test-projects/express-api/.ai-dev/context/flows/auth.json +0 -12
  147. package/test-projects/express-api/.ai-dev/context/flows/user.json +0 -13
  148. package/test-projects/express-api/.ai-dev/conventions.md +0 -51
  149. package/test-projects/express-api/.ai-dev/dependencies.json +0 -54
  150. package/test-projects/express-api/.ai-dev/entrypoints.md +0 -17
  151. package/test-projects/express-api/.ai-dev/modules.json +0 -30
  152. package/test-projects/express-api/.ai-dev/project.json +0 -15
  153. package/test-projects/express-api/.ai-dev/repo_map.json +0 -100
  154. package/test-projects/express-api/.ai-dev/repo_map.md +0 -36
  155. package/test-projects/express-api/.ai-dev/schema.json +0 -5
  156. package/test-projects/express-api/.ai-dev/summary.md +0 -14
  157. package/test-projects/express-api/.ai-dev/symbols.json +0 -7
  158. package/test-projects/express-api/.ai-dev/tech_stack.md +0 -38
  159. package/test-projects/express-api/.ai-dev/tools.json +0 -10
  160. package/test-projects/express-api/controllers/authController.js +0 -32
  161. package/test-projects/express-api/controllers/userController.js +0 -51
  162. package/test-projects/express-api/index.js +0 -30
  163. package/test-projects/express-api/middleware/authMiddleware.js +0 -30
  164. package/test-projects/express-api/models/userRepository.js +0 -25
  165. package/test-projects/express-api/package.json +0 -18
  166. package/test-projects/express-api/services/authService.js +0 -17
  167. package/test-projects/express-api/services/userService.js +0 -28
  168. package/test-projects/fastapi-app/.ai-dev/ai_context.md +0 -89
  169. package/test-projects/fastapi-app/.ai-dev/ai_rules.md +0 -47
  170. package/test-projects/fastapi-app/.ai-dev/architecture.md +0 -39
  171. package/test-projects/fastapi-app/.ai-dev/cache.json +0 -125
  172. package/test-projects/fastapi-app/.ai-dev/conventions.md +0 -51
  173. package/test-projects/fastapi-app/.ai-dev/dependencies.json +0 -244
  174. package/test-projects/fastapi-app/.ai-dev/entrypoints.md +0 -4
  175. package/test-projects/fastapi-app/.ai-dev/files.json +0 -154
  176. package/test-projects/fastapi-app/.ai-dev/graph/knowledge-graph.json +0 -15
  177. package/test-projects/fastapi-app/.ai-dev/graph/module-graph.json +0 -78
  178. package/test-projects/fastapi-app/.ai-dev/graph/symbol-graph.json +0 -1724
  179. package/test-projects/fastapi-app/.ai-dev/graph/symbol-references.json +0 -51
  180. package/test-projects/fastapi-app/.ai-dev/index-state.json +0 -217
  181. package/test-projects/fastapi-app/.ai-dev/modules.json +0 -16
  182. package/test-projects/fastapi-app/.ai-dev/project.json +0 -9
  183. package/test-projects/fastapi-app/.ai-dev/repo_map.json +0 -298
  184. package/test-projects/fastapi-app/.ai-dev/repo_map.md +0 -74
  185. package/test-projects/fastapi-app/.ai-dev/schema.json +0 -5
  186. package/test-projects/fastapi-app/.ai-dev/summary.md +0 -12
  187. package/test-projects/fastapi-app/.ai-dev/symbols.json +0 -1
  188. package/test-projects/fastapi-app/.ai-dev/tech_stack.md +0 -32
  189. package/test-projects/fastapi-app/.ai-dev/tools.json +0 -10
  190. package/test-projects/fastapi-app/README.md +0 -118
  191. package/test-projects/fastapi-app/app/database.py +0 -21
  192. package/test-projects/fastapi-app/app/dependencies.py +0 -107
  193. package/test-projects/fastapi-app/app/main.py +0 -47
  194. package/test-projects/fastapi-app/app/models.py +0 -149
  195. package/test-projects/fastapi-app/app/routers/auth.py +0 -117
  196. package/test-projects/fastapi-app/app/routers/posts.py +0 -272
  197. package/test-projects/fastapi-app/app/schemas.py +0 -191
  198. package/test-projects/fastapi-app/requirements.txt +0 -10
  199. package/test-projects/flask-app/.ai-dev/ai_context.md +0 -94
  200. package/test-projects/flask-app/.ai-dev/ai_rules.md +0 -47
  201. package/test-projects/flask-app/.ai-dev/architecture.md +0 -49
  202. package/test-projects/flask-app/.ai-dev/cache.json +0 -157
  203. package/test-projects/flask-app/.ai-dev/context/features/app.json +0 -25
  204. package/test-projects/flask-app/.ai-dev/context/flows/routes.json +0 -14
  205. package/test-projects/flask-app/.ai-dev/conventions.md +0 -51
  206. package/test-projects/flask-app/.ai-dev/dependencies.json +0 -298
  207. package/test-projects/flask-app/.ai-dev/entrypoints.md +0 -4
  208. package/test-projects/flask-app/.ai-dev/files.json +0 -194
  209. package/test-projects/flask-app/.ai-dev/graph/knowledge-graph.json +0 -60
  210. package/test-projects/flask-app/.ai-dev/graph/module-graph.json +0 -95
  211. package/test-projects/flask-app/.ai-dev/graph/symbol-graph.json +0 -1448
  212. package/test-projects/flask-app/.ai-dev/graph/symbol-references.json +0 -45
  213. package/test-projects/flask-app/.ai-dev/index-state.json +0 -273
  214. package/test-projects/flask-app/.ai-dev/modules.json +0 -21
  215. package/test-projects/flask-app/.ai-dev/project.json +0 -13
  216. package/test-projects/flask-app/.ai-dev/repo_map.json +0 -400
  217. package/test-projects/flask-app/.ai-dev/repo_map.md +0 -98
  218. package/test-projects/flask-app/.ai-dev/summary.md +0 -13
  219. package/test-projects/flask-app/.ai-dev/symbols.json +0 -1
  220. package/test-projects/flask-app/.ai-dev/tech_stack.md +0 -32
  221. package/test-projects/flask-app/.ai-dev/tools.json +0 -10
  222. package/test-projects/flask-app/README.md +0 -129
  223. package/test-projects/flask-app/app/__init__.py +0 -46
  224. package/test-projects/flask-app/app/api/__init__.py +0 -7
  225. package/test-projects/flask-app/app/api/routes.py +0 -122
  226. package/test-projects/flask-app/app/auth/__init__.py +0 -7
  227. package/test-projects/flask-app/app/auth/forms.py +0 -52
  228. package/test-projects/flask-app/app/auth/routes.py +0 -68
  229. package/test-projects/flask-app/app/blog/__init__.py +0 -7
  230. package/test-projects/flask-app/app/blog/forms.py +0 -35
  231. package/test-projects/flask-app/app/blog/routes.py +0 -140
  232. package/test-projects/flask-app/app/main/__init__.py +0 -7
  233. package/test-projects/flask-app/app/main/routes.py +0 -88
  234. package/test-projects/flask-app/app/models.py +0 -177
  235. package/test-projects/flask-app/config.py +0 -64
  236. package/test-projects/flask-app/requirements.txt +0 -10
  237. package/test-projects/laravel-app/.ai-dev/ai_context.md +0 -97
  238. package/test-projects/laravel-app/.ai-dev/ai_rules.md +0 -47
  239. package/test-projects/laravel-app/.ai-dev/architecture.md +0 -60
  240. package/test-projects/laravel-app/.ai-dev/cache.json +0 -161
  241. package/test-projects/laravel-app/.ai-dev/context/features/app.json +0 -21
  242. package/test-projects/laravel-app/.ai-dev/context/flows/.json +0 -9
  243. package/test-projects/laravel-app/.ai-dev/context/flows/category.json +0 -12
  244. package/test-projects/laravel-app/.ai-dev/context/flows/comment.json +0 -12
  245. package/test-projects/laravel-app/.ai-dev/context/flows/post.json +0 -12
  246. package/test-projects/laravel-app/.ai-dev/context/flows/unnamed.json +0 -9
  247. package/test-projects/laravel-app/.ai-dev/conventions.md +0 -51
  248. package/test-projects/laravel-app/.ai-dev/dependencies.json +0 -6
  249. package/test-projects/laravel-app/.ai-dev/entrypoints.md +0 -4
  250. package/test-projects/laravel-app/.ai-dev/files.json +0 -199
  251. package/test-projects/laravel-app/.ai-dev/graph/knowledge-graph.json +0 -98
  252. package/test-projects/laravel-app/.ai-dev/graph/module-graph.json +0 -30
  253. package/test-projects/laravel-app/.ai-dev/graph/symbol-graph.json +0 -5
  254. package/test-projects/laravel-app/.ai-dev/graph/symbol-references.json +0 -1
  255. package/test-projects/laravel-app/.ai-dev/index-state.json +0 -280
  256. package/test-projects/laravel-app/.ai-dev/modules.json +0 -29
  257. package/test-projects/laravel-app/.ai-dev/project.json +0 -17
  258. package/test-projects/laravel-app/.ai-dev/repo_map.json +0 -419
  259. package/test-projects/laravel-app/.ai-dev/repo_map.md +0 -106
  260. package/test-projects/laravel-app/.ai-dev/schema.json +0 -5
  261. package/test-projects/laravel-app/.ai-dev/summary.md +0 -15
  262. package/test-projects/laravel-app/.ai-dev/symbols.json +0 -1
  263. package/test-projects/laravel-app/.ai-dev/tech_stack.md +0 -34
  264. package/test-projects/laravel-app/.ai-dev/tools.json +0 -10
  265. package/test-projects/laravel-app/README.md +0 -107
  266. package/test-projects/laravel-app/app/Http/Controllers/Api/CategoryController.php +0 -88
  267. package/test-projects/laravel-app/app/Http/Controllers/Api/CommentController.php +0 -56
  268. package/test-projects/laravel-app/app/Http/Controllers/Api/PostController.php +0 -174
  269. package/test-projects/laravel-app/app/Http/Controllers/Controller.php +0 -12
  270. package/test-projects/laravel-app/app/Models/Category.php +0 -34
  271. package/test-projects/laravel-app/app/Models/Comment.php +0 -51
  272. package/test-projects/laravel-app/app/Models/Post.php +0 -108
  273. package/test-projects/laravel-app/app/Models/User.php +0 -85
  274. package/test-projects/laravel-app/bootstrap/app.php +0 -25
  275. package/test-projects/laravel-app/composer.json +0 -35
  276. package/test-projects/laravel-app/routes/api.php +0 -40
  277. package/test-projects/nestjs-backend/.ai-dev/ai_context.md +0 -111
  278. package/test-projects/nestjs-backend/.ai-dev/ai_rules.md +0 -52
  279. package/test-projects/nestjs-backend/.ai-dev/architecture.md +0 -49
  280. package/test-projects/nestjs-backend/.ai-dev/cache.json +0 -169
  281. package/test-projects/nestjs-backend/.ai-dev/context/features/src.json +0 -23
  282. package/test-projects/nestjs-backend/.ai-dev/context/flows/auth.controller.json +0 -14
  283. package/test-projects/nestjs-backend/.ai-dev/context/flows/auth.json +0 -10
  284. package/test-projects/nestjs-backend/.ai-dev/context/flows/users..json +0 -10
  285. package/test-projects/nestjs-backend/.ai-dev/context/flows/users.controller.json +0 -14
  286. package/test-projects/nestjs-backend/.ai-dev/context/flows/users.json +0 -10
  287. package/test-projects/nestjs-backend/.ai-dev/conventions.md +0 -52
  288. package/test-projects/nestjs-backend/.ai-dev/dependencies.json +0 -152
  289. package/test-projects/nestjs-backend/.ai-dev/entrypoints.md +0 -18
  290. package/test-projects/nestjs-backend/.ai-dev/files.json +0 -209
  291. package/test-projects/nestjs-backend/.ai-dev/graph/knowledge-graph.json +0 -132
  292. package/test-projects/nestjs-backend/.ai-dev/graph/module-graph.json +0 -29
  293. package/test-projects/nestjs-backend/.ai-dev/graph/symbol-graph.json +0 -304
  294. package/test-projects/nestjs-backend/.ai-dev/graph/symbol-references.json +0 -5
  295. package/test-projects/nestjs-backend/.ai-dev/index-state.json +0 -294
  296. package/test-projects/nestjs-backend/.ai-dev/modules.json +0 -19
  297. package/test-projects/nestjs-backend/.ai-dev/project.json +0 -18
  298. package/test-projects/nestjs-backend/.ai-dev/repo_map.json +0 -427
  299. package/test-projects/nestjs-backend/.ai-dev/repo_map.md +0 -104
  300. package/test-projects/nestjs-backend/.ai-dev/schema.json +0 -5
  301. package/test-projects/nestjs-backend/.ai-dev/summary.md +0 -13
  302. package/test-projects/nestjs-backend/.ai-dev/symbols.json +0 -1
  303. package/test-projects/nestjs-backend/.ai-dev/tech_stack.md +0 -38
  304. package/test-projects/nestjs-backend/.ai-dev/tools.json +0 -10
  305. package/test-projects/nestjs-backend/package.json +0 -22
  306. package/test-projects/nestjs-backend/src/app.module.ts +0 -8
  307. package/test-projects/nestjs-backend/src/auth/auth.controller.ts +0 -22
  308. package/test-projects/nestjs-backend/src/auth/auth.module.ts +0 -11
  309. package/test-projects/nestjs-backend/src/auth/auth.service.ts +0 -28
  310. package/test-projects/nestjs-backend/src/auth/dto/login.dto.ts +0 -4
  311. package/test-projects/nestjs-backend/src/auth/strategies/jwt.strategy.ts +0 -18
  312. package/test-projects/nestjs-backend/src/main.ts +0 -9
  313. package/test-projects/nestjs-backend/src/users/users.controller.ts +0 -32
  314. package/test-projects/nestjs-backend/src/users/users.module.ts +0 -10
  315. package/test-projects/nestjs-backend/src/users/users.service.ts +0 -42
  316. package/test-projects/nestjs-backend/tsconfig.json +0 -21
  317. package/test-projects/python-cli/.ai-dev/ai_context.md +0 -95
  318. package/test-projects/python-cli/.ai-dev/ai_rules.md +0 -47
  319. package/test-projects/python-cli/.ai-dev/architecture.md +0 -55
  320. package/test-projects/python-cli/.ai-dev/cache.json +0 -149
  321. package/test-projects/python-cli/.ai-dev/context/features/cli.json +0 -16
  322. package/test-projects/python-cli/.ai-dev/context/flows/list_.json +0 -9
  323. package/test-projects/python-cli/.ai-dev/context/flows/remove_.json +0 -9
  324. package/test-projects/python-cli/.ai-dev/conventions.md +0 -51
  325. package/test-projects/python-cli/.ai-dev/dependencies.json +0 -66
  326. package/test-projects/python-cli/.ai-dev/entrypoints.md +0 -4
  327. package/test-projects/python-cli/.ai-dev/files.json +0 -184
  328. package/test-projects/python-cli/.ai-dev/graph/knowledge-graph.json +0 -83
  329. package/test-projects/python-cli/.ai-dev/graph/module-graph.json +0 -31
  330. package/test-projects/python-cli/.ai-dev/graph/symbol-graph.json +0 -358
  331. package/test-projects/python-cli/.ai-dev/graph/symbol-references.json +0 -11
  332. package/test-projects/python-cli/.ai-dev/index-state.json +0 -259
  333. package/test-projects/python-cli/.ai-dev/modules.json +0 -21
  334. package/test-projects/python-cli/.ai-dev/project.json +0 -15
  335. package/test-projects/python-cli/.ai-dev/repo_map.json +0 -367
  336. package/test-projects/python-cli/.ai-dev/repo_map.md +0 -93
  337. package/test-projects/python-cli/.ai-dev/schema.json +0 -5
  338. package/test-projects/python-cli/.ai-dev/summary.md +0 -14
  339. package/test-projects/python-cli/.ai-dev/symbols.json +0 -1
  340. package/test-projects/python-cli/.ai-dev/tech_stack.md +0 -32
  341. package/test-projects/python-cli/.ai-dev/tools.json +0 -10
  342. package/test-projects/python-cli/__init__.py +0 -1
  343. package/test-projects/python-cli/cli/__init__.py +0 -1
  344. package/test-projects/python-cli/cli/add_command.py +0 -6
  345. package/test-projects/python-cli/cli/list_command.py +0 -7
  346. package/test-projects/python-cli/cli/remove_command.py +0 -6
  347. package/test-projects/python-cli/main.py +0 -34
  348. package/test-projects/python-cli/models/__init__.py +0 -2
  349. package/test-projects/python-cli/models/task.py +0 -19
  350. package/test-projects/python-cli/models/task_repository.py +0 -44
  351. package/test-projects/rails-app/.ai-dev/ai_context.md +0 -94
  352. package/test-projects/rails-app/.ai-dev/ai_rules.md +0 -47
  353. package/test-projects/rails-app/.ai-dev/architecture.md +0 -49
  354. package/test-projects/rails-app/.ai-dev/cache.json +0 -193
  355. package/test-projects/rails-app/.ai-dev/context/features/app.json +0 -24
  356. package/test-projects/rails-app/.ai-dev/context/features/config.json +0 -13
  357. package/test-projects/rails-app/.ai-dev/context/flows/application.json +0 -9
  358. package/test-projects/rails-app/.ai-dev/context/flows/application_.json +0 -9
  359. package/test-projects/rails-app/.ai-dev/context/flows/comments.json +0 -11
  360. package/test-projects/rails-app/.ai-dev/context/flows/comments_.json +0 -11
  361. package/test-projects/rails-app/.ai-dev/context/flows/posts.json +0 -11
  362. package/test-projects/rails-app/.ai-dev/context/flows/posts_.json +0 -11
  363. package/test-projects/rails-app/.ai-dev/context/flows/routes.json +0 -9
  364. package/test-projects/rails-app/.ai-dev/context/flows/users.json +0 -11
  365. package/test-projects/rails-app/.ai-dev/context/flows/users_.json +0 -11
  366. package/test-projects/rails-app/.ai-dev/conventions.md +0 -51
  367. package/test-projects/rails-app/.ai-dev/dependencies.json +0 -6
  368. package/test-projects/rails-app/.ai-dev/entrypoints.md +0 -4
  369. package/test-projects/rails-app/.ai-dev/files.json +0 -239
  370. package/test-projects/rails-app/.ai-dev/graph/knowledge-graph.json +0 -130
  371. package/test-projects/rails-app/.ai-dev/graph/module-graph.json +0 -27
  372. package/test-projects/rails-app/.ai-dev/graph/symbol-graph.json +0 -5
  373. package/test-projects/rails-app/.ai-dev/graph/symbol-references.json +0 -1
  374. package/test-projects/rails-app/.ai-dev/index-state.json +0 -336
  375. package/test-projects/rails-app/.ai-dev/modules.json +0 -26
  376. package/test-projects/rails-app/.ai-dev/project.json +0 -22
  377. package/test-projects/rails-app/.ai-dev/repo_map.json +0 -486
  378. package/test-projects/rails-app/.ai-dev/repo_map.md +0 -117
  379. package/test-projects/rails-app/.ai-dev/schema.json +0 -5
  380. package/test-projects/rails-app/.ai-dev/summary.md +0 -13
  381. package/test-projects/rails-app/.ai-dev/symbols.json +0 -1
  382. package/test-projects/rails-app/.ai-dev/tech_stack.md +0 -32
  383. package/test-projects/rails-app/.ai-dev/tools.json +0 -10
  384. package/test-projects/rails-app/Gemfile +0 -38
  385. package/test-projects/rails-app/README.md +0 -140
  386. package/test-projects/rails-app/Rakefile +0 -8
  387. package/test-projects/rails-app/app/controllers/api/comments_controller.rb +0 -75
  388. package/test-projects/rails-app/app/controllers/api/posts_controller.rb +0 -68
  389. package/test-projects/rails-app/app/controllers/api/users_controller.rb +0 -54
  390. package/test-projects/rails-app/app/controllers/application_controller.rb +0 -31
  391. package/test-projects/rails-app/app/models/comment.rb +0 -34
  392. package/test-projects/rails-app/app/models/post.rb +0 -36
  393. package/test-projects/rails-app/app/models/user.rb +0 -28
  394. package/test-projects/rails-app/app/services/post_service.rb +0 -92
  395. package/test-projects/rails-app/app/services/user_service.rb +0 -76
  396. package/test-projects/rails-app/config/application.rb +0 -27
  397. package/test-projects/rails-app/config/environment.rb +0 -7
  398. package/test-projects/rails-app/config/routes.rb +0 -15
  399. package/test-projects/react-app/.ai-dev/ai_context.md +0 -96
  400. package/test-projects/react-app/.ai-dev/architecture.md +0 -39
  401. package/test-projects/react-app/.ai-dev/cache.json +0 -153
  402. package/test-projects/react-app/.ai-dev/context/features/src.json +0 -18
  403. package/test-projects/react-app/.ai-dev/context/flows/UsersPage.json +0 -14
  404. package/test-projects/react-app/.ai-dev/context/flows/dashboard.json +0 -9
  405. package/test-projects/react-app/.ai-dev/context/flows/login.json +0 -9
  406. package/test-projects/react-app/.ai-dev/context/flows/users.json +0 -9
  407. package/test-projects/react-app/.ai-dev/dependencies.json +0 -128
  408. package/test-projects/react-app/.ai-dev/entrypoints.md +0 -4
  409. package/test-projects/react-app/.ai-dev/files.json +0 -189
  410. package/test-projects/react-app/.ai-dev/graph/knowledge-graph.json +0 -112
  411. package/test-projects/react-app/.ai-dev/graph/module-graph.json +0 -31
  412. package/test-projects/react-app/.ai-dev/graph/symbol-graph.json +0 -868
  413. package/test-projects/react-app/.ai-dev/graph/symbol-references.json +0 -31
  414. package/test-projects/react-app/.ai-dev/index-state.json +0 -266
  415. package/test-projects/react-app/.ai-dev/modules.json +0 -17
  416. package/test-projects/react-app/.ai-dev/project.json +0 -16
  417. package/test-projects/react-app/.ai-dev/repo_map.json +0 -391
  418. package/test-projects/react-app/.ai-dev/repo_map.md +0 -94
  419. package/test-projects/react-app/.ai-dev/schema.json +0 -5
  420. package/test-projects/react-app/.ai-dev/summary.md +0 -13
  421. package/test-projects/react-app/.ai-dev/symbols.json +0 -1
  422. package/test-projects/react-app/.ai-dev/tools.json +0 -10
  423. package/test-projects/react-app/package.json +0 -16
  424. package/test-projects/react-app/src/App.tsx +0 -21
  425. package/test-projects/react-app/src/context/AuthContext.tsx +0 -41
  426. package/test-projects/react-app/src/hooks/useAuth.ts +0 -10
  427. package/test-projects/react-app/src/main.tsx +0 -10
  428. package/test-projects/react-app/src/pages/DashboardPage.tsx +0 -17
  429. package/test-projects/react-app/src/pages/LoginPage.tsx +0 -41
  430. package/test-projects/react-app/src/pages/UsersPage.tsx +0 -36
  431. package/test-projects/react-app/src/services/userService.ts +0 -37
  432. package/test-projects/salesforce-cli/.ai-dev/ai_context.md +0 -89
  433. package/test-projects/salesforce-cli/.ai-dev/ai_rules.md +0 -47
  434. package/test-projects/salesforce-cli/.ai-dev/architecture.md +0 -39
  435. package/test-projects/salesforce-cli/.ai-dev/cache.json +0 -125
  436. package/test-projects/salesforce-cli/.ai-dev/context/features/force-app.json +0 -14
  437. package/test-projects/salesforce-cli/.ai-dev/context/flows/account.json +0 -9
  438. package/test-projects/salesforce-cli/.ai-dev/context/flows/opportunity.json +0 -9
  439. package/test-projects/salesforce-cli/.ai-dev/conventions.md +0 -51
  440. package/test-projects/salesforce-cli/.ai-dev/dependencies.json +0 -6
  441. package/test-projects/salesforce-cli/.ai-dev/entrypoints.md +0 -4
  442. package/test-projects/salesforce-cli/.ai-dev/files.json +0 -154
  443. package/test-projects/salesforce-cli/.ai-dev/graph/knowledge-graph.json +0 -64
  444. package/test-projects/salesforce-cli/.ai-dev/graph/module-graph.json +0 -13
  445. package/test-projects/salesforce-cli/.ai-dev/graph/symbol-graph.json +0 -148
  446. package/test-projects/salesforce-cli/.ai-dev/graph/symbol-references.json +0 -1
  447. package/test-projects/salesforce-cli/.ai-dev/index-state.json +0 -217
  448. package/test-projects/salesforce-cli/.ai-dev/modules.json +0 -12
  449. package/test-projects/salesforce-cli/.ai-dev/project.json +0 -14
  450. package/test-projects/salesforce-cli/.ai-dev/repo_map.json +0 -328
  451. package/test-projects/salesforce-cli/.ai-dev/repo_map.md +0 -80
  452. package/test-projects/salesforce-cli/.ai-dev/schema.json +0 -5
  453. package/test-projects/salesforce-cli/.ai-dev/summary.md +0 -13
  454. package/test-projects/salesforce-cli/.ai-dev/symbols.json +0 -1
  455. package/test-projects/salesforce-cli/.ai-dev/tech_stack.md +0 -31
  456. package/test-projects/salesforce-cli/.ai-dev/tools.json +0 -10
  457. package/test-projects/salesforce-cli/.forceignore +0 -27
  458. package/test-projects/salesforce-cli/force-app/main/default/classes/AccountController.cls +0 -24
  459. package/test-projects/salesforce-cli/force-app/main/default/classes/OpportunityController.cls +0 -25
  460. package/test-projects/salesforce-cli/force-app/main/default/objects/Project__c.object.xml +0 -45
  461. package/test-projects/salesforce-cli/force-app/main/default/triggers/AccountTrigger.trigger +0 -33
  462. package/test-projects/salesforce-cli/sfdx-project.json +0 -11
  463. package/test-projects/spring-boot-app/.ai-dev/ai_context.md +0 -91
  464. package/test-projects/spring-boot-app/.ai-dev/ai_rules.md +0 -48
  465. package/test-projects/spring-boot-app/.ai-dev/architecture.md +0 -39
  466. package/test-projects/spring-boot-app/.ai-dev/cache.json +0 -173
  467. package/test-projects/spring-boot-app/.ai-dev/context/features/src.json +0 -26
  468. package/test-projects/spring-boot-app/.ai-dev/context/flows/PostController.json +0 -19
  469. package/test-projects/spring-boot-app/.ai-dev/context/flows/UserController.json +0 -19
  470. package/test-projects/spring-boot-app/.ai-dev/context/flows/comment.json +0 -11
  471. package/test-projects/spring-boot-app/.ai-dev/context/flows/post.json +0 -14
  472. package/test-projects/spring-boot-app/.ai-dev/context/flows/user.json +0 -14
  473. package/test-projects/spring-boot-app/.ai-dev/conventions.md +0 -52
  474. package/test-projects/spring-boot-app/.ai-dev/dependencies.json +0 -326
  475. package/test-projects/spring-boot-app/.ai-dev/entrypoints.md +0 -4
  476. package/test-projects/spring-boot-app/.ai-dev/files.json +0 -214
  477. package/test-projects/spring-boot-app/.ai-dev/graph/knowledge-graph.json +0 -231
  478. package/test-projects/spring-boot-app/.ai-dev/graph/module-graph.json +0 -22
  479. package/test-projects/spring-boot-app/.ai-dev/graph/symbol-graph.json +0 -794
  480. package/test-projects/spring-boot-app/.ai-dev/graph/symbol-references.json +0 -70
  481. package/test-projects/spring-boot-app/.ai-dev/index-state.json +0 -301
  482. package/test-projects/spring-boot-app/.ai-dev/modules.json +0 -21
  483. package/test-projects/spring-boot-app/.ai-dev/project.json +0 -17
  484. package/test-projects/spring-boot-app/.ai-dev/repo_map.json +0 -461
  485. package/test-projects/spring-boot-app/.ai-dev/repo_map.md +0 -109
  486. package/test-projects/spring-boot-app/.ai-dev/schema.json +0 -5
  487. package/test-projects/spring-boot-app/.ai-dev/summary.md +0 -12
  488. package/test-projects/spring-boot-app/.ai-dev/symbols.json +0 -1
  489. package/test-projects/spring-boot-app/.ai-dev/tech_stack.md +0 -32
  490. package/test-projects/spring-boot-app/.ai-dev/tools.json +0 -10
  491. package/test-projects/spring-boot-app/.classpath +0 -57
  492. package/test-projects/spring-boot-app/.factorypath +0 -69
  493. package/test-projects/spring-boot-app/.project +0 -34
  494. package/test-projects/spring-boot-app/.settings/org.eclipse.core.resources.prefs +0 -4
  495. package/test-projects/spring-boot-app/.settings/org.eclipse.jdt.apt.core.prefs +0 -4
  496. package/test-projects/spring-boot-app/.settings/org.eclipse.jdt.core.prefs +0 -10
  497. package/test-projects/spring-boot-app/.settings/org.eclipse.m2e.core.prefs +0 -4
  498. package/test-projects/spring-boot-app/README.md +0 -122
  499. package/test-projects/spring-boot-app/pom.xml +0 -79
  500. package/test-projects/spring-boot-app/src/main/java/com/example/demo/DemoApplication.java +0 -12
  501. package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/CommentController.java +0 -89
  502. package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/PostController.java +0 -92
  503. package/test-projects/spring-boot-app/src/main/java/com/example/demo/controllers/UserController.java +0 -84
  504. package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/Comment.java +0 -38
  505. package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/Post.java +0 -56
  506. package/test-projects/spring-boot-app/src/main/java/com/example/demo/models/User.java +0 -44
  507. package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/CommentRepository.java +0 -21
  508. package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/PostRepository.java +0 -18
  509. package/test-projects/spring-boot-app/src/main/java/com/example/demo/repositories/UserRepository.java +0 -15
  510. package/test-projects/spring-boot-app/src/main/java/com/example/demo/services/PostService.java +0 -83
  511. package/test-projects/spring-boot-app/src/main/java/com/example/demo/services/UserService.java +0 -62
  512. package/test-projects/spring-boot-app/src/main/resources/application.properties +0 -22
  513. package/test-projects/spring-boot-app/target/classes/com/example/demo/DemoApplication.class +0 -0
  514. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController$CommentCreateRequest.class +0 -0
  515. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController$CommentUpdateRequest.class +0 -0
  516. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/CommentController.class +0 -0
  517. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController$PostCreateRequest.class +0 -0
  518. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController$PostUpdateRequest.class +0 -0
  519. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/PostController.class +0 -0
  520. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController$UserCreateRequest.class +0 -0
  521. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController$UserUpdateRequest.class +0 -0
  522. package/test-projects/spring-boot-app/target/classes/com/example/demo/controllers/UserController.class +0 -0
  523. package/test-projects/spring-boot-app/target/classes/com/example/demo/models/Comment.class +0 -0
  524. package/test-projects/spring-boot-app/target/classes/com/example/demo/models/Post.class +0 -0
  525. package/test-projects/spring-boot-app/target/classes/com/example/demo/models/User.class +0 -0
  526. package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/CommentRepository.class +0 -0
  527. package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/PostRepository.class +0 -0
  528. package/test-projects/spring-boot-app/target/classes/com/example/demo/repositories/UserRepository.class +0 -0
  529. package/test-projects/spring-boot-app/target/classes/com/example/demo/services/PostService.class +0 -0
  530. package/test-projects/spring-boot-app/target/classes/com/example/demo/services/UserService.class +0 -0
  531. package/tests/e2e/run-e2e.sh +0 -88
  532. /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
+ });