mcp-react-toolkit 1.0.1 → 1.3.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 (275) hide show
  1. package/README.md +194 -44
  2. package/bin/cli.mjs +59 -0
  3. package/node_modules/@mcp-showcase/shared/build/McpServerBase.d.ts +18 -0
  4. package/node_modules/@mcp-showcase/shared/build/McpServerBase.d.ts.map +1 -0
  5. package/node_modules/@mcp-showcase/shared/build/McpServerBase.js +74 -0
  6. package/node_modules/@mcp-showcase/shared/build/McpServerBase.js.map +1 -0
  7. package/node_modules/@mcp-showcase/shared/build/ToolRegistry.d.ts +9 -0
  8. package/node_modules/@mcp-showcase/shared/build/ToolRegistry.d.ts.map +1 -0
  9. package/node_modules/@mcp-showcase/shared/build/ToolRegistry.js +22 -0
  10. package/node_modules/@mcp-showcase/shared/build/ToolRegistry.js.map +1 -0
  11. package/node_modules/@mcp-showcase/shared/build/fs.d.ts +8 -0
  12. package/node_modules/@mcp-showcase/shared/build/fs.d.ts.map +1 -0
  13. package/node_modules/@mcp-showcase/shared/build/fs.js +45 -0
  14. package/node_modules/@mcp-showcase/shared/build/fs.js.map +1 -0
  15. package/node_modules/@mcp-showcase/shared/build/index.d.ts +5 -0
  16. package/node_modules/@mcp-showcase/shared/build/index.d.ts.map +1 -0
  17. package/node_modules/@mcp-showcase/shared/build/index.js +5 -0
  18. package/node_modules/@mcp-showcase/shared/build/index.js.map +1 -0
  19. package/node_modules/@mcp-showcase/shared/build/types.d.ts +36 -0
  20. package/node_modules/@mcp-showcase/shared/build/types.d.ts.map +1 -0
  21. package/node_modules/@mcp-showcase/shared/build/types.js +5 -0
  22. package/node_modules/@mcp-showcase/shared/build/types.js.map +1 -0
  23. package/node_modules/@mcp-showcase/shared/package.json +24 -0
  24. package/node_modules/@mcp-showcase/shared/src/McpServerBase.ts +100 -0
  25. package/node_modules/@mcp-showcase/shared/src/ToolRegistry.ts +38 -0
  26. package/node_modules/@mcp-showcase/shared/src/fs.ts +49 -0
  27. package/node_modules/@mcp-showcase/shared/src/index.ts +12 -0
  28. package/node_modules/@mcp-showcase/shared/src/types.ts +44 -0
  29. package/node_modules/@mcp-showcase/shared/tsconfig.json +8 -0
  30. package/package.json +38 -4
  31. package/tools/accessibility-checker/build/index.js +9 -5
  32. package/tools/accessibility-checker/build/index.js.map +1 -1
  33. package/tools/accessibility-checker/build/rules.d.ts.map +1 -1
  34. package/tools/accessibility-checker/build/rules.js +325 -94
  35. package/tools/accessibility-checker/build/rules.js.map +1 -1
  36. package/tools/code-modernizer/build/tools/01-convert-to-typescript.d.ts.map +1 -1
  37. package/tools/code-modernizer/build/tools/01-convert-to-typescript.js +65 -50
  38. package/tools/code-modernizer/build/tools/01-convert-to-typescript.js.map +1 -1
  39. package/tools/code-modernizer/build/types.d.ts +1 -0
  40. package/tools/code-modernizer/build/types.d.ts.map +1 -1
  41. package/tools/code-modernizer/build/utils/ast-parser.d.ts.map +1 -1
  42. package/tools/code-modernizer/build/utils/ast-parser.js +30 -14
  43. package/tools/code-modernizer/build/utils/ast-parser.js.map +1 -1
  44. package/tools/code-modernizer/build/utils/type-generator.d.ts +1 -1
  45. package/tools/code-modernizer/build/utils/type-generator.d.ts.map +1 -1
  46. package/tools/code-modernizer/build/utils/type-generator.js +72 -23
  47. package/tools/code-modernizer/build/utils/type-generator.js.map +1 -1
  48. package/tools/component-factory/build/index.js +59 -7
  49. package/tools/component-factory/build/index.js.map +1 -1
  50. package/tools/component-fixer/README.md +44 -0
  51. package/tools/component-fixer/build/index.d.ts +3 -0
  52. package/tools/component-fixer/build/index.d.ts.map +1 -0
  53. package/tools/component-fixer/build/index.js +647 -0
  54. package/tools/component-fixer/build/index.js.map +1 -0
  55. package/tools/component-fixer/package.json +20 -0
  56. package/tools/component-reviewer/README.md +54 -0
  57. package/tools/component-reviewer/build/index.d.ts +39 -0
  58. package/tools/component-reviewer/build/index.d.ts.map +1 -0
  59. package/tools/component-reviewer/build/index.js +946 -0
  60. package/tools/component-reviewer/build/index.js.map +1 -0
  61. package/tools/component-reviewer/package.json +20 -0
  62. package/tools/dep-auditor/build/index.d.ts +1 -0
  63. package/tools/dep-auditor/build/index.d.ts.map +1 -1
  64. package/tools/dep-auditor/build/index.js +71 -16
  65. package/tools/dep-auditor/build/index.js.map +1 -1
  66. package/tools/generate-tests/build/analyzer.d.ts +14 -0
  67. package/tools/generate-tests/build/analyzer.d.ts.map +1 -1
  68. package/tools/generate-tests/build/analyzer.js +96 -42
  69. package/tools/generate-tests/build/analyzer.js.map +1 -1
  70. package/tools/generate-tests/build/generators.d.ts.map +1 -1
  71. package/tools/generate-tests/build/generators.js +304 -79
  72. package/tools/generate-tests/build/generators.js.map +1 -1
  73. package/tools/generate-tests/build/index.js +29 -10
  74. package/tools/generate-tests/build/index.js.map +1 -1
  75. package/tools/json-viewer/build/index.js +29 -6
  76. package/tools/json-viewer/build/index.js.map +1 -1
  77. package/tools/legacy-analyzer/README.md +66 -0
  78. package/tools/legacy-analyzer/build/index.d.ts +3 -0
  79. package/tools/legacy-analyzer/build/index.d.ts.map +1 -0
  80. package/tools/legacy-analyzer/build/index.js +209 -0
  81. package/tools/legacy-analyzer/build/index.js.map +1 -0
  82. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.d.ts +3 -0
  83. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.d.ts.map +1 -0
  84. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.js +115 -0
  85. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.js.map +1 -0
  86. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.d.ts +3 -0
  87. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.d.ts.map +1 -0
  88. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.js +85 -0
  89. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.js.map +1 -0
  90. package/tools/legacy-analyzer/build/tools/03-analyze-components.d.ts +3 -0
  91. package/tools/legacy-analyzer/build/tools/03-analyze-components.d.ts.map +1 -0
  92. package/tools/legacy-analyzer/build/tools/03-analyze-components.js +87 -0
  93. package/tools/legacy-analyzer/build/tools/03-analyze-components.js.map +1 -0
  94. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.d.ts +3 -0
  95. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.d.ts.map +1 -0
  96. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.js +133 -0
  97. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.js.map +1 -0
  98. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.d.ts +3 -0
  99. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.d.ts.map +1 -0
  100. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.js +160 -0
  101. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.js.map +1 -0
  102. package/tools/legacy-analyzer/build/tools/06-analyze-routing.d.ts +3 -0
  103. package/tools/legacy-analyzer/build/tools/06-analyze-routing.d.ts.map +1 -0
  104. package/tools/legacy-analyzer/build/tools/06-analyze-routing.js +150 -0
  105. package/tools/legacy-analyzer/build/tools/06-analyze-routing.js.map +1 -0
  106. package/tools/legacy-analyzer/build/tools/07-analyze-styling.d.ts +3 -0
  107. package/tools/legacy-analyzer/build/tools/07-analyze-styling.d.ts.map +1 -0
  108. package/tools/legacy-analyzer/build/tools/07-analyze-styling.js +131 -0
  109. package/tools/legacy-analyzer/build/tools/07-analyze-styling.js.map +1 -0
  110. package/tools/legacy-analyzer/build/tools/08-analyze-assets.d.ts +3 -0
  111. package/tools/legacy-analyzer/build/tools/08-analyze-assets.d.ts.map +1 -0
  112. package/tools/legacy-analyzer/build/tools/08-analyze-assets.js +85 -0
  113. package/tools/legacy-analyzer/build/tools/08-analyze-assets.js.map +1 -0
  114. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.d.ts +3 -0
  115. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.d.ts.map +1 -0
  116. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.js +329 -0
  117. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.js.map +1 -0
  118. package/tools/legacy-analyzer/build/tools/10-detect-duplication.d.ts +3 -0
  119. package/tools/legacy-analyzer/build/tools/10-detect-duplication.d.ts.map +1 -0
  120. package/tools/legacy-analyzer/build/tools/10-detect-duplication.js +192 -0
  121. package/tools/legacy-analyzer/build/tools/10-detect-duplication.js.map +1 -0
  122. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.d.ts +3 -0
  123. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.d.ts.map +1 -0
  124. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.js +232 -0
  125. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.js.map +1 -0
  126. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.d.ts +3 -0
  127. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.d.ts.map +1 -0
  128. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.js +247 -0
  129. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.js.map +1 -0
  130. package/tools/legacy-analyzer/build/tools/13-detect-features.d.ts +3 -0
  131. package/tools/legacy-analyzer/build/tools/13-detect-features.d.ts.map +1 -0
  132. package/tools/legacy-analyzer/build/tools/13-detect-features.js +141 -0
  133. package/tools/legacy-analyzer/build/tools/13-detect-features.js.map +1 -0
  134. package/tools/legacy-analyzer/build/tools/14-classify-files.d.ts +3 -0
  135. package/tools/legacy-analyzer/build/tools/14-classify-files.d.ts.map +1 -0
  136. package/tools/legacy-analyzer/build/tools/14-classify-files.js +76 -0
  137. package/tools/legacy-analyzer/build/tools/14-classify-files.js.map +1 -0
  138. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.d.ts +3 -0
  139. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.d.ts.map +1 -0
  140. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.js +70 -0
  141. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.js.map +1 -0
  142. package/tools/legacy-analyzer/build/tools/16-design-target-structure.d.ts +3 -0
  143. package/tools/legacy-analyzer/build/tools/16-design-target-structure.d.ts.map +1 -0
  144. package/tools/legacy-analyzer/build/tools/16-design-target-structure.js +26 -0
  145. package/tools/legacy-analyzer/build/tools/16-design-target-structure.js.map +1 -0
  146. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.d.ts +3 -0
  147. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.d.ts.map +1 -0
  148. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.js +108 -0
  149. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.js.map +1 -0
  150. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.d.ts +3 -0
  151. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.d.ts.map +1 -0
  152. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.js +137 -0
  153. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.js.map +1 -0
  154. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.d.ts +3 -0
  155. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.d.ts.map +1 -0
  156. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.js +160 -0
  157. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.js.map +1 -0
  158. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.d.ts +3 -0
  159. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.d.ts.map +1 -0
  160. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.js +162 -0
  161. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.js.map +1 -0
  162. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.d.ts +3 -0
  163. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.d.ts.map +1 -0
  164. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.js +108 -0
  165. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.js.map +1 -0
  166. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.d.ts +3 -0
  167. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.d.ts.map +1 -0
  168. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.js +98 -0
  169. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.js.map +1 -0
  170. package/tools/legacy-analyzer/build/types.d.ts +413 -0
  171. package/tools/legacy-analyzer/build/types.d.ts.map +1 -0
  172. package/tools/legacy-analyzer/build/types.js +12 -0
  173. package/tools/legacy-analyzer/build/types.js.map +1 -0
  174. package/tools/legacy-analyzer/build/utils/ast-parser.d.ts +34 -0
  175. package/tools/legacy-analyzer/build/utils/ast-parser.d.ts.map +1 -0
  176. package/tools/legacy-analyzer/build/utils/ast-parser.js +394 -0
  177. package/tools/legacy-analyzer/build/utils/ast-parser.js.map +1 -0
  178. package/tools/legacy-analyzer/build/utils/file-scanner.d.ts +51 -0
  179. package/tools/legacy-analyzer/build/utils/file-scanner.d.ts.map +1 -0
  180. package/tools/legacy-analyzer/build/utils/file-scanner.js +174 -0
  181. package/tools/legacy-analyzer/build/utils/file-scanner.js.map +1 -0
  182. package/tools/legacy-analyzer/build/utils/import-tracker.d.ts +38 -0
  183. package/tools/legacy-analyzer/build/utils/import-tracker.d.ts.map +1 -0
  184. package/tools/legacy-analyzer/build/utils/import-tracker.js +194 -0
  185. package/tools/legacy-analyzer/build/utils/import-tracker.js.map +1 -0
  186. package/tools/legacy-analyzer/build/utils/refactor-helpers.d.ts +88 -0
  187. package/tools/legacy-analyzer/build/utils/refactor-helpers.d.ts.map +1 -0
  188. package/tools/legacy-analyzer/build/utils/refactor-helpers.js +538 -0
  189. package/tools/legacy-analyzer/build/utils/refactor-helpers.js.map +1 -0
  190. package/tools/legacy-analyzer/package.json +20 -0
  191. package/tools/lighthouse-runner/README.md +45 -0
  192. package/tools/lighthouse-runner/build/index.d.ts +6 -0
  193. package/tools/lighthouse-runner/build/index.d.ts.map +1 -0
  194. package/tools/lighthouse-runner/build/index.js +295 -0
  195. package/tools/lighthouse-runner/build/index.js.map +1 -0
  196. package/tools/lighthouse-runner/package.json +20 -0
  197. package/tools/monorepo-manager/build/utils.d.ts.map +1 -1
  198. package/tools/monorepo-manager/build/utils.js +12 -9
  199. package/tools/monorepo-manager/build/utils.js.map +1 -1
  200. package/tools/performance-audit/README.md +37 -0
  201. package/tools/performance-audit/build/index.d.ts +13 -0
  202. package/tools/performance-audit/build/index.d.ts.map +1 -0
  203. package/tools/performance-audit/build/index.js +311 -0
  204. package/tools/performance-audit/build/index.js.map +1 -0
  205. package/tools/performance-audit/package.json +20 -0
  206. package/tools/quality-pipeline/build/index.js +55 -15
  207. package/tools/quality-pipeline/build/index.js.map +1 -1
  208. package/tools/render-analyzer/README.md +43 -0
  209. package/tools/render-analyzer/build/index.d.ts +25 -0
  210. package/tools/render-analyzer/build/index.d.ts.map +1 -0
  211. package/tools/render-analyzer/build/index.js +342 -0
  212. package/tools/render-analyzer/build/index.js.map +1 -0
  213. package/tools/render-analyzer/package.json +20 -0
  214. package/tools/shared/build/fs.d.ts +8 -0
  215. package/tools/shared/build/fs.d.ts.map +1 -0
  216. package/tools/shared/build/fs.js +45 -0
  217. package/tools/shared/build/fs.js.map +1 -0
  218. package/tools/shared/build/index.d.ts +1 -0
  219. package/tools/shared/build/index.d.ts.map +1 -1
  220. package/tools/shared/build/index.js +1 -0
  221. package/tools/shared/build/index.js.map +1 -1
  222. package/tools/shared/package.json +2 -1
  223. package/tools/storybook-generator/README.md +39 -0
  224. package/tools/storybook-generator/build/index.d.ts +13 -0
  225. package/tools/storybook-generator/build/index.d.ts.map +1 -0
  226. package/tools/storybook-generator/build/index.js +478 -0
  227. package/tools/storybook-generator/build/index.js.map +1 -0
  228. package/tools/storybook-generator/package.json +20 -0
  229. package/tools/test-gap-analyzer/README.md +41 -0
  230. package/tools/test-gap-analyzer/build/index.d.ts +20 -0
  231. package/tools/test-gap-analyzer/build/index.d.ts.map +1 -0
  232. package/tools/test-gap-analyzer/build/index.js +371 -0
  233. package/tools/test-gap-analyzer/build/index.js.map +1 -0
  234. package/tools/test-gap-analyzer/package.json +20 -0
  235. package/tools/typescript-enforcer/build/scanner.d.ts.map +1 -1
  236. package/tools/typescript-enforcer/build/scanner.js +13 -1
  237. package/tools/typescript-enforcer/build/scanner.js.map +1 -1
  238. package/tools/typescript-enforcer/build/types.d.ts +1 -0
  239. package/tools/typescript-enforcer/build/types.d.ts.map +1 -1
  240. package/CONTRIBUTING.md +0 -157
  241. package/demo/legacy-app/src/App.jsx +0 -12
  242. package/demo/legacy-app/src/components/Dashboard.jsx +0 -51
  243. package/demo/legacy-app/src/components/UserCard.jsx +0 -32
  244. package/demo/legacy-app/src/hooks/useUsers.js +0 -38
  245. package/demo/legacy-app/src/utils/api.js +0 -30
  246. package/glama.json +0 -4
  247. package/mcp-publisher +0 -0
  248. package/server.json +0 -20
  249. package/tools/accessibility-checker/build/rules.test.d.ts +0 -2
  250. package/tools/accessibility-checker/build/rules.test.d.ts.map +0 -1
  251. package/tools/accessibility-checker/build/rules.test.js.map +0 -1
  252. package/tools/code-modernizer/build/utils/file-ops.test.d.ts +0 -2
  253. package/tools/code-modernizer/build/utils/file-ops.test.d.ts.map +0 -1
  254. package/tools/code-modernizer/build/utils/file-ops.test.js.map +0 -1
  255. package/tools/component-factory/build/utils.test.d.ts +0 -2
  256. package/tools/component-factory/build/utils.test.d.ts.map +0 -1
  257. package/tools/component-factory/build/utils.test.js.map +0 -1
  258. package/tools/dep-auditor/build/index.test.d.ts +0 -2
  259. package/tools/dep-auditor/build/index.test.d.ts.map +0 -1
  260. package/tools/dep-auditor/build/index.test.js.map +0 -1
  261. package/tools/generate-tests/build/analyzer.test.d.ts +0 -2
  262. package/tools/generate-tests/build/analyzer.test.d.ts.map +0 -1
  263. package/tools/generate-tests/build/analyzer.test.js.map +0 -1
  264. package/tools/json-viewer/build/utils.test.d.ts +0 -2
  265. package/tools/json-viewer/build/utils.test.d.ts.map +0 -1
  266. package/tools/json-viewer/build/utils.test.js.map +0 -1
  267. package/tools/monorepo-manager/build/utils.test.d.ts +0 -2
  268. package/tools/monorepo-manager/build/utils.test.d.ts.map +0 -1
  269. package/tools/monorepo-manager/build/utils.test.js.map +0 -1
  270. package/tools/quality-pipeline/build/utils.test.d.ts +0 -2
  271. package/tools/quality-pipeline/build/utils.test.d.ts.map +0 -1
  272. package/tools/quality-pipeline/build/utils.test.js.map +0 -1
  273. package/tools/typescript-enforcer/build/scanner.test.d.ts +0 -2
  274. package/tools/typescript-enforcer/build/scanner.test.d.ts.map +0 -1
  275. package/tools/typescript-enforcer/build/scanner.test.js.map +0 -1
