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