mcp-react-toolkit 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/README.md +24 -24
  2. package/node_modules/@mcp-showcase/shared/build/McpServerBase.d.ts +13 -0
  3. package/node_modules/@mcp-showcase/shared/build/McpServerBase.d.ts.map +1 -1
  4. package/node_modules/@mcp-showcase/shared/build/McpServerBase.js +40 -0
  5. package/node_modules/@mcp-showcase/shared/build/McpServerBase.js.map +1 -1
  6. package/node_modules/@mcp-showcase/shared/build/types.d.ts +11 -0
  7. package/node_modules/@mcp-showcase/shared/build/types.d.ts.map +1 -1
  8. package/node_modules/@mcp-showcase/shared/src/McpServerBase.ts +45 -0
  9. package/node_modules/@mcp-showcase/shared/src/types.ts +12 -0
  10. package/node_modules/@mcp-showcase/ui-kit/README.md +30 -0
  11. package/node_modules/@mcp-showcase/ui-kit/build/components.d.ts +10 -0
  12. package/node_modules/@mcp-showcase/ui-kit/build/components.d.ts.map +1 -0
  13. package/node_modules/@mcp-showcase/ui-kit/build/components.js +177 -0
  14. package/node_modules/@mcp-showcase/ui-kit/build/components.js.map +1 -0
  15. package/node_modules/@mcp-showcase/ui-kit/build/escape.d.ts +3 -0
  16. package/node_modules/@mcp-showcase/ui-kit/build/escape.d.ts.map +1 -0
  17. package/node_modules/@mcp-showcase/ui-kit/build/escape.js +10 -0
  18. package/node_modules/@mcp-showcase/ui-kit/build/escape.js.map +1 -0
  19. package/node_modules/@mcp-showcase/ui-kit/build/fixture.d.ts +4 -0
  20. package/node_modules/@mcp-showcase/ui-kit/build/fixture.d.ts.map +1 -0
  21. package/node_modules/@mcp-showcase/ui-kit/build/fixture.js +52 -0
  22. package/node_modules/@mcp-showcase/ui-kit/build/fixture.js.map +1 -0
  23. package/node_modules/@mcp-showcase/ui-kit/build/generate-template.d.ts +2 -0
  24. package/node_modules/@mcp-showcase/ui-kit/build/generate-template.d.ts.map +1 -0
  25. package/node_modules/@mcp-showcase/ui-kit/build/generate-template.js +19 -0
  26. package/node_modules/@mcp-showcase/ui-kit/build/generate-template.js.map +1 -0
  27. package/node_modules/@mcp-showcase/ui-kit/build/index.d.ts +6 -0
  28. package/node_modules/@mcp-showcase/ui-kit/build/index.d.ts.map +1 -0
  29. package/node_modules/@mcp-showcase/ui-kit/build/index.js +7 -0
  30. package/node_modules/@mcp-showcase/ui-kit/build/index.js.map +1 -0
  31. package/node_modules/@mcp-showcase/ui-kit/build/render.d.ts +3 -0
  32. package/node_modules/@mcp-showcase/ui-kit/build/render.d.ts.map +1 -0
  33. package/node_modules/@mcp-showcase/ui-kit/build/render.js +38 -0
  34. package/node_modules/@mcp-showcase/ui-kit/build/render.js.map +1 -0
  35. package/node_modules/@mcp-showcase/ui-kit/build/result-components.d.ts +9 -0
  36. package/node_modules/@mcp-showcase/ui-kit/build/result-components.d.ts.map +1 -0
  37. package/node_modules/@mcp-showcase/ui-kit/build/result-components.js +105 -0
  38. package/node_modules/@mcp-showcase/ui-kit/build/result-components.js.map +1 -0
  39. package/node_modules/@mcp-showcase/ui-kit/build/result-fixture.d.ts +4 -0
  40. package/node_modules/@mcp-showcase/ui-kit/build/result-fixture.d.ts.map +1 -0
  41. package/node_modules/@mcp-showcase/ui-kit/build/result-fixture.js +39 -0
  42. package/node_modules/@mcp-showcase/ui-kit/build/result-fixture.js.map +1 -0
  43. package/node_modules/@mcp-showcase/ui-kit/build/result-render.d.ts +3 -0
  44. package/node_modules/@mcp-showcase/ui-kit/build/result-render.d.ts.map +1 -0
  45. package/node_modules/@mcp-showcase/ui-kit/build/result-render.js +37 -0
  46. package/node_modules/@mcp-showcase/ui-kit/build/result-render.js.map +1 -0
  47. package/node_modules/@mcp-showcase/ui-kit/build/result-runtime.d.ts +2 -0
  48. package/node_modules/@mcp-showcase/ui-kit/build/result-runtime.d.ts.map +1 -0
  49. package/node_modules/@mcp-showcase/ui-kit/build/result-runtime.js +72 -0
  50. package/node_modules/@mcp-showcase/ui-kit/build/result-runtime.js.map +1 -0
  51. package/node_modules/@mcp-showcase/ui-kit/build/runtime.d.ts +2 -0
  52. package/node_modules/@mcp-showcase/ui-kit/build/runtime.d.ts.map +1 -0
  53. package/node_modules/@mcp-showcase/ui-kit/build/runtime.js +221 -0
  54. package/node_modules/@mcp-showcase/ui-kit/build/runtime.js.map +1 -0
  55. package/node_modules/@mcp-showcase/ui-kit/build/theme.d.ts +2 -0
  56. package/node_modules/@mcp-showcase/ui-kit/build/theme.d.ts.map +1 -0
  57. package/node_modules/@mcp-showcase/ui-kit/build/theme.js +278 -0
  58. package/node_modules/@mcp-showcase/ui-kit/build/theme.js.map +1 -0
  59. package/node_modules/@mcp-showcase/ui-kit/build/types.d.ts +113 -0
  60. package/node_modules/@mcp-showcase/ui-kit/build/types.d.ts.map +1 -0
  61. package/node_modules/@mcp-showcase/ui-kit/build/types.js +35 -0
  62. package/node_modules/@mcp-showcase/ui-kit/build/types.js.map +1 -0
  63. package/node_modules/@mcp-showcase/ui-kit/demo/index.html +653 -0
  64. package/node_modules/@mcp-showcase/ui-kit/demo/result.html +445 -0
  65. package/node_modules/@mcp-showcase/ui-kit/package.json +19 -0
  66. package/node_modules/@mcp-showcase/ui-kit/src/components.ts +191 -0
  67. package/node_modules/@mcp-showcase/ui-kit/src/escape.ts +9 -0
  68. package/node_modules/@mcp-showcase/ui-kit/src/fixture.ts +53 -0
  69. package/node_modules/@mcp-showcase/ui-kit/src/generate-template.ts +21 -0
  70. package/node_modules/@mcp-showcase/ui-kit/src/index.test.ts +72 -0
  71. package/node_modules/@mcp-showcase/ui-kit/src/index.ts +6 -0
  72. package/node_modules/@mcp-showcase/ui-kit/src/render.ts +48 -0
  73. package/node_modules/@mcp-showcase/ui-kit/src/result-components.ts +112 -0
  74. package/node_modules/@mcp-showcase/ui-kit/src/result-fixture.ts +40 -0
  75. package/node_modules/@mcp-showcase/ui-kit/src/result-render.test.ts +47 -0
  76. package/node_modules/@mcp-showcase/ui-kit/src/result-render.ts +47 -0
  77. package/node_modules/@mcp-showcase/ui-kit/src/result-runtime.ts +72 -0
  78. package/node_modules/@mcp-showcase/ui-kit/src/runtime.smoke.test.ts +103 -0
  79. package/node_modules/@mcp-showcase/ui-kit/src/runtime.ts +221 -0
  80. package/node_modules/@mcp-showcase/ui-kit/src/theme.ts +278 -0
  81. package/node_modules/@mcp-showcase/ui-kit/src/types.ts +140 -0
  82. package/node_modules/@mcp-showcase/ui-kit/tsconfig.json +9 -0
  83. package/package.json +6 -4
  84. package/tools/accessibility-checker/build/health-report.d.ts +27 -0
  85. package/tools/accessibility-checker/build/health-report.d.ts.map +1 -0
  86. package/tools/accessibility-checker/build/health-report.js +140 -0
  87. package/tools/accessibility-checker/build/health-report.js.map +1 -0
  88. package/tools/accessibility-checker/build/index.js +7 -1
  89. package/tools/accessibility-checker/build/index.js.map +1 -1
  90. package/tools/accessibility-checker/package.json +1 -0
  91. package/tools/code-modernizer/build/index.js +60 -44
  92. package/tools/code-modernizer/build/index.js.map +1 -1
  93. package/tools/code-modernizer/build/result-report.d.ts +24 -0
  94. package/tools/code-modernizer/build/result-report.d.ts.map +1 -0
  95. package/tools/code-modernizer/build/result-report.js +101 -0
  96. package/tools/code-modernizer/build/result-report.js.map +1 -0
  97. package/tools/code-modernizer/package.json +2 -0
  98. package/tools/component-factory/build/index.js +7 -1
  99. package/tools/component-factory/build/index.js.map +1 -1
  100. package/tools/component-factory/build/result-report.d.ts +11 -0
  101. package/tools/component-factory/build/result-report.d.ts.map +1 -0
  102. package/tools/component-factory/build/result-report.js +104 -0
  103. package/tools/component-factory/build/result-report.js.map +1 -0
  104. package/tools/component-factory/package.json +1 -0
  105. package/tools/component-fixer/build/index.js +6 -6
  106. package/tools/component-fixer/build/index.js.map +1 -1
  107. package/tools/component-fixer/build/result-report.d.ts +37 -0
  108. package/tools/component-fixer/build/result-report.d.ts.map +1 -0
  109. package/tools/component-fixer/build/result-report.js +106 -0
  110. package/tools/component-fixer/build/result-report.js.map +1 -0
  111. package/tools/component-fixer/package.json +1 -0
  112. package/tools/component-reviewer/build/health-report.d.ts +37 -0
  113. package/tools/component-reviewer/build/health-report.d.ts.map +1 -0
  114. package/tools/component-reviewer/build/health-report.js +116 -0
  115. package/tools/component-reviewer/build/health-report.js.map +1 -0
  116. package/tools/component-reviewer/build/index.d.ts.map +1 -1
  117. package/tools/component-reviewer/build/index.js +7 -6
  118. package/tools/component-reviewer/build/index.js.map +1 -1
  119. package/tools/component-reviewer/package.json +1 -0
  120. package/tools/dep-auditor/build/health-report.d.ts +16 -0
  121. package/tools/dep-auditor/build/health-report.d.ts.map +1 -0
  122. package/tools/dep-auditor/build/health-report.js +187 -0
  123. package/tools/dep-auditor/build/health-report.js.map +1 -0
  124. package/tools/dep-auditor/build/index.d.ts.map +1 -1
  125. package/tools/dep-auditor/build/index.js +7 -1
  126. package/tools/dep-auditor/build/index.js.map +1 -1
  127. package/tools/dep-auditor/package.json +1 -0
  128. package/tools/generate-tests/build/index.js +8 -1
  129. package/tools/generate-tests/build/index.js.map +1 -1
  130. package/tools/generate-tests/build/result-report.d.ts +14 -0
  131. package/tools/generate-tests/build/result-report.d.ts.map +1 -0
  132. package/tools/generate-tests/build/result-report.js +124 -0
  133. package/tools/generate-tests/build/result-report.js.map +1 -0
  134. package/tools/generate-tests/package.json +1 -0
  135. package/tools/legacy-analyzer/build/health-report.d.ts +4 -0
  136. package/tools/legacy-analyzer/build/health-report.d.ts.map +1 -0
  137. package/tools/legacy-analyzer/build/health-report.js +164 -0
  138. package/tools/legacy-analyzer/build/health-report.js.map +1 -0
  139. package/tools/legacy-analyzer/build/index.js +15 -1
  140. package/tools/legacy-analyzer/build/index.js.map +1 -1
  141. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.d.ts.map +1 -1
  142. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.js +3 -8
  143. package/tools/legacy-analyzer/build/tools/01-detect-project-tech.js.map +1 -1
  144. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.d.ts.map +1 -1
  145. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.js +25 -3
  146. package/tools/legacy-analyzer/build/tools/05-analyze-api-layer.js.map +1 -1
  147. package/tools/legacy-analyzer/package.json +1 -0
  148. package/tools/lighthouse-runner/build/health-report.d.ts +14 -0
  149. package/tools/lighthouse-runner/build/health-report.d.ts.map +1 -0
  150. package/tools/lighthouse-runner/build/health-report.js +138 -0
  151. package/tools/lighthouse-runner/build/health-report.js.map +1 -0
  152. package/tools/lighthouse-runner/build/index.d.ts.map +1 -1
  153. package/tools/lighthouse-runner/build/index.js +7 -1
  154. package/tools/lighthouse-runner/build/index.js.map +1 -1
  155. package/tools/lighthouse-runner/package.json +1 -0
  156. package/tools/monorepo-manager/build/index.js +9 -1
  157. package/tools/monorepo-manager/build/index.js.map +1 -1
  158. package/tools/monorepo-manager/build/result-report.d.ts +20 -0
  159. package/tools/monorepo-manager/build/result-report.d.ts.map +1 -0
  160. package/tools/monorepo-manager/build/result-report.js +84 -0
  161. package/tools/monorepo-manager/build/result-report.js.map +1 -0
  162. package/tools/monorepo-manager/package.json +1 -0
  163. package/tools/performance-audit/build/health-report.d.ts +30 -0
  164. package/tools/performance-audit/build/health-report.d.ts.map +1 -0
  165. package/tools/performance-audit/build/health-report.js +152 -0
  166. package/tools/performance-audit/build/health-report.js.map +1 -0
  167. package/tools/performance-audit/build/index.d.ts.map +1 -1
  168. package/tools/performance-audit/build/index.js +7 -1
  169. package/tools/performance-audit/build/index.js.map +1 -1
  170. package/tools/performance-audit/package.json +1 -0
  171. package/tools/quality-pipeline/build/health-report.d.ts +11 -0
  172. package/tools/quality-pipeline/build/health-report.d.ts.map +1 -0
  173. package/tools/quality-pipeline/build/health-report.js +137 -0
  174. package/tools/quality-pipeline/build/health-report.js.map +1 -0
  175. package/tools/quality-pipeline/build/index.js +7 -1
  176. package/tools/quality-pipeline/build/index.js.map +1 -1
  177. package/tools/quality-pipeline/package.json +1 -0
  178. package/tools/render-analyzer/build/health-report.d.ts +33 -0
  179. package/tools/render-analyzer/build/health-report.d.ts.map +1 -0
  180. package/tools/render-analyzer/build/health-report.js +142 -0
  181. package/tools/render-analyzer/build/health-report.js.map +1 -0
  182. package/tools/render-analyzer/build/index.d.ts.map +1 -1
  183. package/tools/render-analyzer/build/index.js +7 -1
  184. package/tools/render-analyzer/build/index.js.map +1 -1
  185. package/tools/render-analyzer/package.json +1 -0
  186. package/tools/shared/build/McpServerBase.d.ts +13 -0
  187. package/tools/shared/build/McpServerBase.d.ts.map +1 -1
  188. package/tools/shared/build/McpServerBase.js +40 -0
  189. package/tools/shared/build/McpServerBase.js.map +1 -1
  190. package/tools/shared/build/types.d.ts +11 -0
  191. package/tools/shared/build/types.d.ts.map +1 -1
  192. package/tools/storybook-generator/build/index.d.ts.map +1 -1
  193. package/tools/storybook-generator/build/index.js +9 -1
  194. package/tools/storybook-generator/build/index.js.map +1 -1
  195. package/tools/storybook-generator/build/result-report.d.ts +22 -0
  196. package/tools/storybook-generator/build/result-report.d.ts.map +1 -0
  197. package/tools/storybook-generator/build/result-report.js +77 -0
  198. package/tools/storybook-generator/build/result-report.js.map +1 -0
  199. package/tools/storybook-generator/package.json +1 -0
  200. package/tools/test-gap-analyzer/build/health-report.d.ts +34 -0
  201. package/tools/test-gap-analyzer/build/health-report.d.ts.map +1 -0
  202. package/tools/test-gap-analyzer/build/health-report.js +190 -0
  203. package/tools/test-gap-analyzer/build/health-report.js.map +1 -0
  204. package/tools/test-gap-analyzer/build/index.d.ts.map +1 -1
  205. package/tools/test-gap-analyzer/build/index.js +7 -1
  206. package/tools/test-gap-analyzer/build/index.js.map +1 -1
  207. package/tools/test-gap-analyzer/package.json +1 -0
  208. package/tools/typescript-enforcer/build/health-report.d.ts +33 -0
  209. package/tools/typescript-enforcer/build/health-report.d.ts.map +1 -0
  210. package/tools/typescript-enforcer/build/health-report.js +143 -0
  211. package/tools/typescript-enforcer/build/health-report.js.map +1 -0
  212. package/tools/typescript-enforcer/build/index.js +6 -1
  213. package/tools/typescript-enforcer/build/index.js.map +1 -1
  214. package/tools/typescript-enforcer/package.json +1 -0
  215. package/tools/ui-kit/README.md +30 -0
  216. package/tools/ui-kit/build/components.d.ts +10 -0
  217. package/tools/ui-kit/build/components.d.ts.map +1 -0
  218. package/tools/ui-kit/build/components.js +177 -0
  219. package/tools/ui-kit/build/components.js.map +1 -0
  220. package/tools/ui-kit/build/escape.d.ts +3 -0
  221. package/tools/ui-kit/build/escape.d.ts.map +1 -0
  222. package/tools/ui-kit/build/escape.js +10 -0
  223. package/tools/ui-kit/build/escape.js.map +1 -0
  224. package/tools/ui-kit/build/fixture.d.ts +4 -0
  225. package/tools/ui-kit/build/fixture.d.ts.map +1 -0
  226. package/tools/ui-kit/build/fixture.js +52 -0
  227. package/tools/ui-kit/build/fixture.js.map +1 -0
  228. package/tools/ui-kit/build/generate-template.d.ts +2 -0
  229. package/tools/ui-kit/build/generate-template.d.ts.map +1 -0
  230. package/tools/ui-kit/build/generate-template.js +19 -0
  231. package/tools/ui-kit/build/generate-template.js.map +1 -0
  232. package/tools/ui-kit/build/index.d.ts +6 -0
  233. package/tools/ui-kit/build/index.d.ts.map +1 -0
  234. package/tools/ui-kit/build/index.js +7 -0
  235. package/tools/ui-kit/build/index.js.map +1 -0
  236. package/tools/ui-kit/build/render.d.ts +3 -0
  237. package/tools/ui-kit/build/render.d.ts.map +1 -0
  238. package/tools/ui-kit/build/render.js +38 -0
  239. package/tools/ui-kit/build/render.js.map +1 -0
  240. package/tools/ui-kit/build/result-components.d.ts +9 -0
  241. package/tools/ui-kit/build/result-components.d.ts.map +1 -0
  242. package/tools/ui-kit/build/result-components.js +105 -0
  243. package/tools/ui-kit/build/result-components.js.map +1 -0
  244. package/tools/ui-kit/build/result-fixture.d.ts +4 -0
  245. package/tools/ui-kit/build/result-fixture.d.ts.map +1 -0
  246. package/tools/ui-kit/build/result-fixture.js +39 -0
  247. package/tools/ui-kit/build/result-fixture.js.map +1 -0
  248. package/tools/ui-kit/build/result-render.d.ts +3 -0
  249. package/tools/ui-kit/build/result-render.d.ts.map +1 -0
  250. package/tools/ui-kit/build/result-render.js +37 -0
  251. package/tools/ui-kit/build/result-render.js.map +1 -0
  252. package/tools/ui-kit/build/result-runtime.d.ts +2 -0
  253. package/tools/ui-kit/build/result-runtime.d.ts.map +1 -0
  254. package/tools/ui-kit/build/result-runtime.js +72 -0
  255. package/tools/ui-kit/build/result-runtime.js.map +1 -0
  256. package/tools/ui-kit/build/runtime.d.ts +2 -0
  257. package/tools/ui-kit/build/runtime.d.ts.map +1 -0
  258. package/tools/ui-kit/build/runtime.js +221 -0
  259. package/tools/ui-kit/build/runtime.js.map +1 -0
  260. package/tools/ui-kit/build/theme.d.ts +2 -0
  261. package/tools/ui-kit/build/theme.d.ts.map +1 -0
  262. package/tools/ui-kit/build/theme.js +278 -0
  263. package/tools/ui-kit/build/theme.js.map +1 -0
  264. package/tools/ui-kit/build/types.d.ts +113 -0
  265. package/tools/ui-kit/build/types.d.ts.map +1 -0
  266. package/tools/ui-kit/build/types.js +35 -0
  267. package/tools/ui-kit/build/types.js.map +1 -0
  268. package/tools/ui-kit/package.json +19 -0
