@mohantn/gate-keeper 2.1.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 (272) hide show
  1. package/.github/instructions/dotnet-api-integration.instructions.md +416 -0
  2. package/.github/instructions/dotnet-development.instructions.md +353 -0
  3. package/.github/instructions/dotnet-testing.instructions.md +406 -0
  4. package/.github/instructions/gate-keeper.instructions.md +91 -0
  5. package/.github/instructions/react-development.instructions.md +315 -0
  6. package/.github/instructions/react-testing-optimization.instructions.md +373 -0
  7. package/.github/instructions/uiux.instructions.md +261 -0
  8. package/LICENSE +21 -0
  9. package/README.md +181 -0
  10. package/dist/analyzer/coverage-analyzer.d.ts +126 -0
  11. package/dist/analyzer/coverage-analyzer.d.ts.map +1 -0
  12. package/dist/analyzer/coverage-analyzer.js +633 -0
  13. package/dist/analyzer/coverage-analyzer.js.map +1 -0
  14. package/dist/analyzer/csharp-analyzer.d.ts +28 -0
  15. package/dist/analyzer/csharp-analyzer.d.ts.map +1 -0
  16. package/dist/analyzer/csharp-analyzer.js +437 -0
  17. package/dist/analyzer/csharp-analyzer.js.map +1 -0
  18. package/dist/analyzer/pattern-detector.d.ts +5 -0
  19. package/dist/analyzer/pattern-detector.d.ts.map +1 -0
  20. package/dist/analyzer/pattern-detector.js +74 -0
  21. package/dist/analyzer/pattern-detector.js.map +1 -0
  22. package/dist/analyzer/refactoring-advisor.d.ts +7 -0
  23. package/dist/analyzer/refactoring-advisor.d.ts.map +1 -0
  24. package/dist/analyzer/refactoring-advisor.js +280 -0
  25. package/dist/analyzer/refactoring-advisor.js.map +1 -0
  26. package/dist/analyzer/sonar-eslint-runner.d.ts +3 -0
  27. package/dist/analyzer/sonar-eslint-runner.d.ts.map +1 -0
  28. package/dist/analyzer/sonar-eslint-runner.js +136 -0
  29. package/dist/analyzer/sonar-eslint-runner.js.map +1 -0
  30. package/dist/analyzer/sonar-rule-map.d.ts +19 -0
  31. package/dist/analyzer/sonar-rule-map.d.ts.map +1 -0
  32. package/dist/analyzer/sonar-rule-map.js +67 -0
  33. package/dist/analyzer/sonar-rule-map.js.map +1 -0
  34. package/dist/analyzer/string-analyzer.d.ts +27 -0
  35. package/dist/analyzer/string-analyzer.d.ts.map +1 -0
  36. package/dist/analyzer/string-analyzer.js +274 -0
  37. package/dist/analyzer/string-analyzer.js.map +1 -0
  38. package/dist/analyzer/typescript-analyzer.d.ts +27 -0
  39. package/dist/analyzer/typescript-analyzer.d.ts.map +1 -0
  40. package/dist/analyzer/typescript-analyzer.js +437 -0
  41. package/dist/analyzer/typescript-analyzer.js.map +1 -0
  42. package/dist/analyzer/universal-analyzer.d.ts +10 -0
  43. package/dist/analyzer/universal-analyzer.d.ts.map +1 -0
  44. package/dist/analyzer/universal-analyzer.js +155 -0
  45. package/dist/analyzer/universal-analyzer.js.map +1 -0
  46. package/dist/cache/quality-cache.d.ts +119 -0
  47. package/dist/cache/quality-cache.d.ts.map +1 -0
  48. package/dist/cache/quality-cache.js +130 -0
  49. package/dist/cache/quality-cache.js.map +1 -0
  50. package/dist/cache/sqlite-cache.d.ts +43 -0
  51. package/dist/cache/sqlite-cache.d.ts.map +1 -0
  52. package/dist/cache/sqlite-cache.js +346 -0
  53. package/dist/cache/sqlite-cache.js.map +1 -0
  54. package/dist/cli/query-repl.d.ts +37 -0
  55. package/dist/cli/query-repl.d.ts.map +1 -0
  56. package/dist/cli/query-repl.js +298 -0
  57. package/dist/cli/query-repl.js.map +1 -0
  58. package/dist/cli/repl-algorithms.d.ts +49 -0
  59. package/dist/cli/repl-algorithms.d.ts.map +1 -0
  60. package/dist/cli/repl-algorithms.js +147 -0
  61. package/dist/cli/repl-algorithms.js.map +1 -0
  62. package/dist/cli/setup-core.d.ts +38 -0
  63. package/dist/cli/setup-core.d.ts.map +1 -0
  64. package/dist/cli/setup-core.js +427 -0
  65. package/dist/cli/setup-core.js.map +1 -0
  66. package/dist/cli/setup.d.ts +25 -0
  67. package/dist/cli/setup.d.ts.map +1 -0
  68. package/dist/cli/setup.js +159 -0
  69. package/dist/cli/setup.js.map +1 -0
  70. package/dist/cli-entry.d.ts +19 -0
  71. package/dist/cli-entry.d.ts.map +1 -0
  72. package/dist/cli-entry.js +178 -0
  73. package/dist/cli-entry.js.map +1 -0
  74. package/dist/daemon/watch-mode.d.ts +41 -0
  75. package/dist/daemon/watch-mode.d.ts.map +1 -0
  76. package/dist/daemon/watch-mode.js +163 -0
  77. package/dist/daemon/watch-mode.js.map +1 -0
  78. package/dist/daemon.d.ts +24 -0
  79. package/dist/daemon.d.ts.map +1 -0
  80. package/dist/daemon.js +357 -0
  81. package/dist/daemon.js.map +1 -0
  82. package/dist/github/app.d.ts +34 -0
  83. package/dist/github/app.d.ts.map +1 -0
  84. package/dist/github/app.js +261 -0
  85. package/dist/github/app.js.map +1 -0
  86. package/dist/github/commenter.d.ts +67 -0
  87. package/dist/github/commenter.d.ts.map +1 -0
  88. package/dist/github/commenter.js +155 -0
  89. package/dist/github/commenter.js.map +1 -0
  90. package/dist/graph/dependency-graph.d.ts +28 -0
  91. package/dist/graph/dependency-graph.d.ts.map +1 -0
  92. package/dist/graph/dependency-graph.js +198 -0
  93. package/dist/graph/dependency-graph.js.map +1 -0
  94. package/dist/graph/global-graph.d.ts +65 -0
  95. package/dist/graph/global-graph.d.ts.map +1 -0
  96. package/dist/graph/global-graph.js +153 -0
  97. package/dist/graph/global-graph.js.map +1 -0
  98. package/dist/graph/graph-algorithms.d.ts +90 -0
  99. package/dist/graph/graph-algorithms.d.ts.map +1 -0
  100. package/dist/graph/graph-algorithms.js +180 -0
  101. package/dist/graph/graph-algorithms.js.map +1 -0
  102. package/dist/graph/graph-export.d.ts +68 -0
  103. package/dist/graph/graph-export.d.ts.map +1 -0
  104. package/dist/graph/graph-export.js +264 -0
  105. package/dist/graph/graph-export.js.map +1 -0
  106. package/dist/graph/graph-report.d.ts +34 -0
  107. package/dist/graph/graph-report.d.ts.map +1 -0
  108. package/dist/graph/graph-report.js +136 -0
  109. package/dist/graph/graph-report.js.map +1 -0
  110. package/dist/graph/graph-summary.d.ts +68 -0
  111. package/dist/graph/graph-summary.d.ts.map +1 -0
  112. package/dist/graph/graph-summary.js +213 -0
  113. package/dist/graph/graph-summary.js.map +1 -0
  114. package/dist/graph/graphify-ignore.d.ts +32 -0
  115. package/dist/graph/graphify-ignore.d.ts.map +1 -0
  116. package/dist/graph/graphify-ignore.js +124 -0
  117. package/dist/graph/graphify-ignore.js.map +1 -0
  118. package/dist/graph/question-suggester.d.ts +30 -0
  119. package/dist/graph/question-suggester.d.ts.map +1 -0
  120. package/dist/graph/question-suggester.js +113 -0
  121. package/dist/graph/question-suggester.js.map +1 -0
  122. package/dist/graph/relationship-extractor.d.ts +40 -0
  123. package/dist/graph/relationship-extractor.d.ts.map +1 -0
  124. package/dist/graph/relationship-extractor.js +254 -0
  125. package/dist/graph/relationship-extractor.js.map +1 -0
  126. package/dist/graph/relationship-types.d.ts +24 -0
  127. package/dist/graph/relationship-types.d.ts.map +1 -0
  128. package/dist/graph/relationship-types.js +21 -0
  129. package/dist/graph/relationship-types.js.map +1 -0
  130. package/dist/graph/surprising-connections.d.ts +39 -0
  131. package/dist/graph/surprising-connections.d.ts.map +1 -0
  132. package/dist/graph/surprising-connections.js +127 -0
  133. package/dist/graph/surprising-connections.js.map +1 -0
  134. package/dist/hook-pre-tool-use.d.ts +14 -0
  135. package/dist/hook-pre-tool-use.d.ts.map +1 -0
  136. package/dist/hook-pre-tool-use.js +167 -0
  137. package/dist/hook-pre-tool-use.js.map +1 -0
  138. package/dist/hook-receiver.d.ts +29 -0
  139. package/dist/hook-receiver.d.ts.map +1 -0
  140. package/dist/hook-receiver.js +327 -0
  141. package/dist/hook-receiver.js.map +1 -0
  142. package/dist/hooks/git-hooks.d.ts +30 -0
  143. package/dist/hooks/git-hooks.d.ts.map +1 -0
  144. package/dist/hooks/git-hooks.js +179 -0
  145. package/dist/hooks/git-hooks.js.map +1 -0
  146. package/dist/mcp/cache-preload.d.ts +29 -0
  147. package/dist/mcp/cache-preload.d.ts.map +1 -0
  148. package/dist/mcp/cache-preload.js +103 -0
  149. package/dist/mcp/cache-preload.js.map +1 -0
  150. package/dist/mcp/handlers/analysis.d.ts +4 -0
  151. package/dist/mcp/handlers/analysis.d.ts.map +1 -0
  152. package/dist/mcp/handlers/analysis.js +196 -0
  153. package/dist/mcp/handlers/analysis.js.map +1 -0
  154. package/dist/mcp/handlers/context.d.ts +25 -0
  155. package/dist/mcp/handlers/context.d.ts.map +1 -0
  156. package/dist/mcp/handlers/context.js +382 -0
  157. package/dist/mcp/handlers/context.js.map +1 -0
  158. package/dist/mcp/handlers/graph-intelligence.d.ts +26 -0
  159. package/dist/mcp/handlers/graph-intelligence.d.ts.map +1 -0
  160. package/dist/mcp/handlers/graph-intelligence.js +371 -0
  161. package/dist/mcp/handlers/graph-intelligence.js.map +1 -0
  162. package/dist/mcp/handlers/graph-query.d.ts +25 -0
  163. package/dist/mcp/handlers/graph-query.d.ts.map +1 -0
  164. package/dist/mcp/handlers/graph-query.js +410 -0
  165. package/dist/mcp/handlers/graph-query.js.map +1 -0
  166. package/dist/mcp/handlers/graph.d.ts +5 -0
  167. package/dist/mcp/handlers/graph.d.ts.map +1 -0
  168. package/dist/mcp/handlers/graph.js +283 -0
  169. package/dist/mcp/handlers/graph.js.map +1 -0
  170. package/dist/mcp/handlers/impact-format.d.ts +9 -0
  171. package/dist/mcp/handlers/impact-format.d.ts.map +1 -0
  172. package/dist/mcp/handlers/impact-format.js +189 -0
  173. package/dist/mcp/handlers/impact-format.js.map +1 -0
  174. package/dist/mcp/handlers/impact.d.ts +4 -0
  175. package/dist/mcp/handlers/impact.d.ts.map +1 -0
  176. package/dist/mcp/handlers/impact.js +139 -0
  177. package/dist/mcp/handlers/impact.js.map +1 -0
  178. package/dist/mcp/handlers/improvement.d.ts +4 -0
  179. package/dist/mcp/handlers/improvement.d.ts.map +1 -0
  180. package/dist/mcp/handlers/improvement.js +136 -0
  181. package/dist/mcp/handlers/improvement.js.map +1 -0
  182. package/dist/mcp/handlers/index.d.ts +14 -0
  183. package/dist/mcp/handlers/index.d.ts.map +1 -0
  184. package/dist/mcp/handlers/index.js +36 -0
  185. package/dist/mcp/handlers/index.js.map +1 -0
  186. package/dist/mcp/handlers/platform-installer.d.ts +10 -0
  187. package/dist/mcp/handlers/platform-installer.d.ts.map +1 -0
  188. package/dist/mcp/handlers/platform-installer.js +168 -0
  189. package/dist/mcp/handlers/platform-installer.js.map +1 -0
  190. package/dist/mcp/handlers/pr-review.d.ts +33 -0
  191. package/dist/mcp/handlers/pr-review.d.ts.map +1 -0
  192. package/dist/mcp/handlers/pr-review.js +170 -0
  193. package/dist/mcp/handlers/pr-review.js.map +1 -0
  194. package/dist/mcp/handlers/shared.d.ts +20 -0
  195. package/dist/mcp/handlers/shared.d.ts.map +1 -0
  196. package/dist/mcp/handlers/shared.js +27 -0
  197. package/dist/mcp/handlers/shared.js.map +1 -0
  198. package/dist/mcp/handlers/types.d.ts +46 -0
  199. package/dist/mcp/handlers/types.d.ts.map +1 -0
  200. package/dist/mcp/handlers/types.js +3 -0
  201. package/dist/mcp/handlers/types.js.map +1 -0
  202. package/dist/mcp/helpers.d.ts +36 -0
  203. package/dist/mcp/helpers.d.ts.map +1 -0
  204. package/dist/mcp/helpers.js +199 -0
  205. package/dist/mcp/helpers.js.map +1 -0
  206. package/dist/mcp/installer.d.ts +22 -0
  207. package/dist/mcp/installer.d.ts.map +1 -0
  208. package/dist/mcp/installer.js +341 -0
  209. package/dist/mcp/installer.js.map +1 -0
  210. package/dist/mcp/server.d.ts +111 -0
  211. package/dist/mcp/server.d.ts.map +1 -0
  212. package/dist/mcp/server.js +216 -0
  213. package/dist/mcp/server.js.map +1 -0
  214. package/dist/mcp/token-tracker.d.ts +47 -0
  215. package/dist/mcp/token-tracker.d.ts.map +1 -0
  216. package/dist/mcp/token-tracker.js +93 -0
  217. package/dist/mcp/token-tracker.js.map +1 -0
  218. package/dist/quality-loop/file-lock.d.ts +12 -0
  219. package/dist/quality-loop/file-lock.d.ts.map +1 -0
  220. package/dist/quality-loop/file-lock.js +38 -0
  221. package/dist/quality-loop/file-lock.js.map +1 -0
  222. package/dist/quality-loop/fix-worker.d.ts +44 -0
  223. package/dist/quality-loop/fix-worker.d.ts.map +1 -0
  224. package/dist/quality-loop/fix-worker.js +414 -0
  225. package/dist/quality-loop/fix-worker.js.map +1 -0
  226. package/dist/quality-loop/orchestrator.d.ts +137 -0
  227. package/dist/quality-loop/orchestrator.d.ts.map +1 -0
  228. package/dist/quality-loop/orchestrator.js +894 -0
  229. package/dist/quality-loop/orchestrator.js.map +1 -0
  230. package/dist/quality-loop/queue-manager.d.ts +45 -0
  231. package/dist/quality-loop/queue-manager.d.ts.map +1 -0
  232. package/dist/quality-loop/queue-manager.js +173 -0
  233. package/dist/quality-loop/queue-manager.js.map +1 -0
  234. package/dist/rating/rating-calculator.d.ts +15 -0
  235. package/dist/rating/rating-calculator.d.ts.map +1 -0
  236. package/dist/rating/rating-calculator.js +136 -0
  237. package/dist/rating/rating-calculator.js.map +1 -0
  238. package/dist/types/agent.d.ts +49 -0
  239. package/dist/types/agent.d.ts.map +1 -0
  240. package/dist/types/agent.js +7 -0
  241. package/dist/types/agent.js.map +1 -0
  242. package/dist/types.d.ts +156 -0
  243. package/dist/types.d.ts.map +1 -0
  244. package/dist/types.js +3 -0
  245. package/dist/types.js.map +1 -0
  246. package/dist/util/fix-text.d.ts +7 -0
  247. package/dist/util/fix-text.d.ts.map +1 -0
  248. package/dist/util/fix-text.js +13 -0
  249. package/dist/util/fix-text.js.map +1 -0
  250. package/dist/viz/graph-viz.d.ts +40 -0
  251. package/dist/viz/graph-viz.d.ts.map +1 -0
  252. package/dist/viz/graph-viz.js +332 -0
  253. package/dist/viz/graph-viz.js.map +1 -0
  254. package/dist/viz/viz-helpers.d.ts +13 -0
  255. package/dist/viz/viz-helpers.d.ts.map +1 -0
  256. package/dist/viz/viz-helpers.js +134 -0
  257. package/dist/viz/viz-helpers.js.map +1 -0
  258. package/dist/viz/viz-routes.d.ts +28 -0
  259. package/dist/viz/viz-routes.d.ts.map +1 -0
  260. package/dist/viz/viz-routes.js +333 -0
  261. package/dist/viz/viz-routes.js.map +1 -0
  262. package/dist/viz/viz-scanner.d.ts +20 -0
  263. package/dist/viz/viz-scanner.d.ts.map +1 -0
  264. package/dist/viz/viz-scanner.js +241 -0
  265. package/dist/viz/viz-scanner.js.map +1 -0
  266. package/dist/viz/viz-server.d.ts +38 -0
  267. package/dist/viz/viz-server.d.ts.map +1 -0
  268. package/dist/viz/viz-server.js +240 -0
  269. package/dist/viz/viz-server.js.map +1 -0
  270. package/package.json +89 -0
  271. package/scripts/postinstall.js +28 -0
  272. package/scripts/setup.sh +113 -0
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RefactoringAdvisor = void 0;
4
+ const REFACTORING_MAP = {
5
+ god_class: {
6
+ patternName: 'Extract Service',
7
+ priority: 'high',
8
+ rationale: 'A class with >20 methods violates Single Responsibility and resists change.',
9
+ steps: [
10
+ 'List all methods and group them by the "noun" they operate on.',
11
+ 'Create one new class per group (e.g. UserRepository, UserValidator).',
12
+ 'Move the methods, adjusting access modifiers.',
13
+ 'Replace original class references with constructor-injected dependencies.',
14
+ 'Delete the original god class once all callers are updated.',
15
+ ],
16
+ },
17
+ hook_overload: {
18
+ patternName: 'Extract Custom Hook',
19
+ priority: 'high',
20
+ rationale: 'Components with >7 hooks are hard to test and reuse.',
21
+ steps: [
22
+ 'Identify groups of 2–3 hooks that share a common concern (e.g. form state, auth state).',
23
+ 'Create a `useXxx` file in a `/hooks` directory for each group.',
24
+ 'Move the hook calls and their derived state into the custom hook.',
25
+ 'Return only the values the component needs from the custom hook.',
26
+ 'Replace the inline hook calls in the component with a single `useXxx()` call.',
27
+ ],
28
+ },
29
+ duplicate_hooks: {
30
+ patternName: 'Consolidate Hook Calls',
31
+ priority: 'medium',
32
+ rationale: 'Calling the same hook twice creates redundant subscriptions and subtle bugs.',
33
+ steps: [
34
+ 'Find all calls to the duplicated hook.',
35
+ 'Merge them into a single call at the top of the component.',
36
+ 'Destructure all needed values from the single call.',
37
+ ],
38
+ },
39
+ tight_coupling: {
40
+ patternName: 'Apply Dependency Injection',
41
+ priority: 'high',
42
+ rationale: 'Constructors with >5 parameters signal tightly coupled dependencies.',
43
+ steps: [
44
+ 'Create a `XxxOptions` or `XxxConfig` class that groups related parameters.',
45
+ 'Or: define an interface for each dependency and inject it via the constructor.',
46
+ 'Update the constructor signature to accept the interface/options type.',
47
+ 'Update all call sites.',
48
+ ],
49
+ },
50
+ any_type: {
51
+ patternName: 'Add Type Definitions',
52
+ priority: 'medium',
53
+ rationale: '`any` bypasses the type checker and hides bugs.',
54
+ steps: [
55
+ 'For each `any`, examine the actual runtime shape of the value.',
56
+ 'Create a named interface or type alias in a co-located `types.ts`.',
57
+ 'Replace `any` with the specific type or `unknown` + a type guard.',
58
+ ],
59
+ minCount: 1,
60
+ },
61
+ any_usage: {
62
+ patternName: 'Add Type Definitions',
63
+ priority: 'medium',
64
+ rationale: '`any` bypasses the type checker and hides bugs.',
65
+ steps: [
66
+ 'For each `any`, examine the actual runtime shape of the value.',
67
+ 'Create a named interface or type alias in a co-located `types.ts`.',
68
+ 'Replace `any` with the specific type or `unknown` + a type guard.',
69
+ ],
70
+ minCount: 1,
71
+ },
72
+ console_log: {
73
+ patternName: 'Replace Console Statements',
74
+ priority: 'low',
75
+ rationale: 'console.log leaks internals and clutters production logs.',
76
+ steps: [
77
+ 'Delete debug console.log calls.',
78
+ 'Replace intentional logging with a structured logger (e.g. pino, winston).',
79
+ ],
80
+ },
81
+ missing_key: {
82
+ patternName: 'Add Stable List Keys',
83
+ priority: 'high',
84
+ rationale: 'Missing key props cause React to re-mount list items unnecessarily.',
85
+ steps: [
86
+ 'Add `key={item.id}` (or another stable unique field) to the outermost JSX element inside every `.map()` callback.',
87
+ 'Never use array index as key unless the list is static and never reordered.',
88
+ ],
89
+ },
90
+ inline_handler: {
91
+ patternName: 'Extract Event Handlers',
92
+ priority: 'low',
93
+ rationale: 'Inline arrow functions in JSX create new references on every render.',
94
+ steps: [
95
+ 'Move the inline function body to a named `const handleXxx = useCallback(...)` above the JSX return.',
96
+ 'Pass the named function as the event handler prop.',
97
+ ],
98
+ },
99
+ long_method: {
100
+ patternName: 'Decompose Method',
101
+ priority: 'medium',
102
+ rationale: 'Methods >50 lines are hard to test and reason about.',
103
+ steps: [
104
+ 'Find the natural "paragraphs" in the method (groups of lines with a shared purpose).',
105
+ 'Extract each paragraph into a private helper method with a descriptive name.',
106
+ 'Replace the paragraph in the original method with a single call to the helper.',
107
+ ],
108
+ },
109
+ empty_catch: {
110
+ patternName: 'Handle Exceptions Explicitly',
111
+ priority: 'high',
112
+ rationale: 'Empty catch blocks silently swallow errors, making failures invisible.',
113
+ steps: [
114
+ 'At minimum, log the error: `console.error(err)` or use your structured logger.',
115
+ 'If the error is expected and safe to ignore, add a comment explaining why.',
116
+ 'If the error is unrecoverable, rethrow it.',
117
+ ],
118
+ },
119
+ todo_placeholder: {
120
+ patternName: 'Resolve TODO Markers',
121
+ priority: 'medium',
122
+ rationale: 'TODO/FIXME markers indicate incomplete work that should not reach production.',
123
+ steps: [
124
+ 'Implement the missing functionality, or create a tracked issue.',
125
+ 'Remove the marker once addressed.',
126
+ ],
127
+ },
128
+ unimplemented_stub: {
129
+ patternName: 'Implement Required Functionality',
130
+ priority: 'high',
131
+ rationale: 'Stubs that throw at runtime will crash in production.',
132
+ steps: [
133
+ 'Implement the actual logic.',
134
+ 'If not yet possible, at least return a safe default and log a warning.',
135
+ ],
136
+ },
137
+ tech_debt_marker: {
138
+ patternName: 'Track and Schedule Technical Debt',
139
+ priority: 'low',
140
+ rationale: 'HACK/WORKAROUND markers accumulate and degrade maintainability.',
141
+ steps: [
142
+ 'Create a ticket in your issue tracker referencing the file and line.',
143
+ 'Add a comment with the ticket number next to the marker.',
144
+ 'Schedule the cleanup in the next sprint.',
145
+ ],
146
+ },
147
+ magic_number: {
148
+ patternName: 'Extract Named Constants',
149
+ priority: 'low',
150
+ rationale: 'Magic numbers make code opaque and brittle to change.',
151
+ steps: [
152
+ 'Move each magic number to a `const` at the top of the file or in a `constants.ts`.',
153
+ 'Give it a name that explains what it means, not just its value.',
154
+ ],
155
+ },
156
+ no_test_coverage: {
157
+ patternName: 'Add Unit Tests',
158
+ priority: 'high',
159
+ rationale: 'No test coverage means changes are made blind.',
160
+ steps: [
161
+ 'Create a `*.test.ts` file alongside the source file.',
162
+ 'Write at minimum one test for each exported function.',
163
+ 'Run with `--coverage` to verify coverage registers.',
164
+ ],
165
+ },
166
+ no_test_file: {
167
+ patternName: 'Add Unit Tests',
168
+ priority: 'high',
169
+ rationale: 'No test coverage means changes are made blind.',
170
+ steps: [
171
+ 'Create a `*.test.ts` file alongside the source file.',
172
+ 'Write at minimum one test for each exported function.',
173
+ 'Run with `--coverage` to verify coverage registers.',
174
+ ],
175
+ },
176
+ low_test_coverage: {
177
+ patternName: 'Increase Test Coverage to 80%',
178
+ priority: 'medium',
179
+ rationale: 'Coverage below 50% leaves most logic paths untested.',
180
+ steps: [
181
+ 'Run `npx jest --coverage` and open the HTML report.',
182
+ 'Focus on uncovered branches (conditionals, error paths).',
183
+ 'Add tests until coverage exceeds 80%.',
184
+ ],
185
+ },
186
+ hollow_test_file: {
187
+ patternName: 'Add Real Test Assertions',
188
+ priority: 'high',
189
+ rationale: 'Test files with empty suites or no assertions provide no safety net.',
190
+ steps: [
191
+ 'Review the test file for empty `describe` or `it` blocks.',
192
+ 'Add at least one real assertion per exported function.',
193
+ 'Run tests and verify they fail when code breaks.',
194
+ ],
195
+ },
196
+ };
197
+ const HIGH_IMPORT_HINT = {
198
+ patternName: 'Introduce Module Boundary',
199
+ priority: 'medium',
200
+ rationale: '>15 imports signal a file doing too much; >30 is a coupling crisis.',
201
+ steps: [
202
+ 'Identify clusters of imports that relate to the same concern.',
203
+ 'Create a barrel/index.ts for each cluster.',
204
+ 'Or: split the file into feature-focused modules.',
205
+ 'Aim for ≤15 imports per file.',
206
+ ],
207
+ };
208
+ class RefactoringAdvisor {
209
+ suggest(analysis, cycles) {
210
+ const hints = [];
211
+ // ── 1. Violation-based hints ───────────────────────────
212
+ const violationsByType = new Map();
213
+ for (const v of analysis.violations) {
214
+ const group = violationsByType.get(v.type) ?? [];
215
+ group.push(v);
216
+ violationsByType.set(v.type, group);
217
+ }
218
+ for (const [type, violations] of violationsByType) {
219
+ const rule = REFACTORING_MAP[type];
220
+ if (!rule)
221
+ continue;
222
+ if (rule.minCount !== undefined && violations.length < rule.minCount)
223
+ continue;
224
+ hints.push({
225
+ patternName: rule.patternName,
226
+ violationType: type,
227
+ rationale: rule.rationale,
228
+ steps: rule.steps,
229
+ estimatedRatingGain: this.gainForViolations(violations),
230
+ priority: rule.priority,
231
+ });
232
+ }
233
+ // ── 2. Metrics-based hints ─────────────────────────────
234
+ if (analysis.metrics.importCount > 15) {
235
+ const rule = HIGH_IMPORT_HINT;
236
+ const gain = analysis.metrics.importCount > 30 ? 2.0 : 0.5;
237
+ hints.push({
238
+ patternName: rule.patternName,
239
+ violationType: 'high_import_count',
240
+ rationale: rule.rationale,
241
+ steps: rule.steps,
242
+ estimatedRatingGain: gain,
243
+ priority: rule.priority,
244
+ });
245
+ }
246
+ // ── 3. Cycle-based hints ───────────────────────────────
247
+ const fileCycles = cycles.filter(c => c.nodes.includes(analysis.path));
248
+ if (fileCycles.length > 0) {
249
+ hints.push({
250
+ patternName: 'Break Circular Dependency',
251
+ violationType: 'circular_dependency',
252
+ rationale: `This file participates in ${fileCycles.length} circular dependency cycle(s), costing −${fileCycles.length}.0 rating.`,
253
+ steps: [
254
+ 'Identify which import creates the cycle (usually an upward import).',
255
+ 'Extract shared types into a new `types.ts` or `interfaces.ts` that neither module imports.',
256
+ 'Apply Dependency Inversion: depend on an abstraction (interface), not a concrete implementation.',
257
+ 'Or: merge the two tightly coupled files if they are truly inseparable.',
258
+ ],
259
+ estimatedRatingGain: fileCycles.length * 1.0,
260
+ priority: 'high',
261
+ });
262
+ }
263
+ // ── 4. Sort by estimated gain descending ───────────────
264
+ hints.sort((a, b) => {
265
+ if (b.estimatedRatingGain !== a.estimatedRatingGain) {
266
+ return b.estimatedRatingGain - a.estimatedRatingGain;
267
+ }
268
+ const priorityOrder = { high: 0, medium: 1, low: 2 };
269
+ return priorityOrder[a.priority] - priorityOrder[b.priority];
270
+ });
271
+ return hints;
272
+ }
273
+ gainForViolations(violations) {
274
+ const DEDUCTIONS = { error: 1.5, warning: 0.5, info: 0.1 };
275
+ const total = violations.reduce((sum, v) => sum + (DEDUCTIONS[v.severity] ?? 0), 0);
276
+ return Math.round(total * 10) / 10;
277
+ }
278
+ }
279
+ exports.RefactoringAdvisor = RefactoringAdvisor;
280
+ //# sourceMappingURL=refactoring-advisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refactoring-advisor.js","sourceRoot":"","sources":["../../src/analyzer/refactoring-advisor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Violation } from '../types';
2
+ export declare function runSonarJS(filePath: string, content?: string): Violation[];
3
+ //# sourceMappingURL=sonar-eslint-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonar-eslint-runner.d.ts","sourceRoot":"","sources":["../../src/analyzer/sonar-eslint-runner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAQ,SAAS,EAAE,MAAM,UAAU,CAAC;AAgE3C,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAkC1E"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.runSonarJS = runSonarJS;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const eslint_1 = require("eslint");
43
+ const eslint_plugin_sonarjs_1 = __importDefault(require("eslint-plugin-sonarjs"));
44
+ const sonar_rule_map_1 = require("./sonar-rule-map");
45
+ // `@typescript-eslint/parser` uses a modern package.json "exports" field that
46
+ // classic Node module resolution cannot read — load it via require() instead.
47
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
48
+ const tsParser = require('@typescript-eslint/parser');
49
+ const linter = new eslint_1.Linter();
50
+ // sonarjsPlugin.configs.recommended is a fully-formed flat-config object with
51
+ // all 328 rules pre-configured with their required option tuples. Enabling
52
+ // rules ad-hoc by name fails because some (e.g. sonarjs/no-empty-function)
53
+ // throw without their default options.
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ const recommended = eslint_plugin_sonarjs_1.default.configs.recommended;
56
+ // Rules that crash on a single file without full TS project config get
57
+ // discovered lazily on first failure and remembered for the rest of the
58
+ // process lifetime. Seeded with known offenders so the first call already
59
+ // works without retries.
60
+ const FAILING_RULES = new Set([
61
+ 'sonarjs/no-empty-function',
62
+ 'sonarjs/no-unused-expressions',
63
+ ]);
64
+ const LANGUAGE_OPTIONS = {
65
+ parser: tsParser,
66
+ parserOptions: {
67
+ ecmaVersion: 'latest',
68
+ sourceType: 'module',
69
+ ecmaFeatures: { jsx: true },
70
+ },
71
+ };
72
+ function buildConfig() {
73
+ const disabled = {};
74
+ for (const r of FAILING_RULES)
75
+ disabled[r] = 'off';
76
+ return [{
77
+ ...recommended,
78
+ // Spread AFTER recommended so it doesn't overwrite our files glob.
79
+ // ESLint v9 flat config only lints .js/.cjs/.mjs by default — explicit
80
+ // files are required to include TypeScript and React extensions.
81
+ files: ['**/*.{js,jsx,ts,tsx,mjs,cjs}'],
82
+ languageOptions: LANGUAGE_OPTIONS,
83
+ rules: { ...recommended.rules, ...disabled },
84
+ }];
85
+ }
86
+ const FAIL_RX = /Error while loading rule '([^']+)'/;
87
+ function verifyWithRetry(code, filename) {
88
+ for (let i = 0; i < 30; i++) {
89
+ try {
90
+ return linter.verify(code, buildConfig(), { filename });
91
+ }
92
+ catch (e) {
93
+ const m = FAIL_RX.exec(e.message);
94
+ if (!m || FAILING_RULES.has(m[1]))
95
+ return [];
96
+ FAILING_RULES.add(m[1]);
97
+ }
98
+ }
99
+ return [];
100
+ }
101
+ function runSonarJS(filePath, content) {
102
+ let code;
103
+ try {
104
+ code = content ?? fs.readFileSync(filePath, 'utf8');
105
+ }
106
+ catch {
107
+ return [];
108
+ }
109
+ // ESLint v9 flat config can't match absolute paths outside cwd against its
110
+ // `files` glob — pass only the basename so the relative-path match succeeds.
111
+ const messages = verifyWithRetry(code, path.basename(filePath));
112
+ const out = [];
113
+ for (const m of messages) {
114
+ if (!m.ruleId)
115
+ continue;
116
+ const ruleId = m.ruleId.startsWith('sonarjs/') ? m.ruleId : `sonarjs/${m.ruleId}`;
117
+ const meta = (0, sonar_rule_map_1.mapSonarJSRule)(ruleId);
118
+ const span = {
119
+ line: m.line,
120
+ column: m.column,
121
+ endLine: m.endLine ?? m.line,
122
+ endColumn: m.endColumn ?? m.column,
123
+ };
124
+ out.push({
125
+ type: `sonarjs_${ruleId.replace('sonarjs/', '')}`,
126
+ ruleId,
127
+ severity: meta.severity,
128
+ category: meta.category,
129
+ message: m.message,
130
+ line: m.line,
131
+ span,
132
+ });
133
+ }
134
+ return out;
135
+ }
136
+ //# sourceMappingURL=sonar-eslint-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonar-eslint-runner.js","sourceRoot":"","sources":["../../src/analyzer/sonar-eslint-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { ViolationCategory } from '../types';
2
+ export interface SonarRuleMeta {
3
+ severity: 'error' | 'warning' | 'info';
4
+ category: ViolationCategory;
5
+ deduction: number;
6
+ description: string;
7
+ }
8
+ export declare function mapSonarJSRule(fullRuleId: string): SonarRuleMeta;
9
+ export declare function mapSonarCSCategory(ruleId: string, tags: readonly string[]): ViolationCategory;
10
+ export declare const SONARJS_RULE_LIST: {
11
+ ruleId: string;
12
+ severity: "error" | "warning" | "info";
13
+ deduction: number;
14
+ category: ViolationCategory;
15
+ description: string;
16
+ fixable: boolean;
17
+ source: "sonarjs";
18
+ }[];
19
+ //# sourceMappingURL=sonar-rule-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonar-rule-map.d.ts","sourceRoot":"","sources":["../../src/analyzer/sonar-rule-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAuCD,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAGhE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CAQ7F;AAED,eAAO,MAAM,iBAAiB;;;;;;;;GAQ3B,CAAC"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SONARJS_RULE_LIST = void 0;
4
+ exports.mapSonarJSRule = mapSonarJSRule;
5
+ exports.mapSonarCSCategory = mapSonarCSCategory;
6
+ const DEFAULT_META = {
7
+ severity: 'info',
8
+ category: 'code_smell',
9
+ deduction: 0.1,
10
+ description: 'SonarJS code smell',
11
+ };
12
+ const SONARJS_RULES = {
13
+ 'no-all-duplicated-branches': { severity: 'error', category: 'bug', deduction: 1.5, description: 'All branches in a conditional are identical' },
14
+ 'no-element-overwrite': { severity: 'error', category: 'bug', deduction: 1.5, description: 'Collection element overwritten without read' },
15
+ 'no-empty-collection': { severity: 'warning', category: 'bug', deduction: 0.5, description: 'Iteration over an empty collection' },
16
+ 'no-extra-arguments': { severity: 'error', category: 'bug', deduction: 1.5, description: 'Function called with extra arguments' },
17
+ 'no-identical-conditions': { severity: 'error', category: 'bug', deduction: 1.5, description: 'Identical conditions in if/else chain' },
18
+ 'no-identical-expressions': { severity: 'error', category: 'bug', deduction: 1.5, description: 'Identical sub-expressions on both sides of operator' },
19
+ 'no-ignored-return': { severity: 'warning', category: 'bug', deduction: 0.5, description: 'Return value of a pure function is ignored' },
20
+ 'no-one-iteration-loop': { severity: 'error', category: 'bug', deduction: 1.5, description: 'Loop only executes once' },
21
+ 'no-use-of-empty-return-value': { severity: 'warning', category: 'bug', deduction: 0.5, description: 'Use of return value from a function that returns nothing' },
22
+ 'no-redundant-jump': { severity: 'warning', category: 'code_smell', deduction: 0.5, description: 'Redundant jump statement (continue/return at end of block)' },
23
+ 'cognitive-complexity': { severity: 'warning', category: 'code_smell', deduction: 0.5, description: 'Function cognitive complexity is too high' },
24
+ 'no-duplicate-string': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'String literal duplicated multiple times — extract to a constant' },
25
+ 'no-identical-functions': { severity: 'warning', category: 'code_smell', deduction: 0.5, description: 'Identical function bodies — extract a shared helper' },
26
+ 'prefer-immediate-return': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'Local variable assigned only to be returned' },
27
+ 'no-collapsible-if': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'Nested if can be collapsed into a single condition' },
28
+ 'no-nested-template-literals': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'Nested template literals harm readability' },
29
+ 'no-small-switch': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'Switch with fewer than 3 cases — use if/else' },
30
+ 'no-useless-catch': { severity: 'warning', category: 'code_smell', deduction: 0.5, description: 'Catch that only rethrows is useless' },
31
+ 'prefer-single-boolean-return': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'if (cond) return true; else return false; — return cond directly' },
32
+ 'no-inverted-boolean-check': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'Inverted boolean check — invert the condition instead' },
33
+ 'no-redundant-boolean': { severity: 'info', category: 'code_smell', deduction: 0.1, description: 'Boolean literal compared with === true / === false' },
34
+ 'no-unused-collection': { severity: 'warning', category: 'code_smell', deduction: 0.5, description: 'Collection written but never read' },
35
+ 'no-hardcoded-credentials': { severity: 'error', category: 'vulnerability', deduction: 1.5, description: 'Hardcoded credentials are a security risk' },
36
+ 'no-hardcoded-passwords': { severity: 'error', category: 'vulnerability', deduction: 1.5, description: 'Hardcoded passwords are a security risk' },
37
+ 'no-os-command-from-path': { severity: 'warning', category: 'hotspot', deduction: 0.5, description: 'Running an OS command resolved from PATH is risky' },
38
+ 'pseudo-random': { severity: 'warning', category: 'hotspot', deduction: 0.5, description: 'Math.random() is not cryptographically secure' },
39
+ 'no-clear-text-protocols': { severity: 'warning', category: 'hotspot', deduction: 0.5, description: 'Avoid plaintext network protocols (HTTP, FTP, …)' },
40
+ };
41
+ function mapSonarJSRule(fullRuleId) {
42
+ const shortName = fullRuleId.replace(/^sonarjs\//, '');
43
+ return SONARJS_RULES[shortName] ?? DEFAULT_META;
44
+ }
45
+ function mapSonarCSCategory(ruleId, tags) {
46
+ const upper = tags.map(t => t.toLowerCase());
47
+ if (upper.includes('vulnerability'))
48
+ return 'vulnerability';
49
+ if (upper.includes('security-hotspot') || upper.includes('hotspot'))
50
+ return 'hotspot';
51
+ if (upper.includes('bug') || upper.includes('reliability'))
52
+ return 'bug';
53
+ const knownBugs = new Set(['S2259', 'S2583', 'S3923', 'S2589', 'S1764', 'S2222']);
54
+ if (knownBugs.has(ruleId))
55
+ return 'bug';
56
+ return 'code_smell';
57
+ }
58
+ exports.SONARJS_RULE_LIST = Object.entries(SONARJS_RULES).map(([name, meta]) => ({
59
+ ruleId: `sonarjs/${name}`,
60
+ severity: meta.severity,
61
+ deduction: meta.deduction,
62
+ category: meta.category,
63
+ description: meta.description,
64
+ fixable: false,
65
+ source: 'sonarjs',
66
+ }));
67
+ //# sourceMappingURL=sonar-rule-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonar-rule-map.js","sourceRoot":"","sources":["../../src/analyzer/sonar-rule-map.ts"],"names":[],"mappings":";;;AA8CA,wCAGC;AAED,gDAQC;AAlDD,MAAM,YAAY,GAAkB;IAClC,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,YAAY;IACtB,SAAS,EAAE,GAAG;IACd,WAAW,EAAE,oBAAoB;CAClC,CAAC;AAEF,MAAM,aAAa,GAAkC;IACnD,4BAA4B,EAAI,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,6CAA6C,EAAE;IAC9J,sBAAsB,EAAU,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,6CAA6C,EAAE;IAC9J,qBAAqB,EAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,oCAAoC,EAAE;IACrJ,oBAAoB,EAAY,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,sCAAsC,EAAE;IACvJ,yBAAyB,EAAO,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,uCAAuC,EAAE;IACxJ,0BAA0B,EAAM,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,qDAAqD,EAAE;IACtK,mBAAmB,EAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,4CAA4C,EAAE;IAC7J,uBAAuB,EAAS,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,yBAAyB,EAAE;IAC1I,8BAA8B,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAY,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,0DAA0D,EAAE;IAC3K,mBAAmB,EAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,4DAA4D,EAAE;IAC7K,sBAAsB,EAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,2CAA2C,EAAE;IAC5J,qBAAqB,EAAW,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,kEAAkE,EAAE;IACnL,wBAAwB,EAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,qDAAqD,EAAE;IACtK,yBAAyB,EAAO,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,6CAA6C,EAAE;IAC9J,mBAAmB,EAAa,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,oDAAoD,EAAE;IACrK,6BAA6B,EAAG,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,2CAA2C,EAAE;IAC5J,iBAAiB,EAAe,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,8CAA8C,EAAE;IAC/J,kBAAkB,EAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,qCAAqC,EAAE;IACtJ,8BAA8B,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,kEAAkE,EAAE;IACnL,2BAA2B,EAAK,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,uDAAuD,EAAE;IACxK,sBAAsB,EAAU,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,oDAAoD,EAAE;IACrK,sBAAsB,EAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAK,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,mCAAmC,EAAE;IACpJ,0BAA0B,EAAM,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,2CAA2C,EAAE;IAC5J,wBAAwB,EAAQ,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,yCAAyC,EAAE;IAC1J,yBAAyB,EAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAQ,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,mDAAmD,EAAE;IACpK,eAAe,EAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAQ,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,+CAA+C,EAAE;IAChK,yBAAyB,EAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAQ,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,kDAAkD,EAAE;CACpK,CAAC;AAEF,SAAgB,cAAc,CAAC,UAAkB;IAC/C,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,aAAa,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC;AAClD,CAAC;AAED,SAAgB,kBAAkB,CAAC,MAAc,EAAE,IAAuB;IACxE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,eAAe,CAAC;IAC5D,IAAI,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IACtF,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAClF,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,YAAY,CAAC;AACtB,CAAC;AAEY,QAAA,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,EAAE,WAAW,IAAI,EAAE;IACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;IACvB,SAAS,EAAE,IAAI,CAAC,SAAS;IACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;IACvB,WAAW,EAAE,IAAI,CAAC,WAAW;IAC7B,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,SAAkB;CAC3B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * In-memory code analysis using the TypeScript Compiler API.
3
+ * Analyzes code strings (not files on disk) — used by the MCP server's
4
+ * `analyze_code` tool to evaluate snippets before they touch the filesystem.
5
+ */
6
+ import { Dependency, Metrics, Violation, Language } from '../types';
7
+ export interface StringAnalysisResult {
8
+ language: Language;
9
+ violations: Violation[];
10
+ metrics: Metrics;
11
+ dependencies: Dependency[];
12
+ rating: number;
13
+ }
14
+ export declare class StringAnalyzer {
15
+ private ratingCalc;
16
+ analyze(code: string, language: Language): StringAnalysisResult;
17
+ private analyzeTypeScriptString;
18
+ private analyzeCSharpString;
19
+ private extractDependencies;
20
+ private calculateMetrics;
21
+ private detectTypeScriptViolations;
22
+ private detectReactViolations;
23
+ private bodyContainsJSX;
24
+ private bodyHasKeyProp;
25
+ private detectTodoPlaceholders;
26
+ }
27
+ //# sourceMappingURL=string-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/string-analyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAA0B;IAE5C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,oBAAoB;IAS/D,OAAO,CAAC,uBAAuB;IAsB/B,OAAO,CAAC,mBAAmB;IAmF3B,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,0BAA0B;IAyBlC,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,sBAAsB;CA4C/B"}