mcp-react-toolkit 1.0.0 → 1.2.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 (235) hide show
  1. package/README.md +146 -42
  2. package/package.json +13 -5
  3. package/server.json +20 -0
  4. package/tools/accessibility-checker/build/index.js +9 -5
  5. package/tools/accessibility-checker/build/index.js.map +1 -1
  6. package/tools/accessibility-checker/build/rules.d.ts.map +1 -1
  7. package/tools/accessibility-checker/build/rules.js +325 -94
  8. package/tools/accessibility-checker/build/rules.js.map +1 -1
  9. package/tools/code-modernizer/build/tools/01-convert-to-typescript.d.ts.map +1 -1
  10. package/tools/code-modernizer/build/tools/01-convert-to-typescript.js +65 -50
  11. package/tools/code-modernizer/build/tools/01-convert-to-typescript.js.map +1 -1
  12. package/tools/code-modernizer/build/types.d.ts +1 -0
  13. package/tools/code-modernizer/build/types.d.ts.map +1 -1
  14. package/tools/code-modernizer/build/utils/ast-parser.d.ts.map +1 -1
  15. package/tools/code-modernizer/build/utils/ast-parser.js +30 -14
  16. package/tools/code-modernizer/build/utils/ast-parser.js.map +1 -1
  17. package/tools/code-modernizer/build/utils/type-generator.d.ts +1 -1
  18. package/tools/code-modernizer/build/utils/type-generator.d.ts.map +1 -1
  19. package/tools/code-modernizer/build/utils/type-generator.js +72 -23
  20. package/tools/code-modernizer/build/utils/type-generator.js.map +1 -1
  21. package/tools/component-factory/build/index.js +59 -7
  22. package/tools/component-factory/build/index.js.map +1 -1
  23. package/tools/component-fixer/README.md +44 -0
  24. package/tools/component-fixer/build/index.d.ts +3 -0
  25. package/tools/component-fixer/build/index.d.ts.map +1 -0
  26. package/tools/component-fixer/build/index.js +647 -0
  27. package/tools/component-fixer/build/index.js.map +1 -0
  28. package/tools/component-fixer/build/index.test.d.ts +2 -0
  29. package/tools/component-fixer/build/index.test.d.ts.map +1 -0
  30. package/tools/component-fixer/build/index.test.js.map +1 -0
  31. package/tools/component-fixer/package.json +20 -0
  32. package/tools/component-reviewer/README.md +54 -0
  33. package/tools/component-reviewer/build/index.d.ts +39 -0
  34. package/tools/component-reviewer/build/index.d.ts.map +1 -0
  35. package/tools/component-reviewer/build/index.js +946 -0
  36. package/tools/component-reviewer/build/index.js.map +1 -0
  37. package/tools/component-reviewer/build/index.test.d.ts +2 -0
  38. package/tools/component-reviewer/build/index.test.d.ts.map +1 -0
  39. package/tools/component-reviewer/build/index.test.js.map +1 -0
  40. package/tools/component-reviewer/package.json +20 -0
  41. package/tools/dep-auditor/build/index.d.ts +1 -0
  42. package/tools/dep-auditor/build/index.d.ts.map +1 -1
  43. package/tools/dep-auditor/build/index.js +71 -16
  44. package/tools/dep-auditor/build/index.js.map +1 -1
  45. package/tools/generate-tests/build/analyzer.d.ts +14 -0
  46. package/tools/generate-tests/build/analyzer.d.ts.map +1 -1
  47. package/tools/generate-tests/build/analyzer.js +96 -42
  48. package/tools/generate-tests/build/analyzer.js.map +1 -1
  49. package/tools/generate-tests/build/generators.d.ts.map +1 -1
  50. package/tools/generate-tests/build/generators.js +304 -79
  51. package/tools/generate-tests/build/generators.js.map +1 -1
  52. package/tools/generate-tests/build/index.js +29 -10
  53. package/tools/generate-tests/build/index.js.map +1 -1
  54. package/tools/json-viewer/build/index.js +29 -6
  55. package/tools/json-viewer/build/index.js.map +1 -1
  56. package/tools/legacy-analyzer/README.md +66 -0
  57. package/tools/legacy-analyzer/build/index.d.ts +3 -0
  58. package/tools/legacy-analyzer/build/index.d.ts.map +1 -0
  59. package/tools/legacy-analyzer/build/index.js +209 -0
  60. package/tools/legacy-analyzer/build/index.js.map +1 -0
  61. package/tools/legacy-analyzer/build/index.test.d.ts +2 -0
  62. package/tools/legacy-analyzer/build/index.test.d.ts.map +1 -0
  63. package/tools/legacy-analyzer/build/index.test.js.map +1 -0
  64. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.d.ts +3 -0
  65. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.d.ts.map +1 -0
  66. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.js +115 -0
  67. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.js.map +1 -0
  68. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.d.ts +3 -0
  69. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.d.ts.map +1 -0
  70. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.js +85 -0
  71. package/tools/legacy-analyzer/build/tools/02-analyze-folder-structure.js.map +1 -0
  72. package/tools/legacy-analyzer/build/tools/03-analyze-components.d.ts +3 -0
  73. package/tools/legacy-analyzer/build/tools/03-analyze-components.d.ts.map +1 -0
  74. package/tools/legacy-analyzer/build/tools/03-analyze-components.js +87 -0
  75. package/tools/legacy-analyzer/build/tools/03-analyze-components.js.map +1 -0
  76. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.d.ts +3 -0
  77. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.d.ts.map +1 -0
  78. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.js +133 -0
  79. package/tools/legacy-analyzer/build/tools/04-analyze-state-management.js.map +1 -0
  80. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.d.ts +3 -0
  81. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.d.ts.map +1 -0
  82. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.js +160 -0
  83. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.js.map +1 -0
  84. package/tools/legacy-analyzer/build/tools/06-analyze-routing.d.ts +3 -0
  85. package/tools/legacy-analyzer/build/tools/06-analyze-routing.d.ts.map +1 -0
  86. package/tools/legacy-analyzer/build/tools/06-analyze-routing.js +150 -0
  87. package/tools/legacy-analyzer/build/tools/06-analyze-routing.js.map +1 -0
  88. package/tools/legacy-analyzer/build/tools/07-analyze-styling.d.ts +3 -0
  89. package/tools/legacy-analyzer/build/tools/07-analyze-styling.d.ts.map +1 -0
  90. package/tools/legacy-analyzer/build/tools/07-analyze-styling.js +131 -0
  91. package/tools/legacy-analyzer/build/tools/07-analyze-styling.js.map +1 -0
  92. package/tools/legacy-analyzer/build/tools/08-analyze-assets.d.ts +3 -0
  93. package/tools/legacy-analyzer/build/tools/08-analyze-assets.d.ts.map +1 -0
  94. package/tools/legacy-analyzer/build/tools/08-analyze-assets.js +85 -0
  95. package/tools/legacy-analyzer/build/tools/08-analyze-assets.js.map +1 -0
  96. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.d.ts +3 -0
  97. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.d.ts.map +1 -0
  98. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.js +329 -0
  99. package/tools/legacy-analyzer/build/tools/09-detect-anti-patterns.js.map +1 -0
  100. package/tools/legacy-analyzer/build/tools/10-detect-duplication.d.ts +3 -0
  101. package/tools/legacy-analyzer/build/tools/10-detect-duplication.d.ts.map +1 -0
  102. package/tools/legacy-analyzer/build/tools/10-detect-duplication.js +192 -0
  103. package/tools/legacy-analyzer/build/tools/10-detect-duplication.js.map +1 -0
  104. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.d.ts +3 -0
  105. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.d.ts.map +1 -0
  106. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.js +232 -0
  107. package/tools/legacy-analyzer/build/tools/11-analyze-dependencies-usage.js.map +1 -0
  108. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.d.ts +3 -0
  109. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.d.ts.map +1 -0
  110. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.js +247 -0
  111. package/tools/legacy-analyzer/build/tools/12-analyze-legacy-app.js.map +1 -0
  112. package/tools/legacy-analyzer/build/tools/13-detect-features.d.ts +3 -0
  113. package/tools/legacy-analyzer/build/tools/13-detect-features.d.ts.map +1 -0
  114. package/tools/legacy-analyzer/build/tools/13-detect-features.js +141 -0
  115. package/tools/legacy-analyzer/build/tools/13-detect-features.js.map +1 -0
  116. package/tools/legacy-analyzer/build/tools/14-classify-files.d.ts +3 -0
  117. package/tools/legacy-analyzer/build/tools/14-classify-files.d.ts.map +1 -0
  118. package/tools/legacy-analyzer/build/tools/14-classify-files.js +76 -0
  119. package/tools/legacy-analyzer/build/tools/14-classify-files.js.map +1 -0
  120. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.d.ts +3 -0
  121. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.d.ts.map +1 -0
  122. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.js +70 -0
  123. package/tools/legacy-analyzer/build/tools/15-detect-shared-modules.js.map +1 -0
  124. package/tools/legacy-analyzer/build/tools/16-design-target-structure.d.ts +3 -0
  125. package/tools/legacy-analyzer/build/tools/16-design-target-structure.d.ts.map +1 -0
  126. package/tools/legacy-analyzer/build/tools/16-design-target-structure.js +26 -0
  127. package/tools/legacy-analyzer/build/tools/16-design-target-structure.js.map +1 -0
  128. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.d.ts +3 -0
  129. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.d.ts.map +1 -0
  130. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.js +108 -0
  131. package/tools/legacy-analyzer/build/tools/17-map-files-to-target.js.map +1 -0
  132. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.d.ts +3 -0
  133. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.d.ts.map +1 -0
  134. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.js +137 -0
  135. package/tools/legacy-analyzer/build/tools/18-detect-boundary-violations.js.map +1 -0
  136. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.d.ts +3 -0
  137. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.d.ts.map +1 -0
  138. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.js +160 -0
  139. package/tools/legacy-analyzer/build/tools/19-suggest-module-splitting.js.map +1 -0
  140. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.d.ts +3 -0
  141. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.d.ts.map +1 -0
  142. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.js +162 -0
  143. package/tools/legacy-analyzer/build/tools/20-naming-standardizer.js.map +1 -0
  144. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.d.ts +3 -0
  145. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.d.ts.map +1 -0
  146. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.js +108 -0
  147. package/tools/legacy-analyzer/build/tools/21-generate-refactor-plan.js.map +1 -0
  148. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.d.ts +3 -0
  149. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.d.ts.map +1 -0
  150. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.js +98 -0
  151. package/tools/legacy-analyzer/build/tools/22-refactor-folder-structure.js.map +1 -0
  152. package/tools/legacy-analyzer/build/types.d.ts +413 -0
  153. package/tools/legacy-analyzer/build/types.d.ts.map +1 -0
  154. package/tools/legacy-analyzer/build/types.js +12 -0
  155. package/tools/legacy-analyzer/build/types.js.map +1 -0
  156. package/tools/legacy-analyzer/build/utils/ast-parser.d.ts +34 -0
  157. package/tools/legacy-analyzer/build/utils/ast-parser.d.ts.map +1 -0
  158. package/tools/legacy-analyzer/build/utils/ast-parser.js +394 -0
  159. package/tools/legacy-analyzer/build/utils/ast-parser.js.map +1 -0
  160. package/tools/legacy-analyzer/build/utils/file-scanner.d.ts +51 -0
  161. package/tools/legacy-analyzer/build/utils/file-scanner.d.ts.map +1 -0
  162. package/tools/legacy-analyzer/build/utils/file-scanner.js +174 -0
  163. package/tools/legacy-analyzer/build/utils/file-scanner.js.map +1 -0
  164. package/tools/legacy-analyzer/build/utils/import-tracker.d.ts +38 -0
  165. package/tools/legacy-analyzer/build/utils/import-tracker.d.ts.map +1 -0
  166. package/tools/legacy-analyzer/build/utils/import-tracker.js +194 -0
  167. package/tools/legacy-analyzer/build/utils/import-tracker.js.map +1 -0
  168. package/tools/legacy-analyzer/build/utils/refactor-helpers.d.ts +88 -0
  169. package/tools/legacy-analyzer/build/utils/refactor-helpers.d.ts.map +1 -0
  170. package/tools/legacy-analyzer/build/utils/refactor-helpers.js +538 -0
  171. package/tools/legacy-analyzer/build/utils/refactor-helpers.js.map +1 -0
  172. package/tools/legacy-analyzer/package.json +20 -0
  173. package/tools/lighthouse-runner/README.md +45 -0
  174. package/tools/lighthouse-runner/build/index.d.ts +6 -0
  175. package/tools/lighthouse-runner/build/index.d.ts.map +1 -0
  176. package/tools/lighthouse-runner/build/index.js +295 -0
  177. package/tools/lighthouse-runner/build/index.js.map +1 -0
  178. package/tools/lighthouse-runner/build/index.test.d.ts +2 -0
  179. package/tools/lighthouse-runner/build/index.test.d.ts.map +1 -0
  180. package/tools/lighthouse-runner/build/index.test.js.map +1 -0
  181. package/tools/lighthouse-runner/package.json +20 -0
  182. package/tools/monorepo-manager/build/utils.d.ts.map +1 -1
  183. package/tools/monorepo-manager/build/utils.js +12 -9
  184. package/tools/monorepo-manager/build/utils.js.map +1 -1
  185. package/tools/performance-audit/README.md +37 -0
  186. package/tools/performance-audit/build/index.d.ts +13 -0
  187. package/tools/performance-audit/build/index.d.ts.map +1 -0
  188. package/tools/performance-audit/build/index.js +311 -0
  189. package/tools/performance-audit/build/index.js.map +1 -0
  190. package/tools/performance-audit/build/index.test.d.ts +2 -0
  191. package/tools/performance-audit/build/index.test.d.ts.map +1 -0
  192. package/tools/performance-audit/build/index.test.js.map +1 -0
  193. package/tools/performance-audit/package.json +20 -0
  194. package/tools/quality-pipeline/build/index.js +55 -15
  195. package/tools/quality-pipeline/build/index.js.map +1 -1
  196. package/tools/render-analyzer/README.md +43 -0
  197. package/tools/render-analyzer/build/index.d.ts +25 -0
  198. package/tools/render-analyzer/build/index.d.ts.map +1 -0
  199. package/tools/render-analyzer/build/index.js +342 -0
  200. package/tools/render-analyzer/build/index.js.map +1 -0
  201. package/tools/render-analyzer/build/index.test.d.ts +2 -0
  202. package/tools/render-analyzer/build/index.test.d.ts.map +1 -0
  203. package/tools/render-analyzer/build/index.test.js.map +1 -0
  204. package/tools/render-analyzer/package.json +20 -0
  205. package/tools/shared/build/fs.d.ts +8 -0
  206. package/tools/shared/build/fs.d.ts.map +1 -0
  207. package/tools/shared/build/fs.js +45 -0
  208. package/tools/shared/build/fs.js.map +1 -0
  209. package/tools/shared/build/index.d.ts +1 -0
  210. package/tools/shared/build/index.d.ts.map +1 -1
  211. package/tools/shared/build/index.js +1 -0
  212. package/tools/shared/build/index.js.map +1 -1
  213. package/tools/storybook-generator/README.md +39 -0
  214. package/tools/storybook-generator/build/index.d.ts +13 -0
  215. package/tools/storybook-generator/build/index.d.ts.map +1 -0
  216. package/tools/storybook-generator/build/index.js +478 -0
  217. package/tools/storybook-generator/build/index.js.map +1 -0
  218. package/tools/storybook-generator/build/index.test.d.ts +2 -0
  219. package/tools/storybook-generator/build/index.test.d.ts.map +1 -0
  220. package/tools/storybook-generator/build/index.test.js.map +1 -0
  221. package/tools/storybook-generator/package.json +20 -0
  222. package/tools/test-gap-analyzer/README.md +41 -0
  223. package/tools/test-gap-analyzer/build/index.d.ts +20 -0
  224. package/tools/test-gap-analyzer/build/index.d.ts.map +1 -0
  225. package/tools/test-gap-analyzer/build/index.js +371 -0
  226. package/tools/test-gap-analyzer/build/index.js.map +1 -0
  227. package/tools/test-gap-analyzer/build/index.test.d.ts +2 -0
  228. package/tools/test-gap-analyzer/build/index.test.d.ts.map +1 -0
  229. package/tools/test-gap-analyzer/build/index.test.js.map +1 -0
  230. package/tools/test-gap-analyzer/package.json +20 -0
  231. package/tools/typescript-enforcer/build/scanner.d.ts.map +1 -1
  232. package/tools/typescript-enforcer/build/scanner.js +13 -1
  233. package/tools/typescript-enforcer/build/scanner.js.map +1 -1
  234. package/tools/typescript-enforcer/build/types.d.ts +1 -0
  235. package/tools/typescript-enforcer/build/types.d.ts.map +1 -1