@@ -0,0 +1,278 @@
1
+ // ============================================================================
2
+ // THEME — dual light (default) + dark, toggled at runtime via [data-theme].
3
+ // Grade accent is driven by [data-band="good|warn|bad"] on the root so a
4
+ // failing repo still *feels* urgent in either mode.
5
+ // Dependency-free: plain CSS custom properties, no Tailwind at runtime.
6
+ // ============================================================================
7
+
8
+ export const STYLES = /* css */ `
9
+ *,*::before,*::after{box-sizing:border-box}
10
+ html{-webkit-text-size-adjust:100%}
11
+ body{margin:0}
12
+
13
+ :root{
14
+ --font:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
15
+ --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
16
+
17
+ /* light (default) */
18
+ --bg:#f7f7f6;
19
+ --surface:#ffffff;
20
+ --surface-2:#fbfbfa;
21
+ --text:#16161a;
22
+ --muted:#6b7280;
23
+ --faint:#9aa0aa;
24
+ --border:#ebe9e4;
25
+ --border-strong:#dedcd5;
26
+ --shadow:0 1px 2px rgba(16,16,20,.04),0 8px 24px -12px rgba(16,16,20,.10);
27
+ --ring:rgba(99,102,241,.45);
28
+
29
+ --good:#059669; --good-soft:#ecfdf5;
30
+ --warn:#d97706; --warn-soft:#fffbeb;
31
+ --bad:#e11d48; --bad-soft:#fff1f2;
32
+
33
+ --sev-critical:#e11d48; --sev-high:#ea580c; --sev-medium:#d97706; --sev-low:#64748b;
34
+ --sev-critical-soft:#fff1f2; --sev-high-soft:#fff7ed; --sev-medium-soft:#fffbeb; --sev-low-soft:#f1f5f9;
35
+
36
+ --accent:var(--good);
37
+ --accent-soft:var(--good-soft);
38
+ --radius:14px;
39
+ --radius-sm:10px;
40
+ }
41
+
42
+ [data-theme="dark"]{
43
+ --bg:#0a0b0d;
44
+ --surface:#141519;
45
+ --surface-2:#0f1013;
46
+ --text:#f3f4f6;
47
+ --muted:#9aa1ad;
48
+ --faint:#6b7280;
49
+ --border:rgba(255,255,255,.07);
50
+ --border-strong:rgba(255,255,255,.12);
51
+ --shadow:0 1px 2px rgba(0,0,0,.4),0 16px 40px -20px rgba(0,0,0,.7);
52
+ --ring:rgba(129,140,248,.55);
53
+
54
+ --good:#34d399; --good-soft:rgba(52,211,153,.12);
55
+ --warn:#fbbf24; --warn-soft:rgba(251,191,36,.12);
56
+ --bad:#fb7185; --bad-soft:rgba(251,113,133,.12);
57
+
58
+ --sev-critical:#fb7185; --sev-high:#fb923c; --sev-medium:#fbbf24; --sev-low:#94a3b8;
59
+ --sev-critical-soft:rgba(251,113,133,.12); --sev-high-soft:rgba(251,146,60,.12);
60
+ --sev-medium-soft:rgba(251,191,36,.12); --sev-low-soft:rgba(148,163,184,.12);
61
+ }
62
+
63
+ [data-band="good"]{--accent:var(--good);--accent-soft:var(--good-soft)}
64
+ [data-band="warn"]{--accent:var(--warn);--accent-soft:var(--warn-soft)}
65
+ [data-band="bad"]{--accent:var(--bad);--accent-soft:var(--bad-soft)}
66
+
67
+ body{
68
+ font-family:var(--font);
69
+ background:var(--bg);
70
+ color:var(--text);
71
+ font-size:14px;
72
+ line-height:1.5;
73
+ -webkit-font-smoothing:antialiased;
74
+ font-variant-numeric:tabular-nums;
75
+ }
76
+ .num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
77
+
78
+ .wrap{max-width:1040px;margin:0 auto;padding:28px 24px 64px}
79
+
80
+ /* header */
81
+ .hdr{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:24px}
82
+ .brand{display:flex;align-items:center;gap:11px;min-width:0}
83
+ .brand .dot{width:30px;height:30px;border-radius:9px;background:var(--accent-soft);color:var(--accent);
84
+ display:grid;place-items:center;flex:none;border:1px solid var(--border)}
85
+ .brand h1{font-size:15px;font-weight:650;margin:0;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
86
+ .brand .sub{font-size:12px;color:var(--muted);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
87
+ .hdr-actions{display:flex;align-items:center;gap:8px;flex:none}
88
+
89
+ .btn{appearance:none;font-family:inherit;font-size:12.5px;font-weight:550;color:var(--text);
90
+ background:var(--surface);border:1px solid var(--border-strong);border-radius:9px;padding:7px 11px;
91
+ cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:.16s ease;line-height:1}
92
+ .btn:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}
93
+ .btn:active{transform:translateY(0)}
94
+ .btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--ring)}
95
+ .btn.icon{padding:7px;width:32px;height:32px;justify-content:center}
96
+ .btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
97
+ [data-theme="dark"] .btn.primary{color:#0a0b0d}
98
+ .btn.primary:hover{filter:brightness(1.05);color:#fff}
99
+ [data-theme="dark"] .btn.primary:hover{color:#0a0b0d}
100
+
101
+ /* hero */
102
+ .hero{display:grid;grid-template-columns:auto 1fr;gap:28px;align-items:center;
103
+ background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
104
+ padding:26px 28px;box-shadow:var(--shadow);margin-bottom:18px}
105
+ .gauge{position:relative;width:148px;height:148px;flex:none}
106
+ .gauge svg{transform:rotate(-90deg)}
107
+ .gauge .track{stroke:var(--border-strong);fill:none}
108
+ .gauge .arc{stroke:var(--accent);fill:none;stroke-linecap:round;transition:stroke-dashoffset 1.1s cubic-bezier(.22,1,.36,1)}
109
+ .gauge .center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;line-height:1}
110
+ .gauge .score{font-size:42px;font-weight:680;letter-spacing:-.03em;line-height:1}
111
+ .gauge .of{font-size:11px;color:var(--faint);margin-top:3px}
112
+ .hero-meta{min-width:0}
113
+ .grade-row{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}
114
+ .grade{font-size:13px;font-weight:650;color:var(--accent);background:var(--accent-soft);
115
+ border:1px solid var(--border);border-radius:7px;padding:3px 9px}
116
+ .verdict{font-size:18px;font-weight:620;letter-spacing:-.01em}
117
+ .hero p{color:var(--muted);margin:2px 0 14px;font-size:13px}
118
+ .chips{display:flex;flex-wrap:wrap;gap:7px}
119
+ .chip{font-size:12px;color:var(--muted);background:var(--surface-2);border:1px solid var(--border);
120
+ border-radius:999px;padding:4px 10px;display:inline-flex;gap:5px}
121
+ .chip b{color:var(--text);font-weight:600}
122
+
123
+ /* section heading */
124
+ .sec{margin:26px 0 12px;display:flex;align-items:center;justify-content:space-between;gap:12px}
125
+ .sec h2{font-size:13px;font-weight:620;letter-spacing:.02em;text-transform:uppercase;color:var(--muted);margin:0}
126
+ .sec .count{font-size:12px;color:var(--faint)}
127
+
128
+ /* category cards */
129
+ .cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:12px}
130
+ .card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:15px 16px;
131
+ box-shadow:var(--shadow);transition:.16s ease;display:flex;flex-direction:column}
132
+ .card:hover{border-color:var(--border-strong);transform:translateY(-2px)}
133
+ .card .top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:9px}
134
+ .card .name{font-weight:600;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
135
+ .card .badge{font-size:11px;font-weight:600;padding:2px 8px;border-radius:999px;flex:none}
136
+ .badge.good{color:var(--good);background:var(--good-soft)}
137
+ .badge.warn{color:var(--warn);background:var(--warn-soft)}
138
+ .badge.bad{color:var(--bad);background:var(--bad-soft)}
139
+ .card .sum{color:var(--muted);font-size:12.5px;line-height:1.45;min-height:3.9em;
140
+ display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}
141
+ .bar{height:5px;border-radius:999px;background:var(--border-strong);overflow:hidden;margin-top:11px}
142
+ .bar > i{display:block;height:100%;border-radius:999px;transition:width 1s cubic-bezier(.22,1,.36,1)}
143
+ .bar > i.good{background:var(--good)} .bar > i.warn{background:var(--warn)} .bar > i.bad{background:var(--bad)}
144
+ .card .foot{display:flex;justify-content:space-between;align-items:center;margin-top:9px;font-size:11.5px;color:var(--faint)}
145
+
146
+ /* toolbar */
147
+ .toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}
148
+ .search{flex:1;min-width:180px;position:relative}
149
+ .search input{width:100%;font-family:inherit;font-size:13px;color:var(--text);background:var(--surface);
150
+ border:1px solid var(--border-strong);border-radius:9px;padding:8px 11px 8px 32px}
151
+ .search input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
152
+ .search svg{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--faint)}
153
+ .filter{display:flex;gap:4px;background:var(--surface-2);border:1px solid var(--border);border-radius:9px;padding:3px}
154
+ .filter button{appearance:none;font-family:inherit;font-size:12px;font-weight:550;color:var(--muted);
155
+ background:transparent;border:0;border-radius:6px;padding:5px 10px;cursor:pointer;transition:.14s}
156
+ .filter button[aria-pressed="true"]{background:var(--surface);color:var(--text);box-shadow:var(--shadow)}
157
+ .filter button:hover{color:var(--text)}
158
+
159
+ /* table */
160
+ .table-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
161
+ box-shadow:var(--shadow);overflow:hidden}
162
+ table{width:100%;border-collapse:collapse;font-size:13px;table-layout:fixed}
163
+ thead th:nth-child(1),tbody td:nth-child(1){width:96px}
164
+ thead th:nth-child(3),tbody td:nth-child(3){width:120px}
165
+ thead th:nth-child(4),tbody td:nth-child(4){width:160px}
166
+ thead th{text-align:left;font-size:11px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;
167
+ color:var(--faint);padding:11px 16px;border-bottom:1px solid var(--border);cursor:pointer;user-select:none;white-space:nowrap}
168
+ thead th .arr{opacity:.4;font-size:9px;margin-left:3px}
169
+ thead th[aria-sort] .arr{opacity:1;color:var(--accent)}
170
+ tbody tr{border-bottom:1px solid var(--border);cursor:pointer;transition:background .12s}
171
+ tbody tr:last-child{border-bottom:0}
172
+ tbody tr:hover{background:var(--surface-2)}
173
+ tbody td{padding:11px 16px;vertical-align:top}
174
+ .sev{display:inline-flex;align-items:center;gap:6px;font-weight:600;font-size:12px;white-space:nowrap}
175
+ .sev .pip{width:7px;height:7px;border-radius:999px;flex:none}
176
+ .sev.critical{color:var(--sev-critical)} .sev.critical .pip{background:var(--sev-critical)}
177
+ .sev.high{color:var(--sev-high)} .sev.high .pip{background:var(--sev-high)}
178
+ .sev.medium{color:var(--sev-medium)} .sev.medium .pip{background:var(--sev-medium)}
179
+ .sev.low{color:var(--sev-low)} .sev.low .pip{background:var(--sev-low)}
180
+ .cell-title{font-weight:550;color:var(--text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}
181
+ .cell-file{font-family:var(--mono);font-size:11.5px;color:var(--muted);overflow-wrap:anywhere;word-break:normal;max-width:200px}
182
+ .tag{font-size:11px;color:var(--muted);background:var(--surface-2);border:1px solid var(--border);
183
+ border-radius:6px;padding:2px 7px;white-space:nowrap}
184
+ .empty{padding:40px 16px;text-align:center;color:var(--muted)}
185
+ .empty .big{font-size:15px;color:var(--text);font-weight:600;margin-bottom:4px}
186
+
187
+ /* drawer */
188
+ .scrim{position:fixed;inset:0;background:rgba(10,11,13,.42);opacity:0;pointer-events:none;transition:.2s;z-index:40}
189
+ .scrim.open{opacity:1;pointer-events:auto}
190
+ .drawer{position:fixed;top:0;right:0;height:100%;width:min(440px,92vw);background:var(--surface);
191
+ border-left:1px solid var(--border);box-shadow:-24px 0 60px -30px rgba(0,0,0,.5);
192
+ transform:translateX(100%);transition:transform .26s cubic-bezier(.22,1,.36,1);z-index:50;
193
+ display:flex;flex-direction:column}
194
+ .drawer.open{transform:translateX(0)}
195
+ .drawer header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
196
+ padding:20px 22px 16px;border-bottom:1px solid var(--border)}
197
+ .drawer header h3{margin:0;font-size:16px;font-weight:640;letter-spacing:-.01em;line-height:1.35}
198
+ .drawer .body{padding:18px 22px;overflow-y:auto;flex:1}
199
+ .drawer .field{margin-bottom:16px}
200
+ .drawer .field .k{font-size:11px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--faint);margin-bottom:5px}
201
+ .drawer .field .v{font-size:13.5px;color:var(--text)}
202
+ .drawer .field .v.mono{font-family:var(--mono);font-size:12px;color:var(--muted);word-break:break-all}
203
+ .drawer .acts{padding:16px 22px;border-top:1px solid var(--border);display:flex;flex-wrap:wrap;gap:8px}
204
+ .kv{display:flex;gap:8px;flex-wrap:wrap}
205
+ .kv .pair{font-size:12px;color:var(--muted);background:var(--surface-2);border:1px solid var(--border);border-radius:7px;padding:4px 9px}
206
+ .kv .pair b{color:var(--text);font-weight:600}
207
+
208
+ /* fix-first */
209
+ .queue{display:flex;flex-direction:column;gap:8px}
210
+ .qitem{display:flex;align-items:center;gap:12px;background:var(--surface);border:1px solid var(--border);
211
+ border-radius:var(--radius-sm);padding:11px 14px;box-shadow:var(--shadow);cursor:pointer;transition:.14s}
212
+ .qitem:hover{border-color:var(--accent);transform:translateX(2px)}
213
+ .qitem .rank{width:22px;height:22px;border-radius:7px;background:var(--accent-soft);color:var(--accent);
214
+ font-size:12px;font-weight:680;display:grid;place-items:center;flex:none}
215
+ .qitem .qt{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
216
+ .qitem .qt .t{display:block;font-weight:550;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
217
+ .qitem .qt .s{display:block;font-size:11.5px;color:var(--faint)}
218
+
219
+ /* toast */
220
+ .toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%) translateY(20px);opacity:0;
221
+ background:var(--text);color:var(--bg);font-size:13px;font-weight:550;padding:10px 16px;border-radius:10px;
222
+ box-shadow:var(--shadow);transition:.22s;z-index:60;pointer-events:none;max-width:90vw}
223
+ .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
224
+
225
+ .foot-note{margin-top:34px;text-align:center;font-size:11.5px;color:var(--faint)}
226
+ .foot-note a{color:var(--muted)}
227
+
228
+ @media (max-width:560px){
229
+ .hero{grid-template-columns:1fr;justify-items:center;text-align:center}
230
+ .hero-meta{text-align:center}.chips{justify-content:center}.grade-row{justify-content:center}
231
+ }
232
+ /* result view */
233
+ .result-hero{display:flex;align-items:center;gap:18px;flex-wrap:wrap;
234
+ background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
235
+ padding:22px 26px;box-shadow:var(--shadow);margin-bottom:18px}
236
+ .result-hero .glyph{width:52px;height:52px;border-radius:14px;background:var(--accent-soft);color:var(--accent);
237
+ display:grid;place-items:center;flex:none;border:1px solid var(--border)}
238
+ .result-hero .rh-main{min-width:0;flex:1}
239
+ .result-hero .rh-title{font-size:20px;font-weight:660;letter-spacing:-.02em;line-height:1.2}
240
+ .result-hero .rh-sub{color:var(--muted);font-size:13px;margin-top:3px}
241
+ .status-pill{font-size:12px;font-weight:650;padding:4px 10px;border-radius:999px;white-space:nowrap}
242
+ .status-pill.good{color:var(--good);background:var(--good-soft)}
243
+ .status-pill.warn{color:var(--warn);background:var(--warn-soft)}
244
+ .status-pill.bad{color:var(--bad);background:var(--bad-soft)}
245
+ .result-hero .chips{margin-top:0}
246
+
247
+ .changes{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
248
+ .change-row{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border);transition:background .12s}
249
+ .change-row:last-child{border-bottom:0}
250
+ .change-row.clickable{cursor:pointer}
251
+ .change-row.clickable:hover{background:var(--surface-2)}
252
+ .kind{font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:3px 8px;border-radius:6px;flex:none;width:74px;text-align:center}
253
+ .kind.created{color:var(--good);background:var(--good-soft)}
254
+ .kind.modified{color:var(--warn);background:var(--warn-soft)}
255
+ .kind.deleted{color:var(--bad);background:var(--bad-soft)}
256
+ .kind.renamed{color:var(--sev-low);background:var(--sev-low-soft)}
257
+ .change-main{flex:1;min-width:0}
258
+ .change-path{font-family:var(--mono);font-size:12.5px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
259
+ .change-sum{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
260
+ .change-delta{font-family:var(--mono);font-size:11.5px;flex:none;white-space:nowrap}
261
+ .change-delta .add{color:var(--good)} .change-delta .del{color:var(--bad)}
262
+
263
+ .section{margin-top:10px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
264
+ .section-item{display:flex;align-items:flex-start;gap:10px;padding:11px 16px;border-bottom:1px solid var(--border)}
265
+ .section-item:last-child{border-bottom:0}
266
+ .section-item .ip{width:7px;height:7px;border-radius:999px;margin-top:6px;flex:none;background:var(--faint)}
267
+ .section-item .ip.ok{background:var(--good)} .section-item .ip.warn{background:var(--warn)} .section-item .ip.error{background:var(--bad)}
268
+ .section-item .it{font-size:13px;font-weight:550}
269
+ .section-item .id{font-size:12px;color:var(--muted)}
270
+ .next-steps{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
271
+ .diff{font-family:var(--mono);font-size:12px;line-height:1.55;white-space:pre-wrap;word-break:break-word;
272
+ background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px}
273
+ .diff .dl-add{color:var(--good)} .diff .dl-del{color:var(--bad)} .diff .dl-ctx{color:var(--muted)}
274
+
275
+ @media (prefers-reduced-motion:reduce){
276
+ *{transition:none!important;animation:none!important}
277
+ }
278
+ `;
@@ -0,0 +1,140 @@
1
+ // ============================================================================
2
+ // HEALTH REPORT SCHEMA — the generic, tool-agnostic contract.
3
+ // Any MCP tool that maps its output to this shape gets the full premium UI.
4
+ // legacy-analyzer is the flagship producer; component-reviewer, dep-auditor,
5
+ // quality-pipeline etc. can map into the same schema later.
6
+ // ============================================================================
7
+
8
+ export type Severity = "critical" | "high" | "medium" | "low";
9
+ export type CategoryStatus = "good" | "warn" | "bad";
10
+
11
+ /** An agentic action a UI element can trigger back in the host (or fall back to in a browser). */
12
+ export type ReportAction =
13
+ | { id: string; label: string; kind: "tool"; tool: string; params?: Record<string, unknown>; fallback: string }
14
+ | { id: string; label: string; kind: "prompt"; prompt: string; fallback?: string }
15
+ | { id: string; label: string; kind: "link"; href: string };
16
+
17
+ export interface LabelValue {
18
+ label: string;
19
+ value: string;
20
+ }
21
+
22
+ export interface ReportCategory {
23
+ id: string;
24
+ name: string;
25
+ /** 0-100; omit when a numeric score is not meaningful. */
26
+ score?: number;
27
+ status: CategoryStatus;
28
+ summary: string;
29
+ issueCount: number;
30
+ details?: LabelValue[];
31
+ }
32
+
33
+ export interface ReportIssue {
34
+ id: string;
35
+ /** Matches a ReportCategory.id. */
36
+ category: string;
37
+ severity: Severity;
38
+ title: string;
39
+ description?: string;
40
+ file?: string;
41
+ meta?: LabelValue[];
42
+ actions?: ReportAction[];
43
+ }
44
+
45
+ export interface ReportMeta {
46
+ title: string;
47
+ subtitle?: string;
48
+ /** The thing being analysed (repo path, package name). */
49
+ target: string;
50
+ /** ISO date string. */
51
+ generatedAt: string;
52
+ /** Producing tool name, e.g. "legacy-analyzer". */
53
+ tool: string;
54
+ }
55
+
56
+ export interface HealthReport {
57
+ meta: ReportMeta;
58
+ /** 0-100 headline score. */
59
+ score: number;
60
+ totalIssues: number;
61
+ /** Tech/context chips shown in the hero. */
62
+ chips?: LabelValue[];
63
+ categories: ReportCategory[];
64
+ issues: ReportIssue[];
65
+ /** Top prioritised actions ("Fix-First Queue"). */
66
+ topActions?: ReportAction[];
67
+ }
68
+
69
+ export type Grade = "A+" | "A" | "B" | "C" | "D" | "F";
70
+
71
+ export function scoreToGrade(score: number): Grade {
72
+ if (score >= 95) return "A+";
73
+ if (score >= 85) return "A";
74
+ if (score >= 70) return "B";
75
+ if (score >= 55) return "C";
76
+ if (score >= 40) return "D";
77
+ return "F";
78
+ }
79
+
80
+ /** Health band drives the accent colour in both themes. */
81
+ export function scoreToBand(score: number): CategoryStatus {
82
+ if (score >= 70) return "good";
83
+ if (score >= 45) return "warn";
84
+ return "bad";
85
+ }
86
+
87
+ // ============================================================================
88
+ // RESULT REPORT — for ACTION/generative tools (scaffold, fix, convert, generate)
89
+ // that produce file changes rather than an audit score. Rendered by
90
+ // renderResultHTML. Shares meta, ReportAction, and the chrome with HealthReport.
91
+ // ============================================================================
92
+
93
+ export type FileChangeKind = "created" | "modified" | "deleted" | "renamed";
94
+ export type ResultStatus = "success" | "partial" | "noop";
95
+ export type ItemStatus = "ok" | "warn" | "error";
96
+
97
+ export interface FileChange {
98
+ path: string;
99
+ kind: FileChangeKind;
100
+ /** One-line description of what changed. */
101
+ summary?: string;
102
+ additions?: number;
103
+ deletions?: number;
104
+ language?: string;
105
+ /** Optional unified-diff or code snippet shown in the detail drawer. */
106
+ diff?: string;
107
+ }
108
+
109
+ export interface ResultSectionItem {
110
+ title: string;
111
+ detail?: string;
112
+ status?: ItemStatus;
113
+ }
114
+
115
+ /** A grouped list — e.g. "Steps", "Workspaces", "Warnings". */
116
+ export interface ResultSection {
117
+ title: string;
118
+ items: ResultSectionItem[];
119
+ }
120
+
121
+ export interface ResultReport {
122
+ meta: ReportMeta;
123
+ /** Headline outcome, e.g. "Created 3 files", "Applied 7 fixes". */
124
+ headline: string;
125
+ status: ResultStatus;
126
+ /** Context metrics shown as chips in the hero. */
127
+ stats?: LabelValue[];
128
+ /** File-level changes — the main grid. */
129
+ changes?: FileChange[];
130
+ /** Optional grouped detail lists. */
131
+ sections?: ResultSection[];
132
+ /** Follow-up actions (review, run tests, open file). */
133
+ nextActions?: ReportAction[];
134
+ }
135
+
136
+ export function statusToBand(status: ResultStatus): CategoryStatus {
137
+ if (status === "success") return "good";
138
+ if (status === "partial") return "warn";
139
+ return "good";
140
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./build",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src"],
8
+ "exclude": ["src/**/*.test.ts"]
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-react-toolkit",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "mcpName": "io.github.Nishant-Chaudhary5338/mcp-react-toolkit",
5
5
  "description": "17 MCP servers for React + TypeScript development automation — component scaffolding, dep auditing, WCAG checking, test generation, TypeScript enforcement, render analysis, performance audit, Lighthouse, Storybook generation, legacy app analysis, component review/fix, and monorepo management.",