@@ -0,0 +1,3 @@
1
+ import type { AnalyzeComponentsOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function analyzeComponents(appPath: string, config?: Partial<AnalyzerConfig>): Promise<AnalyzeComponentsOutput>;
3
+ //# sourceMappingURL=03-analyze-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"03-analyze-components.d.ts","sourceRoot":"","sources":["../../src/tools/03-analyze-components.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,uBAAuB,EAAiB,cAAc,EAAE,MAAM,aAAa,CAAC;AAE1F,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAoF3H"}
@@ -0,0 +1,87 @@
1
+ // ============================================================================
2
+ // TOOL #3: analyze-components
3
+ // Scans all components: count, large components, complex components
4
+ // ============================================================================
5
+ import * as path from 'path';
6
+ import * as fs from 'fs';
7
+ import { findSourceFiles, resolveSourceDir } from '../utils/file-scanner.js';
8
+ import { analyzeComponent } from '../utils/ast-parser.js';
9
+ import { DEFAULT_CONFIG } from '../types.js';
10
+ export async function analyzeComponents(appPath, config) {
11
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
12
+ const srcPath = resolveSourceDir(appPath);
13
+ const files = await findSourceFiles(srcPath);
14
+ // Include all JS/JSX/TS/TSX files — apps like CRA use lowercase App.js or index.js
15
+ const componentFiles = files;
16
+ const largeComponents = [];
17
+ const complexComponents = [];
18
+ for (const file of componentFiles) {
19
+ const relPath = path.relative(appPath, file);
20
+ // Read raw content first (works for both JS and TS)
21
+ let content;
22
+ try {
23
+ content = fs.readFileSync(file, 'utf8');
24
+ }
25
+ catch {
26
+ continue;
27
+ }
28
+ // Try AST analysis — may fail for plain JS files
29
+ const analysis = analyzeComponent(file);
30
+ const responsibilities = [];
31
+ const importSources = (analysis?.imports ?? []).map((i) => i.source.toLowerCase());
32
+ // All responsibility checks use regex on raw content (works for both JS and TS)
33
+ const hasState = /\buseState\s*\(|React\.useState\s*\(|\buseReducer\s*\(|React\.useReducer\s*\(/.test(content)
34
+ || (analysis?.hooks.some((h) => h.name === 'useState' || h.name === 'useReducer') ?? false);
35
+ if (hasState)
36
+ responsibilities.push('state-management');
37
+ const hasEffect = /\buseEffect\s*\(|React\.useEffect\s*\(/.test(content)
38
+ || (analysis?.hooks.some((h) => h.name === 'useEffect') ?? false);
39
+ if (hasEffect)
40
+ responsibilities.push('side-effects');
41
+ if (content.includes('fetch(') || content.includes('axios.') || importSources.some((s) => s.includes('api'))) {
42
+ responsibilities.push('api-calls');
43
+ }
44
+ if (importSources.some((s) => s.includes('router') || s.includes('navigate'))) {
45
+ responsibilities.push('routing');
46
+ }
47
+ if (content.includes('onSubmit') || content.includes('FormData') || content.includes('handleSubmit')) {
48
+ responsibilities.push('form-handling');
49
+ }
50
+ const jsxTagCount = (content.match(/<[A-Z][a-zA-Z]*|<[a-z]+[\s>]/g) || []).length;
51
+ const astJsxCount = analysis?.jsxElements.length ?? 0;
52
+ if (astJsxCount > 15 || jsxTagCount > 15)
53
+ responsibilities.push('heavy-rendering');
54
+ const lines = content.split('\n').length;
55
+ const stateVarCount = (content.match(/\buseState\s*\(|React\.useState\s*\(/g) || []).length;
56
+ const hookCount = analysis?.hooks.length ?? 0;
57
+ const jsxDepth = analysis?.jsxMaxDepth ?? 0;
58
+ const componentName = analysis?.name ?? path.basename(file, path.extname(file));
59
+ const componentInfo = {
60
+ name: componentName,
61
+ file: relPath,
62
+ lines,
63
+ jsxMaxDepth: jsxDepth,
64
+ responsibilities,
65
+ };
66
+ // Skip non-component files (no JSX, no hooks, not enough evidence)
67
+ const isLikelyComponent = jsxTagCount > 0 || hasState || hasEffect || content.includes('return (') || content.includes('return(');
68
+ if (!isLikelyComponent)
69
+ continue;
70
+ if (lines > mergedConfig.largeComponentLines) {
71
+ largeComponents.push(componentInfo);
72
+ }
73
+ // Complex: multiple responsibilities, or deep nesting, or many hooks, or many state vars
74
+ const isComplex = responsibilities.length >= 3 ||
75
+ jsxDepth > 6 ||
76
+ hookCount >= 5 ||
77
+ stateVarCount >= 3;
78
+ if (isComplex)
79
+ complexComponents.push(componentInfo);
80
+ }
81
+ return {
82
+ totalComponents: componentFiles.length,
83
+ largeComponents: largeComponents.sort((a, b) => b.lines - a.lines),
84
+ complexComponents: complexComponents.sort((a, b) => b.responsibilities.length - a.responsibilities.length),
85
+ };
86
+ }
87
+ //# sourceMappingURL=03-analyze-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"03-analyze-components.js","sourceRoot":"","sources":["../../src/tools/03-analyze-components.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AnalyzeStateOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function analyzeStateManagement(appPath: string, config?: Partial<AnalyzerConfig>): Promise<AnalyzeStateOutput>;
3
+ //# sourceMappingURL=04-analyze-state-management.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"04-analyze-state-management.d.ts","sourceRoot":"","sources":["../../src/tools/04-analyze-state-management.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,cAAc,EAAE,MAAM,aAAa,CAAC;AAErF,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA+I3H"}
@@ -0,0 +1,133 @@
1
+ // ============================================================================
2
+ // TOOL #4: analyze-state-management
3
+ // Detects Redux, Context API, local state patterns, and advanced patterns
4
+ // ============================================================================
5
+ import * as path from 'path';
6
+ import { findSourceFiles, readFileContent, resolveSourceDir } from '../utils/file-scanner.js';
7
+ import { parseFile, extractImports, extractHooks } from '../utils/ast-parser.js';
8
+ export async function analyzeStateManagement(appPath, config) {
9
+ const srcPath = resolveSourceDir(appPath);
10
+ const files = await findSourceFiles(srcPath);
11
+ let reduxUsage = 0;
12
+ let contextUsage = 0;
13
+ let localStateUsage = 0;
14
+ const patterns = {
15
+ normalizedState: false,
16
+ derivedState: false,
17
+ reselectUsed: false,
18
+ };
19
+ const issues = [];
20
+ const stateHeavyComponents = [];
21
+ let hasEntitiesPattern = false;
22
+ let hasIdsPattern = false;
23
+ let hasDerivedState = false;
24
+ let hasCreateSelector = false;
25
+ let totalLocalStateCalls = 0;
26
+ for (const file of files) {
27
+ const content = readFileContent(file);
28
+ if (!content)
29
+ continue;
30
+ const relPath = path.relative(appPath, file);
31
+ // AST-based analysis (best effort)
32
+ let astHooks = [];
33
+ let astImportSources = [];
34
+ const parsed = parseFile(file);
35
+ if (parsed) {
36
+ const imports = extractImports(parsed.ast);
37
+ astHooks = extractHooks(parsed.ast);
38
+ astImportSources = imports.map((i) => i.source);
39
+ }
40
+ // Redux detection
41
+ const hasRedux = astImportSources.some((s) => s.includes('redux') || s.includes('@reduxjs/toolkit') || s.includes('react-redux')) || content.includes('useSelector') || content.includes('useDispatch') || content.includes('createStore');
42
+ if (hasRedux)
43
+ reduxUsage++;
44
+ // Context API detection
45
+ const hasContext = content.includes('createContext') || content.includes('useContext') || content.includes('React.createContext');
46
+ if (hasContext)
47
+ contextUsage++;
48
+ // Local state detection — covers both imported useState and React.useState namespace style
49
+ const astStateHooks = astHooks.filter((h) => h.name === 'useState' || h.name === 'useReducer');
50
+ const regexStateCount = (content.match(/\buseState\s*\(/g) || []).length
51
+ + (content.match(/React\.useState\s*\(/g) || []).length
52
+ + (content.match(/\buseReducer\s*\(/g) || []).length
53
+ + (content.match(/React\.useReducer\s*\(/g) || []).length;
54
+ const localStateCount = Math.max(astStateHooks.length, regexStateCount);
55
+ if (localStateCount > 0) {
56
+ localStateUsage++;
57
+ totalLocalStateCalls += localStateCount;
58
+ // Flag components with excessive local state (potential god component)
59
+ if (localStateCount >= 3) {
60
+ stateHeavyComponents.push(`${relPath} (${localStateCount} state variables)`);
61
+ }
62
+ }
63
+ // Reselect detection
64
+ if (content.includes('createSelector') || astImportSources.some((s) => s.includes('reselect'))) {
65
+ hasCreateSelector = true;
66
+ }
67
+ // Normalized state detection
68
+ if (content.includes('entities') && (content.includes('ids') || content.includes('allIds'))) {
69
+ hasEntitiesPattern = true;
70
+ hasIdsPattern = true;
71
+ }
72
+ if (content.includes('byId') || content.includes('entitiesById')) {
73
+ hasEntitiesPattern = true;
74
+ }
75
+ // Derived state detection
76
+ const hasMemo = content.includes('useMemo') || content.includes('React.useMemo');
77
+ if (hasMemo && localStateCount > 0)
78
+ hasDerivedState = true;
79
+ if (content.includes('getDerived') || content.includes('selectDerived'))
80
+ hasDerivedState = true;
81
+ // Mixed Redux + excessive local state
82
+ if (hasRedux && localStateCount > 5) {
83
+ issues.push(`${relPath}: Mix of Redux and excessive local state (${localStateCount} useState calls). Consider consolidating.`);
84
+ }
85
+ // Large Redux slices
86
+ if (content.includes('createSlice') && content.split('\n').length > 200) {
87
+ issues.push(`${relPath}: Large Redux slice. Consider splitting into smaller slices.`);
88
+ }
89
+ }
90
+ patterns.normalizedState = hasEntitiesPattern && hasIdsPattern;
91
+ patterns.derivedState = hasDerivedState;
92
+ patterns.reselectUsed = hasCreateSelector;
93
+ let stateType;
94
+ const hasRedux = reduxUsage > 0;
95
+ const hasContext = contextUsage > 0;
96
+ const hasLocal = localStateUsage > 0;
97
+ if (hasRedux && (hasContext || hasLocal)) {
98
+ stateType = 'mixed';
99
+ }
100
+ else if (hasRedux) {
101
+ stateType = 'redux';
102
+ }
103
+ else if (hasContext) {
104
+ stateType = 'context';
105
+ }
106
+ else if (hasLocal) {
107
+ stateType = 'local';
108
+ }
109
+ else {
110
+ stateType = 'none';
111
+ }
112
+ if (stateType === 'mixed') {
113
+ issues.push('Mixed state management detected (Redux + Context/Local). Consider standardizing on one approach.');
114
+ }
115
+ if (hasRedux && !hasCreateSelector) {
116
+ issues.push('Redux used without Reselect. Consider using memoized selectors for performance.');
117
+ }
118
+ if (contextUsage > 5) {
119
+ issues.push(`High Context API usage (${contextUsage} files). Consider if some contexts should be Redux stores or Zustand.`);
120
+ }
121
+ if (stateType === 'local' && totalLocalStateCalls > 5) {
122
+ issues.push(`All state is local useState (${totalLocalStateCalls} calls across ${localStateUsage} files). Consider extracting to Context or Zustand for complex shared state.`);
123
+ }
124
+ if (stateHeavyComponents.length > 0) {
125
+ issues.push(`Components with many state variables (potential god components): ${stateHeavyComponents.join(', ')}`);
126
+ }
127
+ return {
128
+ stateType,
129
+ patterns,
130
+ issues,
131
+ };
132
+ }
133
+ //# sourceMappingURL=04-analyze-state-management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"04-analyze-state-management.js","sourceRoot":"","sources":["../../src/tools/04-analyze-state-management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AnalyzeApiOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function analyzeApiLayer(appPath: string, config?: Partial<AnalyzerConfig>): Promise<AnalyzeApiOutput>;
3
+ //# sourceMappingURL=05-analyze-api-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"05-analyze-api-layer.d.ts","sourceRoot":"","sources":["../../src/tools/05-analyze-api-layer.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKpE,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2JlH"}
@@ -0,0 +1,160 @@
1
+ // ============================================================================
2
+ // TOOL #5: analyze-api-layer
3
+ // Detects API patterns: axios/fetch/superagent usage, Next.js API routes,
4
+ // centralized vs scattered pattern, and duplicate endpoints
5
+ // ============================================================================
6
+ import * as path from 'path';
7
+ import { findSourceFiles, readFileContent, resolveSourceDir } from '../utils/file-scanner.js';
8
+ import { parseFile, extractImports } from '../utils/ast-parser.js';
9
+ const API_CLIENTS = ['axios', 'node-fetch', 'got', 'superagent', 'ky', 'undici'];
10
+ const API_INDICATORS = ['fetch(', 'axios.', 'api.', '/api/', 'useSWR', 'useQuery', 'useMutation'];
11
+ export async function analyzeApiLayer(appPath, config) {
12
+ const srcPath = resolveSourceDir(appPath);
13
+ const files = await findSourceFiles(srcPath);
14
+ const clients = new Set();
15
+ const issues = [];
16
+ const apiEndpoints = new Map(); // endpoint -> files
17
+ let centralizedFiles = 0;
18
+ let scatteredFiles = 0;
19
+ const duplicateEndpoints = [];
20
+ // Files that look like API service files
21
+ // Next.js API routes are inherently centralized (pages/api/ or app/api/)
22
+ const isNextJsApiRoute = (f) => {
23
+ const rel = f.replace(appPath, '');
24
+ return rel.includes('/pages/api/') || rel.includes('/app/api/');
25
+ };
26
+ const apiServiceFiles = files.filter((f) => {
27
+ if (isNextJsApiRoute(f))
28
+ return true;
29
+ const lower = f.toLowerCase();
30
+ const base = path.basename(lower, path.extname(lower));
31
+ const API_SERVICE_NAMES = ['agent', 'api', 'http', 'client', 'request', 'fetcher', 'axios', 'service'];
32
+ return lower.includes('/api/') || lower.includes('/service') || lower.includes('/services/') ||
33
+ lower.includes('client.') || lower.includes('/api-client') || API_SERVICE_NAMES.includes(base);
34
+ });
35
+ for (const file of files) {
36
+ const content = readFileContent(file);
37
+ if (!content)
38
+ continue;
39
+ const relPath = path.relative(appPath, file);
40
+ const isApiService = apiServiceFiles.includes(file);
41
+ // Content-based detection (works for both JS and TS files)
42
+ const hasFetch = content.includes('fetch(');
43
+ const hasAxios = content.includes('axios.get(') || content.includes('axios.post(') || content.includes('axios(');
44
+ const hasSuperagent = content.includes('superagent.') || content.includes('superagent-promise');
45
+ const hasGot = content.includes('got.get(') || content.includes('got.post(') || content.includes("from 'got'") || content.includes('from "got"');
46
+ const hasKy = content.includes('ky.get(') || content.includes('ky.post(') || content.includes("from 'ky'") || content.includes('from "ky"');
47
+ // Register clients detected by content
48
+ if (hasFetch && !content.includes('axios') && !hasSuperagent)
49
+ clients.add('fetch');
50
+ if (hasAxios)
51
+ clients.add('axios');
52
+ if (hasSuperagent)
53
+ clients.add('superagent');
54
+ if (hasGot)
55
+ clients.add('got');
56
+ if (hasKy)
57
+ clients.add('ky');
58
+ const hasApiIndicator = API_INDICATORS.some((indicator) => content.includes(indicator));
59
+ const hasApiCall = hasApiIndicator || hasFetch || hasAxios || hasSuperagent || hasGot || hasKy;
60
+ if (hasApiCall) {
61
+ if (isApiService)
62
+ centralizedFiles++;
63
+ else
64
+ scatteredFiles++;
65
+ }
66
+ // Extract API endpoints (skip CDN, schema, and asset URLs)
67
+ const EXCLUDED_URL_PATTERNS = ['w3.org', 'schemas.', 'xmlns', 'cdn.', 'fonts.', 'cdnjs.', 'unpkg.', 'jsdelivr.', 'cloudflare.com/ajax', 'localhost', '127.0.0.1', '0.0.0.0'];
68
+ const endpointRegex = /['"`](\/api\/[^'"`\s]+|https?:\/\/[^'"`\s]+)['"`]/g;
69
+ let endpointMatch;
70
+ while ((endpointMatch = endpointRegex.exec(content)) !== null) {
71
+ const endpoint = endpointMatch[1];
72
+ if (EXCLUDED_URL_PATTERNS.some((pat) => endpoint.includes(pat)))
73
+ continue;
74
+ if (!apiEndpoints.has(endpoint))
75
+ apiEndpoints.set(endpoint, []);
76
+ apiEndpoints.get(endpoint).push(relPath);
77
+ }
78
+ // Detect fetch without response handling (fire-and-forget)
79
+ if (hasFetch) {
80
+ const fetchMatches = [...content.matchAll(/fetch\s*\([^)]+\)/g)];
81
+ for (const m of fetchMatches) {
82
+ const idx = m.index ?? 0;
83
+ const after = content.slice(idx, idx + 200);
84
+ if (!after.includes('.then(') && !after.includes('await') && !after.includes('.json(')) {
85
+ issues.push(`${relPath}: fetch() result not handled — response never read or awaited.`);
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ // Detect missing Content-Type on mutating requests
91
+ if (hasFetch && (content.includes("method: 'POST'") || content.includes('method: "POST"') ||
92
+ content.includes("method: 'PUT'") || content.includes("method: 'PATCH'"))) {
93
+ if (!content.includes('Content-Type') && !content.includes('content-type')) {
94
+ issues.push(`${relPath}: POST/PUT fetch call missing Content-Type header.`);
95
+ }
96
+ }
97
+ // AST-based: detect library imports (best effort, skip if AST fails for .js)
98
+ const parsed = parseFile(file);
99
+ if (parsed) {
100
+ const imports = extractImports(parsed.ast);
101
+ const importSources = imports.map((i) => i.source);
102
+ for (const client of API_CLIENTS) {
103
+ if (importSources.some((s) => s.includes(client)))
104
+ clients.add(client);
105
+ }
106
+ }
107
+ }
108
+ // Find duplicate endpoints
109
+ for (const [endpoint, filesUsingIt] of apiEndpoints) {
110
+ if (filesUsingIt.length > 1) {
111
+ duplicateEndpoints.push(`${endpoint} (used in ${filesUsingIt.length} files)`);
112
+ }
113
+ }
114
+ // Determine pattern
115
+ let apiPattern;
116
+ if (centralizedFiles === 0 && scatteredFiles === 0) {
117
+ apiPattern = 'none';
118
+ }
119
+ else if (centralizedFiles > 0 && scatteredFiles === 0) {
120
+ apiPattern = 'centralized';
121
+ }
122
+ else if (scatteredFiles > centralizedFiles) {
123
+ apiPattern = 'scattered';
124
+ }
125
+ else {
126
+ apiPattern = 'mixed';
127
+ }
128
+ // Issues
129
+ if (apiPattern === 'scattered') {
130
+ issues.push('API calls scattered across components. Consider creating a centralized API service layer.');
131
+ }
132
+ if (apiPattern === 'mixed') {
133
+ issues.push('Mixed API patterns. Some calls centralized, some scattered. Standardize for consistency.');
134
+ }
135
+ if (duplicateEndpoints.length > 0) {
136
+ issues.push(`Duplicate API endpoints detected: ${duplicateEndpoints.join(', ')}`);
137
+ }
138
+ if (clients.size > 1) {
139
+ issues.push(`Multiple HTTP clients detected (${Array.from(clients).join(', ')}). Consider using one consistently.`);
140
+ }
141
+ if (clients.size === 0 && apiPattern !== 'none') {
142
+ issues.push('API calls detected but no recognized HTTP client found. May be using a custom wrapper.');
143
+ }
144
+ // Check for missing error handling
145
+ for (const file of files) {
146
+ const content = readFileContent(file);
147
+ if (!content)
148
+ continue;
149
+ if ((content.includes('fetch(') || content.includes('axios.')) && !content.includes('.catch') && !content.includes('try {')) {
150
+ issues.push(`${path.relative(appPath, file)}: API calls without error handling.`);
151
+ }
152
+ }
153
+ return {
154
+ apiPattern,
155
+ clients: Array.from(clients),
156
+ duplicateEndpoints,
157
+ issues,
158
+ };
159
+ }
160
+ //# sourceMappingURL=05-analyze-api-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"05-analyze-api-layer.js","sourceRoot":"","sources":["../../src/tools/05-analyze-api-layer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AnalyzeRoutingOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function analyzeRouting(appPath: string, config?: Partial<AnalyzerConfig>): Promise<AnalyzeRoutingOutput>;
3
+ //# sourceMappingURL=06-analyze-routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"06-analyze-routing.d.ts","sourceRoot":"","sources":["../../src/tools/06-analyze-routing.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIxE,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA+JrH"}
@@ -0,0 +1,150 @@
1
+ // ============================================================================
2
+ // TOOL #6: analyze-routing
3
+ // Detects routing: react-router, Next.js file-based (pages/ and app/), Remix, Gatsby
4
+ // ============================================================================
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import { findSourceFiles, readFileContent } from '../utils/file-scanner.js';
8
+ import { parseFile, extractImports, extractJSX } from '../utils/ast-parser.js';
9
+ const ROUTING_LIBRARIES = ['react-router-dom', 'react-router', '@reach/router', 'wouter', 'preact-router', '@remix-run/react'];
10
+ export async function analyzeRouting(appPath, config) {
11
+ // Detect Next.js / Remix file-based routing before doing source file scan
12
+ const nextPagesDir = path.join(appPath, 'pages');
13
+ const nextAppDir = path.join(appPath, 'app');
14
+ const srcPagesDir = path.join(appPath, 'src', 'pages');
15
+ const srcAppDir = path.join(appPath, 'src', 'app');
16
+ const hasNextPages = fs.existsSync(nextPagesDir) || fs.existsSync(srcPagesDir);
17
+ const hasNextApp = fs.existsSync(nextAppDir) || fs.existsSync(srcAppDir);
18
+ if (hasNextPages || hasNextApp) {
19
+ const routerType = hasNextApp ? 'app-router' : 'pages-router';
20
+ const lib = hasNextApp ? 'next/navigation' : 'next/router';
21
+ const routeDir = hasNextApp
22
+ ? (fs.existsSync(nextAppDir) ? nextAppDir : srcAppDir)
23
+ : (fs.existsSync(nextPagesDir) ? nextPagesDir : srcPagesDir);
24
+ // Count page files (each file = one route in Next.js)
25
+ let routeCount = 0;
26
+ const countPages = (dir) => {
27
+ if (!fs.existsSync(dir))
28
+ return;
29
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
30
+ if (entry.isDirectory())
31
+ countPages(path.join(dir, entry.name));
32
+ else if (entry.name.match(/\.(tsx|ts|jsx|js)$/) && !entry.name.startsWith('_') && !entry.name.includes('.test.') && entry.name !== 'layout.tsx' && entry.name !== 'loading.tsx') {
33
+ routeCount++;
34
+ }
35
+ }
36
+ };
37
+ countPages(routeDir);
38
+ const issues = [];
39
+ if (routeCount > 20) {
40
+ issues.push(`${routeCount} route files. Consider using Next.js Route Groups to organize routes.`);
41
+ }
42
+ return {
43
+ routingLibrary: lib,
44
+ routingType: 'nested',
45
+ lazyLoading: true, // Next.js does automatic code splitting per page
46
+ routeCount,
47
+ issues,
48
+ };
49
+ }
50
+ const srcPath = path.join(appPath, 'src');
51
+ const files = await findSourceFiles(srcPath);
52
+ let routingLibrary = null;
53
+ let routeCount = 0;
54
+ let hasNestedRoutes = false;
55
+ let hasLazyLoading = false;
56
+ const issues = [];
57
+ const routeFiles = [];
58
+ for (const file of files) {
59
+ const content = readFileContent(file);
60
+ if (!content)
61
+ continue;
62
+ // Content-based routing library detection (works for .js files too)
63
+ for (const lib of ROUTING_LIBRARIES) {
64
+ if (content.includes(`from '${lib}'`) || content.includes(`from "${lib}"`) ||
65
+ content.includes(`require('${lib}')`) || content.includes(`require("${lib}")`)) {
66
+ routingLibrary = lib;
67
+ routeFiles.push(path.relative(appPath, file));
68
+ break;
69
+ }
70
+ }
71
+ // Content-based route counting via regex (reliable for both JS and TS)
72
+ const routeTagMatches = content.match(/<Route[\s/]/g) || [];
73
+ routeCount += routeTagMatches.length;
74
+ // Detect nested routes via content
75
+ if (content.includes('<Route') || content.includes('<route')) {
76
+ // Nested: Route inside Switch inside another Route, or Routes v6 pattern
77
+ if (content.includes('<Routes>') || (content.match(/<Route[\s\S]*?<Route/m))) {
78
+ hasNestedRoutes = true;
79
+ }
80
+ }
81
+ // Detect lazy loading
82
+ if (content.includes('React.lazy') || content.includes('lazy(') || content.includes('Suspense')) {
83
+ hasLazyLoading = true;
84
+ }
85
+ // Detect dynamic imports for routes
86
+ if (content.includes('import(') && (content.includes('Route') || content.includes('route'))) {
87
+ hasLazyLoading = true;
88
+ }
89
+ // Also try AST-based extraction for richer data (optional)
90
+ const parsed = parseFile(file);
91
+ if (parsed) {
92
+ const imports = extractImports(parsed.ast);
93
+ const importSources = imports.map((i) => i.source);
94
+ for (const lib of ROUTING_LIBRARIES) {
95
+ if (importSources.some((s) => s.includes(lib))) {
96
+ routingLibrary = lib;
97
+ }
98
+ }
99
+ // AST-based nested route detection via depth
100
+ const jsxElements = extractJSX(parsed.ast);
101
+ const routeAtDepth = jsxElements.filter((e) => (e.tagName === 'Route' || e.tagName === 'route') && e.depth > 2);
102
+ if (routeAtDepth.length > 0) {
103
+ hasNestedRoutes = true;
104
+ }
105
+ }
106
+ }
107
+ // Determine routing type
108
+ let routingType;
109
+ if (!routingLibrary || routeCount === 0) {
110
+ routingType = 'none';
111
+ }
112
+ else if (hasNestedRoutes) {
113
+ routingType = 'nested';
114
+ }
115
+ else {
116
+ routingType = 'flat';
117
+ }
118
+ // Issues
119
+ if (!routingLibrary && files.length > 5) {
120
+ issues.push('No routing library detected. App may be using custom routing or is a single-page view.');
121
+ }
122
+ if (routingLibrary && !hasLazyLoading && routeCount > 10) {
123
+ issues.push(`${routeCount} routes without lazy loading. Consider using React.lazy() for code splitting.`);
124
+ }
125
+ if (routingType === 'flat' && routeCount > 15) {
126
+ issues.push('Many flat routes detected. Consider organizing routes into nested groups.');
127
+ }
128
+ // Check for hardcoded route strings in components
129
+ let hardcodedRoutes = 0;
130
+ for (const file of files) {
131
+ const content = readFileContent(file);
132
+ if (!content)
133
+ continue;
134
+ // Look for navigate() calls or href patterns
135
+ const navMatches = content.match(/navigate\s*\(\s*['"`]\/[^'"`]*['"`]\)/g) || [];
136
+ const hrefMatches = content.match(/href\s*=\s*['"`]\/[^'"`]*['"`]/g) || [];
137
+ hardcodedRoutes += navMatches.length + hrefMatches.length;
138
+ }
139
+ if (hardcodedRoutes > 5) {
140
+ issues.push(`${hardcodedRoutes} hardcoded route strings found. Consider using route constants.`);
141
+ }
142
+ return {
143
+ routingLibrary,
144
+ routingType,
145
+ lazyLoading: hasLazyLoading,
146
+ routeCount,
147
+ issues,
148
+ };
149
+ }
150
+ //# sourceMappingURL=06-analyze-routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"06-analyze-routing.js","sourceRoot":"","sources":["../../src/tools/06-analyze-routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AnalyzeStylingOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function analyzeStyling(appPath: string, config?: Partial<AnalyzerConfig>): Promise<AnalyzeStylingOutput>;
3
+ //# sourceMappingURL=07-analyze-styling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"07-analyze-styling.d.ts","sourceRoot":"","sources":["../../src/tools/07-analyze-styling.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAiBxE,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAqHrH"}