@@ -0,0 +1,141 @@
1
+ // ============================================================================
2
+ // TOOL #13: detect-features
3
+ // Identifies logical features/domains in the app using file names, routing,
4
+ // folder grouping, and import clustering
5
+ // ============================================================================
6
+ import * as path from 'path';
7
+ import { findSourceFiles, resolveSourceDir } from '../utils/file-scanner.js';
8
+ import { buildImportGraph, resolveImportPath } from '../utils/import-tracker.js';
9
+ import { detectFeatureFromPath, detectFeatureFromRoute, extractRoutePaths, } from '../utils/refactor-helpers.js';
10
+ export async function detectFeatures(appPath, config) {
11
+ const srcPath = resolveSourceDir(appPath);
12
+ const files = await findSourceFiles(srcPath);
13
+ if (files.length === 0) {
14
+ return { features: [], featureMap: {} };
15
+ }
16
+ // Phase 1: Detect features from file paths
17
+ const pathFeatures = new Map();
18
+ for (const file of files) {
19
+ const feature = detectFeatureFromPath(file, srcPath);
20
+ if (feature) {
21
+ if (!pathFeatures.has(feature)) {
22
+ pathFeatures.set(feature, new Set());
23
+ }
24
+ pathFeatures.get(feature).add(path.relative(srcPath, file));
25
+ }
26
+ }
27
+ // Phase 2: Detect features from routing
28
+ const routes = await extractRoutePaths(appPath);
29
+ const routeFeatures = new Map();
30
+ for (const route of routes) {
31
+ const feature = detectFeatureFromRoute(route.path);
32
+ if (feature) {
33
+ if (!routeFeatures.has(feature)) {
34
+ routeFeatures.set(feature, []);
35
+ }
36
+ routeFeatures.get(feature).push(route.component);
37
+ }
38
+ }
39
+ // Phase 3: Detect features from import clustering
40
+ const graph = await buildImportGraph(srcPath);
41
+ const importFeatures = new Map();
42
+ const visited = new Set();
43
+ for (const file of files) {
44
+ if (visited.has(file))
45
+ continue;
46
+ const feature = detectFeatureFromPath(file, srcPath);
47
+ if (!feature)
48
+ continue;
49
+ if (!importFeatures.has(feature)) {
50
+ importFeatures.set(feature, new Set());
51
+ }
52
+ importFeatures.get(feature).add(path.relative(srcPath, file));
53
+ visited.add(file);
54
+ // Follow imports to cluster related files
55
+ const imports = graph[file]?.imports || [];
56
+ for (const imp of imports) {
57
+ const resolved = resolveImportPath(file, imp.source, srcPath, files);
58
+ if (resolved && !visited.has(resolved)) {
59
+ const basename = path.basename(resolved, path.extname(resolved));
60
+ // Only cluster components and pages, not utils
61
+ if (/^[A-Z]/.test(basename) || basename.toLowerCase().includes('page')) {
62
+ importFeatures.get(feature).add(path.relative(srcPath, resolved));
63
+ visited.add(resolved);
64
+ }
65
+ }
66
+ }
67
+ }
68
+ // Merge all feature detection sources
69
+ const allFeatures = new Set();
70
+ const featureMap = {};
71
+ // Merge path-based features
72
+ for (const [feature, files] of pathFeatures) {
73
+ allFeatures.add(feature);
74
+ if (!featureMap[feature])
75
+ featureMap[feature] = [];
76
+ for (const f of files) {
77
+ if (!featureMap[feature].includes(f)) {
78
+ featureMap[feature].push(f);
79
+ }
80
+ }
81
+ }
82
+ // Merge route-based features
83
+ for (const [feature] of routeFeatures) {
84
+ allFeatures.add(feature);
85
+ if (!featureMap[feature])
86
+ featureMap[feature] = [];
87
+ }
88
+ // Merge import-clustered features
89
+ for (const [feature, files] of importFeatures) {
90
+ allFeatures.add(feature);
91
+ if (!featureMap[feature])
92
+ featureMap[feature] = [];
93
+ for (const f of files) {
94
+ if (!featureMap[feature].includes(f)) {
95
+ featureMap[feature].push(f);
96
+ }
97
+ }
98
+ }
99
+ // Also detect features from folder names at top level
100
+ const folders = new Set();
101
+ for (const file of files) {
102
+ const relPath = path.relative(srcPath, file);
103
+ const parts = relPath.split(path.sep);
104
+ if (parts.length >= 2) {
105
+ folders.add(parts[0]);
106
+ }
107
+ }
108
+ // If no features detected from files, use folder names
109
+ if (allFeatures.size === 0) {
110
+ for (const folder of folders) {
111
+ if (folder !== 'components' &&
112
+ folder !== 'utils' &&
113
+ folder !== 'hooks' &&
114
+ folder !== 'lib' &&
115
+ folder !== 'types' &&
116
+ folder !== 'config' &&
117
+ folder !== 'api' &&
118
+ folder !== 'services' &&
119
+ folder !== 'assets' &&
120
+ folder !== 'styles' &&
121
+ folder !== 'store' &&
122
+ folder !== 'context') {
123
+ allFeatures.add(folder);
124
+ featureMap[folder] = files
125
+ .filter((f) => path.relative(srcPath, f).startsWith(folder))
126
+ .map((f) => path.relative(srcPath, f));
127
+ }
128
+ }
129
+ }
130
+ // Sort features alphabetically
131
+ const features = Array.from(allFeatures).sort();
132
+ // Sort file lists within each feature
133
+ for (const feature of features) {
134
+ featureMap[feature].sort();
135
+ }
136
+ return {
137
+ features,
138
+ featureMap,
139
+ };
140
+ }
141
+ //# sourceMappingURL=13-detect-features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"13-detect-features.js","sourceRoot":"","sources":["../../src/tools/13-detect-features.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ClassifyFilesOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function classifyFiles(appPath: string, config?: Partial<AnalyzerConfig>): Promise<ClassifyFilesOutput>;
3
+ //# sourceMappingURL=14-classify-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"14-classify-files.d.ts","sourceRoot":"","sources":["../../src/tools/14-classify-files.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,mBAAmB,EAAsB,cAAc,EAAE,MAAM,aAAa,CAAC;AAE3F,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CA2E9B"}
@@ -0,0 +1,76 @@
1
+ // ============================================================================
2
+ // TOOL #14: classify-files
3
+ // Classifies each file into feature-specific, shared, utility, or config
4
+ // ============================================================================
5
+ import * as path from 'path';
6
+ import { findSourceFiles, resolveSourceDir } from '../utils/file-scanner.js';
7
+ import { buildImportGraph, resolveImportPath } from '../utils/import-tracker.js';
8
+ import { classifyFileType, detectFeatureFromPath, getFileFeature, } from '../utils/refactor-helpers.js';
9
+ export async function classifyFiles(appPath, config) {
10
+ const srcPath = resolveSourceDir(appPath);
11
+ const files = await findSourceFiles(srcPath);
12
+ if (files.length === 0) {
13
+ return { files: [] };
14
+ }
15
+ // Build import graph for cross-feature analysis
16
+ const graph = await buildImportGraph(srcPath);
17
+ // Count how many different features import each file
18
+ const importedByFeatures = new Map();
19
+ for (const file of files) {
20
+ const imports = graph[file]?.imports || [];
21
+ const fromFeature = getFileFeature(file, srcPath);
22
+ for (const imp of imports) {
23
+ const resolved = resolveImportPath(file, imp.source, srcPath, files);
24
+ if (!resolved)
25
+ continue;
26
+ if (!importedByFeatures.has(resolved)) {
27
+ importedByFeatures.set(resolved, new Set());
28
+ }
29
+ if (fromFeature) {
30
+ importedByFeatures.get(resolved).add(fromFeature);
31
+ }
32
+ }
33
+ }
34
+ // Classify each file
35
+ const classifications = [];
36
+ for (const file of files) {
37
+ const relPath = path.relative(srcPath, file);
38
+ let type;
39
+ let feature;
40
+ // First check: if imported by 2+ different features, it's shared
41
+ const importingFeatures = importedByFeatures.get(file);
42
+ if (importingFeatures && importingFeatures.size >= 2) {
43
+ type = 'shared';
44
+ }
45
+ else {
46
+ // Use path-based classification
47
+ type = classifyFileType(file, srcPath);
48
+ }
49
+ // Detect feature for feature-specific files
50
+ if (type === 'feature') {
51
+ const detectedFeature = detectFeatureFromPath(file, srcPath);
52
+ if (detectedFeature) {
53
+ feature = detectedFeature;
54
+ }
55
+ else {
56
+ // If no feature detected, reclassify as shared
57
+ type = 'shared';
58
+ }
59
+ }
60
+ classifications.push({
61
+ path: relPath,
62
+ type,
63
+ feature,
64
+ });
65
+ }
66
+ // Sort by type then by path
67
+ classifications.sort((a, b) => {
68
+ const typeOrder = { feature: 0, shared: 1, utility: 2, config: 3 };
69
+ const typeDiff = typeOrder[a.type] - typeOrder[b.type];
70
+ if (typeDiff !== 0)
71
+ return typeDiff;
72
+ return a.path.localeCompare(b.path);
73
+ });
74
+ return { files: classifications };
75
+ }
76
+ //# sourceMappingURL=14-classify-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"14-classify-files.js","sourceRoot":"","sources":["../../src/tools/14-classify-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DetectSharedModulesOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function detectSharedModules(appPath: string, config?: Partial<AnalyzerConfig>): Promise<DetectSharedModulesOutput>;
3
+ //# sourceMappingURL=15-detect-shared-modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"15-detect-shared-modules.d.ts","sourceRoot":"","sources":["../../src/tools/15-detect-shared-modules.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7E,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,yBAAyB,CAAC,CAwEpC"}
@@ -0,0 +1,70 @@
1
+ // ============================================================================
2
+ // TOOL #15: detect-shared-modules
3
+ // Identifies files used across multiple features
4
+ // ============================================================================
5
+ import * as path from 'path';
6
+ import { findSourceFiles, resolveSourceDir } from '../utils/file-scanner.js';
7
+ import { buildImportGraph, resolveImportPath } from '../utils/import-tracker.js';
8
+ import { getFileFeature } from '../utils/refactor-helpers.js';
9
+ export async function detectSharedModules(appPath, config) {
10
+ const srcPath = resolveSourceDir(appPath);
11
+ const files = await findSourceFiles(srcPath);
12
+ if (files.length === 0) {
13
+ return { shared: [], usageCounts: {} };
14
+ }
15
+ const graph = await buildImportGraph(srcPath);
16
+ // Track which features use each file
17
+ const fileUsageByFeature = new Map();
18
+ for (const file of files) {
19
+ const fromFeature = getFileFeature(file, srcPath);
20
+ if (!fromFeature)
21
+ continue;
22
+ const imports = graph[file]?.imports || [];
23
+ for (const imp of imports) {
24
+ // Only track internal imports (relative paths)
25
+ if (!imp.source.startsWith('.'))
26
+ continue;
27
+ const resolved = resolveImportPath(file, imp.source, srcPath, files);
28
+ if (!resolved)
29
+ continue;
30
+ if (!fileUsageByFeature.has(resolved)) {
31
+ fileUsageByFeature.set(resolved, new Set());
32
+ }
33
+ fileUsageByFeature.get(resolved).add(fromFeature);
34
+ }
35
+ }
36
+ // Also track files that are imported by many files (high fan-in)
37
+ const fileImportCount = new Map();
38
+ for (const file of files) {
39
+ const importers = graph[file]?.importedBy || [];
40
+ fileImportCount.set(file, importers.length);
41
+ }
42
+ // Identify shared modules: used by 2+ features OR high import count
43
+ const shared = [];
44
+ const usageCounts = {};
45
+ for (const [file, features] of fileUsageByFeature) {
46
+ const relPath = path.relative(srcPath, file);
47
+ if (features.size >= 2) {
48
+ if (!shared.includes(relPath)) {
49
+ shared.push(relPath);
50
+ }
51
+ usageCounts[relPath] = features.size;
52
+ }
53
+ }
54
+ // Also add files with high import count (>=5 importers) that aren't already shared
55
+ for (const [file, count] of fileImportCount) {
56
+ const relPath = path.relative(srcPath, file);
57
+ if (count >= 5 && !shared.includes(relPath)) {
58
+ // Only add if it's not a component-specific file
59
+ const feature = getFileFeature(file, srcPath);
60
+ if (!feature) {
61
+ shared.push(relPath);
62
+ usageCounts[relPath] = count;
63
+ }
64
+ }
65
+ }
66
+ // Sort by usage count descending
67
+ shared.sort((a, b) => (usageCounts[b] || 0) - (usageCounts[a] || 0));
68
+ return { shared, usageCounts };
69
+ }
70
+ //# sourceMappingURL=15-detect-shared-modules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"15-detect-shared-modules.js","sourceRoot":"","sources":["../../src/tools/15-detect-shared-modules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DesignTargetStructureOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function designTargetStructure(appPath: string, config?: Partial<AnalyzerConfig>, features?: string[]): Promise<DesignTargetStructureOutput>;
3
+ //# sourceMappingURL=16-design-target-structure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"16-design-target-structure.d.ts","sourceRoot":"","sources":["../../src/tools/16-design-target-structure.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG/E,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,2BAA2B,CAAC,CAwBtC"}
@@ -0,0 +1,26 @@
1
+ // ============================================================================
2
+ // TOOL #16: design-target-structure
3
+ // Generates scalable folder structure based on detected features
4
+ // ============================================================================
5
+ import { FEATURE_SUBDIRS, SHARED_DIRS, APP_DIRS } from '../utils/refactor-helpers.js';
6
+ export async function designTargetStructure(appPath, config, features) {
7
+ const featureList = features || [];
8
+ // Build feature structure
9
+ const featuresStructure = {};
10
+ for (const feature of featureList) {
11
+ featuresStructure[feature] = [...FEATURE_SUBDIRS];
12
+ }
13
+ // If no features detected, create a default structure
14
+ if (featureList.length === 0) {
15
+ featuresStructure['common'] = ['components', 'hooks', 'api'];
16
+ }
17
+ const structure = {
18
+ src: {
19
+ features: featuresStructure,
20
+ shared: SHARED_DIRS,
21
+ app: APP_DIRS,
22
+ },
23
+ };
24
+ return { structure };
25
+ }
26
+ //# sourceMappingURL=16-design-target-structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"16-design-target-structure.js","sourceRoot":"","sources":["../../src/tools/16-design-target-structure.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,oCAAoC;AACpC,iEAAiE;AACjE,+EAA+E;AAG/E,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAe,EACf,MAAgC,EAChC,QAAmB;IAEnB,MAAM,WAAW,GAAG,QAAQ,IAAI,EAAE,CAAC;IAEnC,0BAA0B;IAC1B,MAAM,iBAAiB,GAA6B,EAAE,CAAC;IAEvD,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC;IACpD,CAAC;IAED,sDAAsD;IACtD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,SAAS,GAA6C;QAC1D,GAAG,EAAE;YACH,QAAQ,EAAE,iBAAiB;YAC3B,MAAM,EAAE,WAAW;YACnB,GAAG,EAAE,QAAQ;SACd;KACF,CAAC;IAEF,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { MapFilesToTargetOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function mapFilesToTarget(appPath: string, config?: Partial<AnalyzerConfig>): Promise<MapFilesToTargetOutput>;
3
+ //# sourceMappingURL=17-map-files-to-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"17-map-files-to-target.d.ts","sourceRoot":"","sources":["../../src/tools/17-map-files-to-target.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,sBAAsB,EAAY,cAAc,EAAE,MAAM,aAAa,CAAC;AAEpF,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAsHjC"}
@@ -0,0 +1,108 @@
1
+ // ============================================================================
2
+ // TOOL #17: map-files-to-target
3
+ // Maps existing files to new target structure
4
+ // ============================================================================
5
+ import * as path from 'path';
6
+ import { findSourceFiles, resolveSourceDir } from '../utils/file-scanner.js';
7
+ import { detectFeatures } from './13-detect-features.js';
8
+ import { classifyFiles } from './14-classify-files.js';
9
+ import { detectFeatureFromPath, generateTargetPath, } from '../utils/refactor-helpers.js';
10
+ export async function mapFilesToTarget(appPath, config) {
11
+ const srcPath = resolveSourceDir(appPath);
12
+ const files = await findSourceFiles(srcPath);
13
+ if (files.length === 0) {
14
+ return { moves: [], unmapped: [] };
15
+ }
16
+ // Get features and classifications
17
+ const { features, featureMap } = await detectFeatures(appPath, config);
18
+ const { files: classifications } = await classifyFiles(appPath, config);
19
+ // Create classification lookup
20
+ const classificationMap = new Map(classifications.map((c) => [c.path, c]));
21
+ const moves = [];
22
+ const unmapped = [];
23
+ for (const file of files) {
24
+ const relPath = path.relative(srcPath, file);
25
+ const classification = classificationMap.get(relPath);
26
+ // Skip entry point files (index.js/tsx, App.js/tsx, etc.)
27
+ const basename = path.basename(file);
28
+ if (basename === 'index.tsx' ||
29
+ basename === 'index.ts' ||
30
+ basename === 'index.jsx' ||
31
+ basename === 'index.js' ||
32
+ basename === 'App.tsx' ||
33
+ basename === 'App.ts' ||
34
+ basename === 'App.jsx' ||
35
+ basename === 'App.js' ||
36
+ basename === 'index.css' ||
37
+ basename === 'index.scss' ||
38
+ basename === 'react-app-env.d.ts' ||
39
+ basename === 'reportWebVitals.ts' ||
40
+ basename === 'reportWebVitals.js' ||
41
+ basename === 'setupTests.ts' ||
42
+ basename === 'setupTests.js') {
43
+ continue;
44
+ }
45
+ // Determine target path
46
+ const targetPath = generateTargetPath(file, srcPath, features, featureMap);
47
+ // Check if file is already in the right place
48
+ const currentNormalized = relPath.replace(/\\/g, '/');
49
+ const targetNormalized = targetPath.replace(/\\/g, '/');
50
+ if (currentNormalized === targetNormalized) {
51
+ continue; // File is already in the right place
52
+ }
53
+ // Determine reason for the move
54
+ let reason = '';
55
+ if (classification) {
56
+ switch (classification.type) {
57
+ case 'feature':
58
+ reason = `Feature-specific file for "${classification.feature}" feature`;
59
+ break;
60
+ case 'shared':
61
+ reason = 'Shared module used across multiple features';
62
+ break;
63
+ case 'utility':
64
+ reason = 'Utility function should be in shared/utils';
65
+ break;
66
+ case 'config':
67
+ reason = 'Configuration file should be in shared/types';
68
+ break;
69
+ }
70
+ }
71
+ else {
72
+ reason = 'Reorganize to target structure';
73
+ }
74
+ moves.push({
75
+ from: relPath,
76
+ to: targetPath,
77
+ reason,
78
+ });
79
+ }
80
+ // Files that couldn't be cleanly mapped
81
+ for (const file of files) {
82
+ const relPath = path.relative(srcPath, file);
83
+ const inMoves = moves.some((m) => m.from === relPath);
84
+ const basename = path.basename(file);
85
+ // Skip entry points
86
+ if (basename === 'index.tsx' ||
87
+ basename === 'index.ts' ||
88
+ basename === 'index.jsx' ||
89
+ basename === 'index.js' ||
90
+ basename === 'App.tsx' ||
91
+ basename === 'App.ts' ||
92
+ basename === 'App.jsx' ||
93
+ basename === 'App.js') {
94
+ continue;
95
+ }
96
+ if (!inMoves) {
97
+ const feature = detectFeatureFromPath(file, srcPath);
98
+ if (!feature) {
99
+ unmapped.push(relPath);
100
+ }
101
+ }
102
+ }
103
+ // Sort moves by target path
104
+ moves.sort((a, b) => a.to.localeCompare(b.to));
105
+ unmapped.sort();
106
+ return { moves, unmapped };
107
+ }
108
+ //# sourceMappingURL=17-map-files-to-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"17-map-files-to-target.js","sourceRoot":"","sources":["../../src/tools/17-map-files-to-target.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DetectBoundaryViolationsOutput, AnalyzerConfig } from '../types.js';
2
+ export declare function detectBoundaryViolations(appPath: string, config?: Partial<AnalyzerConfig>): Promise<DetectBoundaryViolationsOutput>;
3
+ //# sourceMappingURL=18-detect-boundary-violations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"18-detect-boundary-violations.d.ts","sourceRoot":"","sources":["../../src/tools/18-detect-boundary-violations.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,8BAA8B,EAAqB,cAAc,EAAE,MAAM,aAAa,CAAC;AAErG,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,8BAA8B,CAAC,CA4IzC"}
@@ -0,0 +1,137 @@
1
+ // ============================================================================
2
+ // TOOL #18: detect-boundary-violations
3
+ // Identifies cross-feature imports, deep relative imports, and tight coupling
4
+ // ============================================================================
5
+ import * as path from 'path';
6
+ import { findSourceFiles, resolveSourceDir } from '../utils/file-scanner.js';
7
+ import { buildImportGraph, resolveImportPath, findDeepImports, findCrossFeatureImports } from '../utils/import-tracker.js';
8
+ import { areTightlyCoupled, } from '../utils/refactor-helpers.js';
9
+ export async function detectBoundaryViolations(appPath, config) {
10
+ const srcPath = resolveSourceDir(appPath);
11
+ const files = await findSourceFiles(srcPath);
12
+ if (files.length === 0) {
13
+ return {
14
+ violations: [],
15
+ summary: {
16
+ crossFeatureImports: 0,
17
+ deepRelativeImports: 0,
18
+ circularDependencies: 0,
19
+ tightCoupling: 0,
20
+ },
21
+ };
22
+ }
23
+ const graph = await buildImportGraph(srcPath);
24
+ const violations = [];
25
+ // 1. Cross-feature imports
26
+ const crossFeatureImports = findCrossFeatureImports(graph, appPath);
27
+ for (const imp of crossFeatureImports) {
28
+ const fromRel = path.relative(srcPath, imp.from);
29
+ const toRel = path.relative(srcPath, imp.to);
30
+ violations.push({
31
+ type: 'cross-feature-import',
32
+ from: fromRel,
33
+ to: toRel,
34
+ description: `File imports across feature boundary: "${imp.importPath}"`,
35
+ severity: 'error',
36
+ });
37
+ }
38
+ // 2. Deep relative imports (../../../ pattern)
39
+ const deepImports = findDeepImports(graph);
40
+ for (const di of deepImports) {
41
+ const fileRel = path.relative(srcPath, di.file);
42
+ violations.push({
43
+ type: 'deep-relative-import',
44
+ from: fileRel,
45
+ to: di.import,
46
+ description: `Deep relative import (${di.depth} levels): "${di.import}"`,
47
+ severity: di.depth >= 3 ? 'error' : 'warning',
48
+ });
49
+ }
50
+ // 3. Circular dependencies
51
+ const visited = new Set();
52
+ const recursionStack = new Set();
53
+ const cycles = [];
54
+ function detectCycles(file, path_) {
55
+ if (recursionStack.has(file)) {
56
+ const cycleStart = path_.indexOf(file);
57
+ if (cycleStart !== -1) {
58
+ cycles.push([...path_.slice(cycleStart), file]);
59
+ }
60
+ return;
61
+ }
62
+ if (visited.has(file))
63
+ return;
64
+ visited.add(file);
65
+ recursionStack.add(file);
66
+ path_.push(file);
67
+ const imports = graph[file]?.imports || [];
68
+ for (const imp of imports) {
69
+ const resolved = resolveImportPath(file, imp.source, srcPath, files);
70
+ if (resolved) {
71
+ detectCycles(resolved, [...path_]);
72
+ }
73
+ }
74
+ path_.pop();
75
+ recursionStack.delete(file);
76
+ }
77
+ for (const file of files) {
78
+ if (!visited.has(file)) {
79
+ detectCycles(file, []);
80
+ }
81
+ }
82
+ for (const cycle of cycles) {
83
+ const relPaths = cycle.map((f) => path.relative(srcPath, f));
84
+ violations.push({
85
+ type: 'circular-dependency',
86
+ from: relPaths[0],
87
+ to: relPaths[1] || relPaths[0],
88
+ description: `Circular dependency: ${relPaths.join(' → ')}`,
89
+ severity: 'error',
90
+ });
91
+ }
92
+ // 4. Tight coupling (mutual imports)
93
+ const coupledPairs = new Set();
94
+ for (let i = 0; i < files.length; i++) {
95
+ for (let j = i + 1; j < files.length; j++) {
96
+ const pairKey = [files[i], files[j]].sort().join('::');
97
+ if (coupledPairs.has(pairKey))
98
+ continue;
99
+ if (areTightlyCoupled(graph, files[i], files[j])) {
100
+ coupledPairs.add(pairKey);
101
+ const fromRel = path.relative(srcPath, files[i]);
102
+ const toRel = path.relative(srcPath, files[j]);
103
+ violations.push({
104
+ type: 'tight-coupling',
105
+ from: fromRel,
106
+ to: toRel,
107
+ description: `Tight coupling: mutual imports between files`,
108
+ severity: 'warning',
109
+ });
110
+ }
111
+ }
112
+ }
113
+ // Deduplicate violations
114
+ const seen = new Set();
115
+ const uniqueViolations = violations.filter((v) => {
116
+ const key = `${v.type}:${v.from}:${v.to}`;
117
+ if (seen.has(key))
118
+ return false;
119
+ seen.add(key);
120
+ return true;
121
+ });
122
+ // Calculate summary
123
+ const summary = {
124
+ crossFeatureImports: uniqueViolations.filter((v) => v.type === 'cross-feature-import').length,
125
+ deepRelativeImports: uniqueViolations.filter((v) => v.type === 'deep-relative-import').length,
126
+ circularDependencies: uniqueViolations.filter((v) => v.type === 'circular-dependency').length,
127
+ tightCoupling: uniqueViolations.filter((v) => v.type === 'tight-coupling').length,
128
+ };
129
+ // Sort by severity (errors first)
130
+ uniqueViolations.sort((a, b) => {
131
+ if (a.severity === b.severity)
132
+ return a.type.localeCompare(b.type);
133
+ return a.severity === 'error' ? -1 : 1;
134
+ });
135
+ return { violations: uniqueViolations, summary };
136
+ }
137
+ //# sourceMappingURL=18-detect-boundary-violations.js.map