6
6
  "keywords": [
@@ -40,6 +40,7 @@
40
40
  ],
41
41
  "workspaces": [
42
42
  "tools/shared",
43
+ "tools/ui-kit",
43
44
  "tools/json-viewer",
44
45
  "tools/component-factory",
45
46
  "tools/code-modernizer",
@@ -61,9 +62,9 @@
61
62
  "client"
62
63
  ],
63
64
  "scripts": {
64
- "build": "npm run build -w tools/shared && npm run build -w tools/json-viewer && npm run build -w tools/component-factory && npm run build -w tools/code-modernizer && npm run build -w tools/quality-pipeline && npm run build -w tools/dep-auditor && npm run build -w tools/accessibility-checker && npm run build -w tools/generate-tests && npm run build -w tools/typescript-enforcer && npm run build -w tools/monorepo-manager && npm run build -w tools/render-analyzer && npm run build -w tools/storybook-generator && npm run build -w tools/performance-audit && npm run build -w tools/lighthouse-runner && npm run build -w tools/test-gap-analyzer && npm run build -w tools/component-reviewer && npm run build -w tools/component-fixer && npm run build -w tools/legacy-analyzer && npm run build -w server",
65
+ "build": "npm run build -w tools/shared && npm run build -w tools/ui-kit && npm run build -w tools/json-viewer && npm run build -w tools/component-factory && npm run build -w tools/code-modernizer && npm run build -w tools/quality-pipeline && npm run build -w tools/dep-auditor && npm run build -w tools/accessibility-checker && npm run build -w tools/generate-tests && npm run build -w tools/typescript-enforcer && npm run build -w tools/monorepo-manager && npm run build -w tools/render-analyzer && npm run build -w tools/storybook-generator && npm run build -w tools/performance-audit && npm run build -w tools/lighthouse-runner && npm run build -w tools/test-gap-analyzer && npm run build -w tools/component-reviewer && npm run build -w tools/component-fixer && npm run build -w tools/legacy-analyzer && npm run build -w server",
65
66
  "dev": "concurrently \"npm run dev -w server\" \"npm run dev -w client\"",
66
- "test": "npm run test -w tools/json-viewer && npm run test -w tools/quality-pipeline && npm run test -w tools/component-factory && npm run test -w tools/code-modernizer && npm run test -w tools/dep-auditor && npm run test -w tools/accessibility-checker && npm run test -w tools/generate-tests && npm run test -w tools/typescript-enforcer && npm run test -w tools/monorepo-manager && npm run test -w tools/render-analyzer && npm run test -w tools/storybook-generator && npm run test -w tools/performance-audit && npm run test -w tools/lighthouse-runner && npm run test -w tools/test-gap-analyzer && npm run test -w tools/component-reviewer && npm run test -w tools/component-fixer && npm run test -w tools/legacy-analyzer",
67
+ "test": "npm run test -w tools/ui-kit && npm run test -w tools/json-viewer && npm run test -w tools/quality-pipeline && npm run test -w tools/component-factory && npm run test -w tools/code-modernizer && npm run test -w tools/dep-auditor && npm run test -w tools/accessibility-checker && npm run test -w tools/generate-tests && npm run test -w tools/typescript-enforcer && npm run test -w tools/monorepo-manager && npm run test -w tools/render-analyzer && npm run test -w tools/storybook-generator && npm run test -w tools/performance-audit && npm run test -w tools/lighthouse-runner && npm run test -w tools/test-gap-analyzer && npm run test -w tools/component-reviewer && npm run test -w tools/component-fixer && npm run test -w tools/legacy-analyzer",
67
68
  "install:all": "npm install"
68
69
  },
