codesift-mcp 0.2.18 → 0.4.0

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 (461) hide show
  1. package/README.md +143 -20
  2. package/dist/cache/hono-cache.d.ts +50 -0
  3. package/dist/cache/hono-cache.d.ts.map +1 -0
  4. package/dist/cache/hono-cache.js +132 -0
  5. package/dist/cache/hono-cache.js.map +1 -0
  6. package/dist/cli/setup.d.ts.map +1 -1
  7. package/dist/cli/setup.js +17 -2
  8. package/dist/cli/setup.js.map +1 -1
  9. package/dist/formatters-shortening.d.ts +13 -0
  10. package/dist/formatters-shortening.d.ts.map +1 -1
  11. package/dist/formatters-shortening.js +131 -0
  12. package/dist/formatters-shortening.js.map +1 -1
  13. package/dist/formatters.d.ts +38 -0
  14. package/dist/formatters.d.ts.map +1 -1
  15. package/dist/formatters.js +498 -0
  16. package/dist/formatters.js.map +1 -1
  17. package/dist/instructions.d.ts +1 -1
  18. package/dist/instructions.d.ts.map +1 -1
  19. package/dist/instructions.js +27 -26
  20. package/dist/instructions.js.map +1 -1
  21. package/dist/lsp/lsp-servers.d.ts.map +1 -1
  22. package/dist/lsp/lsp-servers.js +5 -0
  23. package/dist/lsp/lsp-servers.js.map +1 -1
  24. package/dist/lsp/lsp-tools.d.ts.map +1 -1
  25. package/dist/lsp/lsp-tools.js +1 -0
  26. package/dist/lsp/lsp-tools.js.map +1 -1
  27. package/dist/parser/astro-template.d.ts +47 -0
  28. package/dist/parser/astro-template.d.ts.map +1 -0
  29. package/dist/parser/astro-template.js +171 -0
  30. package/dist/parser/astro-template.js.map +1 -0
  31. package/dist/parser/extractors/_shared.d.ts +4 -0
  32. package/dist/parser/extractors/_shared.d.ts.map +1 -1
  33. package/dist/parser/extractors/_shared.js +8 -0
  34. package/dist/parser/extractors/_shared.js.map +1 -1
  35. package/dist/parser/extractors/astro.d.ts +4 -5
  36. package/dist/parser/extractors/astro.d.ts.map +1 -1
  37. package/dist/parser/extractors/astro.js +102 -26
  38. package/dist/parser/extractors/astro.js.map +1 -1
  39. package/dist/parser/extractors/gradle-kts.d.ts +4 -0
  40. package/dist/parser/extractors/gradle-kts.d.ts.map +1 -0
  41. package/dist/parser/extractors/gradle-kts.js +246 -0
  42. package/dist/parser/extractors/gradle-kts.js.map +1 -0
  43. package/dist/parser/extractors/hono-inline-analyzer.d.ts +34 -0
  44. package/dist/parser/extractors/hono-inline-analyzer.d.ts.map +1 -0
  45. package/dist/parser/extractors/hono-inline-analyzer.js +465 -0
  46. package/dist/parser/extractors/hono-inline-analyzer.js.map +1 -0
  47. package/dist/parser/extractors/hono-model.d.ts +196 -0
  48. package/dist/parser/extractors/hono-model.d.ts.map +1 -0
  49. package/dist/parser/extractors/hono-model.js +10 -0
  50. package/dist/parser/extractors/hono-model.js.map +1 -0
  51. package/dist/parser/extractors/hono.d.ts +118 -0
  52. package/dist/parser/extractors/hono.d.ts.map +1 -0
  53. package/dist/parser/extractors/hono.js +1527 -0
  54. package/dist/parser/extractors/hono.js.map +1 -0
  55. package/dist/parser/extractors/kotlin.d.ts +4 -0
  56. package/dist/parser/extractors/kotlin.d.ts.map +1 -0
  57. package/dist/parser/extractors/kotlin.js +521 -0
  58. package/dist/parser/extractors/kotlin.js.map +1 -0
  59. package/dist/parser/extractors/php.d.ts +22 -0
  60. package/dist/parser/extractors/php.d.ts.map +1 -0
  61. package/dist/parser/extractors/php.js +326 -0
  62. package/dist/parser/extractors/php.js.map +1 -0
  63. package/dist/parser/extractors/python.d.ts.map +1 -1
  64. package/dist/parser/extractors/python.js +234 -11
  65. package/dist/parser/extractors/python.js.map +1 -1
  66. package/dist/parser/extractors/sql.d.ts +33 -0
  67. package/dist/parser/extractors/sql.d.ts.map +1 -0
  68. package/dist/parser/extractors/sql.js +506 -0
  69. package/dist/parser/extractors/sql.js.map +1 -0
  70. package/dist/parser/extractors/typescript.d.ts.map +1 -1
  71. package/dist/parser/extractors/typescript.js +166 -3
  72. package/dist/parser/extractors/typescript.js.map +1 -1
  73. package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
  74. package/dist/parser/languages/tree-sitter-kotlin.wasm +0 -0
  75. package/dist/parser/languages/tree-sitter-php.wasm +0 -0
  76. package/dist/parser/languages/tree-sitter-php_only.wasm +0 -0
  77. package/dist/parser/languages/tree-sitter-python.wasm +0 -0
  78. package/dist/parser/parser-manager.d.ts +32 -0
  79. package/dist/parser/parser-manager.d.ts.map +1 -1
  80. package/dist/parser/parser-manager.js +82 -3
  81. package/dist/parser/parser-manager.js.map +1 -1
  82. package/dist/parser/symbol-extractor.d.ts.map +1 -1
  83. package/dist/parser/symbol-extractor.js +16 -0
  84. package/dist/parser/symbol-extractor.js.map +1 -1
  85. package/dist/register-tools.d.ts +37 -1
  86. package/dist/register-tools.d.ts.map +1 -1
  87. package/dist/register-tools.js +2657 -191
  88. package/dist/register-tools.js.map +1 -1
  89. package/dist/search/reranker.js +1 -1
  90. package/dist/search/reranker.js.map +1 -1
  91. package/dist/server-helpers.d.ts.map +1 -1
  92. package/dist/server-helpers.js +11 -0
  93. package/dist/server-helpers.js.map +1 -1
  94. package/dist/server.js +28 -1
  95. package/dist/server.js.map +1 -1
  96. package/dist/storage/index-store.d.ts +15 -1
  97. package/dist/storage/index-store.d.ts.map +1 -1
  98. package/dist/storage/index-store.js +27 -1
  99. package/dist/storage/index-store.js.map +1 -1
  100. package/dist/storage/session-state.d.ts +1 -1
  101. package/dist/storage/session-state.d.ts.map +1 -1
  102. package/dist/storage/session-state.js +6 -4
  103. package/dist/storage/session-state.js.map +1 -1
  104. package/dist/tools/agent-config-tools.d.ts +24 -0
  105. package/dist/tools/agent-config-tools.d.ts.map +1 -0
  106. package/dist/tools/agent-config-tools.js +119 -0
  107. package/dist/tools/agent-config-tools.js.map +1 -0
  108. package/dist/tools/architecture-tools.d.ts +23 -0
  109. package/dist/tools/architecture-tools.d.ts.map +1 -0
  110. package/dist/tools/architecture-tools.js +140 -0
  111. package/dist/tools/architecture-tools.js.map +1 -0
  112. package/dist/tools/astro-config.d.ts +33 -0
  113. package/dist/tools/astro-config.d.ts.map +1 -0
  114. package/dist/tools/astro-config.js +260 -0
  115. package/dist/tools/astro-config.js.map +1 -0
  116. package/dist/tools/astro-islands.d.ts +61 -0
  117. package/dist/tools/astro-islands.d.ts.map +1 -0
  118. package/dist/tools/astro-islands.js +240 -0
  119. package/dist/tools/astro-islands.js.map +1 -0
  120. package/dist/tools/astro-routes.d.ts +49 -0
  121. package/dist/tools/astro-routes.d.ts.map +1 -0
  122. package/dist/tools/astro-routes.js +119 -0
  123. package/dist/tools/astro-routes.js.map +1 -0
  124. package/dist/tools/audit-tools.d.ts +38 -0
  125. package/dist/tools/audit-tools.d.ts.map +1 -0
  126. package/dist/tools/audit-tools.js +248 -0
  127. package/dist/tools/audit-tools.js.map +1 -0
  128. package/dist/tools/celery-tools.d.ts +38 -0
  129. package/dist/tools/celery-tools.d.ts.map +1 -0
  130. package/dist/tools/celery-tools.js +154 -0
  131. package/dist/tools/celery-tools.js.map +1 -0
  132. package/dist/tools/clone-tools.js +1 -1
  133. package/dist/tools/clone-tools.js.map +1 -1
  134. package/dist/tools/complexity-tools.d.ts +4 -0
  135. package/dist/tools/complexity-tools.d.ts.map +1 -1
  136. package/dist/tools/complexity-tools.js +78 -4
  137. package/dist/tools/complexity-tools.js.map +1 -1
  138. package/dist/tools/compose-tools.d.ts +60 -0
  139. package/dist/tools/compose-tools.d.ts.map +1 -0
  140. package/dist/tools/compose-tools.js +203 -0
  141. package/dist/tools/compose-tools.js.map +1 -0
  142. package/dist/tools/coupling-tools.d.ts +50 -0
  143. package/dist/tools/coupling-tools.d.ts.map +1 -0
  144. package/dist/tools/coupling-tools.js +262 -0
  145. package/dist/tools/coupling-tools.js.map +1 -0
  146. package/dist/tools/dependency-audit-tools.d.ts +65 -0
  147. package/dist/tools/dependency-audit-tools.d.ts.map +1 -0
  148. package/dist/tools/dependency-audit-tools.js +553 -0
  149. package/dist/tools/dependency-audit-tools.js.map +1 -0
  150. package/dist/tools/django-settings.d.ts +22 -0
  151. package/dist/tools/django-settings.d.ts.map +1 -0
  152. package/dist/tools/django-settings.js +301 -0
  153. package/dist/tools/django-settings.js.map +1 -0
  154. package/dist/tools/frequency-tools.js +1 -1
  155. package/dist/tools/frequency-tools.js.map +1 -1
  156. package/dist/tools/graph-tools.d.ts +8 -2
  157. package/dist/tools/graph-tools.d.ts.map +1 -1
  158. package/dist/tools/graph-tools.js +44 -3
  159. package/dist/tools/graph-tools.js.map +1 -1
  160. package/dist/tools/hilt-tools.d.ts +55 -0
  161. package/dist/tools/hilt-tools.d.ts.map +1 -0
  162. package/dist/tools/hilt-tools.js +258 -0
  163. package/dist/tools/hilt-tools.js.map +1 -0
  164. package/dist/tools/hono-analyze-app.d.ts +48 -0
  165. package/dist/tools/hono-analyze-app.d.ts.map +1 -0
  166. package/dist/tools/hono-analyze-app.js +102 -0
  167. package/dist/tools/hono-analyze-app.js.map +1 -0
  168. package/dist/tools/hono-api-contract.d.ts +22 -0
  169. package/dist/tools/hono-api-contract.d.ts.map +1 -0
  170. package/dist/tools/hono-api-contract.js +80 -0
  171. package/dist/tools/hono-api-contract.js.map +1 -0
  172. package/dist/tools/hono-conditional-middleware.d.ts +27 -0
  173. package/dist/tools/hono-conditional-middleware.d.ts.map +1 -0
  174. package/dist/tools/hono-conditional-middleware.js +62 -0
  175. package/dist/tools/hono-conditional-middleware.js.map +1 -0
  176. package/dist/tools/hono-context-flow.d.ts +24 -0
  177. package/dist/tools/hono-context-flow.d.ts.map +1 -0
  178. package/dist/tools/hono-context-flow.js +78 -0
  179. package/dist/tools/hono-context-flow.js.map +1 -0
  180. package/dist/tools/hono-dead-routes.d.ts +26 -0
  181. package/dist/tools/hono-dead-routes.d.ts.map +1 -0
  182. package/dist/tools/hono-dead-routes.js +109 -0
  183. package/dist/tools/hono-dead-routes.js.map +1 -0
  184. package/dist/tools/hono-env-regression.d.ts +29 -0
  185. package/dist/tools/hono-env-regression.d.ts.map +1 -0
  186. package/dist/tools/hono-env-regression.js +157 -0
  187. package/dist/tools/hono-env-regression.js.map +1 -0
  188. package/dist/tools/hono-inline-analyze.d.ts +31 -0
  189. package/dist/tools/hono-inline-analyze.d.ts.map +1 -0
  190. package/dist/tools/hono-inline-analyze.js +67 -0
  191. package/dist/tools/hono-inline-analyze.js.map +1 -0
  192. package/dist/tools/hono-middleware-chain.d.ts +22 -0
  193. package/dist/tools/hono-middleware-chain.d.ts.map +1 -0
  194. package/dist/tools/hono-middleware-chain.js +84 -0
  195. package/dist/tools/hono-middleware-chain.js.map +1 -0
  196. package/dist/tools/hono-modules.d.ts +22 -0
  197. package/dist/tools/hono-modules.d.ts.map +1 -0
  198. package/dist/tools/hono-modules.js +126 -0
  199. package/dist/tools/hono-modules.js.map +1 -0
  200. package/dist/tools/hono-response-types.d.ts +37 -0
  201. package/dist/tools/hono-response-types.d.ts.map +1 -0
  202. package/dist/tools/hono-response-types.js +84 -0
  203. package/dist/tools/hono-response-types.js.map +1 -0
  204. package/dist/tools/hono-rpc-types.d.ts +21 -0
  205. package/dist/tools/hono-rpc-types.d.ts.map +1 -0
  206. package/dist/tools/hono-rpc-types.js +57 -0
  207. package/dist/tools/hono-rpc-types.js.map +1 -0
  208. package/dist/tools/hono-security.d.ts +21 -0
  209. package/dist/tools/hono-security.d.ts.map +1 -0
  210. package/dist/tools/hono-security.js +98 -0
  211. package/dist/tools/hono-security.js.map +1 -0
  212. package/dist/tools/hono-visualize.d.ts +13 -0
  213. package/dist/tools/hono-visualize.d.ts.map +1 -0
  214. package/dist/tools/hono-visualize.js +72 -0
  215. package/dist/tools/hono-visualize.js.map +1 -0
  216. package/dist/tools/hotspot-tools.d.ts.map +1 -1
  217. package/dist/tools/hotspot-tools.js +9 -7
  218. package/dist/tools/hotspot-tools.js.map +1 -1
  219. package/dist/tools/index-tools.d.ts +17 -0
  220. package/dist/tools/index-tools.d.ts.map +1 -1
  221. package/dist/tools/index-tools.js +210 -10
  222. package/dist/tools/index-tools.js.map +1 -1
  223. package/dist/tools/kotlin-tools.d.ts +142 -0
  224. package/dist/tools/kotlin-tools.d.ts.map +1 -0
  225. package/dist/tools/kotlin-tools.js +572 -0
  226. package/dist/tools/kotlin-tools.js.map +1 -0
  227. package/dist/tools/legacy-hono-conventions.d.ts +14 -0
  228. package/dist/tools/legacy-hono-conventions.d.ts.map +1 -0
  229. package/dist/tools/legacy-hono-conventions.js +152 -0
  230. package/dist/tools/legacy-hono-conventions.js.map +1 -0
  231. package/dist/tools/migration-lint-tools.d.ts +26 -0
  232. package/dist/tools/migration-lint-tools.d.ts.map +1 -0
  233. package/dist/tools/migration-lint-tools.js +247 -0
  234. package/dist/tools/migration-lint-tools.js.map +1 -0
  235. package/dist/tools/model-tools.d.ts +30 -0
  236. package/dist/tools/model-tools.d.ts.map +1 -0
  237. package/dist/tools/model-tools.js +145 -0
  238. package/dist/tools/model-tools.js.map +1 -0
  239. package/dist/tools/nest-ext-tools.d.ts +92 -0
  240. package/dist/tools/nest-ext-tools.d.ts.map +1 -0
  241. package/dist/tools/nest-ext-tools.js +359 -0
  242. package/dist/tools/nest-ext-tools.js.map +1 -0
  243. package/dist/tools/nest-tools.d.ts +171 -0
  244. package/dist/tools/nest-tools.d.ts.map +1 -0
  245. package/dist/tools/nest-tools.js +1042 -0
  246. package/dist/tools/nest-tools.js.map +1 -0
  247. package/dist/tools/nextjs-api-contract-readers.d.ts +14 -0
  248. package/dist/tools/nextjs-api-contract-readers.d.ts.map +1 -0
  249. package/dist/tools/nextjs-api-contract-readers.js +204 -0
  250. package/dist/tools/nextjs-api-contract-readers.js.map +1 -0
  251. package/dist/tools/nextjs-api-contract-tools.d.ts +57 -0
  252. package/dist/tools/nextjs-api-contract-tools.d.ts.map +1 -0
  253. package/dist/tools/nextjs-api-contract-tools.js +144 -0
  254. package/dist/tools/nextjs-api-contract-tools.js.map +1 -0
  255. package/dist/tools/nextjs-boundary-tools.d.ts +39 -0
  256. package/dist/tools/nextjs-boundary-tools.d.ts.map +1 -0
  257. package/dist/tools/nextjs-boundary-tools.js +152 -0
  258. package/dist/tools/nextjs-boundary-tools.js.map +1 -0
  259. package/dist/tools/nextjs-component-tools.d.ts +121 -0
  260. package/dist/tools/nextjs-component-tools.d.ts.map +1 -0
  261. package/dist/tools/nextjs-component-tools.js +460 -0
  262. package/dist/tools/nextjs-component-tools.js.map +1 -0
  263. package/dist/tools/nextjs-data-flow-tools.d.ts +42 -0
  264. package/dist/tools/nextjs-data-flow-tools.d.ts.map +1 -0
  265. package/dist/tools/nextjs-data-flow-tools.js +158 -0
  266. package/dist/tools/nextjs-data-flow-tools.js.map +1 -0
  267. package/dist/tools/nextjs-framework-audit-tools.d.ts +37 -0
  268. package/dist/tools/nextjs-framework-audit-tools.d.ts.map +1 -0
  269. package/dist/tools/nextjs-framework-audit-tools.js +211 -0
  270. package/dist/tools/nextjs-framework-audit-tools.js.map +1 -0
  271. package/dist/tools/nextjs-link-tools.d.ts +41 -0
  272. package/dist/tools/nextjs-link-tools.d.ts.map +1 -0
  273. package/dist/tools/nextjs-link-tools.js +157 -0
  274. package/dist/tools/nextjs-link-tools.js.map +1 -0
  275. package/dist/tools/nextjs-metadata-tools.d.ts +74 -0
  276. package/dist/tools/nextjs-metadata-tools.d.ts.map +1 -0
  277. package/dist/tools/nextjs-metadata-tools.js +252 -0
  278. package/dist/tools/nextjs-metadata-tools.js.map +1 -0
  279. package/dist/tools/nextjs-middleware-coverage-tools.d.ts +41 -0
  280. package/dist/tools/nextjs-middleware-coverage-tools.d.ts.map +1 -0
  281. package/dist/tools/nextjs-middleware-coverage-tools.js +88 -0
  282. package/dist/tools/nextjs-middleware-coverage-tools.js.map +1 -0
  283. package/dist/tools/nextjs-route-tools.d.ts +100 -0
  284. package/dist/tools/nextjs-route-tools.d.ts.map +1 -0
  285. package/dist/tools/nextjs-route-tools.js +493 -0
  286. package/dist/tools/nextjs-route-tools.js.map +1 -0
  287. package/dist/tools/nextjs-security-readers.d.ts +22 -0
  288. package/dist/tools/nextjs-security-readers.d.ts.map +1 -0
  289. package/dist/tools/nextjs-security-readers.js +318 -0
  290. package/dist/tools/nextjs-security-readers.js.map +1 -0
  291. package/dist/tools/nextjs-security-scoring.d.ts +15 -0
  292. package/dist/tools/nextjs-security-scoring.d.ts.map +1 -0
  293. package/dist/tools/nextjs-security-scoring.js +65 -0
  294. package/dist/tools/nextjs-security-scoring.js.map +1 -0
  295. package/dist/tools/nextjs-security-tools.d.ts +75 -0
  296. package/dist/tools/nextjs-security-tools.d.ts.map +1 -0
  297. package/dist/tools/nextjs-security-tools.js +153 -0
  298. package/dist/tools/nextjs-security-tools.js.map +1 -0
  299. package/dist/tools/nextjs-tools.d.ts +15 -0
  300. package/dist/tools/nextjs-tools.d.ts.map +1 -0
  301. package/dist/tools/nextjs-tools.js +15 -0
  302. package/dist/tools/nextjs-tools.js.map +1 -0
  303. package/dist/tools/outline-tools.d.ts.map +1 -1
  304. package/dist/tools/outline-tools.js +20 -0
  305. package/dist/tools/outline-tools.js.map +1 -1
  306. package/dist/tools/pattern-tools.d.ts +8 -0
  307. package/dist/tools/pattern-tools.d.ts.map +1 -1
  308. package/dist/tools/pattern-tools.js +561 -3
  309. package/dist/tools/pattern-tools.js.map +1 -1
  310. package/dist/tools/perf-tools.d.ts +32 -0
  311. package/dist/tools/perf-tools.d.ts.map +1 -0
  312. package/dist/tools/perf-tools.js +227 -0
  313. package/dist/tools/perf-tools.js.map +1 -0
  314. package/dist/tools/php-tools.d.ts +176 -0
  315. package/dist/tools/php-tools.d.ts.map +1 -0
  316. package/dist/tools/php-tools.js +543 -0
  317. package/dist/tools/php-tools.js.map +1 -0
  318. package/dist/tools/prisma-schema-tools.d.ts +44 -0
  319. package/dist/tools/prisma-schema-tools.d.ts.map +1 -0
  320. package/dist/tools/prisma-schema-tools.js +358 -0
  321. package/dist/tools/prisma-schema-tools.js.map +1 -0
  322. package/dist/tools/project-tools.d.ts +115 -6
  323. package/dist/tools/project-tools.d.ts.map +1 -1
  324. package/dist/tools/project-tools.js +594 -217
  325. package/dist/tools/project-tools.js.map +1 -1
  326. package/dist/tools/pyproject-tools.d.ts +23 -0
  327. package/dist/tools/pyproject-tools.d.ts.map +1 -0
  328. package/dist/tools/pyproject-tools.js +133 -0
  329. package/dist/tools/pyproject-tools.js.map +1 -0
  330. package/dist/tools/pytest-tools.d.ts +20 -0
  331. package/dist/tools/pytest-tools.d.ts.map +1 -0
  332. package/dist/tools/pytest-tools.js +106 -0
  333. package/dist/tools/pytest-tools.js.map +1 -0
  334. package/dist/tools/python-callers.d.ts +28 -0
  335. package/dist/tools/python-callers.d.ts.map +1 -0
  336. package/dist/tools/python-callers.js +110 -0
  337. package/dist/tools/python-callers.js.map +1 -0
  338. package/dist/tools/python-circular-imports.d.ts +19 -0
  339. package/dist/tools/python-circular-imports.d.ts.map +1 -0
  340. package/dist/tools/python-circular-imports.js +126 -0
  341. package/dist/tools/python-circular-imports.js.map +1 -0
  342. package/dist/tools/python-deps-analyzer.d.ts +46 -0
  343. package/dist/tools/python-deps-analyzer.d.ts.map +1 -0
  344. package/dist/tools/python-deps-analyzer.js +227 -0
  345. package/dist/tools/python-deps-analyzer.js.map +1 -0
  346. package/dist/tools/query-tools.d.ts +23 -0
  347. package/dist/tools/query-tools.d.ts.map +1 -0
  348. package/dist/tools/query-tools.js +256 -0
  349. package/dist/tools/query-tools.js.map +1 -0
  350. package/dist/tools/react-tools.d.ts +218 -0
  351. package/dist/tools/react-tools.d.ts.map +1 -0
  352. package/dist/tools/react-tools.js +714 -0
  353. package/dist/tools/react-tools.js.map +1 -0
  354. package/dist/tools/report-tools.js +47 -0
  355. package/dist/tools/report-tools.js.map +1 -1
  356. package/dist/tools/review-diff-tools.d.ts +2 -6
  357. package/dist/tools/review-diff-tools.d.ts.map +1 -1
  358. package/dist/tools/review-diff-tools.js +51 -66
  359. package/dist/tools/review-diff-tools.js.map +1 -1
  360. package/dist/tools/room-tools.d.ts +36 -0
  361. package/dist/tools/room-tools.d.ts.map +1 -0
  362. package/dist/tools/room-tools.js +147 -0
  363. package/dist/tools/room-tools.js.map +1 -0
  364. package/dist/tools/route-tools.d.ts +27 -1
  365. package/dist/tools/route-tools.d.ts.map +1 -1
  366. package/dist/tools/route-tools.js +744 -18
  367. package/dist/tools/route-tools.js.map +1 -1
  368. package/dist/tools/ruff-tools.d.ts +32 -0
  369. package/dist/tools/ruff-tools.d.ts.map +1 -0
  370. package/dist/tools/ruff-tools.js +114 -0
  371. package/dist/tools/ruff-tools.js.map +1 -0
  372. package/dist/tools/search-ranker.d.ts.map +1 -1
  373. package/dist/tools/search-ranker.js +7 -0
  374. package/dist/tools/search-ranker.js.map +1 -1
  375. package/dist/tools/serialization-tools.d.ts +24 -0
  376. package/dist/tools/serialization-tools.d.ts.map +1 -0
  377. package/dist/tools/serialization-tools.js +156 -0
  378. package/dist/tools/serialization-tools.js.map +1 -0
  379. package/dist/tools/sql-tools.d.ts +234 -0
  380. package/dist/tools/sql-tools.d.ts.map +1 -0
  381. package/dist/tools/sql-tools.js +1037 -0
  382. package/dist/tools/sql-tools.js.map +1 -0
  383. package/dist/tools/status-tools.d.ts +10 -0
  384. package/dist/tools/status-tools.d.ts.map +1 -0
  385. package/dist/tools/status-tools.js +32 -0
  386. package/dist/tools/status-tools.js.map +1 -0
  387. package/dist/tools/symbol-tools.d.ts +19 -0
  388. package/dist/tools/symbol-tools.d.ts.map +1 -1
  389. package/dist/tools/symbol-tools.js +78 -4
  390. package/dist/tools/symbol-tools.js.map +1 -1
  391. package/dist/tools/test-impact-tools.d.ts +29 -0
  392. package/dist/tools/test-impact-tools.d.ts.map +1 -0
  393. package/dist/tools/test-impact-tools.js +156 -0
  394. package/dist/tools/test-impact-tools.js.map +1 -0
  395. package/dist/tools/typecheck-tools.d.ts +39 -0
  396. package/dist/tools/typecheck-tools.d.ts.map +1 -0
  397. package/dist/tools/typecheck-tools.js +191 -0
  398. package/dist/tools/typecheck-tools.js.map +1 -0
  399. package/dist/tools/wiring-tools.d.ts +19 -0
  400. package/dist/tools/wiring-tools.d.ts.map +1 -0
  401. package/dist/tools/wiring-tools.js +147 -0
  402. package/dist/tools/wiring-tools.js.map +1 -0
  403. package/dist/types.d.ts +9 -1
  404. package/dist/types.d.ts.map +1 -1
  405. package/dist/utils/framework-detect.d.ts +18 -2
  406. package/dist/utils/framework-detect.d.ts.map +1 -1
  407. package/dist/utils/framework-detect.js +150 -3
  408. package/dist/utils/framework-detect.js.map +1 -1
  409. package/dist/utils/import-graph.d.ts +36 -0
  410. package/dist/utils/import-graph.d.ts.map +1 -1
  411. package/dist/utils/import-graph.js +212 -9
  412. package/dist/utils/import-graph.js.map +1 -1
  413. package/dist/utils/language-detect.d.ts +21 -0
  414. package/dist/utils/language-detect.d.ts.map +1 -0
  415. package/dist/utils/language-detect.js +183 -0
  416. package/dist/utils/language-detect.js.map +1 -0
  417. package/dist/utils/nextjs-ast-readers.d.ts +44 -0
  418. package/dist/utils/nextjs-ast-readers.d.ts.map +1 -0
  419. package/dist/utils/nextjs-ast-readers.js +341 -0
  420. package/dist/utils/nextjs-ast-readers.js.map +1 -0
  421. package/dist/utils/nextjs-audit-cache.d.ts +51 -0
  422. package/dist/utils/nextjs-audit-cache.d.ts.map +1 -0
  423. package/dist/utils/nextjs-audit-cache.js +116 -0
  424. package/dist/utils/nextjs-audit-cache.js.map +1 -0
  425. package/dist/utils/nextjs-metadata-readers.d.ts +65 -0
  426. package/dist/utils/nextjs-metadata-readers.d.ts.map +1 -0
  427. package/dist/utils/nextjs-metadata-readers.js +447 -0
  428. package/dist/utils/nextjs-metadata-readers.js.map +1 -0
  429. package/dist/utils/nextjs.d.ts +42 -0
  430. package/dist/utils/nextjs.d.ts.map +1 -0
  431. package/dist/utils/nextjs.js +284 -0
  432. package/dist/utils/nextjs.js.map +1 -0
  433. package/dist/utils/python-import-resolver.d.ts +42 -0
  434. package/dist/utils/python-import-resolver.d.ts.map +1 -0
  435. package/dist/utils/python-import-resolver.js +101 -0
  436. package/dist/utils/python-import-resolver.js.map +1 -0
  437. package/dist/utils/python-imports.d.ts +28 -0
  438. package/dist/utils/python-imports.d.ts.map +1 -0
  439. package/dist/utils/python-imports.js +117 -0
  440. package/dist/utils/python-imports.js.map +1 -0
  441. package/dist/utils/react-alias.d.ts +15 -0
  442. package/dist/utils/react-alias.d.ts.map +1 -0
  443. package/dist/utils/react-alias.js +31 -0
  444. package/dist/utils/react-alias.js.map +1 -0
  445. package/dist/utils/test-file.d.ts.map +1 -1
  446. package/dist/utils/test-file.js +7 -0
  447. package/dist/utils/test-file.js.map +1 -1
  448. package/dist/utils/walk.d.ts +22 -0
  449. package/dist/utils/walk.d.ts.map +1 -1
  450. package/dist/utils/walk.js +70 -2
  451. package/dist/utils/walk.js.map +1 -1
  452. package/package.json +3 -2
  453. package/rules/codesift.md +34 -5
  454. package/rules/codesift.mdc +34 -5
  455. package/rules/codex.md +34 -5
  456. package/rules/gemini.md +34 -5
  457. package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
  458. package/src/parser/languages/tree-sitter-kotlin.wasm +0 -0
  459. package/src/parser/languages/tree-sitter-php.wasm +0 -0
  460. package/src/parser/languages/tree-sitter-php_only.wasm +0 -0
  461. package/src/parser/languages/tree-sitter-python.wasm +0 -0
