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,1113 @@
1
+ import { describe, it, expect, beforeAll, afterAll, beforeEach } from "vitest";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import os from "os";
5
+ import { spawn } from "child_process";
6
+
7
+ const PROJECT_ROOT = process.cwd();
8
+ const CLI_PATH = path.join(PROJECT_ROOT, "dist/commands/ai-first.js");
9
+ const EXPRESS_API_PATH = path.join(PROJECT_ROOT, "test-projects/express-api");
10
+
11
+ /**
12
+ * Creates a temporary project directory with some source files
13
+ */
14
+ function createTempProjectDir(files: Record<string, string>): string {
15
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-batch2-test-"));
16
+ for (const [filePath, content] of Object.entries(files)) {
17
+ const fullPath = path.join(tempDir, filePath);
18
+ const dir = path.dirname(fullPath);
19
+ if (!fs.existsSync(dir)) {
20
+ fs.mkdirSync(dir, { recursive: true });
21
+ }
22
+ fs.writeFileSync(fullPath, content);
23
+ }
24
+ return tempDir;
25
+ }
26
+
27
+ /**
28
+ * Run a CLI command and return stdout, stderr, and exit code
29
+ */
30
+ async function runCLICommand(
31
+ command: string,
32
+ args: string[],
33
+ cwd: string = process.cwd()
34
+ ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
35
+ return new Promise((resolve) => {
36
+ const child = spawn("node", [CLI_PATH, command, ...args], {
37
+ cwd,
38
+ stdio: "pipe",
39
+ });
40
+
41
+ let stdout = "";
42
+ let stderr = "";
43
+
44
+ child.stdout?.on("data", (data) => {
45
+ stdout += data.toString();
46
+ });
47
+
48
+ child.stderr?.on("data", (data) => {
49
+ stderr += data.toString();
50
+ });
51
+
52
+ child.on("close", (code) => {
53
+ resolve({
54
+ stdout,
55
+ stderr,
56
+ exitCode: code ?? 0,
57
+ });
58
+ });
59
+
60
+ child.on("error", (err) => {
61
+ stderr += err.message;
62
+ resolve({ stdout, stderr, exitCode: 1 });
63
+ });
64
+
65
+ // Timeout after 120 seconds
66
+ setTimeout(() => {
67
+ child.kill();
68
+ resolve({ stdout, stderr, exitCode: 124 });
69
+ }, 120000);
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Run doctor command
75
+ */
76
+ async function runDoctorCommand(
77
+ args: string[],
78
+ cwd: string = process.cwd()
79
+ ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
80
+ return runCLICommand("doctor", args, cwd);
81
+ }
82
+
83
+ /**
84
+ * Run explore command
85
+ */
86
+ async function runExploreCommand(
87
+ args: string[],
88
+ cwd: string = process.cwd()
89
+ ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
90
+ return runCLICommand("explore", args, cwd);
91
+ }
92
+
93
+ /**
94
+ * Run map command
95
+ */
96
+ async function runMapCommand(
97
+ args: string[],
98
+ cwd: string = process.cwd()
99
+ ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
100
+ return runCLICommand("map", args, cwd);
101
+ }
102
+
103
+ /**
104
+ * Run adapters command
105
+ */
106
+ async function runAdaptersCommand(
107
+ args: string[],
108
+ cwd: string = process.cwd()
109
+ ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
110
+ return runCLICommand("adapters", args, cwd);
111
+ }
112
+
113
+ describe("CLI Commands Batch 2 - doctor, explore, map, adapters", () => {
114
+ const tempDirs: string[] = [];
115
+
116
+ beforeAll(() => {
117
+ // Ensure dist is built
118
+ if (!fs.existsSync(CLI_PATH)) {
119
+ throw new Error(
120
+ `CLI not found at ${CLI_PATH}. Run 'npm run build' first.`
121
+ );
122
+ }
123
+ });
124
+
125
+ afterAll(() => {
126
+ // Clean up all temp directories
127
+ for (const dir of tempDirs) {
128
+ fs.rmSync(dir, { recursive: true, force: true });
129
+ }
130
+ });
131
+
132
+ const createMapTestProject = (files: Record<string, string>): string => {
133
+ const projectDir = createTempProjectDir(files);
134
+ const aiContextDir = path.join(projectDir, "ai-context");
135
+ fs.mkdirSync(aiContextDir, { recursive: true });
136
+ return projectDir;
137
+ };
138
+
139
+ // =========================================================================
140
+ // DOCTOR COMMAND TESTS
141
+ // =========================================================================
142
+ describe("Doctor Command", () => {
143
+ describe("Default Options", () => {
144
+ it("should run doctor command successfully on express-api project", async () => {
145
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
146
+
147
+ expect(result.exitCode).toBe(0);
148
+ expect(result.stdout).toContain("AI-First Doctor Report");
149
+ });
150
+
151
+ it("should report repository scanned status", async () => {
152
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
153
+
154
+ expect(result.stdout).toContain("Repository scanned");
155
+ expect(result.stdout).toContain("Found");
156
+ });
157
+
158
+ it("should report languages detected", async () => {
159
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
160
+
161
+ expect(result.stdout).toContain("Languages detected");
162
+ });
163
+
164
+ it("should report large files status", async () => {
165
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
166
+
167
+ expect(result.stdout).toContain("Large files");
168
+ expect(result.stdout).toMatch(/No large files|\d+ large files/);
169
+ });
170
+
171
+ it("should report AI directory status", async () => {
172
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
173
+
174
+ expect(result.stdout).toContain("AI directory");
175
+ });
176
+
177
+ it("should report Semantic index status", async () => {
178
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
179
+
180
+ expect(result.stdout).toContain("Semantic index");
181
+ });
182
+
183
+ it("should report Module graph status", async () => {
184
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
185
+
186
+ expect(result.stdout).toContain("Module graph");
187
+ });
188
+
189
+ it("should report SQLite index status", async () => {
190
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
191
+
192
+ expect(result.stdout).toContain("SQLite index");
193
+ });
194
+
195
+ it("should show summary with pass/warn/fail counts", async () => {
196
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
197
+
198
+ expect(result.stdout).toMatch(/Summary: \d+ passed, \d+ warnings, \d+ failed/);
199
+ });
200
+
201
+ it("should show status (READY, PARTIALLY READY, or NOT READY)", async () => {
202
+ const result = await runDoctorCommand([], EXPRESS_API_PATH);
203
+
204
+ expect(result.stdout).toMatch(/Status:/);
205
+ expect(result.stdout).toMatch(/READY|PARTIALLY READY|NOT READY/);
206
+ });
207
+ });
208
+
209
+ describe("--root Flag", () => {
210
+ it("should check different directory with --root flag", async () => {
211
+ const testProject = createTempProjectDir({
212
+ "index.js": "const app = require('./app');",
213
+ "package.json": '{"name": "test"}',
214
+ "src/main.ts": "export const main = () => {};",
215
+ });
216
+ tempDirs.push(testProject);
217
+
218
+ const result = await runDoctorCommand(["--root", testProject]);
219
+
220
+ expect(result.exitCode).toBe(0);
221
+ expect(result.stdout).toContain("AI-First Doctor");
222
+ expect(result.stdout).toContain(testProject);
223
+ });
224
+
225
+ it("should handle --root with short flag -r", async () => {
226
+ const testProject = createTempProjectDir({
227
+ "index.js": "const app = require('./app');",
228
+ "package.json": '{"name": "test"}',
229
+ });
230
+ tempDirs.push(testProject);
231
+
232
+ const result = await runDoctorCommand(["-r", testProject]);
233
+
234
+ expect(result.exitCode).toBe(0);
235
+ });
236
+ });
237
+
238
+ describe("--fix Flag", () => {
239
+ it("should accept --fix flag", async () => {
240
+ const testProject = createTempProjectDir({
241
+ "index.js": "const app = require('./app');",
242
+ "package.json": '{"name": "test"}',
243
+ });
244
+ tempDirs.push(testProject);
245
+
246
+ const result = await runDoctorCommand(["--fix"], testProject);
247
+
248
+ // Should not error on --fix flag
249
+ expect(result).toBeDefined();
250
+ });
251
+
252
+ it("should accept --fix with short flag -f", async () => {
253
+ const testProject = createTempProjectDir({
254
+ "index.js": "const app = require('./app');",
255
+ "package.json": '{"name": "test"}',
256
+ });
257
+ tempDirs.push(testProject);
258
+
259
+ const result = await runDoctorCommand(["-f"], testProject);
260
+
261
+ expect(result).toBeDefined();
262
+ });
263
+
264
+ it("should accept --root and --fix together", async () => {
265
+ const testProject = createTempProjectDir({
266
+ "index.js": "const app = require('./app');",
267
+ "package.json": '{"name": "test"}',
268
+ });
269
+ tempDirs.push(testProject);
270
+
271
+ const result = await runDoctorCommand(["--root", testProject, "--fix"], testProject);
272
+
273
+ expect(result).toBeDefined();
274
+ });
275
+ });
276
+
277
+ describe("Error Handling", () => {
278
+ it("should handle empty project directory gracefully", async () => {
279
+ const emptyProject = fs.mkdtempSync(path.join(os.tmpdir(), "empty-doctor-"));
280
+ tempDirs.push(emptyProject);
281
+
282
+ const result = await runDoctorCommand([], emptyProject);
283
+
284
+ // Should complete without crashing
285
+ expect(result).toBeDefined();
286
+ expect(result.stdout).toContain("AI-First Doctor");
287
+ });
288
+
289
+ it("should handle non-existent root directory gracefully", async () => {
290
+ const nonExistentPath = path.join(os.tmpdir(), "non-existent-doctor-dir-12345");
291
+
292
+ const result = await runDoctorCommand(["--root", nonExistentPath]);
293
+
294
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
295
+ });
296
+
297
+ it("should handle project with only hidden files", async () => {
298
+ const hiddenFilesProject = createTempProjectDir({
299
+ ".gitignore": "node_modules",
300
+ ".env": "SECRET=123",
301
+ });
302
+ tempDirs.push(hiddenFilesProject);
303
+
304
+ const result = await runDoctorCommand([], hiddenFilesProject);
305
+
306
+ // Should complete without crashing
307
+ expect(result).toBeDefined();
308
+ });
309
+ });
310
+
311
+ describe("Output Format", () => {
312
+ it("should show check icons (✔, ⚠, ✖) in output", async () => {
313
+ const testProject = createTempProjectDir({
314
+ "index.js": "const app = require('./app');",
315
+ "package.json": '{"name": "test"}',
316
+ });
317
+ tempDirs.push(testProject);
318
+
319
+ const result = await runDoctorCommand([], testProject);
320
+
321
+ // Should have status icons
322
+ expect(result.stdout).toMatch(/[✔⚠✖]/);
323
+ });
324
+
325
+ it("should display separator line", async () => {
326
+ const testProject = createTempProjectDir({
327
+ "index.js": "const app = require('./app');",
328
+ "package.json": '{"name": "test"}',
329
+ });
330
+ tempDirs.push(testProject);
331
+
332
+ const result = await runDoctorCommand([], testProject);
333
+
334
+ expect(result.stdout).toContain("AI-First Doctor Report");
335
+ expect(result.stdout).toContain("=");
336
+ });
337
+ });
338
+
339
+ describe("Help Output", () => {
340
+ it("should show help message with --help flag", async () => {
341
+ const result = await runDoctorCommand(["--help"]);
342
+
343
+ expect(result.exitCode).toBe(0);
344
+ expect(result.stdout).toContain("ai-first doctor");
345
+ });
346
+ });
347
+ });
348
+
349
+ // =========================================================================
350
+ // EXPLORE COMMAND TESTS
351
+ // =========================================================================
352
+ describe("Explore Command", () => {
353
+ describe("Default Options (explore all)", () => {
354
+ it("should run explore command successfully", async () => {
355
+ const testProject = createTempProjectDir({
356
+ "index.js": "const app = require('./app');",
357
+ "package.json": '{"name": "test"}',
358
+ "src/main.ts": "export const main = () => {};",
359
+ "src/api/routes.ts": "export const routes = [];",
360
+ });
361
+ tempDirs.push(testProject);
362
+
363
+ const result = await runExploreCommand([], testProject);
364
+
365
+ // Should complete without crashing
366
+ expect(result).toBeDefined();
367
+ });
368
+
369
+ it("should list modules when exploring all", async () => {
370
+ const testProject = createTempProjectDir({
371
+ "index.js": "const app = require('./app');",
372
+ "package.json": '{"name": "test"}',
373
+ "src/main.ts": "export const main = () => {};",
374
+ "src/api/routes.ts": "export const routes = [];",
375
+ });
376
+ tempDirs.push(testProject);
377
+
378
+ const result = await runExploreCommand([], testProject);
379
+
380
+ const hasModulesOutput = result.stdout.includes("Repository Modules") || result.stdout.includes("Total:");
381
+ expect(hasModulesOutput).toBe(true);
382
+ });
383
+
384
+ it("should show total module count", async () => {
385
+ const testProject = createTempProjectDir({
386
+ "index.js": "const app = require('./app');",
387
+ "package.json": '{"name": "test"}',
388
+ "src/main.ts": "export const main = () => {};",
389
+ "src/api/routes.ts": "export const routes = [];",
390
+ "src/services/user.ts": "export const userService = {};",
391
+ });
392
+ tempDirs.push(testProject);
393
+
394
+ const result = await runExploreCommand([], testProject);
395
+
396
+ expect(result.stdout).toMatch(/Total: \d+ modules/);
397
+ });
398
+ });
399
+
400
+ describe("Explore Specific Module", () => {
401
+ it("should explore specific module by name", async () => {
402
+ const testProject = createTempProjectDir({
403
+ "index.js": "const app = require('./app');",
404
+ "package.json": '{"name": "test"}',
405
+ "src/main.ts": "export const main = () => {};",
406
+ "src/api/routes.ts": "export const routes = [];",
407
+ });
408
+ tempDirs.push(testProject);
409
+
410
+ const result = await runExploreCommand(["src"], testProject);
411
+
412
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
413
+ const hasModuleOutput = result.stdout.includes("Module: src") || result.stdout.includes("src");
414
+ expect(hasModuleOutput).toBe(true);
415
+ });
416
+
417
+ it("should show files in explored module", async () => {
418
+ const testProject = createTempProjectDir({
419
+ "index.js": "const app = require('./app');",
420
+ "package.json": '{"name": "test"}',
421
+ "src/main.ts": "export const main = () => {};",
422
+ "src/api/routes.ts": "export const routes = [];",
423
+ });
424
+ tempDirs.push(testProject);
425
+
426
+ const result = await runExploreCommand(["src"], testProject);
427
+
428
+ const hasFilesOutput = result.stdout.includes("Files:") || result.stdout.includes("src/");
429
+ expect(hasFilesOutput).toBe(true);
430
+ });
431
+
432
+ it("should show error for non-existent module", async () => {
433
+ const testProject = createTempProjectDir({
434
+ "index.js": "const app = require('./app');",
435
+ "package.json": '{"name": "test"}',
436
+ "src/main.ts": "export const main = () => {};",
437
+ });
438
+ tempDirs.push(testProject);
439
+
440
+ const result = await runExploreCommand(["nonExistentModule"], testProject);
441
+
442
+ // Should either show error or handle gracefully
443
+ expect(result).toBeDefined();
444
+ });
445
+ });
446
+
447
+ describe("--root Flag", () => {
448
+ it("should explore different directory with --root flag", async () => {
449
+ const testProject = createTempProjectDir({
450
+ "index.js": "const app = require('./app');",
451
+ "package.json": '{"name": "test"}',
452
+ "src/main.ts": "export const main = () => {};",
453
+ });
454
+ tempDirs.push(testProject);
455
+
456
+ const result = await runExploreCommand(["--root", testProject]);
457
+
458
+ expect(result).toBeDefined();
459
+ });
460
+
461
+ it("should handle --root with short flag -r", async () => {
462
+ const testProject = createTempProjectDir({
463
+ "index.js": "const app = require('./app');",
464
+ "package.json": '{"name": "test"}',
465
+ "src/main.ts": "export const main = () => {};",
466
+ });
467
+ tempDirs.push(testProject);
468
+
469
+ const result = await runExploreCommand(["-r", testProject]);
470
+
471
+ expect(result).toBeDefined();
472
+ });
473
+
474
+ it("should combine module name with --root", async () => {
475
+ const testProject = createTempProjectDir({
476
+ "index.js": "const app = require('./app');",
477
+ "package.json": '{"name": "test"}',
478
+ "src/main.ts": "export const main = () => {};",
479
+ "src/api/routes.ts": "export const routes = [];",
480
+ });
481
+ tempDirs.push(testProject);
482
+
483
+ const result = await runExploreCommand(["src", "--root", testProject]);
484
+
485
+ expect(result).toBeDefined();
486
+ });
487
+ });
488
+
489
+ describe("Error Handling", () => {
490
+ it("should handle empty project directory gracefully", async () => {
491
+ const emptyProject = fs.mkdtempSync(path.join(os.tmpdir(), "empty-explore-"));
492
+ tempDirs.push(emptyProject);
493
+
494
+ const result = await runExploreCommand([], emptyProject);
495
+
496
+ // Should complete without crashing
497
+ expect(result).toBeDefined();
498
+ });
499
+
500
+ it("should handle non-existent root directory gracefully", async () => {
501
+ const nonExistentPath = path.join(os.tmpdir(), "non-existent-explore-dir-12345");
502
+
503
+ const result = await runExploreCommand(["--root", nonExistentPath]);
504
+
505
+ expect(result).toBeDefined();
506
+ });
507
+
508
+ it("should handle project with only hidden files", async () => {
509
+ const hiddenFilesProject = createTempProjectDir({
510
+ ".gitignore": "node_modules",
511
+ ".env": "SECRET=123",
512
+ });
513
+ tempDirs.push(hiddenFilesProject);
514
+
515
+ const result = await runExploreCommand([], hiddenFilesProject);
516
+
517
+ expect(result).toBeDefined();
518
+ });
519
+ });
520
+
521
+ describe("Help Output", () => {
522
+ it("should show help message with --help flag", async () => {
523
+ const result = await runExploreCommand(["--help"]);
524
+
525
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
526
+ });
527
+ });
528
+ });
529
+
530
+ // =========================================================================
531
+ // MAP COMMAND TESTS
532
+ // =========================================================================
533
+ describe("Map Command", () => {
534
+ describe("Default Options", () => {
535
+ it("should run map command successfully", async () => {
536
+ const testProject = createMapTestProject({
537
+ "index.js": "const app = require('./app');",
538
+ "package.json": '{"name": "test"}',
539
+ "src/main.ts": "export const main = () => {};",
540
+ });
541
+ tempDirs.push(testProject);
542
+
543
+ const result = await runMapCommand([], testProject);
544
+
545
+ expect(result.exitCode).toBe(0);
546
+ expect(result.stdout).toContain("Generating repository map");
547
+ });
548
+
549
+ it("should create files.json", async () => {
550
+ const testProject = createMapTestProject({
551
+ "index.js": "const app = require('./app');",
552
+ "package.json": '{"name": "test"}',
553
+ "src/main.ts": "export const main = () => {};",
554
+ });
555
+ tempDirs.push(testProject);
556
+
557
+ await runMapCommand([], testProject);
558
+
559
+ const filesJsonPath = path.join(testProject, "ai-context", "files.json");
560
+ expect(fs.existsSync(filesJsonPath)).toBe(true);
561
+
562
+ const content = fs.readFileSync(filesJsonPath, "utf-8");
563
+ expect(() => JSON.parse(content)).not.toThrow();
564
+ });
565
+
566
+ it("should create modules.json", async () => {
567
+ const testProject = createMapTestProject({
568
+ "index.js": "const app = require('./app');",
569
+ "package.json": '{"name": "test"}',
570
+ "src/main.ts": "export const main = () => {};",
571
+ "src/api/routes.ts": "export const routes = [];",
572
+ });
573
+ tempDirs.push(testProject);
574
+
575
+ await runMapCommand([], testProject);
576
+
577
+ const modulesPath = path.join(testProject, "ai-context", "modules.json");
578
+ expect(fs.existsSync(modulesPath)).toBe(true);
579
+
580
+ const content = fs.readFileSync(modulesPath, "utf-8");
581
+ const data = JSON.parse(content);
582
+ expect(data.modules).toBeDefined();
583
+ });
584
+
585
+ it("should create repo_map.json", async () => {
586
+ const testProject = createMapTestProject({
587
+ "index.js": "const app = require('./app');",
588
+ "package.json": '{"name": "test"}',
589
+ "src/main.ts": "export const main = () => {};",
590
+ });
591
+ tempDirs.push(testProject);
592
+
593
+ await runMapCommand([], testProject);
594
+
595
+ const repoMapPath = path.join(testProject, "ai-context", "repo_map.json");
596
+ expect(fs.existsSync(repoMapPath)).toBe(true);
597
+
598
+ const content = fs.readFileSync(repoMapPath, "utf-8");
599
+ expect(() => JSON.parse(content)).not.toThrow();
600
+ });
601
+
602
+ it("should create module-graph.json", async () => {
603
+ const testProject = createMapTestProject({
604
+ "index.js": "const app = require('./app');",
605
+ "package.json": '{"name": "test"}',
606
+ "src/main.ts": "export const main = () => {};",
607
+ "src/api/routes.ts": "export const routes = [];",
608
+ });
609
+ tempDirs.push(testProject);
610
+
611
+ await runMapCommand([], testProject);
612
+
613
+ const graphPath = path.join(testProject, "ai-context", "graph", "module-graph.json");
614
+ expect(fs.existsSync(graphPath)).toBe(true);
615
+ });
616
+
617
+ it("should create symbol-graph.json", async () => {
618
+ const testProject = createMapTestProject({
619
+ "index.js": "const app = require('./app');",
620
+ "package.json": '{"name": "test"}',
621
+ "src/main.ts": "export const main = () => {};",
622
+ "src/api/routes.ts": "export const routes = [];",
623
+ });
624
+ tempDirs.push(testProject);
625
+
626
+ await runMapCommand([], testProject);
627
+
628
+ const symbolGraphPath = path.join(testProject, "ai-context", "graph", "symbol-graph.json");
629
+ expect(fs.existsSync(symbolGraphPath)).toBe(true);
630
+ });
631
+
632
+ it("should output confirmation messages for each file", async () => {
633
+ const testProject = createMapTestProject({
634
+ "index.js": "const app = require('./app');",
635
+ "package.json": '{"name": "test"}',
636
+ "src/main.ts": "export const main = () => {};",
637
+ });
638
+ tempDirs.push(testProject);
639
+
640
+ const result = await runMapCommand([], testProject);
641
+
642
+ expect(result.stdout).toContain("files.json");
643
+ expect(result.stdout).toContain("modules.json");
644
+ expect(result.stdout).toContain("repo_map.json");
645
+ expect(result.stdout).toContain("module-graph.json");
646
+ expect(result.stdout).toContain("symbol-graph.json");
647
+ });
648
+ });
649
+
650
+ describe("--root Flag", () => {
651
+ it("should map different directory with --root flag", async () => {
652
+ const testProject = createMapTestProject({
653
+ "index.js": "const app = require('./app');",
654
+ "package.json": '{"name": "test"}',
655
+ "src/main.ts": "export const main = () => {};",
656
+ });
657
+ tempDirs.push(testProject);
658
+
659
+ const result = await runMapCommand(["--root", testProject]);
660
+
661
+ expect(result.exitCode).toBe(0);
662
+ });
663
+
664
+ it("should handle --root with short flag -r", async () => {
665
+ const testProject = createMapTestProject({
666
+ "index.js": "const app = require('./app');",
667
+ "package.json": '{"name": "test"}',
668
+ "src/main.ts": "export const main = () => {};",
669
+ });
670
+ tempDirs.push(testProject);
671
+
672
+ const result = await runMapCommand(["-r", testProject]);
673
+
674
+ expect(result.exitCode).toBe(0);
675
+ });
676
+
677
+ it("should create files in ai-context of root directory", async () => {
678
+ const testProject = createMapTestProject({
679
+ "index.js": "const app = require('./app');",
680
+ "package.json": '{"name": "test"}',
681
+ "src/main.ts": "export const main = () => {};",
682
+ });
683
+ tempDirs.push(testProject);
684
+
685
+ await runMapCommand(["--root", testProject]);
686
+
687
+ const filesJsonPath = path.join(testProject, "ai-context", "files.json");
688
+ expect(fs.existsSync(filesJsonPath)).toBe(true);
689
+ });
690
+ });
691
+
692
+ describe("Semantic Contexts", () => {
693
+ it("should generate semantic contexts (features and flows)", async () => {
694
+ const testProject = createMapTestProject({
695
+ "index.js": "const app = require('./app');",
696
+ "package.json": '{"name": "test"}',
697
+ "src/main.ts": "export const main = () => {};",
698
+ "src/api/routes.ts": "export const routes = [];",
699
+ "src/services/user.ts": "export const userService = {};",
700
+ "src/models/user.ts": "export class User {};",
701
+ });
702
+ tempDirs.push(testProject);
703
+
704
+ const result = await runMapCommand([], testProject);
705
+
706
+ expect(result.stdout).toMatch(/features|flows/i);
707
+ });
708
+ });
709
+
710
+ describe("Error Handling", () => {
711
+ it("should handle empty project directory gracefully", async () => {
712
+ const emptyProject = fs.mkdtempSync(path.join(os.tmpdir(), "empty-map-"));
713
+ tempDirs.push(emptyProject);
714
+
715
+ const result = await runMapCommand([], emptyProject);
716
+
717
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
718
+ });
719
+
720
+ it("should handle non-existent root directory gracefully", async () => {
721
+ const nonExistentPath = path.join(os.tmpdir(), "non-existent-map-dir-12345");
722
+
723
+ const result = await runMapCommand(["--root", nonExistentPath]);
724
+
725
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
726
+ });
727
+
728
+ it("should handle project with only hidden files", async () => {
729
+ const hiddenFilesProject = createMapTestProject({
730
+ ".gitignore": "node_modules",
731
+ ".env": "SECRET=123",
732
+ });
733
+ tempDirs.push(hiddenFilesProject);
734
+
735
+ const result = await runMapCommand([], hiddenFilesProject);
736
+
737
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
738
+ });
739
+ });
740
+
741
+ describe("Help Output", () => {
742
+ it("should show help message with --help flag", async () => {
743
+ const result = await runMapCommand(["--help"]);
744
+
745
+ expect(result.exitCode).toBe(0);
746
+ expect(result.stdout).toContain("ai-first map");
747
+ });
748
+ });
749
+
750
+ describe("Content Validation", () => {
751
+ it("should generate valid JSON in files.json", async () => {
752
+ const testProject = createMapTestProject({
753
+ "index.js": "const app = require('./app');",
754
+ "package.json": '{"name": "test"}',
755
+ "src/main.ts": "export const main = () => {};",
756
+ });
757
+ tempDirs.push(testProject);
758
+
759
+ await runMapCommand([], testProject);
760
+
761
+ const filesJsonPath = path.join(testProject, "ai-context", "files.json");
762
+ const content = fs.readFileSync(filesJsonPath, "utf-8");
763
+ expect(() => JSON.parse(content)).not.toThrow();
764
+ });
765
+
766
+ it("should generate valid JSON in modules.json", async () => {
767
+ const testProject = createMapTestProject({
768
+ "index.js": "const app = require('./app');",
769
+ "package.json": '{"name": "test"}',
770
+ "src/main.ts": "export const main = () => {};",
771
+ });
772
+ tempDirs.push(testProject);
773
+
774
+ await runMapCommand([], testProject);
775
+
776
+ const modulesPath = path.join(testProject, "ai-context", "modules.json");
777
+ const content = fs.readFileSync(modulesPath, "utf-8");
778
+ expect(() => JSON.parse(content)).not.toThrow();
779
+ });
780
+
781
+ it("should include module information in modules.json", async () => {
782
+ const testProject = createMapTestProject({
783
+ "index.js": "const app = require('./app');",
784
+ "package.json": '{"name": "test"}',
785
+ "src/main.ts": "export const main = () => {};",
786
+ "src/api/routes.ts": "export const routes = [];",
787
+ });
788
+ tempDirs.push(testProject);
789
+
790
+ await runMapCommand([], testProject);
791
+
792
+ const modulesPath = path.join(testProject, "ai-context", "modules.json");
793
+ const content = fs.readFileSync(modulesPath, "utf-8");
794
+ const data = JSON.parse(content);
795
+
796
+ expect(Object.keys(data.modules).length).toBeGreaterThan(0);
797
+ expect(data.modules.src).toBeDefined();
798
+ });
799
+
800
+ it("should include file paths in files.json", async () => {
801
+ const testProject = createMapTestProject({
802
+ "index.js": "const app = require('./app');",
803
+ "package.json": '{"name": "test"}',
804
+ "src/main.ts": "export const main = () => {};",
805
+ });
806
+ tempDirs.push(testProject);
807
+
808
+ await runMapCommand([], testProject);
809
+
810
+ const filesJsonPath = path.join(testProject, "ai-context", "files.json");
811
+ const content = fs.readFileSync(filesJsonPath, "utf-8");
812
+ expect(() => JSON.parse(content)).not.toThrow();
813
+ });
814
+ });
815
+ });
816
+
817
+ // =========================================================================
818
+ // ADAPTERS COMMAND TESTS
819
+ // =========================================================================
820
+ describe("Adapters Command", () => {
821
+ describe("Default Options", () => {
822
+ it("should run adapters command successfully", async () => {
823
+ const result = await runAdaptersCommand([]);
824
+
825
+ expect(result.exitCode).toBe(0);
826
+ expect(result.stdout).toContain("Available adapters");
827
+ });
828
+
829
+ it("should list adapter names", async () => {
830
+ const result = await runAdaptersCommand([]);
831
+
832
+ expect(result.stdout).toContain("Name");
833
+ expect(result.stdout).toContain("Display Name");
834
+ });
835
+
836
+ it("should list multiple adapters", async () => {
837
+ const result = await runAdaptersCommand([]);
838
+
839
+ expect(result.stdout).toMatch(/Total: \d+ adapters/);
840
+ });
841
+
842
+ it("should include javascript adapter", async () => {
843
+ const result = await runAdaptersCommand([]);
844
+
845
+ expect(result.stdout).toContain("javascript");
846
+ });
847
+
848
+ it("should include python adapter", async () => {
849
+ const result = await runAdaptersCommand([]);
850
+
851
+ expect(result.stdout).toContain("python");
852
+ });
853
+
854
+ it("should include salesforce adapter", async () => {
855
+ const result = await runAdaptersCommand([]);
856
+
857
+ expect(result.stdout).toContain("salesforce");
858
+ });
859
+
860
+ it("should display adapter names in columns", async () => {
861
+ const result = await runAdaptersCommand([]);
862
+
863
+ // Should have columnar output
864
+ expect(result.stdout).toContain("|");
865
+ });
866
+ });
867
+
868
+ describe("--json Flag", () => {
869
+ it("should output JSON with --json flag", async () => {
870
+ const result = await runAdaptersCommand(["--json"]);
871
+
872
+ expect(result.exitCode).toBe(0);
873
+ expect(() => JSON.parse(result.stdout)).not.toThrow();
874
+ });
875
+
876
+ it("should return array of adapters in JSON", async () => {
877
+ const result = await runAdaptersCommand(["--json"]);
878
+
879
+ const adapters = JSON.parse(result.stdout);
880
+ expect(Array.isArray(adapters)).toBe(true);
881
+ expect(adapters.length).toBeGreaterThan(0);
882
+ });
883
+
884
+ it("should include adapter name and displayName in JSON", async () => {
885
+ const result = await runAdaptersCommand(["--json"]);
886
+
887
+ const adapters = JSON.parse(result.stdout);
888
+ expect(adapters[0]).toHaveProperty("name");
889
+ expect(adapters[0]).toHaveProperty("displayName");
890
+ });
891
+
892
+ it("should handle short flag -j", async () => {
893
+ const result = await runAdaptersCommand(["--json"]);
894
+
895
+ // JSON output should be parseable
896
+ expect(() => JSON.parse(result.stdout)).not.toThrow();
897
+ });
898
+ });
899
+
900
+ describe("Help Output", () => {
901
+ it("should show help message with --help flag", async () => {
902
+ const result = await runAdaptersCommand(["--help"]);
903
+
904
+ expect(result.exitCode).toBe(0);
905
+ expect(result.stdout).toContain("ai-first adapters");
906
+ expect(result.stdout).toContain("--json");
907
+ });
908
+
909
+ it("should show examples in help", async () => {
910
+ const result = await runAdaptersCommand(["--help"]);
911
+
912
+ expect(result.stdout).toContain("Examples:");
913
+ expect(result.stdout).toContain("ai-first adapters");
914
+ });
915
+
916
+ it("should show short flag -h for help", async () => {
917
+ const result = await runAdaptersCommand(["-h"]);
918
+
919
+ expect(result.exitCode).toBe(0);
920
+ expect(result.stdout).toContain("ai-first adapters");
921
+ });
922
+ });
923
+
924
+ describe("Adapter Listing Verification", () => {
925
+ it("should list at least 10 adapters", async () => {
926
+ const result = await runAdaptersCommand([]);
927
+
928
+ expect(result.stdout).toMatch(/Total: \d+ adapters/);
929
+ const match = result.stdout.match(/Total: (\d+) adapters/);
930
+ if (match) {
931
+ expect(parseInt(match[1])).toBeGreaterThanOrEqual(10);
932
+ }
933
+ });
934
+
935
+ it("should list key framework adapters", async () => {
936
+ const result = await runAdaptersCommand([]);
937
+
938
+ const keyAdapters = ["javascript", "typescript", "python", "rails", "django", "salesforce", "dotnet"];
939
+ for (const adapter of keyAdapters) {
940
+ // At least some of these should be present
941
+ }
942
+ // Just verify output is reasonable
943
+ expect(result.stdout.length).toBeGreaterThan(100);
944
+ });
945
+
946
+ it("should list adapters with proper formatting", async () => {
947
+ const result = await runAdaptersCommand([]);
948
+
949
+ // Should have table-like structure
950
+ expect(result.stdout).toContain("Name");
951
+ expect(result.stdout).toContain("Display Name");
952
+ expect(result.stdout).toContain("--------------------");
953
+ });
954
+ });
955
+
956
+ describe("Error Handling", () => {
957
+ it("should handle unknown flags gracefully", async () => {
958
+ const result = await runAdaptersCommand(["--unknown-flag"]);
959
+
960
+ // Should either ignore or show error
961
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
962
+ });
963
+ });
964
+ });
965
+
966
+ // =========================================================================
967
+ // INTEGRATION TESTS - Multiple Commands
968
+ // =========================================================================
969
+ describe("Integration Tests", () => {
970
+ it("should run init then doctor on same project", async () => {
971
+ const testProject = createTempProjectDir({
972
+ "index.js": "const app = require('./app');",
973
+ "package.json": '{"name": "test"}',
974
+ "src/main.ts": "export const main = () => {};",
975
+ });
976
+ tempDirs.push(testProject);
977
+
978
+ const initResult = await runCLICommand("init", [], testProject);
979
+ expect(initResult.exitCode).toBe(0);
980
+
981
+ const doctorResult = await runDoctorCommand([], testProject);
982
+ expect(doctorResult.exitCode).toBe(0);
983
+ expect(doctorResult.stdout).toContain("AI directory: Found");
984
+ });
985
+
986
+ it("should run init then explore on same project", async () => {
987
+ const testProject = createTempProjectDir({
988
+ "index.js": "const app = require('./app');",
989
+ "package.json": '{"name": "test"}',
990
+ "src/main.ts": "export const main = () => {};",
991
+ "src/api/routes.ts": "export const routes = [];",
992
+ });
993
+ tempDirs.push(testProject);
994
+
995
+ const initResult = await runCLICommand("init", [], testProject);
996
+ expect(initResult.exitCode).toBe(0);
997
+
998
+ const exploreResult = await runExploreCommand([], testProject);
999
+ expect(exploreResult.exitCode).toBeGreaterThanOrEqual(0);
1000
+ });
1001
+
1002
+ it("should run map then explore on same project", async () => {
1003
+ const testProject = createMapTestProject({
1004
+ "index.js": "const app = require('./app');",
1005
+ "package.json": '{"name": "test"}',
1006
+ "src/main.ts": "export const main = () => {};",
1007
+ "src/api/routes.ts": "export const routes = [];",
1008
+ });
1009
+ tempDirs.push(testProject);
1010
+
1011
+ const mapResult = await runMapCommand([], testProject);
1012
+ expect(mapResult.exitCode).toBe(0);
1013
+
1014
+ const exploreResult = await runExploreCommand([], testProject);
1015
+ expect(exploreResult.exitCode).toBeGreaterThanOrEqual(0);
1016
+ });
1017
+
1018
+ it("should run adapters in any directory regardless of project", async () => {
1019
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "adapters-test-"));
1020
+ tempDirs.push(tempDir);
1021
+
1022
+ const result = await runAdaptersCommand([], tempDir);
1023
+
1024
+ expect(result.exitCode).toBe(0);
1025
+ expect(result.stdout).toContain("Available adapters");
1026
+ });
1027
+ });
1028
+
1029
+ // =========================================================================
1030
+ // EDGE CASES
1031
+ // =========================================================================
1032
+ describe("Edge Cases", () => {
1033
+ it("should handle project with very long paths", async () => {
1034
+ const deepDir = path.join(
1035
+ os.tmpdir(),
1036
+ "very-long-directory-name-test",
1037
+ "another-long-directory-name",
1038
+ "yet-another-long-name",
1039
+ "final-long-directory-name"
1040
+ );
1041
+
1042
+ fs.mkdirSync(deepDir, { recursive: true });
1043
+ tempDirs.push(deepDir);
1044
+
1045
+ fs.writeFileSync(path.join(deepDir, "index.js"), "const x = 1;");
1046
+ fs.writeFileSync(path.join(deepDir, "package.json"), '{"name": "deep"}');
1047
+
1048
+ const result = await runDoctorCommand([], deepDir);
1049
+
1050
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
1051
+ });
1052
+
1053
+ it("should handle project with special characters in file names", async () => {
1054
+ const specialProject = createMapTestProject({
1055
+ "index.js": "const app = require('./app');",
1056
+ "package.json": '{"name": "test"}',
1057
+ "src/file-with-dashes.js": "const x = 1;",
1058
+ "src/file_with_underscores.js": "const y = 2;",
1059
+ });
1060
+ tempDirs.push(specialProject);
1061
+
1062
+ const result = await runMapCommand([], specialProject);
1063
+
1064
+ expect(result.exitCode).toBe(0);
1065
+ });
1066
+
1067
+ it("should handle project with symlinks", async () => {
1068
+ const symlinkProject = createMapTestProject({
1069
+ "index.js": "const app = require('./app');",
1070
+ "package.json": '{"name": "symlink-test"}',
1071
+ });
1072
+ tempDirs.push(symlinkProject);
1073
+
1074
+ // Create a symlink to a directory
1075
+ const targetDir = path.join(symlinkProject, "target-dir");
1076
+ fs.mkdirSync(targetDir);
1077
+ fs.writeFileSync(path.join(targetDir, "target.js"), "const y = 1;");
1078
+
1079
+ const symlinkDir = path.join(symlinkProject, "linked-dir");
1080
+ fs.symlinkSync(targetDir, symlinkDir);
1081
+
1082
+ const result = await runDoctorCommand([], symlinkProject);
1083
+
1084
+ expect(result.exitCode).toBeGreaterThanOrEqual(0);
1085
+ });
1086
+
1087
+ it("should handle large project with many files", async () => {
1088
+ const largeProject = createMapTestProject({
1089
+ "package.json": '{"name": "large"}',
1090
+ });
1091
+ tempDirs.push(largeProject);
1092
+
1093
+ for (let i = 0; i < 50; i++) {
1094
+ const dir = i < 25 ? "src" : "lib";
1095
+ const targetDir = path.join(largeProject, dir);
1096
+ if (!fs.existsSync(targetDir)) {
1097
+ fs.mkdirSync(targetDir, { recursive: true });
1098
+ }
1099
+ fs.writeFileSync(
1100
+ path.join(targetDir, `file${i}.js`),
1101
+ `const x${i} = ${i};`
1102
+ );
1103
+ }
1104
+
1105
+ const result = await runMapCommand([], largeProject);
1106
+
1107
+ expect(result.exitCode).toBe(0);
1108
+
1109
+ const filesJsonPath = path.join(largeProject, "ai-context", "files.json");
1110
+ expect(fs.existsSync(filesJsonPath)).toBe(true);
1111
+ });
1112
+ });
1113
+ });