mcp-react-toolkit 1.0.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 (228) hide show
  1. package/CONTRIBUTING.md +157 -0
  2. package/HOW_IT_WORKS.md +270 -0
  3. package/README.md +259 -0
  4. package/demo/legacy-app/src/App.jsx +12 -0
  5. package/demo/legacy-app/src/components/Dashboard.jsx +51 -0
  6. package/demo/legacy-app/src/components/UserCard.jsx +32 -0
  7. package/demo/legacy-app/src/hooks/useUsers.js +38 -0
  8. package/demo/legacy-app/src/utils/api.js +30 -0
  9. package/glama.json +4 -0
  10. package/package.json +39 -0
  11. package/tools/accessibility-checker/build/index.d.ts +3 -0
  12. package/tools/accessibility-checker/build/index.d.ts.map +1 -0
  13. package/tools/accessibility-checker/build/index.js +112 -0
  14. package/tools/accessibility-checker/build/index.js.map +1 -0
  15. package/tools/accessibility-checker/build/rules.d.ts +22 -0
  16. package/tools/accessibility-checker/build/rules.d.ts.map +1 -0
  17. package/tools/accessibility-checker/build/rules.js +244 -0
  18. package/tools/accessibility-checker/build/rules.js.map +1 -0
  19. package/tools/accessibility-checker/build/rules.test.d.ts +2 -0
  20. package/tools/accessibility-checker/build/rules.test.d.ts.map +1 -0
  21. package/tools/accessibility-checker/build/rules.test.js.map +1 -0
  22. package/tools/accessibility-checker/package.json +20 -0
  23. package/tools/code-modernizer/build/index.d.ts +3 -0
  24. package/tools/code-modernizer/build/index.d.ts.map +1 -0
  25. package/tools/code-modernizer/build/index.js +58 -0
  26. package/tools/code-modernizer/build/index.js.map +1 -0
  27. package/tools/code-modernizer/build/tools/01-convert-to-typescript.d.ts +3 -0
  28. package/tools/code-modernizer/build/tools/01-convert-to-typescript.d.ts.map +1 -0
  29. package/tools/code-modernizer/build/tools/01-convert-to-typescript.js +110 -0
  30. package/tools/code-modernizer/build/tools/01-convert-to-typescript.js.map +1 -0
  31. package/tools/code-modernizer/build/types.d.ts +57 -0
  32. package/tools/code-modernizer/build/types.d.ts.map +1 -0
  33. package/tools/code-modernizer/build/types.js +5 -0
  34. package/tools/code-modernizer/build/types.js.map +1 -0
  35. package/tools/code-modernizer/build/utils/ast-parser.d.ts +6 -0
  36. package/tools/code-modernizer/build/utils/ast-parser.d.ts.map +1 -0
  37. package/tools/code-modernizer/build/utils/ast-parser.js +177 -0
  38. package/tools/code-modernizer/build/utils/ast-parser.js.map +1 -0
  39. package/tools/code-modernizer/build/utils/file-ops.d.ts +8 -0
  40. package/tools/code-modernizer/build/utils/file-ops.d.ts.map +1 -0
  41. package/tools/code-modernizer/build/utils/file-ops.js +63 -0
  42. package/tools/code-modernizer/build/utils/file-ops.js.map +1 -0
  43. package/tools/code-modernizer/build/utils/file-ops.test.d.ts +2 -0
  44. package/tools/code-modernizer/build/utils/file-ops.test.d.ts.map +1 -0
  45. package/tools/code-modernizer/build/utils/file-ops.test.js.map +1 -0
  46. package/tools/code-modernizer/build/utils/type-generator.d.ts +4 -0
  47. package/tools/code-modernizer/build/utils/type-generator.d.ts.map +1 -0
  48. package/tools/code-modernizer/build/utils/type-generator.js +37 -0
  49. package/tools/code-modernizer/build/utils/type-generator.js.map +1 -0
  50. package/tools/code-modernizer/package.json +23 -0
  51. package/tools/component-factory/build/index.d.ts +3 -0
  52. package/tools/component-factory/build/index.d.ts.map +1 -0
  53. package/tools/component-factory/build/index.js +534 -0
  54. package/tools/component-factory/build/index.js.map +1 -0
  55. package/tools/component-factory/build/utils.d.ts +6 -0
  56. package/tools/component-factory/build/utils.d.ts.map +1 -0
  57. package/tools/component-factory/build/utils.js +11 -0
  58. package/tools/component-factory/build/utils.js.map +1 -0
  59. package/tools/component-factory/build/utils.test.d.ts +2 -0
  60. package/tools/component-factory/build/utils.test.d.ts.map +1 -0
  61. package/tools/component-factory/build/utils.test.js.map +1 -0
  62. package/tools/component-factory/package.json +20 -0
  63. package/tools/component-factory/templates/accordion.tsx +57 -0
  64. package/tools/component-factory/templates/alert.tsx +59 -0
  65. package/tools/component-factory/templates/aspect-ratio.tsx +8 -0
  66. package/tools/component-factory/templates/avatar.tsx +51 -0
  67. package/tools/component-factory/templates/badge.tsx +37 -0
  68. package/tools/component-factory/templates/breadcrumb.tsx +116 -0
  69. package/tools/component-factory/templates/button.tsx +57 -0
  70. package/tools/component-factory/templates/calendar.tsx +66 -0
  71. package/tools/component-factory/templates/card.tsx +80 -0
  72. package/tools/component-factory/templates/checkbox.tsx +31 -0
  73. package/tools/component-factory/templates/collapsible.tsx +11 -0
  74. package/tools/component-factory/templates/command.tsx +150 -0
  75. package/tools/component-factory/templates/context-menu.tsx +199 -0
  76. package/tools/component-factory/templates/dialog.tsx +123 -0
  77. package/tools/component-factory/templates/drawer.tsx +118 -0
  78. package/tools/component-factory/templates/dropdown-menu.tsx +201 -0
  79. package/tools/component-factory/templates/form.tsx +178 -0
  80. package/tools/component-factory/templates/hover-card.tsx +29 -0
  81. package/tools/component-factory/templates/input-otp.tsx +71 -0
  82. package/tools/component-factory/templates/input.tsx +23 -0
  83. package/tools/component-factory/templates/label.tsx +27 -0
  84. package/tools/component-factory/templates/menubar.tsx +236 -0
  85. package/tools/component-factory/templates/navigation-menu.tsx +128 -0
  86. package/tools/component-factory/templates/pagination.tsx +120 -0
  87. package/tools/component-factory/templates/popover.tsx +31 -0
  88. package/tools/component-factory/templates/progress.tsx +28 -0
  89. package/tools/component-factory/templates/radio-group.tsx +44 -0
  90. package/tools/component-factory/templates/scroll-area.tsx +48 -0
  91. package/tools/component-factory/templates/select.tsx +159 -0
  92. package/tools/component-factory/templates/separator.tsx +32 -0
  93. package/tools/component-factory/templates/sheet.tsx +140 -0
  94. package/tools/component-factory/templates/skeleton.tsx +15 -0
  95. package/tools/component-factory/templates/slider.tsx +28 -0
  96. package/tools/component-factory/templates/sonner.tsx +31 -0
  97. package/tools/component-factory/templates/switch.tsx +29 -0
  98. package/tools/component-factory/templates/table.tsx +117 -0
  99. package/tools/component-factory/templates/tabs.tsx +56 -0
  100. package/tools/component-factory/templates/textarea.tsx +22 -0
  101. package/tools/component-factory/templates/toggle-group.tsx +61 -0
  102. package/tools/component-factory/templates/toggle.tsx +45 -0
  103. package/tools/component-factory/templates/tooltip.tsx +30 -0
  104. package/tools/dep-auditor/build/index.d.ts +18 -0
  105. package/tools/dep-auditor/build/index.d.ts.map +1 -0
  106. package/tools/dep-auditor/build/index.js +247 -0
  107. package/tools/dep-auditor/build/index.js.map +1 -0
  108. package/tools/dep-auditor/build/index.test.d.ts +2 -0
  109. package/tools/dep-auditor/build/index.test.d.ts.map +1 -0
  110. package/tools/dep-auditor/build/index.test.js.map +1 -0
  111. package/tools/dep-auditor/package.json +20 -0
  112. package/tools/generate-tests/build/analyzer.d.ts +31 -0
  113. package/tools/generate-tests/build/analyzer.d.ts.map +1 -0
  114. package/tools/generate-tests/build/analyzer.js +105 -0
  115. package/tools/generate-tests/build/analyzer.js.map +1 -0
  116. package/tools/generate-tests/build/analyzer.test.d.ts +2 -0
  117. package/tools/generate-tests/build/analyzer.test.d.ts.map +1 -0
  118. package/tools/generate-tests/build/analyzer.test.js.map +1 -0
  119. package/tools/generate-tests/build/generators.d.ts +6 -0
  120. package/tools/generate-tests/build/generators.d.ts.map +1 -0
  121. package/tools/generate-tests/build/generators.js +161 -0
  122. package/tools/generate-tests/build/generators.js.map +1 -0
  123. package/tools/generate-tests/build/index.d.ts +3 -0
  124. package/tools/generate-tests/build/index.d.ts.map +1 -0
  125. package/tools/generate-tests/build/index.js +148 -0
  126. package/tools/generate-tests/build/index.js.map +1 -0
  127. package/tools/generate-tests/package.json +20 -0
  128. package/tools/json-viewer/build/index.d.ts +3 -0
  129. package/tools/json-viewer/build/index.d.ts.map +1 -0
  130. package/tools/json-viewer/build/index.js +282 -0
  131. package/tools/json-viewer/build/index.js.map +1 -0
  132. package/tools/json-viewer/build/utils.d.ts +5 -0
  133. package/tools/json-viewer/build/utils.d.ts.map +1 -0
  134. package/tools/json-viewer/build/utils.js +40 -0
  135. package/tools/json-viewer/build/utils.js.map +1 -0
  136. package/tools/json-viewer/build/utils.test.d.ts +2 -0
  137. package/tools/json-viewer/build/utils.test.d.ts.map +1 -0
  138. package/tools/json-viewer/build/utils.test.js.map +1 -0
  139. package/tools/json-viewer/package.json +20 -0
  140. package/tools/monorepo-manager/build/index.d.ts +3 -0
  141. package/tools/monorepo-manager/build/index.d.ts.map +1 -0
  142. package/tools/monorepo-manager/build/index.js +318 -0
  143. package/tools/monorepo-manager/build/index.js.map +1 -0
  144. package/tools/monorepo-manager/build/types.d.ts +17 -0
  145. package/tools/monorepo-manager/build/types.d.ts.map +1 -0
  146. package/tools/monorepo-manager/build/types.js +2 -0
  147. package/tools/monorepo-manager/build/types.js.map +1 -0
  148. package/tools/monorepo-manager/build/utils.d.ts +9 -0
  149. package/tools/monorepo-manager/build/utils.d.ts.map +1 -0
  150. package/tools/monorepo-manager/build/utils.js +135 -0
  151. package/tools/monorepo-manager/build/utils.js.map +1 -0
  152. package/tools/monorepo-manager/build/utils.test.d.ts +2 -0
  153. package/tools/monorepo-manager/build/utils.test.d.ts.map +1 -0
  154. package/tools/monorepo-manager/build/utils.test.js.map +1 -0
  155. package/tools/monorepo-manager/package.json +20 -0
  156. package/tools/quality-pipeline/build/index.d.ts +3 -0
  157. package/tools/quality-pipeline/build/index.d.ts.map +1 -0
  158. package/tools/quality-pipeline/build/index.js +538 -0
  159. package/tools/quality-pipeline/build/index.js.map +1 -0
  160. package/tools/quality-pipeline/build/utils.d.ts +9 -0
  161. package/tools/quality-pipeline/build/utils.d.ts.map +1 -0
  162. package/tools/quality-pipeline/build/utils.js +15 -0
  163. package/tools/quality-pipeline/build/utils.js.map +1 -0
  164. package/tools/quality-pipeline/build/utils.test.d.ts +2 -0
  165. package/tools/quality-pipeline/build/utils.test.d.ts.map +1 -0
  166. package/tools/quality-pipeline/build/utils.test.js.map +1 -0
  167. package/tools/quality-pipeline/package.json +20 -0
  168. package/tools/shared/build/McpServerBase.d.ts +18 -0
  169. package/tools/shared/build/McpServerBase.d.ts.map +1 -0
  170. package/tools/shared/build/McpServerBase.js +74 -0
  171. package/tools/shared/build/McpServerBase.js.map +1 -0
  172. package/tools/shared/build/ToolRegistry.d.ts +9 -0
  173. package/tools/shared/build/ToolRegistry.d.ts.map +1 -0
  174. package/tools/shared/build/ToolRegistry.js +22 -0
  175. package/tools/shared/build/ToolRegistry.js.map +1 -0
  176. package/tools/shared/build/index.d.ts +4 -0
  177. package/tools/shared/build/index.d.ts.map +1 -0
  178. package/tools/shared/build/index.js +4 -0
  179. package/tools/shared/build/index.js.map +1 -0
  180. package/tools/shared/build/types.d.ts +36 -0
  181. package/tools/shared/build/types.d.ts.map +1 -0
  182. package/tools/shared/build/types.js +5 -0
  183. package/tools/shared/build/types.js.map +1 -0
  184. package/tools/shared/package.json +23 -0
  185. package/tools/typescript-enforcer/build/index.d.ts +3 -0
  186. package/tools/typescript-enforcer/build/index.d.ts.map +1 -0
  187. package/tools/typescript-enforcer/build/index.js +155 -0
  188. package/tools/typescript-enforcer/build/index.js.map +1 -0
  189. package/tools/typescript-enforcer/build/rules/branded-types.d.ts +3 -0
  190. package/tools/typescript-enforcer/build/rules/branded-types.d.ts.map +1 -0
  191. package/tools/typescript-enforcer/build/rules/branded-types.js +4 -0
  192. package/tools/typescript-enforcer/build/rules/branded-types.js.map +1 -0
  193. package/tools/typescript-enforcer/build/rules/discriminated-unions.d.ts +3 -0
  194. package/tools/typescript-enforcer/build/rules/discriminated-unions.d.ts.map +1 -0
  195. package/tools/typescript-enforcer/build/rules/discriminated-unions.js +4 -0
  196. package/tools/typescript-enforcer/build/rules/discriminated-unions.js.map +1 -0
  197. package/tools/typescript-enforcer/build/rules/generics.d.ts +3 -0
  198. package/tools/typescript-enforcer/build/rules/generics.d.ts.map +1 -0
  199. package/tools/typescript-enforcer/build/rules/generics.js +182 -0
  200. package/tools/typescript-enforcer/build/rules/generics.js.map +1 -0
  201. package/tools/typescript-enforcer/build/rules/modifiers.d.ts +3 -0
  202. package/tools/typescript-enforcer/build/rules/modifiers.d.ts.map +1 -0
  203. package/tools/typescript-enforcer/build/rules/modifiers.js +214 -0
  204. package/tools/typescript-enforcer/build/rules/modifiers.js.map +1 -0
  205. package/tools/typescript-enforcer/build/rules/no-any.d.ts +3 -0
  206. package/tools/typescript-enforcer/build/rules/no-any.d.ts.map +1 -0
  207. package/tools/typescript-enforcer/build/rules/no-any.js +138 -0
  208. package/tools/typescript-enforcer/build/rules/no-any.js.map +1 -0
  209. package/tools/typescript-enforcer/build/rules/type-guards.d.ts +3 -0
  210. package/tools/typescript-enforcer/build/rules/type-guards.d.ts.map +1 -0
  211. package/tools/typescript-enforcer/build/rules/type-guards.js +176 -0
  212. package/tools/typescript-enforcer/build/rules/type-guards.js.map +1 -0
  213. package/tools/typescript-enforcer/build/rules/utility-types.d.ts +3 -0
  214. package/tools/typescript-enforcer/build/rules/utility-types.d.ts.map +1 -0
  215. package/tools/typescript-enforcer/build/rules/utility-types.js +101 -0
  216. package/tools/typescript-enforcer/build/rules/utility-types.js.map +1 -0
  217. package/tools/typescript-enforcer/build/scanner.d.ts +4 -0
  218. package/tools/typescript-enforcer/build/scanner.d.ts.map +1 -0
  219. package/tools/typescript-enforcer/build/scanner.js +114 -0
  220. package/tools/typescript-enforcer/build/scanner.js.map +1 -0
  221. package/tools/typescript-enforcer/build/scanner.test.d.ts +2 -0
  222. package/tools/typescript-enforcer/build/scanner.test.d.ts.map +1 -0
  223. package/tools/typescript-enforcer/build/scanner.test.js.map +1 -0
  224. package/tools/typescript-enforcer/build/types.d.ts +55 -0
  225. package/tools/typescript-enforcer/build/types.d.ts.map +1 -0
  226. package/tools/typescript-enforcer/build/types.js +2 -0
  227. package/tools/typescript-enforcer/build/types.js.map +1 -0
  228. package/tools/typescript-enforcer/package.json +20 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@mcp-showcase/monorepo-manager",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./build/index.js",