@@ -0,0 +1,1042 @@
1
+ /**
2
+ * NestJS analysis tools — B1-B5 + C (nest_audit meta-orchestrator).
3
+ * Discoverable via discover_tools(query="nestjs").
4
+ */
5
+ import { readFile } from "node:fs/promises";
6
+ import { join } from "node:path";
7
+ import { getCodeIndex } from "./index-tools.js";
8
+ import { extractNestConventions } from "./project-tools.js";
9
+ // ---------------------------------------------------------------------------
10
+ // B5: nest_lifecycle_map — types + implementation
11
+ // ---------------------------------------------------------------------------
12
+ const LIFECYCLE_HOOKS = new Set([
13
+ "onModuleInit",
14
+ "onModuleDestroy",
15
+ "onApplicationBootstrap",
16
+ "onApplicationShutdown",
17
+ "beforeApplicationShutdown",
18
+ ]);
19
+ export async function nestLifecycleMap(repo) {
20
+ const index = await getCodeIndex(repo);
21
+ if (!index) {
22
+ throw new Error(`Repository "${repo}" not found. Index it first with index_folder.`);
23
+ }
24
+ const hooks = [];
25
+ const errors = [];
26
+ for (const sym of index.symbols) {
27
+ if (!LIFECYCLE_HOOKS.has(sym.name))
28
+ continue;
29
+ if (sym.kind !== "method" && sym.kind !== "function")
30
+ continue;
31
+ // Determine parent class name from source or file context
32
+ let className = "Unknown";
33
+ const source = sym.source ?? "";
34
+ // Try to find the enclosing class via parent_id (if available)
35
+ const symAny = sym;
36
+ if (symAny.parent_id) {
37
+ const parentSym = index.symbols.find((s) => s.id === symAny.parent_id);
38
+ if (parentSym)
39
+ className = parentSym.name;
40
+ }
41
+ // Fallback: look for class name in source
42
+ if (className === "Unknown") {
43
+ // Check if there's a class symbol in the same file that contains this method
44
+ const classSym = index.symbols.find((s) => s.file === sym.file && s.kind === "class" && s.start_line <= sym.start_line && s.end_line >= sym.end_line);
45
+ if (classSym)
46
+ className = classSym.name;
47
+ }
48
+ const isAsync = /async\s/.test(source.slice(0, 50));
49
+ hooks.push({
50
+ class_name: className,
51
+ file: sym.file,
52
+ hook: sym.name,
53
+ is_async: isAsync,
54
+ });
55
+ }
56
+ return { hooks, ...(errors.length > 0 ? { errors } : {}) };
57
+ }
58
+ export async function nestModuleGraph(repo, options) {
59
+ const index = await getCodeIndex(repo);
60
+ if (!index)
61
+ throw new Error(`Repository "${repo}" not found. Index it first with index_folder.`);
62
+ const maxModules = options?.max_modules ?? 200;
63
+ const moduleFiles = index.files.filter((f) => f.path.endsWith(".module.ts") || f.path.endsWith(".module.js"));
64
+ const modules = [];
65
+ const edges = [];
66
+ const errors = [];
67
+ let truncated = false;
68
+ // Parse each module file
69
+ for (const file of moduleFiles) {
70
+ if (modules.length >= maxModules) {
71
+ truncated = true;
72
+ break;
73
+ }
74
+ let source;
75
+ try {
76
+ source = await readFile(join(index.root, file.path), "utf-8");
77
+ }
78
+ catch (err) {
79
+ errors.push({ file: file.path, reason: `readFile failed: ${err instanceof Error ? err.message : String(err)}` });
80
+ continue;
81
+ }
82
+ const conv = extractNestConventions(source, file.path);
83
+ // Find the module class name from source
84
+ const classMatch = /export\s+class\s+(\w+Module)\b/.exec(source);
85
+ const moduleName = classMatch?.[1] ?? file.path.replace(/.*\//, "").replace(/\.module\.[jt]sx?$/, "Module");
86
+ // Check for @Global()
87
+ const isGlobal = /@Global\s*\(\s*\)/.test(source) || conv.modules.some((m) => m.is_global && m.name === moduleName);
88
+ // Extract exports array
89
+ const exportNames = [];
90
+ const exportsMatch = /exports:\s*\[([^\]]*)\]/s.exec(source);
91
+ if (exportsMatch) {
92
+ const inner = exportsMatch[1];
93
+ for (const m of inner.matchAll(/(\w+)/g)) {
94
+ exportNames.push(m[1]);
95
+ }
96
+ }
97
+ // Extract provider names
98
+ const providerNames = [];
99
+ const providersMatch = /providers:\s*\[([^\]]*)\]/s.exec(source);
100
+ if (providersMatch) {
101
+ const inner = providersMatch[1];
102
+ for (const m of inner.matchAll(/(?:useClass:\s*)?(\w+(?:Service|Provider|Guard|Interceptor|Pipe|Filter|Factory|Strategy))\b/g)) {
103
+ providerNames.push(m[1]);
104
+ }
105
+ }
106
+ modules.push({
107
+ name: moduleName,
108
+ file: file.path,
109
+ is_global: isGlobal,
110
+ imports: conv.modules.map((m) => m.name),
111
+ exports: exportNames,
112
+ providers: providerNames,
113
+ controllers: conv.controllers,
114
+ });
115
+ }
116
+ // Build edges: module → imported module
117
+ const moduleNames = new Set(modules.map((m) => m.name));
118
+ for (const mod of modules) {
119
+ for (const imp of mod.imports) {
120
+ if (moduleNames.has(imp)) {
121
+ edges.push({ from: mod.name, to: imp });
122
+ }
123
+ }
124
+ }
125
+ // Detect circular deps via DFS
126
+ const circular_deps = detectCycles(modules.map((m) => m.name), edges);
127
+ return {
128
+ modules,
129
+ edges,
130
+ circular_deps,
131
+ ...(errors.length > 0 ? { errors } : {}),
132
+ ...(truncated ? { truncated } : {}),
133
+ };
134
+ }
135
+ /** DFS cycle detection on directed graph. Exported for reuse in nest-ext-tools.ts (G12). */
136
+ export function detectCycles(nodes, edges) {
137
+ const adj = new Map();
138
+ for (const n of nodes)
139
+ adj.set(n, []);
140
+ for (const e of edges)
141
+ adj.get(e.from)?.push(e.to);
142
+ const cycles = [];
143
+ const visited = new Set();
144
+ const inStack = new Set();
145
+ const path = [];
146
+ function dfs(node) {
147
+ if (inStack.has(node)) {
148
+ const cycleStart = path.indexOf(node);
149
+ if (cycleStart >= 0)
150
+ cycles.push(path.slice(cycleStart).concat(node));
151
+ return;
152
+ }
153
+ if (visited.has(node))
154
+ return;
155
+ visited.add(node);
156
+ inStack.add(node);
157
+ path.push(node);
158
+ for (const next of adj.get(node) ?? [])
159
+ dfs(next);
160
+ path.pop();
161
+ inStack.delete(node);
162
+ }
163
+ for (const n of nodes)
164
+ dfs(n);
165
+ return cycles;
166
+ }
167
+ // ---------------------------------------------------------------------------
168
+ // Shared helpers: constructor injection parsing (CQ14)
169
+ // ---------------------------------------------------------------------------
170
+ /** Extract constructor parameter body using paren counting (handles decorated params) */
171
+ function extractConstructorBody(source) {
172
+ const ctorIdx = source.indexOf("constructor(");
173
+ if (ctorIdx === -1)
174
+ return null;
175
+ const start = ctorIdx + "constructor(".length;
176
+ let depth = 1;
177
+ let i = start;
178
+ while (i < source.length && depth > 0) {
179
+ if (source[i] === "(")
180
+ depth++;
181
+ else if (source[i] === ")")
182
+ depth--;
183
+ i++;
184
+ }
185
+ return depth === 0 ? source.slice(start, i - 1) : null;
186
+ }
187
+ /** Extract injected type names from a constructor body string */
188
+ function extractInjectedTypes(ctorBody) {
189
+ const types = [];
190
+ // R-6 fix: separate depth counters for () and <> to avoid cross-corruption
191
+ const params = [];
192
+ let parenDepth = 0;
193
+ let angleDepth = 0;
194
+ let current = "";
195
+ for (const ch of ctorBody) {
196
+ if (ch === "(")
197
+ parenDepth++;
198
+ else if (ch === ")")
199
+ parenDepth--;
200
+ else if (ch === "<")
201
+ angleDepth++;
202
+ else if (ch === ">")
203
+ angleDepth--;
204
+ if (ch === "," && parenDepth === 0 && angleDepth === 0) {
205
+ params.push(current.trim());
206
+ current = "";
207
+ }
208
+ else {
209
+ current += ch;
210
+ }
211
+ }
212
+ if (current.trim())
213
+ params.push(current.trim());
214
+ for (const param of params) {
215
+ // Extract type after the last `:` — handles decorators before the param name
216
+ const colonIdx = param.lastIndexOf(":");
217
+ if (colonIdx === -1)
218
+ continue;
219
+ const typeStr = param.slice(colonIdx + 1).trim();
220
+ // G3: Detect container generics like Repository<User>, Model<Comment>, Repo<X>.
221
+ // For container types, unwrap and return the inner type parameter so consumers
222
+ // can distinguish Repository<Article> from Repository<Comment>.
223
+ const genericMatch = typeStr.match(/^(\w+)<\s*(\w+)\s*(?:,[^>]*)?>/);
224
+ if (genericMatch) {
225
+ const outer = genericMatch[1];
226
+ const inner = genericMatch[2];
227
+ if (/^(Repository|Repo|Model|Collection|Array|Set|Map|List|Observable|Promise|Ref|Token|Provider|Class)$/.test(outer)) {
228
+ types.push(inner);
229
+ continue;
230
+ }
231
+ }
232
+ // Non-container type — return the outer name as before
233
+ const typeMatch = typeStr.match(/^(\w+)/);
234
+ if (typeMatch)
235
+ types.push(typeMatch[1]);
236
+ }
237
+ return types;
238
+ }
239
+ /** Parse @Injectable() classes from source */
240
+ function parseInjectableClasses(source) {
241
+ const results = [];
242
+ const re = /@Injectable\s*\(([^)]*)\)\s*(?:export\s+)?class\s+(\w+)/g;
243
+ let m;
244
+ while ((m = re.exec(source)) !== null) {
245
+ const args = m[1] ?? "";
246
+ const name = m[2];
247
+ const scopeMatch = args.match(/scope:\s*Scope\.(\w+)/);
248
+ results.push({ name, ...(scopeMatch ? { scope: scopeMatch[1] } : {}) });
249
+ }
250
+ return results;
251
+ }
252
+ export async function nestDIGraph(repo, options) {
253
+ const index = await getCodeIndex(repo);
254
+ if (!index)
255
+ throw new Error(`Repository "${repo}" not found. Index it first with index_folder.`);
256
+ const maxNodes = options?.max_nodes ?? 200;
257
+ const focus = options?.focus;
258
+ const nodes = [];
259
+ const edges = [];
260
+ const errors = [];
261
+ let truncated = false;
262
+ // Scan files for @Injectable classes
263
+ const candidateFiles = index.files.filter((f) => {
264
+ if (focus && !f.path.includes(focus))
265
+ return false;
266
+ return f.path.endsWith(".ts") || f.path.endsWith(".js");
267
+ });
268
+ for (const file of candidateFiles) {
269
+ if (nodes.length >= maxNodes) {
270
+ truncated = true;
271
+ break;
272
+ }
273
+ let source;
274
+ try {
275
+ source = await readFile(join(index.root, file.path), "utf-8");
276
+ }
277
+ catch (err) {
278
+ errors.push({ file: file.path, reason: `readFile failed: ${err instanceof Error ? err.message : String(err)}` });
279
+ continue;
280
+ }
281
+ const injectables = parseInjectableClasses(source);
282
+ for (const inj of injectables) {
283
+ if (nodes.length >= maxNodes) {
284
+ truncated = true;
285
+ break;
286
+ }
287
+ nodes.push({
288
+ name: inj.name,
289
+ file: file.path,
290
+ kind: "provider",
291
+ ...(inj.scope ? { scope: inj.scope } : {}),
292
+ });
293
+ // Extract constructor injection
294
+ // Find the class body for this specific injectable
295
+ const classIdx = source.indexOf(`class ${inj.name}`);
296
+ if (classIdx === -1)
297
+ continue;
298
+ const classSource = source.slice(classIdx);
299
+ const ctorBody = extractConstructorBody(classSource);
300
+ if (!ctorBody)
301
+ continue;
302
+ const injectedTypes = extractInjectedTypes(ctorBody);
303
+ for (const type of injectedTypes) {
304
+ edges.push({ from: inj.name, to: type, via: "inject" });
305
+ }
306
+ }
307
+ }
308
+ // Detect cycles
309
+ const nodeNames = nodes.map((n) => n.name);
310
+ const cycles = detectCycles(nodeNames, edges.map((e) => ({ from: e.from, to: e.to })));
311
+ return {
312
+ nodes,
313
+ edges,
314
+ cycles,
315
+ cross_module_warnings: [], // TODO: implement cross-module warnings in future task
316
+ ...(errors.length > 0 ? { errors } : {}),
317
+ ...(truncated ? { truncated } : {}),
318
+ };
319
+ }
320
+ // ---------------------------------------------------------------------------
321
+ // Shared helpers: guard/interceptor/pipe parsing (CQ14)
322
+ // ---------------------------------------------------------------------------
323
+ /** Parse @UseGuards(...) from source, returns guard class names.
324
+ * R-8 fix: handles both class-ref form @UseGuards(AuthGuard) and
325
+ * instantiation form @UseGuards(new ThrottlerGuard()). */
326
+ function parseUseGuards(source) {
327
+ const results = [];
328
+ // Match the full @UseGuards(...) arg including nested parens for `new Guard()`
329
+ const re = /@UseGuards\s*\(\s*([^)]*(?:\([^)]*\)[^)]*)*)\s*\)/g;
330
+ let m;
331
+ while ((m = re.exec(source)) !== null) {
332
+ const args = m[1];
333
+ // Extract class names — both bare refs and `new ClassName(...)` instantiations
334
+ for (const part of args.split(",")) {
335
+ const trimmed = part.trim();
336
+ if (!trimmed)
337
+ continue;
338
+ const newMatch = /new\s+(\w+)/.exec(trimmed);
339
+ if (newMatch) {
340
+ results.push(newMatch[1]);
341
+ continue;
342
+ }
343
+ const bareMatch = /^(\w+)$/.exec(trimmed);
344
+ if (bareMatch)
345
+ results.push(bareMatch[1]);
346
+ }
347
+ }
348
+ return results;
349
+ }
350
+ /** Parse @UseInterceptors(...) from source */
351
+ function parseUseInterceptors(source) {
352
+ const results = [];
353
+ const re = /@UseInterceptors\s*\(\s*([\w\s,]+)\s*\)/g;
354
+ let m;
355
+ while ((m = re.exec(source)) !== null) {
356
+ for (const name of m[1].split(",").map((s) => s.trim()).filter(Boolean)) {
357
+ results.push(name);
358
+ }
359
+ }
360
+ return results;
361
+ }
362
+ /** Parse @UsePipes(...) from source */
363
+ function parseUsePipes(source) {
364
+ const results = [];
365
+ const re = /@UsePipes\s*\(\s*([\w\s,]+)\s*\)/g;
366
+ let m;
367
+ while ((m = re.exec(source)) !== null) {
368
+ for (const name of m[1].split(",").map((s) => s.trim()).filter(Boolean)) {
369
+ results.push(name);
370
+ }
371
+ }
372
+ return results;
373
+ }
374
+ /** Parse @UseFilters(...) from source */
375
+ function parseUseFilters(source) {
376
+ const results = [];
377
+ const re = /@UseFilters\s*\(\s*([\w\s,]+)\s*\)/g;
378
+ let m;
379
+ while ((m = re.exec(source)) !== null) {
380
+ for (const name of m[1].split(",").map((s) => s.trim()).filter(Boolean)) {
381
+ results.push(name);
382
+ }
383
+ }
384
+ return results;
385
+ }
386
+ /** Built-in NestJS decorators that should NOT be reported as custom metadata */
387
+ const BUILTIN_DECORATORS = new Set([
388
+ "Get", "Post", "Put", "Delete", "Patch", "Options", "Head", "All",
389
+ "Controller", "Injectable", "Module", "Global",
390
+ "UseGuards", "UseInterceptors", "UsePipes", "UseFilters",
391
+ "Param", "Body", "Query", "Headers", "Req", "Res", "Next", "Ip", "Session", "HostParam",
392
+ "Version", "ApiOperation", "ApiBearerAuth", "ApiTags", "ApiResponse", "ApiProperty", "ApiParam", "ApiBody", "ApiQuery",
393
+ "HealthCheck", "HealthIndicator",
394
+ "Catch", "Optional", "Inject", "InjectRepository", "InjectModel",
395
+ "Resolver", "Query" /*gql*/, "Mutation", "Subscription", "Args", "ResolveField",
396
+ "WebSocketGateway", "SubscribeMessage", "MessageBody", "ConnectedSocket",
397
+ "MessagePattern", "EventPattern", "Payload", "Ctx",
398
+ "Cron", "Interval", "Timeout", "OnEvent",
399
+ "Entity", "Column", "PrimaryGeneratedColumn", "PrimaryColumn", "OneToMany", "ManyToOne", "OneToOne", "ManyToMany",
400
+ "JoinColumn", "JoinTable", "CreateDateColumn", "UpdateDateColumn", "DeleteDateColumn", "Index", "Unique",
401
+ ]);
402
+ /**
403
+ * G4: Parse custom decorators on methods (e.g. @Roles('admin'), @Public(), @CurrentUser()).
404
+ * Returns decorator name + raw argument string (may be empty).
405
+ * Excludes built-in NestJS decorators (BUILTIN_DECORATORS set).
406
+ */
407
+ function parseCustomDecorators(source) {
408
+ const results = [];
409
+ // Match @PascalCase(args) — capture name and argument text
410
+ const re = /@([A-Z]\w*)\s*\(([^)]*)\)/g;
411
+ let m;
412
+ while ((m = re.exec(source)) !== null) {
413
+ const name = m[1];
414
+ if (BUILTIN_DECORATORS.has(name))
415
+ continue;
416
+ // Strip quotes from simple string args for readable output
417
+ const args = m[2].trim().replace(/^['"`]|['"`]$/g, "");
418
+ results.push({ name, args });
419
+ }
420
+ return results;
421
+ }
422
+ /** G1: glob-like matching for NestJS middleware forRoutes against resolved route paths */
423
+ function matchMiddlewareRoute(mwRoute, routePath, routeMethod) {
424
+ // Method filter
425
+ if (mwRoute.method && mwRoute.method !== "ALL" && mwRoute.method !== routeMethod)
426
+ return false;
427
+ // Normalise both sides to leading-slash form for comparison
428
+ const norm = (p) => "/" + p.replace(/^\/+|\/+$/g, "");
429
+ const mwNorm = norm(mwRoute.path);
430
+ const routeNorm = norm(routePath);
431
+ // '*' matches everything
432
+ if (mwNorm === "/*" || mwRoute.path === "*")
433
+ return true;
434
+ // Convert NestJS glob (users/*) into anchored regex
435
+ // escape regex metachars except '*', then replace '*' with '.*'
436
+ const escaped = mwNorm.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
437
+ const re = new RegExp(`^${escaped}($|/)`);
438
+ return re.test(routeNorm);
439
+ }
440
+ export async function nestGuardChain(repo, options) {
441
+ const index = await getCodeIndex(repo);
442
+ if (!index)
443
+ throw new Error(`Repository "${repo}" not found. Index it first with index_folder.`);
444
+ const maxRoutes = options?.max_routes ?? 300;
445
+ const routes = [];
446
+ const errors = [];
447
+ let truncated = false;
448
+ // 1. Collect global guards/interceptors/pipes from module files + G1 middleware chains
449
+ const globalChain = [];
450
+ const middlewareEntries = [];
451
+ for (const file of index.files) {
452
+ if (!file.path.endsWith(".module.ts") && !file.path.endsWith(".module.js"))
453
+ continue;
454
+ let source;
455
+ try {
456
+ source = await readFile(join(index.root, file.path), "utf-8");
457
+ }
458
+ catch (err) {
459
+ errors.push({ file: file.path, reason: `readFile failed: ${err instanceof Error ? err.message : String(err)}` });
460
+ continue;
461
+ }
462
+ const conv = extractNestConventions(source, file.path);
463
+ for (const g of conv.global_guards)
464
+ globalChain.push({ layer: "global", type: "guard", name: g.name, file: g.file });
465
+ for (const f of conv.global_filters)
466
+ globalChain.push({ layer: "global", type: "filter", name: f.name, file: f.file });
467
+ for (const p of conv.global_pipes)
468
+ globalChain.push({ layer: "global", type: "pipe", name: p.name, file: p.file });
469
+ for (const i of conv.global_interceptors)
470
+ globalChain.push({ layer: "global", type: "interceptor", name: i.name, file: i.file });
471
+ // G1: defensive default since middleware_chains is optional on older profiles
472
+ for (const mw of conv.middleware_chains ?? []) {
473
+ middlewareEntries.push({ middleware: mw.middleware, routes: mw.routes, file: mw.file });
474
+ }
475
+ }
476
+ // 2. Scan controller files
477
+ const controllerFiles = index.files.filter((f) => f.path.endsWith(".controller.ts") || f.path.endsWith(".controller.js"));
478
+ const methods = ["Get", "Post", "Put", "Delete", "Patch"];
479
+ for (const file of controllerFiles) {
480
+ if (routes.length >= maxRoutes) {
481
+ truncated = true;
482
+ break;
483
+ }
484
+ let source;
485
+ try {
486
+ source = await readFile(join(index.root, file.path), "utf-8");
487
+ }
488
+ catch (err) {
489
+ errors.push({ file: file.path, reason: `readFile failed: ${err instanceof Error ? err.message : String(err)}` });
490
+ continue;
491
+ }
492
+ // Controller-level info
493
+ const ctrlMatch = /@Controller\s*\(\s*['"`]([^'"`]*)['"`]/.exec(source);
494
+ const ctrlPrefix = ctrlMatch?.[1] ?? "";
495
+ const ctrlClassMatch = /class\s+(\w+)/.exec(source);
496
+ const ctrlClass = ctrlClassMatch?.[1] ?? "UnknownController";
497
+ // Controller-level decorators (before class body — find source before first method)
498
+ const classIdx = source.indexOf(`class ${ctrlClass}`);
499
+ const ctrlHeader = classIdx >= 0 ? source.slice(0, classIdx) : "";
500
+ const ctrlGuards = parseUseGuards(ctrlHeader).map((n) => ({ layer: "controller", type: "guard", name: n }));
501
+ const ctrlInterceptors = parseUseInterceptors(ctrlHeader).map((n) => ({ layer: "controller", type: "interceptor", name: n }));
502
+ const ctrlPipes = parseUsePipes(ctrlHeader).map((n) => ({ layer: "controller", type: "pipe", name: n }));
503
+ const ctrlFilters = parseUseFilters(ctrlHeader).map((n) => ({ layer: "controller", type: "filter", name: n }));
504
+ const ctrlLevelChain = [...ctrlGuards, ...ctrlInterceptors, ...ctrlPipes, ...ctrlFilters];
505
+ // Collect ALL method decorator positions first to bound lookback correctly
506
+ const allMethodPositions = [];
507
+ for (const method of methods) {
508
+ const reStr = new RegExp(`@${method}\\s*\\(\\s*['"\`]([^'"\`]*)['"\`]\\s*\\)`, "g");
509
+ const reEmpty = new RegExp(`@${method}\\s*\\(\\s*\\)`, "g");
510
+ let m;
511
+ while ((m = reStr.exec(source)) !== null)
512
+ allMethodPositions.push({ method, path: m[1] ?? "", pos: m.index });
513
+ while ((m = reEmpty.exec(source)) !== null)
514
+ allMethodPositions.push({ method, path: "", pos: m.index });
515
+ }
516
+ allMethodPositions.sort((a, b) => a.pos - b.pos);
517
+ for (let idx = 0; idx < allMethodPositions.length; idx++) {
518
+ if (routes.length >= maxRoutes) {
519
+ truncated = true;
520
+ break;
521
+ }
522
+ const mm = allMethodPositions[idx];
523
+ // Normalise: collapse slashes, trim trailing slash (except for root "/")
524
+ const rawPath = `/${ctrlPrefix}/${mm.path}`.replace(/\/+/g, "/");
525
+ const fullPath = rawPath.length > 1 ? rawPath.replace(/\/$/, "") : rawPath;
526
+ if (options?.path && fullPath !== options.path)
527
+ continue;
528
+ // Lookback window: from previous method decorator (or class start) to current
529
+ const prevEnd = idx > 0 ? allMethodPositions[idx - 1].pos + 10 : (classIdx >= 0 ? classIdx : 0);
530
+ const methodCtx = source.slice(Math.max(prevEnd, 0), mm.pos);
531
+ const methodGuards = parseUseGuards(methodCtx).map((n) => ({ layer: "method", type: "guard", name: n }));
532
+ const methodInterceptors = parseUseInterceptors(methodCtx).map((n) => ({ layer: "method", type: "interceptor", name: n }));
533
+ const methodPipes = parseUsePipes(methodCtx).map((n) => ({ layer: "method", type: "pipe", name: n }));
534
+ const methodFilters = parseUseFilters(methodCtx).map((n) => ({ layer: "method", type: "filter", name: n }));
535
+ // G4: custom decorators (e.g. @Roles('admin'), @Public()) — method-level only
536
+ const methodMetadata = parseCustomDecorators(methodCtx).map((d) => ({
537
+ layer: "method",
538
+ type: "metadata",
539
+ name: d.name,
540
+ ...(d.args ? { args: d.args } : {}),
541
+ }));
542
+ // G1: match middleware entries against this route
543
+ const middlewareChain = [];
544
+ for (const mw of middlewareEntries) {
545
+ for (const mwRoute of mw.routes) {
546
+ if (matchMiddlewareRoute(mwRoute, fullPath, mm.method.toUpperCase())) {
547
+ middlewareChain.push({ layer: "middleware", type: "guard", name: mw.middleware, file: mw.file });
548
+ break;
549
+ }
550
+ }
551
+ }
552
+ routes.push({
553
+ route: fullPath,
554
+ method: mm.method.toUpperCase(),
555
+ controller: ctrlClass,
556
+ file: file.path,
557
+ chain: [...globalChain, ...middlewareChain, ...ctrlLevelChain, ...methodGuards, ...methodInterceptors, ...methodPipes, ...methodFilters, ...methodMetadata],
558
+ });
559
+ }
560
+ }
561
+ return {
562
+ routes,
563
+ ...(errors.length > 0 ? { errors } : {}),
564
+ ...(truncated ? { truncated } : {}),
565
+ };
566
+ }
567
+ export async function nestRouteInventory(repo, options) {
568
+ const index = await getCodeIndex(repo);
569
+ if (!index)
570
+ throw new Error(`Repository "${repo}" not found. Index it first with index_folder.`);
571
+ const maxRoutes = options?.max_routes ?? 500;
572
+ const errors = [];
573
+ let truncated = false;
574
+ // Use findNestJSHandlers with wildcard path to get ALL routes
575
+ // We pass "/**" as a wildcard — but findNestJSHandlers uses matchPath which
576
+ // doesn't support wildcards. Instead, we scan controllers ourselves.
577
+ const controllerFiles = index.files.filter((f) => f.path.endsWith(".controller.ts") || f.path.endsWith(".controller.js"));
578
+ const routes = [];
579
+ const methods = ["Get", "Post", "Put", "Delete", "Patch"];
580
+ for (const file of controllerFiles) {
581
+ if (routes.length >= maxRoutes) {
582
+ truncated = true;
583
+ break;
584
+ }
585
+ let source;
586
+ try {
587
+ source = await readFile(join(index.root, file.path), "utf-8");
588
+ }
589
+ catch (err) {
590
+ errors.push({ file: file.path, reason: `readFile failed: ${err instanceof Error ? err.message : String(err)}` });
591
+ continue;
592
+ }
593
+ const ctrlMatchStr = /@Controller\s*\(\s*['"`]([^'"`]*)['"`]/.exec(source);
594
+ // G9: also try @Controller({ path: '...', version: '...' }) object form
595
+ const ctrlObjMatch = !ctrlMatchStr ? /@Controller\s*\(\s*\{[^}]*path:\s*['"`]([^'"`]*)['"`]/.exec(source) : null;
596
+ const ctrlMatchEmpty = !ctrlMatchStr && !ctrlObjMatch ? /@Controller\s*\(\s*\)/.exec(source) : null;
597
+ const ctrlPrefix = ctrlMatchStr?.[1] ?? ctrlObjMatch?.[1] ?? (ctrlMatchEmpty ? "" : "");
598
+ const ctrlClassMatch = /class\s+(\w+)/.exec(source);
599
+ const ctrlClass = ctrlClassMatch?.[1] ?? "UnknownController";
600
+ // Guards at controller level
601
+ const classIdx = source.indexOf(`class ${ctrlClass}`);
602
+ const ctrlHeader = classIdx >= 0 ? source.slice(0, classIdx) : "";
603
+ const ctrlGuards = parseUseGuards(ctrlHeader);
604
+ // G9: controller-level version — method can override
605
+ const ctrlVersion = parseControllerVersion(ctrlHeader);
606
+ // Collect all method decorator positions first — enables bounded lookback per method
607
+ const allMethodDecoratorPositions = [];
608
+ for (const method of methods) {
609
+ const reStr = new RegExp(`@${method}\\s*\\(\\s*['"\`]([^'"\`]*)['"\`]\\s*\\)`, "g");
610
+ const reEmpty = new RegExp(`@${method}\\s*\\(\\s*\\)`, "g");
611
+ let m;
612
+ while ((m = reStr.exec(source)) !== null) {
613
+ allMethodDecoratorPositions.push({ method, path: m[1] ?? "", pos: m.index, matchLen: m[0].length });
614
+ }
615
+ while ((m = reEmpty.exec(source)) !== null) {
616
+ allMethodDecoratorPositions.push({ method, path: "", pos: m.index, matchLen: m[0].length });
617
+ }
618
+ }
619
+ allMethodDecoratorPositions.sort((a, b) => a.pos - b.pos);
620
+ for (let idx = 0; idx < allMethodDecoratorPositions.length; idx++) {
621
+ if (routes.length >= maxRoutes) {
622
+ truncated = true;
623
+ break;
624
+ }
625
+ const mm = allMethodDecoratorPositions[idx];
626
+ const handler = resolveHandlerName(source, mm.pos + mm.matchLen);
627
+ if (!handler)
628
+ continue;
629
+ const rawPath = mm.path
630
+ ? `/${ctrlPrefix}/${mm.path}`.replace(/\/+/g, "/")
631
+ : `/${ctrlPrefix}`.replace(/\/+/g, "/") || "/";
632
+ const fullPath = rawPath.length > 1 ? rawPath.replace(/\/$/, "") : rawPath;
633
+ if (routes.some((r) => r.file === file.path && r.handler === handler && r.method === mm.method.toUpperCase()))
634
+ continue;
635
+ // Bounded backward lookback: from previous decorator end to current decorator start
636
+ const prevEnd = idx > 0
637
+ ? allMethodDecoratorPositions[idx - 1].pos + allMethodDecoratorPositions[idx - 1].matchLen + 20
638
+ : (classIdx >= 0 ? classIdx : 0);
639
+ routes.push(buildRouteBounded(mm.method, fullPath, handler, mm.pos, prevEnd));
640
+ }
641
+ // buildRoute is replaced by buildRouteBounded which takes the lookback start
642
+ function buildRouteBounded(method, fullPath, handler, methodIdx, lookbackStart) {
643
+ const before = source.slice(Math.max(lookbackStart, 0), methodIdx);
644
+ let endPos = methodIdx + 800;
645
+ const hNameRe = new RegExp(`\\b${handler}\\s*\\(`);
646
+ const hMatch = hNameRe.exec(source.slice(methodIdx, methodIdx + 800));
647
+ if (hMatch)
648
+ endPos = methodIdx + hMatch.index;
649
+ const after = source.slice(methodIdx, Math.min(source.length, endPos));
650
+ const methodCtx = before + after;
651
+ // Bound paramCtx to the method's own signature via paren counting —
652
+ // prevents leakage from adjacent methods in the same file.
653
+ const paramCtx = extractMethodSignature(source, endPos);
654
+ const methodGuards = parseUseGuards(methodCtx);
655
+ const allGuards = [...ctrlGuards, ...methodGuards];
656
+ const methodVersion = parseVersionFromContext(methodCtx);
657
+ const swagger = parseSwaggerFromContext(methodCtx, ctrlHeader);
658
+ const healthCheck = isHealthCheck(methodCtx);
659
+ const inlinePipes = parseInlinePipes(methodCtx);
660
+ const entry = {
661
+ method: method.toUpperCase(),
662
+ path: fullPath,
663
+ handler,
664
+ controller: ctrlClass,
665
+ file: file.path,
666
+ guards: allGuards,
667
+ params: parseParamDecorators(paramCtx),
668
+ };
669
+ const version = methodVersion ?? ctrlVersion;
670
+ if (version)
671
+ entry.version = version;
672
+ if (swagger)
673
+ entry.swagger = swagger;
674
+ if (healthCheck)
675
+ entry.is_health_check = true;
676
+ if (inlinePipes.length > 0)
677
+ entry.inline_pipes = inlinePipes;
678
+ return entry;
679
+ }
680
+ }
681
+ const protectedCount = routes.filter((r) => r.guards.length > 0).length;
682
+ return {
683
+ routes,
684
+ stats: {
685
+ total_routes: routes.length,
686
+ protected: protectedCount,
687
+ unprotected: routes.length - protectedCount,
688
+ },
689
+ ...(errors.length > 0 ? { errors } : {}),
690
+ ...(truncated ? { truncated } : {}),
691
+ };
692
+ }
693
+ /**
694
+ * Extract the method parameter signature starting at the handler name position.
695
+ * Paren-counts to find the matching `)` for the parameter list — prevents
696
+ * scanning into adjacent methods which would produce duplicate @Param/@Body.
697
+ */
698
+ function extractMethodSignature(source, handlerNamePos) {
699
+ // Find the opening paren of the handler's parameter list
700
+ let i = handlerNamePos;
701
+ // Skip handler name + whitespace
702
+ while (i < source.length && /[\w\s]/.test(source[i]))
703
+ i++;
704
+ if (source[i] !== "(")
705
+ return source.slice(handlerNamePos, Math.min(source.length, handlerNamePos + 400));
706
+ // Paren-count to find matching close
707
+ let depth = 1;
708
+ const start = i + 1;
709
+ i++;
710
+ while (i < source.length && depth > 0) {
711
+ if (source[i] === "(")
712
+ depth++;
713
+ else if (source[i] === ")")
714
+ depth--;
715
+ if (depth === 0)
716
+ break;
717
+ i++;
718
+ }
719
+ return source.slice(start, i);
720
+ }
721
+ /** Parse @Param/@Body/@Query decorators from source context */
722
+ function parseParamDecorators(source) {
723
+ const params = [];
724
+ const re = /@(Param|Body|Query|Headers)\s*\(\s*(?:['"`](\w+)['"`])?\s*\)/g;
725
+ let m;
726
+ while ((m = re.exec(source)) !== null) {
727
+ params.push({ decorator: m[1], name: m[2] ?? "" });
728
+ }
729
+ return params;
730
+ }
731
+ /**
732
+ * Resolve the method handler name after a @Get/@Post/etc decorator.
733
+ * Skips intermediate stacked decorators (@Version, @ApiOperation, @UseGuards, etc.)
734
+ * using paren counting to handle nested args like @UsePipes(new Pipe({...})).
735
+ */
736
+ function resolveHandlerName(source, afterDecoratorPos) {
737
+ let pos = afterDecoratorPos;
738
+ const maxScan = pos + 1000;
739
+ while (pos < Math.min(source.length, maxScan)) {
740
+ // Skip whitespace and newlines
741
+ while (pos < source.length && /\s/.test(source[pos]))
742
+ pos++;
743
+ if (pos >= source.length)
744
+ return undefined;
745
+ // If we hit another decorator, skip the whole decorator including args (paren count)
746
+ if (source[pos] === "@") {
747
+ pos++; // skip @
748
+ // skip decorator name
749
+ while (pos < source.length && /\w/.test(source[pos]))
750
+ pos++;
751
+ // skip args if present (paren-counted)
752
+ while (pos < source.length && /\s/.test(source[pos]))
753
+ pos++;
754
+ if (source[pos] === "(") {
755
+ let depth = 1;
756
+ pos++;
757
+ while (pos < source.length && depth > 0) {
758
+ if (source[pos] === "(")
759
+ depth++;
760
+ else if (source[pos] === ")")
761
+ depth--;
762
+ pos++;
763
+ }
764
+ }
765
+ continue;
766
+ }
767
+ // Skip keywords like async, public, private
768
+ const kwMatch = /^(?:async|public|private|protected)\s+/.exec(source.slice(pos));
769
+ if (kwMatch) {
770
+ pos += kwMatch[0].length;
771
+ continue;
772
+ }
773
+ // Should now be at the method name
774
+ const nameMatch = /^(\w+)\s*\(/.exec(source.slice(pos));
775
+ if (nameMatch)
776
+ return nameMatch[1];
777
+ return undefined;
778
+ }
779
+ return undefined;
780
+ }
781
+ /** G9: Extract @Version('n') or @Controller({ version: 'n' }) — method-level takes precedence */
782
+ function parseVersionFromContext(methodCtx) {
783
+ const m = /@Version\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/.exec(methodCtx);
784
+ return m ? m[1] : undefined;
785
+ }
786
+ function parseControllerVersion(ctrlHeader) {
787
+ const m = /@Controller\s*\(\s*\{[^}]*version:\s*['"`]([^'"`]+)['"`]/.exec(ctrlHeader);
788
+ return m ? m[1] : undefined;
789
+ }
790
+ /** G10: Extract Swagger annotations */
791
+ function parseSwaggerFromContext(methodCtx, ctrlHeader) {
792
+ const result = {};
793
+ const summaryMatch = /@ApiOperation\s*\(\s*\{[^}]*summary:\s*['"`]([^'"`]+)['"`]/.exec(methodCtx);
794
+ if (summaryMatch)
795
+ result.summary = summaryMatch[1];
796
+ if (/@ApiBearerAuth\s*\(/.test(methodCtx) || /@ApiBearerAuth\s*\(/.test(ctrlHeader)) {
797
+ result.bearer = true;
798
+ }
799
+ const tagsMatch = /@ApiTags\s*\(\s*((?:['"`][^'"`]+['"`]\s*,?\s*)+)\)/.exec(ctrlHeader);
800
+ if (tagsMatch) {
801
+ const tags = [...tagsMatch[1].matchAll(/['"`]([^'"`]+)['"`]/g)].map((m) => m[1]);
802
+ if (tags.length > 0)
803
+ result.tags = tags;
804
+ }
805
+ return Object.keys(result).length > 0 ? result : undefined;
806
+ }
807
+ /** G13: Check for @HealthCheck() decorator on method */
808
+ function isHealthCheck(methodCtx) {
809
+ return /@HealthCheck\s*\(\s*\)/.test(methodCtx);
810
+ }
811
+ /** G11: Extract inline pipe constructions from @UsePipes(new ValidationPipe(...)) */
812
+ function parseInlinePipes(methodCtx) {
813
+ const pipes = [];
814
+ const re = /@UsePipes\s*\(\s*new\s+(\w+Pipe)\s*\(/g;
815
+ let m;
816
+ while ((m = re.exec(methodCtx)) !== null)
817
+ pipes.push(m[1]);
818
+ return pipes;
819
+ }
820
+ const ALL_NEST_CHECKS = [
821
+ "modules", "routes", "di", "guards", "lifecycle", "patterns",
822
+ "graphql", "websocket", "schedule", "typeorm", "microservice",
823
+ ];
824
+ export async function nestAudit(repo, options) {
825
+ const index = await getCodeIndex(repo);
826
+ if (!index)
827
+ throw new Error(`Repository "${repo}" not found. Index it first with index_folder.`);
828
+ // Check if this is a NestJS repo
829
+ const { detectFrameworks } = await import("../utils/framework-detect.js");
830
+ const frameworks = detectFrameworks(index);
831
+ if (!frameworks.has("nestjs")) {
832
+ return {
833
+ framework_detected: false,
834
+ summary: { total_routes: 0, cycles: 0, violations: 0, anti_pattern_hits: 0, failed_checks: 0, truncated_checks: [] },
835
+ };
836
+ }
837
+ const enabledChecks = new Set((options?.checks ?? [...ALL_NEST_CHECKS]));
838
+ const tasks = [];
839
+ if (enabledChecks.has("lifecycle")) {
840
+ tasks.push(nestLifecycleMap(repo).then((r) => ({ name: "lifecycle", result: r }))
841
+ .catch((e) => ({ name: "lifecycle", error: e instanceof Error ? e.message : String(e) })));
842
+ }
843
+ if (enabledChecks.has("modules")) {
844
+ tasks.push(nestModuleGraph(repo).then((r) => ({ name: "modules", result: r }))
845
+ .catch((e) => ({ name: "modules", error: e instanceof Error ? e.message : String(e) })));
846
+ }
847
+ if (enabledChecks.has("di")) {
848
+ tasks.push(nestDIGraph(repo).then((r) => ({ name: "di", result: r }))
849
+ .catch((e) => ({ name: "di", error: e instanceof Error ? e.message : String(e) })));
850
+ }
851
+ if (enabledChecks.has("guards")) {
852
+ tasks.push(nestGuardChain(repo).then((r) => ({ name: "guards", result: r }))
853
+ .catch((e) => ({ name: "guards", error: e instanceof Error ? e.message : String(e) })));
854
+ }
855
+ if (enabledChecks.has("routes")) {
856
+ tasks.push(nestRouteInventory(repo).then((r) => ({ name: "routes", result: r }))
857
+ .catch((e) => ({ name: "routes", error: e instanceof Error ? e.message : String(e) })));
858
+ }
859
+ if (enabledChecks.has("patterns")) {
860
+ tasks.push((async () => {
861
+ const { searchPatterns, listPatterns } = await import("./pattern-tools.js");
862
+ const nestPatterns = listPatterns().filter((p) => p.name.startsWith("nest-"));
863
+ const results = [];
864
+ for (const p of nestPatterns) {
865
+ const r = await searchPatterns(repo, p.name);
866
+ if (r.matches.length > 0)
867
+ results.push({ pattern: p.name, count: r.matches.length });
868
+ }
869
+ return { name: "patterns", result: results };
870
+ })().catch((e) => ({ name: "patterns", error: e instanceof Error ? e.message : String(e) })));
871
+ }
872
+ // Wave 2 checks — lazy import to avoid eager loading if nest-ext-tools isn't needed
873
+ if (enabledChecks.has("graphql")) {
874
+ tasks.push((async () => {
875
+ const { nestGraphQLMap } = await import("./nest-ext-tools.js");
876
+ return { name: "graphql", result: await nestGraphQLMap(repo) };
877
+ })().catch((e) => ({ name: "graphql", error: e instanceof Error ? e.message : String(e) })));
878
+ }
879
+ if (enabledChecks.has("websocket")) {
880
+ tasks.push((async () => {
881
+ const { nestWebSocketMap } = await import("./nest-ext-tools.js");
882
+ return { name: "websocket", result: await nestWebSocketMap(repo) };
883
+ })().catch((e) => ({ name: "websocket", error: e instanceof Error ? e.message : String(e) })));
884
+ }
885
+ if (enabledChecks.has("schedule")) {
886
+ tasks.push((async () => {
887
+ const { nestScheduleMap } = await import("./nest-ext-tools.js");
888
+ return { name: "schedule", result: await nestScheduleMap(repo) };
889
+ })().catch((e) => ({ name: "schedule", error: e instanceof Error ? e.message : String(e) })));
890
+ }
891
+ if (enabledChecks.has("typeorm")) {
892
+ tasks.push((async () => {
893
+ const { nestTypeOrmMap } = await import("./nest-ext-tools.js");
894
+ return { name: "typeorm", result: await nestTypeOrmMap(repo) };
895
+ })().catch((e) => ({ name: "typeorm", error: e instanceof Error ? e.message : String(e) })));
896
+ }
897
+ if (enabledChecks.has("microservice")) {
898
+ tasks.push((async () => {
899
+ const { nestMicroserviceMap } = await import("./nest-ext-tools.js");
900
+ return { name: "microservice", result: await nestMicroserviceMap(repo) };
901
+ })().catch((e) => ({ name: "microservice", error: e instanceof Error ? e.message : String(e) })));
902
+ }
903
+ const settled = await Promise.all(tasks);
904
+ // Aggregate
905
+ const auditErrors = [];
906
+ const warnings = [];
907
+ const truncatedChecks = [];
908
+ let lifecycleResult;
909
+ let moduleResult;
910
+ let diResult;
911
+ let guardResult;
912
+ let routeResult;
913
+ let patternResults;
914
+ let graphqlResult;
915
+ let websocketResult;
916
+ let scheduleResult;
917
+ let typeormResult;
918
+ let microserviceResult;
919
+ for (const item of settled) {
920
+ if (item.error) {
921
+ auditErrors.push({ check: item.name, reason: item.error });
922
+ continue;
923
+ }
924
+ switch (item.name) {
925
+ case "lifecycle":
926
+ lifecycleResult = item.result;
927
+ break;
928
+ case "modules": {
929
+ const r = item.result;
930
+ moduleResult = r;
931
+ if (r.truncated)
932
+ truncatedChecks.push("modules");
933
+ if (r.errors)
934
+ warnings.push(...r.errors);
935
+ break;
936
+ }
937
+ case "di": {
938
+ const r = item.result;
939
+ diResult = r;
940
+ if (r.truncated)
941
+ truncatedChecks.push("di");
942
+ if (r.errors)
943
+ warnings.push(...r.errors);
944
+ break;
945
+ }
946
+ case "guards": {
947
+ const r = item.result;
948
+ guardResult = r;
949
+ if (r.truncated)
950
+ truncatedChecks.push("guards");
951
+ if (r.errors)
952
+ warnings.push(...r.errors);
953
+ break;
954
+ }
955
+ case "routes": {
956
+ const r = item.result;
957
+ routeResult = r;
958
+ if (r.truncated)
959
+ truncatedChecks.push("routes");
960
+ if (r.errors)
961
+ warnings.push(...r.errors);
962
+ break;
963
+ }
964
+ case "patterns":
965
+ patternResults = item.result;
966
+ break;
967
+ case "graphql": {
968
+ const r = item.result;
969
+ graphqlResult = r;
970
+ if (r.truncated)
971
+ truncatedChecks.push("graphql");
972
+ if (r.errors)
973
+ warnings.push(...r.errors);
974
+ break;
975
+ }
976
+ case "websocket": {
977
+ const r = item.result;
978
+ websocketResult = r;
979
+ if (r.truncated)
980
+ truncatedChecks.push("websocket");
981
+ if (r.errors)
982
+ warnings.push(...r.errors);
983
+ break;
984
+ }
985
+ case "schedule": {
986
+ const r = item.result;
987
+ scheduleResult = r;
988
+ if (r.truncated)
989
+ truncatedChecks.push("schedule");
990
+ if (r.errors)
991
+ warnings.push(...r.errors);
992
+ break;
993
+ }
994
+ case "typeorm": {
995
+ const r = item.result;
996
+ typeormResult = r;
997
+ if (r.truncated)
998
+ truncatedChecks.push("typeorm");
999
+ if (r.errors)
1000
+ warnings.push(...r.errors);
1001
+ break;
1002
+ }
1003
+ case "microservice": {
1004
+ const r = item.result;
1005
+ microserviceResult = r;
1006
+ if (r.truncated)
1007
+ truncatedChecks.push("microservice");
1008
+ if (r.errors)
1009
+ warnings.push(...r.errors);
1010
+ break;
1011
+ }
1012
+ }
1013
+ }
1014
+ const totalRoutes = routeResult?.stats.total_routes ?? 0;
1015
+ const cycles = (moduleResult?.circular_deps.length ?? 0) + (diResult?.cycles.length ?? 0) + (typeormResult?.cycles.length ?? 0);
1016
+ const antiPatternHits = patternResults?.reduce((sum, p) => sum + p.count, 0) ?? 0;
1017
+ return {
1018
+ framework_detected: true,
1019
+ ...(lifecycleResult ? { lifecycle_map: lifecycleResult } : {}),
1020
+ ...(moduleResult ? { module_graph: moduleResult } : {}),
1021
+ ...(diResult ? { di_graph: diResult } : {}),
1022
+ ...(guardResult ? { guard_chain: guardResult } : {}),
1023
+ ...(routeResult ? { route_inventory: routeResult } : {}),
1024
+ ...(graphqlResult ? { graphql_map: graphqlResult } : {}),
1025
+ ...(websocketResult ? { websocket_map: websocketResult } : {}),
1026
+ ...(scheduleResult ? { schedule_map: scheduleResult } : {}),
1027
+ ...(typeormResult ? { typeorm_map: typeormResult } : {}),
1028
+ ...(microserviceResult ? { microservice_map: microserviceResult } : {}),
1029
+ ...(patternResults ? { anti_patterns: patternResults } : {}),
1030
+ summary: {
1031
+ total_routes: totalRoutes,
1032
+ cycles,
1033
+ violations: 0, // TODO: boundary violations from module_graph
1034
+ anti_pattern_hits: antiPatternHits,
1035
+ failed_checks: auditErrors.length,
1036
+ truncated_checks: truncatedChecks,
1037
+ },
1038
+ ...(warnings.length > 0 ? { warnings } : {}),
1039
+ ...(auditErrors.length > 0 ? { errors: auditErrors } : {}),
1040
+ };
1041
+ }
1042
+ //# sourceMappingURL=nest-tools.js.map