69
70
  "dependencies": {
@@ -74,7 +75,8 @@
74
75
  "glob": "^10.3.10"
75
76
  },
76
77
  "bundleDependencies": [
77
- "@mcp-showcase/shared"
78
+ "@mcp-showcase/shared",
79
+ "@mcp-showcase/ui-kit"
78
80
  ],
79
81
  "devDependencies": {
80
82
  "concurrently": "^8.2.2"
@@ -0,0 +1,27 @@
1
+ import { HealthReport } from "@mcp-showcase/ui-kit";
2
+ type A11yImpact = "critical" | "serious" | "moderate" | "minor";
3
+ interface A11yIssueLike {
4
+ rule: string;
5
+ impact: A11yImpact;
6
+ element: string;
7
+ file: string;
8
+ line: number;
9
+ description: string;
10
+ fix: string;
11
+ wcag: string;
12
+ }
13
+ interface A11ySummaryLike {
14
+ filesScanned: number;
15
+ totalIssues: number;
16
+ critical: number;
17
+ serious: number;
18
+ moderate: number;
19
+ minor: number;
20
+ }
21
+ export interface A11yResultLike {
22
+ summary: A11ySummaryLike;
23
+ issues: A11yIssueLike[];
24
+ }
25
+ export declare function toHealthReport(result: A11yResultLike, generatedAt: string): HealthReport;
26
+ export {};
27
+ //# sourceMappingURL=health-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-report.d.ts","sourceRoot":"","sources":["../src/health-report.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAoE,MAAM,sBAAsB,CAAC;AAEtH,KAAK,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAEhE,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,eAAe;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAwHD,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,CA0BxF"}
@@ -0,0 +1,140 @@
1
+ // Map accessibility-checker result -> shared ui-kit HealthReport for the MCP App dashboard.
2
+ import * as path from "path";
3
+ import { scoreToBand } from "@mcp-showcase/ui-kit";
4
+ const WEIGHT = { critical: 26, high: 15, medium: 8, low: 3 };
5
+ const RULE_TO_CATEGORY = {
6
+ "image-alt": "images",
7
+ "button-name": "keyboard",
8
+ "link-name": "keyboard",
9
+ "tabindex": "keyboard",
10
+ "aria-roles": "aria",
11
+ "aria-hidden-focus": "aria",
12
+ "label": "forms",
13
+ "input-image-alt": "forms",
14
+ "color-contrast": "contrast",
15
+ "html-lang": "structure",
16
+ "landmark-one-main": "structure",
17
+ "heading-order": "structure",
18
+ "duplicate-id": "structure",
19
+ };
20
+ const CAT_NAMES = {
21
+ images: "Images",
22
+ keyboard: "Keyboard & Focus",
23
+ aria: "ARIA",
24
+ forms: "Forms",
25
+ contrast: "Color Contrast",
26
+ structure: "Page Structure",
27
+ other: "Other",
28
+ };
29
+ function toSeverity(impact) {
30
+ if (impact === "critical")
31
+ return "critical";
32
+ if (impact === "serious")
33
+ return "high";
34
+ if (impact === "moderate")
35
+ return "medium";
36
+ return "low";
37
+ }
38
+ function buildIssues(result) {
39
+ return result.issues.map((i, idx) => {
40
+ const actions = [
41
+ {
42
+ id: `fix:${i.rule}:${idx}`,
43
+ label: "Fix with component-fixer",
44
+ kind: "tool",
45
+ tool: "component-fixer",
46
+ params: { file: i.file, rule: i.rule },
47
+ fallback: `In ${path.basename(i.file)} line ${i.line}: ${i.fix}`,
48
+ },
49
+ {
50
+ id: `explain:${i.rule}:${idx}`,
51
+ label: "Explain this violation",
52
+ kind: "prompt",
53
+ prompt: `WCAG ${i.wcag} — ${i.description}. Explain why this matters and show a concrete fix for: ${i.element}`,
54
+ },
55
+ ];
56
+ return {
57
+ id: `${i.rule}:${idx}`,
58
+ category: RULE_TO_CATEGORY[i.rule] ?? "other",
59
+ severity: toSeverity(i.impact),
60
+ title: i.description,
61
+ description: i.fix,
62
+ file: `${path.basename(i.file)}:${i.line}`,
63
+ meta: [
64
+ { label: "Rule", value: i.rule },
65
+ { label: "WCAG", value: i.wcag },
66
+ { label: "Line", value: String(i.line) },
67
+ { label: "Element", value: i.element.slice(0, 80) },
68
+ ],
69
+ actions,
70
+ };
71
+ });
72
+ }
73
+ function buildCategories(issues) {
74
+ const catIds = [...new Set([...Object.keys(CAT_NAMES), ...issues.map((i) => i.category)])];
75
+ return catIds.map((id) => {
76
+ const own = issues.filter((i) => i.category === id);
77
+ const penalty = own.reduce((sum, i) => sum + WEIGHT[i.severity], 0);
78
+ const score = Math.max(0, Math.min(100, 100 - penalty));
79
+ const worst = own.slice().sort((a, b) => WEIGHT[b.severity] - WEIGHT[a.severity])[0];
80
+ return {
81
+ id,
82
+ name: CAT_NAMES[id] ?? id,
83
+ score,
84
+ status: scoreToBand(score),
85
+ summary: own.length === 0 ? "No issues detected." : worst.title,
86
+ issueCount: own.length,
87
+ };
88
+ });
89
+ }
90
+ function buildTopActions(result, targetPath) {
91
+ const { summary } = result;
92
+ const urgentCount = summary.critical + summary.serious;
93
+ const actions = [];
94
+ if (urgentCount > 0) {
95
+ actions.push({
96
+ id: "top:critical",
97
+ label: `Fix ${urgentCount} critical/serious violation${urgentCount === 1 ? "" : "s"}`,
98
+ kind: "tool",
99
+ tool: "component-fixer",
100
+ params: { path: targetPath, severity: "critical" },
101
+ fallback: `Address the ${urgentCount} critical and serious WCAG violations in ${targetPath}.`,
102
+ });
103
+ }
104
+ if (summary.totalIssues > 0) {
105
+ actions.push({
106
+ id: "top:audit",
107
+ label: "Re-run accessibility audit after fixes",
108
+ kind: "prompt",
109
+ prompt: `After applying accessibility fixes in ${targetPath}, re-run check_accessibility and confirm all critical violations are resolved.`,
110
+ });
111
+ }
112
+ actions.push({ id: "top:wcag", label: "View WCAG 2.1 quick reference", kind: "link", href: "https://www.w3.org/WAI/WCAG21/quickref/" });
113
+ return actions.slice(0, 3);
114
+ }
115
+ export function toHealthReport(result, generatedAt) {
116
+ const issues = buildIssues(result);
117
+ const { summary } = result;
118
+ const targetPath = result.issues[0]?.file ?? "unknown";
119
+ const target = path.basename(path.dirname(targetPath)) || path.basename(targetPath);
120
+ const penalty = summary.critical * WEIGHT.critical +
121
+ summary.serious * WEIGHT.high +
122
+ summary.moderate * WEIGHT.medium +
123
+ summary.minor * WEIGHT.low;
124
+ const score = Math.max(0, Math.min(100, 100 - penalty));
125
+ return {
126
+ meta: { title: "Accessibility Audit", subtitle: `${summary.filesScanned} file${summary.filesScanned === 1 ? "" : "s"} scanned`, target, generatedAt, tool: "accessibility-checker" },
127
+ score,
128
+ totalIssues: summary.totalIssues,
129
+ chips: [
130
+ { label: "Files", value: String(summary.filesScanned) },
131
+ { label: "Critical", value: String(summary.critical) },
132
+ { label: "Serious", value: String(summary.serious) },
133
+ { label: "Moderate + Minor", value: String(summary.moderate + summary.minor) },
134
+ ],
135
+ topActions: buildTopActions(result, targetPath),
136
+ categories: buildCategories(issues),
137
+ issues,
138
+ };
139
+ }
140
+ //# sourceMappingURL=health-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-report.js","sourceRoot":"","sources":["../src/health-report.ts"],"names":[],"mappings":"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"}