6
+ "scripts": {
7
+ "build": "tsc && chmod +x build/index.js",
8
+ "dev": "tsc --watch",
9
+ "test": "vitest run"
10
+ },
11
+ "dependencies": {
12
+ "@mcp-showcase/shared": "*",
13
+ "@modelcontextprotocol/sdk": "^1.12.0"
14
+ },
15
+ "devDependencies": {
16
+ "@types/node": "^20.0.0",
17
+ "typescript": "^5.0.0",
18
+ "vitest": "^2.0.0"
19
+ }
20
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,538 @@
1
+ #!/usr/bin/env node
2
+ import { McpServerBase } from '@mcp-showcase/shared';
3
+ import { execSync } from 'child_process';
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+ import * as os from 'os';
7
+ import { calculateGrade } from './utils.js';
8
+ // ============================================================================
9
+ // HELPERS
10
+ // ============================================================================
11
+ function scanDirectory(dir, exts, skipDirs = ['node_modules', 'build', 'dist', '.next', '.turbo', 'coverage']) {
12
+ const files = [];
13
+ if (!fs.existsSync(dir))
14
+ return files;
15
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
16
+ for (const entry of entries) {
17
+ const fullPath = path.join(dir, entry.name);
18
+ if (entry.isDirectory()) {
19
+ if (skipDirs.includes(entry.name))
20
+ continue;
21
+ files.push(...scanDirectory(fullPath, exts, skipDirs));
22
+ }
23
+ else if (exts.some(e => entry.name.endsWith(e))) {
24
+ files.push(fullPath);
25
+ }
26
+ }
27
+ return files;
28
+ }
29
+ /** Read a source file, skipping generated/test/stories files */
30
+ function readSourceFiles(dir, exts) {
31
+ return scanDirectory(dir, exts)
32
+ .filter(f => !f.includes('.test.') && !f.includes('.spec.') && !f.includes('.stories.') && !f.includes('__tests__'))
33
+ .map(file => {
34
+ const content = fs.readFileSync(file, 'utf-8');
35
+ return { file, content, lines: content.split('\n') };
36
+ });
37
+ }
38
+ // ============================================================================
39
+ // STAGE: TESTS
40
+ // ============================================================================
41
+ function runTestStage(projectRoot) {
42
+ const start = Date.now();
43
+ const hasVitest = fs.existsSync(path.join(projectRoot, 'vitest.config.ts'))
44
+ || fs.existsSync(path.join(projectRoot, 'vitest.config.js'));
45
+ const hasJest = fs.existsSync(path.join(projectRoot, 'jest.config.js'))
46
+ || fs.existsSync(path.join(projectRoot, 'jest.config.ts'));
47
+ if (!hasVitest && !hasJest) {
48
+ // Check package.json test script
49
+ const pkgPath = path.join(projectRoot, 'package.json');
50
+ if (!fs.existsSync(pkgPath)) {
51
+ return { name: 'Tests', status: 'skip', duration: 0, summary: 'No test runner found', details: {} };
52
+ }
53
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
54
+ if (!pkg.scripts?.test) {
55
+ return { name: 'Tests', status: 'skip', duration: 0, summary: 'No test script in package.json', details: {} };
56
+ }
57
+ }
58
+ try {
59
+ if (hasVitest) {
60
+ // Vitest JSON reporter writes to a file — use --outputFile
61
+ const outFile = path.join(os.tmpdir(), `vitest-result-${Date.now()}.json`);
62
+ try {
63
+ execSync(`npx vitest run --reporter=json --outputFile=${outFile}`, { cwd: projectRoot, encoding: 'utf-8', timeout: 120000, stdio: 'pipe' });
64
+ }
65
+ catch {
66
+ // vitest exits non-zero when tests fail — that's fine, result file still written
67
+ }
68
+ if (fs.existsSync(outFile)) {
69
+ const data = JSON.parse(fs.readFileSync(outFile, 'utf-8'));
70
+ fs.unlinkSync(outFile);
71
+ const passed = data.numPassedTests ?? 0;
72
+ const failed = data.numFailedTests ?? 0;
73
+ const skipped = data.numPendingTests ?? 0;
74
+ return {
75
+ name: 'Tests',
76
+ status: failed > 0 ? 'fail' : 'pass',
77
+ duration: Date.now() - start,
78
+ summary: `${passed} passed, ${failed} failed${skipped ? `, ${skipped} skipped` : ''}`,
79
+ details: { passed, failed, skipped, runner: 'vitest' },
80
+ };
81
+ }
82
+ // fallback: parse vitest verbose text output
83
+ const output = execSync(`npx vitest run 2>&1 || true`, { cwd: projectRoot, encoding: 'utf-8', timeout: 120000 });
84
+ const passMatch = output.match(/(\d+)\s+passed/);
85
+ const failMatch = output.match(/(\d+)\s+failed/);
86
+ const passed = passMatch ? parseInt(passMatch[1]) : 0;
87
+ const failed = failMatch ? parseInt(failMatch[1]) : 0;
88
+ return {
89
+ name: 'Tests',
90
+ status: failed > 0 ? 'fail' : passed > 0 ? 'pass' : 'warn',
91
+ duration: Date.now() - start,
92
+ summary: passed + failed > 0 ? `${passed} passed, ${failed} failed` : 'Could not parse test output',
93
+ details: { passed, failed, runner: 'vitest' },
94
+ };
95
+ }
96
+ if (hasJest) {
97
+ const output = execSync(`npx jest --json 2>&1 || true`, { cwd: projectRoot, encoding: 'utf-8', timeout: 120000, maxBuffer: 20 * 1024 * 1024 });
98
+ const jsonStart = output.indexOf('{');
99
+ if (jsonStart !== -1) {
100
+ try {
101
+ const data = JSON.parse(output.slice(jsonStart));
102
+ const passed = data.numPassedTests ?? 0;
103
+ const failed = data.numFailedTests ?? 0;
104
+ return {
105
+ name: 'Tests',
106
+ status: failed > 0 ? 'fail' : 'pass',
107
+ duration: Date.now() - start,
108
+ summary: `${passed} passed, ${failed} failed`,
109
+ details: { passed, failed, runner: 'jest' },
110
+ };
111
+ }
112
+ catch { /* fall through */ }
113
+ }
114
+ }
115
+ return { name: 'Tests', status: 'warn', duration: Date.now() - start, summary: 'Test output could not be parsed', details: {} };
116
+ }
117
+ catch (error) {
118
+ return {
119
+ name: 'Tests',
120
+ status: 'fail',
121
+ duration: Date.now() - start,
122
+ summary: `Test execution error: ${error instanceof Error ? error.message.slice(0, 120) : String(error)}`,
123
+ details: { error: true },
124
+ };
125
+ }
126
+ }
127
+ // ============================================================================
128
+ // STAGE: PERFORMANCE
129
+ // ============================================================================
130
+ const HEAVY_IMPORTS = {
131
+ 'moment': '~300KB — use date-fns or dayjs instead',
132
+ 'lodash': '~70KB — import specific methods or use native JS',
133
+ 'jquery': '~90KB — use native DOM APIs',
134
+ 'underscore': '~60KB — use native JS',
135
+ 'ramda': '~50KB — use native JS',
136
+ 'rxjs': '~100KB — use if already in deps, avoid adding fresh',
137
+ 'immutable': '~60KB — use structuredClone or immer',
138
+ 'ant-design': 'Very large — ensure tree-shaking is configured',
139
+ '@material-ui/core': 'Large — ensure tree-shaking is configured',
140
+ 'xlsx': '~800KB — consider server-side or async chunk',
141
+ 'pdfjs-dist': 'Large — always lazy-load',
142
+ 'three': 'Very large — always lazy-load',
143
+ };
144
+ function runPerformanceStage(projectRoot) {
145
+ const start = Date.now();
146
+ try {
147
+ const sources = readSourceFiles(projectRoot, ['.ts', '.tsx', '.js', '.jsx']);
148
+ const heavyImports = [];
149
+ const memoryLeaks = [];
150
+ const consoleLogs = [];
151
+ const largeFunctions = [];
152
+ for (const { file, content, lines } of sources) {
153
+ const rel = path.relative(projectRoot, file);
154
+ // Heavy imports
155
+ for (const [lib, advice] of Object.entries(HEAVY_IMPORTS)) {
156
+ if (new RegExp(`from ['"]${lib}['"]`).test(content) ||
157
+ new RegExp(`require\\(['"]${lib}['"]\\)`).test(content)) {
158
+ heavyImports.push({ file: rel, lib, advice });
159
+ }
160
+ }
161
+ // Memory leaks: scan full useEffect block (up to 50 lines)
162
+ for (let i = 0; i < lines.length; i++) {
163
+ if (/useEffect\s*\(/.test(lines[i])) {
164
+ const block = lines.slice(i, Math.min(i + 50, lines.length)).join('\n');
165
+ if (/addEventListener/.test(block) && !/removeEventListener/.test(block)) {
166
+ memoryLeaks.push({ file: rel, line: i + 1, type: 'missing removeEventListener' });
167
+ }
168
+ if (/setInterval/.test(block) && !/clearInterval/.test(block)) {
169
+ memoryLeaks.push({ file: rel, line: i + 1, type: 'missing clearInterval' });
170
+ }
171
+ if (/setTimeout/.test(block) && !/clearTimeout/.test(block) && /\[/.test(block)) {
172
+ // Only flag if there's a dependency array (re-runs on change)
173
+ memoryLeaks.push({ file: rel, line: i + 1, type: 'possible clearTimeout missing' });
174
+ }
175
+ }
176
+ // console.log/debug (not in test files, already filtered)
177
+ if (/console\.(log|debug|info)\s*\(/.test(lines[i])) {
178
+ consoleLogs.push({ file: rel, line: i + 1 });
179
+ }
180
+ }
181
+ // Large functions (>60 lines between function declaration and closing)
182
+ const funcMatches = [...content.matchAll(/\n(export\s+)?(async\s+)?function\s+\w+/g)];
183
+ for (const match of funcMatches) {
184
+ const lineNum = content.slice(0, match.index).split('\n').length;
185
+ let depth = 0, end = match.index ?? 0;
186
+ for (let j = match.index ?? 0; j < content.length; j++) {
187
+ if (content[j] === '{')
188
+ depth++;
189
+ else if (content[j] === '}') {
190
+ depth--;
191
+ if (depth === 0) {
192
+ end = j;
193
+ break;
194
+ }
195
+ }
196
+ }
197
+ const funcLines = content.slice(match.index ?? 0, end).split('\n').length;
198
+ if (funcLines > 60)
199
+ largeFunctions.push({ file: rel, line: lineNum, lines: funcLines });
200
+ }
201
+ }
202
+ const critical = heavyImports.length + memoryLeaks.length;
203
+ const warnings = consoleLogs.length + largeFunctions.length;
204
+ return {
205
+ name: 'Performance',
206
+ status: critical > 0 ? 'fail' : warnings > 5 ? 'warn' : 'pass',
207
+ duration: Date.now() - start,
208
+ summary: `${critical} critical issues, ${warnings} warnings across ${sources.length} files`,
209
+ details: {
210
+ filesScanned: sources.length,
211
+ heavyImports,
212
+ memoryLeaks,
213
+ consoleLogs: consoleLogs.slice(0, 10),
214
+ consoleLogCount: consoleLogs.length,
215
+ largeFunctions,
216
+ },
217
+ };
218
+ }
219
+ catch (error) {
220
+ return {
221
+ name: 'Performance',
222
+ status: 'warn',
223
+ duration: Date.now() - start,
224
+ summary: `Performance analysis error: ${error instanceof Error ? error.message.slice(0, 100) : String(error)}`,
225
+ details: { error: true },
226
+ };
227
+ }
228
+ }
229
+ // ============================================================================
230
+ // STAGE: ACCESSIBILITY
231
+ // ============================================================================
232
+ function runAccessibilityStage(projectRoot) {
233
+ const start = Date.now();
234
+ try {
235
+ const sources = readSourceFiles(projectRoot, ['.tsx', '.jsx', '.html']);
236
+ const issues = [];
237
+ for (const { file, content, lines } of sources) {
238
+ const rel = path.relative(projectRoot, file);
239
+ // Use full content for multiline patterns
240
+ // 1. <img> without alt
241
+ for (const m of content.matchAll(/<img\b([^>]*?)\/?>|<img\b([^>]*?)>[\s\S]*?<\/img>/g)) {
242
+ const attrs = m[1] ?? m[2] ?? '';
243
+ if (!attrs.includes('alt=') && !attrs.includes('aria-label=') && !attrs.includes('aria-hidden=')) {
244
+ const lineNum = content.slice(0, m.index).split('\n').length;
245
+ issues.push({ file: rel, line: lineNum, rule: 'image-alt', impact: 'critical', detail: 'img element missing alt attribute' });
246
+ }
247
+ }
248
+ // 2. Buttons with no text content (multiline aware)
249
+ for (const m of content.matchAll(/<button\b([^>]*?)>([\s\S]*?)<\/button>/g)) {
250
+ const attrs = m[1] ?? '';
251
+ const inner = (m[2] ?? '').trim().replace(/<[^>]+>/g, '').trim();
252
+ if (!inner && !attrs.includes('aria-label=') && !attrs.includes('aria-labelledby=') && !attrs.includes('title=')) {
253
+ const lineNum = content.slice(0, m.index).split('\n').length;
254
+ issues.push({ file: rel, line: lineNum, rule: 'button-name', impact: 'critical', detail: 'Button has no accessible text' });
255
+ }
256
+ }
257
+ // 3. <input> without label association (multiline aware)
258
+ for (const m of content.matchAll(/<input\b([^>]*?)\/?>|<input\b([^>]*?)>/g)) {
259
+ const attrs = m[1] ?? m[2] ?? '';
260
+ if (attrs.includes('type="hidden"') || attrs.includes("type='hidden'"))
261
+ continue;
262
+ if (!attrs.includes('aria-label=') && !attrs.includes('aria-labelledby=') && !attrs.includes('id=')) {
263
+ const lineNum = content.slice(0, m.index).split('\n').length;
264
+ issues.push({ file: rel, line: lineNum, rule: 'input-label', impact: 'critical', detail: 'Input has no accessible label' });
265
+ }
266
+ }
267
+ // 4. Positive tabindex
268
+ for (const m of content.matchAll(/tabIndex=\{?["']?([1-9]\d*)["']?\}?/g)) {
269
+ const lineNum = content.slice(0, m.index).split('\n').length;
270
+ issues.push({ file: rel, line: lineNum, rule: 'tabindex', impact: 'serious', detail: `tabIndex="${m[1]}" disrupts keyboard navigation` });
271
+ }
272
+ // 5. onClick without onKeyDown/onKeyPress on non-interactive elements
273
+ for (const m of content.matchAll(/<(div|span|p|li|td|section|article)\b([^>]*?)onClick=/g)) {
274
+ const attrs = m[2] ?? '';
275
+ const lineNum = content.slice(0, m.index).split('\n').length;
276
+ // Only flag if no keyboard handler or role
277
+ const surroundingBlock = content.slice(Math.max(0, m.index - 10), (m.index ?? 0) + 200);
278
+ if (!surroundingBlock.includes('onKeyDown') && !surroundingBlock.includes('onKeyPress') && !surroundingBlock.includes('role=')) {
279
+ issues.push({ file: rel, line: lineNum, rule: 'click-events-have-key-events', impact: 'serious', detail: `<${m[1]}> has onClick but no keyboard handler or role` });
280
+ }
281
+ }
282
+ // 6. Missing lang attribute on <html>
283
+ if (file.endsWith('.html') && !content.includes('lang=')) {
284
+ issues.push({ file: rel, line: 1, rule: 'html-has-lang', impact: 'serious', detail: '<html> missing lang attribute' });
285
+ }
286
+ // 7. Heading hierarchy — h1 usage
287
+ const h1Count = (content.match(/<h1[\s>]/g) ?? []).length;
288
+ if (h1Count > 1) {
289
+ issues.push({ file: rel, line: 1, rule: 'heading-order', impact: 'moderate', detail: `${h1Count} <h1> elements — only one per page` });
290
+ }
291
+ // 8. autoFocus (can cause confusion for screen reader users)
292
+ if (content.includes('autoFocus') || content.includes('autofocus')) {
293
+ const m = content.match(/autoFocus|autofocus/);
294
+ const lineNum = m ? content.slice(0, content.indexOf(m[0])).split('\n').length : 1;
295
+ issues.push({ file: rel, line: lineNum, rule: 'no-autofocus', impact: 'moderate', detail: 'autoFocus can disorient screen reader users' });
296
+ }
297
+ }
298
+ const critical = issues.filter(i => i.impact === 'critical').length;
299
+ const serious = issues.filter(i => i.impact === 'serious').length;
300
+ const moderate = issues.filter(i => i.impact === 'moderate').length;
301
+ return {
302
+ name: 'Accessibility',
303
+ status: critical > 0 ? 'fail' : serious > 0 ? 'warn' : moderate > 2 ? 'warn' : 'pass',
304
+ duration: Date.now() - start,
305
+ summary: `${issues.length} issues — ${critical} critical, ${serious} serious, ${moderate} moderate`,
306
+ details: {
307
+ filesScanned: sources.length,
308
+ totalIssues: issues.length,
309
+ critical,
310
+ serious,
311
+ moderate,
312
+ issues: issues.slice(0, 25),
313
+ },
314
+ };
315
+ }
316
+ catch (error) {
317
+ return {
318
+ name: 'Accessibility',
319
+ status: 'warn',
320
+ duration: Date.now() - start,
321
+ summary: `A11y analysis error: ${error instanceof Error ? error.message.slice(0, 100) : String(error)}`,
322
+ details: { error: true },
323
+ };
324
+ }
325
+ }
326
+ // ============================================================================
327
+ // STAGE: DESIGN TOKENS
328
+ // ============================================================================
329
+ function runDesignTokensStage(projectRoot) {
330
+ const start = Date.now();
331
+ try {
332
+ const sources = readSourceFiles(projectRoot, ['.ts', '.tsx', '.js', '.jsx', '.css', '.scss']);
333
+ const violations = [];
334
+ for (const { file, lines } of sources) {
335
+ const rel = path.relative(projectRoot, file);
336
+ for (let i = 0; i < lines.length; i++) {
337
+ const line = lines[i];
338
+ const trimmed = line.trim();
339
+ // Skip comments and pure imports
340
+ if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('import '))
341
+ continue;
342
+ // Skip token definition files themselves
343
+ if (file.includes('token') || file.includes('theme') || file.includes('variable') || file.includes('design-system'))
344
+ continue;
345
+ // Skip CSS variable declarations (they're defining tokens, not using hardcoded values)
346
+ if (/--[\w-]+\s*:/.test(line))
347
+ continue;
348
+ // Hardcoded hex colors (but not in CSS variable usage)
349
+ const hexMatches = [...line.matchAll(/#([0-9a-fA-F]{3,8})\b/g)];
350
+ for (const m of hexMatches) {
351
+ // Skip if it's being assigned to a CSS variable or is part of a token file import
352
+ if (!line.includes('var(--') && !line.includes('tokens.')) {
353
+ violations.push({ file: rel, line: i + 1, type: 'color', value: m[0] });
354
+ }
355
+ }
356
+ // ANY hardcoded pixel value in style props / CSS — use regex not whitelist
357
+ const pxMatches = [...line.matchAll(/(?<![a-zA-Z'"`])(\d+(?:\.\d+)?px)(?!['"`]?\s*[,)]?\s*\/\*\s*token)/g)];
358
+ for (const m of pxMatches) {
359
+ const val = parseFloat(m[1]);
360
+ // Skip 0px, 1px (borders), 100%, and very large px (likely not spacing)
361
+ if (val === 0 || val === 1 || val > 200)
362
+ continue;
363
+ // Only flag inside style/css-like contexts
364
+ if (line.includes('style=') || line.includes('padding') || line.includes('margin') ||
365
+ line.includes('gap') || line.includes('width') || line.includes('height') ||
366
+ line.includes('top:') || line.includes('left:') || line.includes('bottom:') ||
367
+ line.includes('right:') || line.includes('font-size') || line.includes('fontSize') ||
368
+ file.endsWith('.css') || file.endsWith('.scss')) {
369
+ violations.push({ file: rel, line: i + 1, type: val > 30 ? 'spacing' : 'spacing-sm', value: m[1] });
370
+ }
371
+ }
372
+ // Hardcoded font families
373
+ const fontFamilyMatch = line.match(/fontFamily\s*:\s*['"`]([^'"`]+)['"`]/);
374
+ if (fontFamilyMatch && !line.includes('var(--')) {
375
+ violations.push({ file: rel, line: i + 1, type: 'font-family', value: fontFamilyMatch[1] });
376
+ }
377
+ // Magic z-index values
378
+ const zIndexMatch = line.match(/z(?:Index|-index)\s*[=:]\s*(\d{2,})/);
379
+ if (zIndexMatch && !['100', '999', '1000', '9999'].includes(zIndexMatch[1])) {
380
+ violations.push({ file: rel, line: i + 1, type: 'z-index', value: zIndexMatch[1] });
381
+ }
382
+ }
383
+ }
384
+ const byType = violations.reduce((acc, v) => {
385
+ acc[v.type] = (acc[v.type] ?? 0) + 1;
386
+ return acc;
387
+ }, {});
388
+ return {
389
+ name: 'Design Tokens',
390
+ status: violations.length > 30 ? 'fail' : violations.length > 10 ? 'warn' : 'pass',
391
+ duration: Date.now() - start,
392
+ summary: `${violations.length} hardcoded values — ${byType.color ?? 0} colors, ${(byType.spacing ?? 0) + (byType['spacing-sm'] ?? 0)} spacing, ${byType['font-family'] ?? 0} fonts`,
393
+ details: {
394
+ filesScanned: sources.length,
395
+ totalViolations: violations.length,
396
+ byType,
397
+ sample: violations.slice(0, 20),
398
+ },
399
+ };
400
+ }
401
+ catch (error) {
402
+ return {
403
+ name: 'Design Tokens',
404
+ status: 'warn',
405
+ duration: Date.now() - start,
406
+ summary: `Design token analysis error: ${error instanceof Error ? error.message.slice(0, 100) : String(error)}`,
407
+ details: { error: true },
408
+ };
409
+ }
410
+ }
411
+ // ============================================================================
412
+ // STAGE: TYPE SAFETY (bonus — new stage)
413
+ // ============================================================================
414
+ function runTypeSafetyStage(projectRoot) {
415
+ const start = Date.now();
416
+ const tsconfigPath = path.join(projectRoot, 'tsconfig.json');
417
+ if (!fs.existsSync(tsconfigPath)) {
418
+ return { name: 'Type Safety', status: 'skip', duration: 0, summary: 'No tsconfig.json found', details: {} };
419
+ }
420
+ try {
421
+ execSync('npx tsc --noEmit 2>&1', { cwd: projectRoot, encoding: 'utf-8', timeout: 60000, stdio: 'pipe' });
422
+ return {
423
+ name: 'Type Safety',
424
+ status: 'pass',
425
+ duration: Date.now() - start,
426
+ summary: 'No TypeScript errors',
427
+ details: { errors: 0 },
428
+ };
429
+ }
430
+ catch (error) {
431
+ const output = error instanceof Error && 'stdout' in error ? String(error.stdout) : String(error);
432
+ const errorLines = output.split('\n').filter(l => l.includes('error TS'));
433
+ const errorCount = errorLines.length;
434
+ const files = new Set(errorLines.map(l => l.split('(')[0])).size;
435
+ return {
436
+ name: 'Type Safety',
437
+ status: errorCount > 0 ? 'fail' : 'warn',
438
+ duration: Date.now() - start,
439
+ summary: `${errorCount} TypeScript errors across ${files} files`,
440
+ details: {
441
+ errorCount,
442
+ filesAffected: files,
443
+ sample: errorLines.slice(0, 10).map(l => l.trim()),
444
+ },
445
+ };
446
+ }
447
+ }
448
+ // ============================================================================
449
+ // MAIN SERVER
450
+ // ============================================================================
451
+ class QualityPipelineServer extends McpServerBase {
452
+ constructor() {
453
+ super({ name: 'quality-pipeline', version: '2.0.0' });
454
+ process.on('SIGINT', async () => {
455
+ await this.server.close();
456
+ process.exit(0);
457
+ });
458
+ }
459
+ registerTools() {
460
+ this.addTool('run_full_pipeline', 'Run the complete quality pipeline: tests, type safety, performance, accessibility, design tokens', {
461
+ type: 'object',
462
+ properties: {
463
+ projectRoot: { type: 'string', description: 'Root directory of the project to analyze' },
464
+ skipStages: {
465
+ type: 'array',
466
+ items: { type: 'string', enum: ['tests', 'types', 'performance', 'accessibility', 'design'] },
467
+ description: 'Stages to skip',
468
+ default: [],
469
+ },
470
+ },
471
+ required: ['projectRoot'],
472
+ }, this.handleFullPipeline.bind(this));
473
+ this.addTool('run_partial_pipeline', 'Run specific stages of the quality pipeline', {
474
+ type: 'object',
475
+ properties: {
476
+ projectRoot: { type: 'string', description: 'Root directory of the project to analyze' },
477
+ stages: {
478
+ type: 'array',
479
+ items: { type: 'string', enum: ['tests', 'types', 'performance', 'accessibility', 'design'] },
480
+ description: 'Stages to run',
481
+ },
482
+ },
483
+ required: ['projectRoot', 'stages'],
484
+ }, this.handlePartialPipeline.bind(this));
485
+ }
486
+ buildStages(projectRoot, skip) {
487
+ const run = (name, fn) => skip.includes(name)
488
+ ? { name: fn().name, status: 'skip', duration: 0, summary: 'Skipped', details: {} }
489
+ : fn();
490
+ return [
491
+ run('tests', () => runTestStage(projectRoot)),
492
+ run('types', () => runTypeSafetyStage(projectRoot)),
493
+ run('performance', () => runPerformanceStage(projectRoot)),
494
+ run('accessibility', () => runAccessibilityStage(projectRoot)),
495
+ run('design', () => runDesignTokensStage(projectRoot)),
496
+ ];
497
+ }
498
+ assembleResult(stages, totalStart) {
499
+ const active = stages.filter(s => s.status !== 'skip');
500
+ return {
501
+ overallStatus: active.some(s => s.status === 'fail') ? 'fail'
502
+ : active.some(s => s.status === 'warn') ? 'warn' : 'pass',
503
+ grade: calculateGrade(stages),
504
+ totalDuration: Date.now() - totalStart,
505
+ stages,
506
+ timestamp: new Date().toISOString(),
507
+ };
508
+ }
509
+ async handleFullPipeline(args) {
510
+ const { projectRoot, skipStages = [] } = args;
511
+ try {
512
+ const totalStart = Date.now();
513
+ const stages = this.buildStages(projectRoot, skipStages);
514
+ return this.success({ result: this.assembleResult(stages, totalStart) });
515
+ }
516
+ catch (error) {
517
+ return this.error(error);
518
+ }
519
+ }
520
+ async handlePartialPipeline(args) {
521
+ const { projectRoot, stages: stageNames } = args;
522
+ try {
523
+ const totalStart = Date.now();
524
+ const allStages = ['tests', 'types', 'performance', 'accessibility', 'design'];
525
+ const skip = allStages.filter(s => !stageNames.includes(s));
526
+ const stages = this.buildStages(projectRoot, skip);
527
+ return this.success({ result: this.assembleResult(stages, totalStart) });
528
+ }
529
+ catch (error) {
530
+ return this.error(error);
531
+ }
532
+ }
533
+ }
534
+ // ============================================================================
535
+ // ENTRY POINT
536
+ // ============================================================================
537
+ new QualityPipelineServer().run().catch(console.error);
538
+ //# sourceMappingURL=index.js.map