@kb-labs/studio-app 0.6.0 → 2.8.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 (175) hide show
  1. package/dist/index.html +1 -0
  2. package/dist/main.1d68e922.js +522 -0
  3. package/dist/main.1d68e922.js.map +1 -0
  4. package/dist/main.80b70197.css +2 -0
  5. package/dist/main.80b70197.css.map +1 -0
  6. package/dist/mf-manifest.json +241 -0
  7. package/dist/mf-stats.json +271 -0
  8. package/package.json +56 -39
  9. package/server.js +68 -0
  10. package/.env.example +0 -10
  11. package/UI-KIT-COMPONENTS.md +0 -783
  12. package/UI-KIT-PLAN.md +0 -326
  13. package/eslint-rules/no-direct-antd-import.js +0 -151
  14. package/eslint.config.ts +0 -27
  15. package/index.html +0 -17
  16. package/postcss.config.js +0 -7
  17. package/public/favicon.ico +0 -0
  18. package/rspack.config.mjs +0 -118
  19. package/src/App.tsx +0 -46
  20. package/src/components/devtools/devtools-log-feed.module.css +0 -165
  21. package/src/components/devtools/devtools-log-feed.tsx +0 -300
  22. package/src/components/devtools/devtools-panel.module.css +0 -121
  23. package/src/components/devtools/devtools-panel.tsx +0 -115
  24. package/src/components/empty-state.tsx +0 -28
  25. package/src/components/error-boundary.tsx +0 -210
  26. package/src/components/health-banner.module.css +0 -103
  27. package/src/components/health-banner.tsx +0 -134
  28. package/src/components/health-indicator.tsx +0 -12
  29. package/src/components/page-header.tsx +0 -49
  30. package/src/components/page-transition.tsx +0 -24
  31. package/src/components/role-switcher.tsx +0 -148
  32. package/src/components/run-badge.tsx +0 -13
  33. package/src/components/ui/icons.tsx +0 -509
  34. package/src/components/ui/index.ts +0 -25
  35. package/src/components/ui/kb-config-provider.tsx +0 -130
  36. package/src/components/ui/kb-header.module.css +0 -51
  37. package/src/components/ui/kb-header.tsx +0 -112
  38. package/src/components/ui/kb-notification-bell.module.css +0 -103
  39. package/src/components/ui/kb-notification-bell.tsx +0 -199
  40. package/src/components/ui/kb-page-layout.tsx +0 -66
  41. package/src/components/ui/kb-quick-search.module.css +0 -86
  42. package/src/components/ui/kb-quick-search.tsx +0 -196
  43. package/src/components/ui/kb-sidebar.module.css +0 -47
  44. package/src/components/ui/kb-sidebar.tsx +0 -196
  45. package/src/components/ui/kb-stat-card.module.css +0 -21
  46. package/src/components/ui/kb-stat-card.tsx +0 -22
  47. package/src/components/ui/kb-stat-grid.tsx +0 -22
  48. package/src/components/ui/kb-status-bar.module.css +0 -49
  49. package/src/components/ui/kb-status-bar.tsx +0 -145
  50. package/src/components/ui/kb-system-health-indicator.tsx +0 -229
  51. package/src/components/ui/kb-theme-toggle.tsx +0 -42
  52. package/src/components/ui/theme-adapter.ts +0 -812
  53. package/src/components/ui/theme-transition-overlay.tsx +0 -70
  54. package/src/components/ui/utils.ts +0 -6
  55. package/src/components/widget-error-boundary.tsx +0 -172
  56. package/src/config/env.ts +0 -5
  57. package/src/config/feature-flags.ts +0 -482
  58. package/src/config/studio.config.schema.ts +0 -88
  59. package/src/config/studio.config.ts +0 -84
  60. package/src/env.d.ts +0 -23
  61. package/src/hooks/use-command-palette.ts +0 -6
  62. package/src/hooks/use-devtools-store.ts +0 -25
  63. package/src/hooks/use-feature-flags.ts +0 -101
  64. package/src/index.css +0 -10
  65. package/src/layouts/dashboard-grid.tsx +0 -122
  66. package/src/layouts/index.ts +0 -12
  67. package/src/layouts/two-pane.tsx +0 -134
  68. package/src/main.tsx +0 -15
  69. package/src/modules/analytics/components/analytics-daily-stats-chart.tsx +0 -257
  70. package/src/modules/analytics/components/analytics-date-range-picker.tsx +0 -121
  71. package/src/modules/analytics/pages/analytics-cache-page.tsx +0 -285
  72. package/src/modules/analytics/pages/analytics-embeddings-page.tsx +0 -274
  73. package/src/modules/analytics/pages/analytics-events-page.tsx +0 -425
  74. package/src/modules/analytics/pages/analytics-llm-page.tsx +0 -434
  75. package/src/modules/analytics/pages/analytics-overview-page.tsx +0 -336
  76. package/src/modules/analytics/pages/analytics-page.tsx +0 -20
  77. package/src/modules/analytics/pages/analytics-storage-page.tsx +0 -344
  78. package/src/modules/analytics/pages/analytics-vectorstore-page.tsx +0 -279
  79. package/src/modules/analytics/routes/index.tsx +0 -133
  80. package/src/modules/analytics/utils/formatters.test.ts +0 -148
  81. package/src/modules/analytics/utils/formatters.ts +0 -100
  82. package/src/modules/auth/pages/login-page.module.css +0 -113
  83. package/src/modules/auth/pages/login-page.tsx +0 -80
  84. package/src/modules/auth/routes/index.tsx +0 -24
  85. package/src/modules/dashboard/components/ActivityTimelineWidget.tsx +0 -199
  86. package/src/modules/dashboard/components/AiInsightsWidget.tsx +0 -358
  87. package/src/modules/dashboard/components/AnimatedMetricCard.css +0 -88
  88. package/src/modules/dashboard/components/AnimatedMetricCard.tsx +0 -125
  89. package/src/modules/dashboard/components/HeroMetricCard.css +0 -114
  90. package/src/modules/dashboard/components/HeroMetricCard.tsx +0 -152
  91. package/src/modules/dashboard/components/HeroMetricsWidget.tsx +0 -146
  92. package/src/modules/dashboard/components/SystemResourcesWidget.tsx +0 -197
  93. package/src/modules/dashboard/components/dashboard-empty.tsx +0 -22
  94. package/src/modules/dashboard/components/dashboard-kpis-widget.tsx +0 -59
  95. package/src/modules/dashboard/components/dashboard-kpis.tsx +0 -13
  96. package/src/modules/dashboard/components/dashboard-latency-percentiles-widget.tsx +0 -85
  97. package/src/modules/dashboard/components/dashboard-metrics-widget.tsx +0 -78
  98. package/src/modules/dashboard/components/dashboard-plugins-widget.tsx +0 -67
  99. package/src/modules/dashboard/components/dashboard-requests-widget.tsx +0 -62
  100. package/src/modules/dashboard/layouts/dashboard-layout.tsx +0 -16
  101. package/src/modules/dashboard/pages/ai-insights-page.tsx +0 -563
  102. package/src/modules/dashboard/pages/dashboard-animations.css +0 -317
  103. package/src/modules/dashboard/pages/dashboard-page.tsx +0 -13
  104. package/src/modules/dashboard/routes/index.tsx +0 -70
  105. package/src/modules/observability/pages/devkit-page.tsx +0 -263
  106. package/src/modules/observability/pages/incident-detail-page.tsx +0 -571
  107. package/src/modules/observability/pages/incidents-page.tsx +0 -370
  108. package/src/modules/observability/pages/log-detail-page.tsx +0 -508
  109. package/src/modules/observability/pages/logs-page.tsx +0 -1129
  110. package/src/modules/observability/pages/prometheus-metrics-page.tsx +0 -486
  111. package/src/modules/observability/pages/state-broker-page.tsx +0 -229
  112. package/src/modules/observability/pages/system-events-page.tsx +0 -255
  113. package/src/modules/observability/routes/index.tsx +0 -133
  114. package/src/modules/plugins/components/marketplace-card.tsx +0 -153
  115. package/src/modules/plugins/components/plugin-ai-assistant-modal.tsx +0 -374
  116. package/src/modules/plugins/components/plugin-card.tsx +0 -136
  117. package/src/modules/plugins/components/plugin-detail/capabilities-summary.tsx +0 -101
  118. package/src/modules/plugins/components/plugin-detail/cli-commands-table.tsx +0 -101
  119. package/src/modules/plugins/components/plugin-detail/index.ts +0 -7
  120. package/src/modules/plugins/components/plugin-detail/jobs-table.tsx +0 -64
  121. package/src/modules/plugins/components/plugin-detail/permissions/env-permissions.tsx +0 -30
  122. package/src/modules/plugins/components/plugin-detail/permissions/filesystem-permissions.tsx +0 -68
  123. package/src/modules/plugins/components/plugin-detail/permissions/index.ts +0 -6
  124. package/src/modules/plugins/components/plugin-detail/permissions/network-permissions.tsx +0 -43
  125. package/src/modules/plugins/components/plugin-detail/permissions/platform-services.tsx +0 -242
  126. package/src/modules/plugins/components/plugin-detail/permissions/resource-quotas.tsx +0 -96
  127. package/src/modules/plugins/components/plugin-detail/permissions/shell-permissions.tsx +0 -55
  128. package/src/modules/plugins/components/plugin-detail/permissions-view.tsx +0 -47
  129. package/src/modules/plugins/components/plugin-detail/plugin-header.tsx +0 -169
  130. package/src/modules/plugins/components/plugin-detail/rest-routes-table.tsx +0 -159
  131. package/src/modules/plugins/components/plugin-detail/workflows-table.tsx +0 -40
  132. package/src/modules/plugins/components/plugin-grid.tsx +0 -20
  133. package/src/modules/plugins/components/plugin-table.tsx +0 -178
  134. package/src/modules/plugins/pages/marketplace-page.tsx +0 -200
  135. package/src/modules/plugins/pages/plugin-detail-page.tsx +0 -1145
  136. package/src/modules/plugins/routes/index.tsx +0 -48
  137. package/src/modules/plugins/utils/index.ts +0 -1
  138. package/src/modules/plugins/utils/schema-helpers.ts +0 -21
  139. package/src/modules/settings/components/api-routes-viewer.tsx +0 -415
  140. package/src/modules/settings/components/appearance-settings.tsx +0 -200
  141. package/src/modules/settings/components/configuration-settings.tsx +0 -321
  142. package/src/modules/settings/components/data-privacy-settings.tsx +0 -111
  143. package/src/modules/settings/components/experimental-settings.tsx +0 -243
  144. package/src/modules/settings/components/navigation-settings.tsx +0 -198
  145. package/src/modules/settings/components/notifications-settings.tsx +0 -40
  146. package/src/modules/settings/pages/settings-page.tsx +0 -298
  147. package/src/modules/settings/routes/index.tsx +0 -47
  148. package/src/pages/README-assistant.md +0 -91
  149. package/src/pages/login-page.tsx +0 -177
  150. package/src/pages/not-found-page.tsx +0 -85
  151. package/src/providers/auth-provider.tsx +0 -40
  152. package/src/providers/command-palette-provider.tsx +0 -193
  153. package/src/providers/data-sources-provider.tsx +0 -27
  154. package/src/providers/devtools-provider.tsx +0 -72
  155. package/src/providers/navigation-items-provider.tsx +0 -38
  156. package/src/providers/registry-v2-provider.tsx +0 -93
  157. package/src/providers/settings-provider.tsx +0 -158
  158. package/src/router.tsx +0 -302
  159. package/src/routes/helpers.tsx +0 -25
  160. package/src/routes/plugin-page-v2.tsx +0 -52
  161. package/src/routes/types.ts +0 -18
  162. package/src/styles/antd-overrides.css +0 -211
  163. package/src/styles/base.css +0 -190
  164. package/src/styles/settings.css +0 -75
  165. package/src/styles/variables.css +0 -94
  166. package/src/utils/analytics.ts +0 -183
  167. package/src/utils/apply-navigation-categories.ts +0 -83
  168. package/src/utils/commands.ts +0 -252
  169. package/src/utils/export.ts +0 -174
  170. package/src/utils/format-date.ts +0 -166
  171. package/src/utils/logger.ts +0 -110
  172. package/tailwind.config.ts +0 -13
  173. package/tsconfig.json +0 -13
  174. package/vitest-setup.ts +0 -1
  175. /package/{public → dist}/favicon.svg +0 -0
@@ -1,317 +0,0 @@
1
- /* Dashboard Widget Animations */
2
-
3
- /* Fade-in animation for widgets */
4
- @keyframes fadeInUp {
5
- from {
6
- opacity: 0;
7
- transform: translateY(20px);
8
- }
9
- to {
10
- opacity: 1;
11
- transform: translateY(0);
12
- }
13
- }
14
-
15
- @keyframes fadeIn {
16
- from {
17
- opacity: 0;
18
- }
19
- to {
20
- opacity: 1;
21
- }
22
- }
23
-
24
- /* Apply animations to widgets with staggered delays */
25
- .dashboard-widget {
26
- animation: fadeInUp 0.6s ease-out forwards;
27
- animation-delay: calc(var(--widget-index) * 0.08s);
28
- opacity: 0;
29
- }
30
-
31
- /* Grid layout smooth transitions */
32
- .react-grid-item {
33
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
34
- }
35
-
36
- .react-grid-item.react-grid-placeholder {
37
- background: rgba(24, 144, 255, 0.1) !important;
38
- opacity: 0.8 !important;
39
- transition: all 0.2s ease !important;
40
- border: 2px dashed #1890ff !important;
41
- border-radius: 8px !important;
42
- }
43
-
44
- /* Widget hover effect */
45
- .dashboard-widget:hover {
46
- transform: translateY(-2px);
47
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
48
- }
49
-
50
- /* Drag handle hover */
51
- .drag-handle {
52
- transition: all 0.2s ease;
53
- opacity: 0.5;
54
- }
55
-
56
- .dashboard-widget:hover .drag-handle {
57
- opacity: 1;
58
- color: #1890ff !important;
59
- }
60
-
61
- /* Loading shimmer effect for skeleton */
62
- @keyframes shimmer {
63
- 0% {
64
- background-position: -1000px 0;
65
- }
66
- 100% {
67
- background-position: 1000px 0;
68
- }
69
- }
70
-
71
- .skeleton-loading {
72
- animation: shimmer 2s infinite linear;
73
- background: linear-gradient(
74
- 90deg,
75
- #f0f0f0 25%,
76
- #e0e0e0 37%,
77
- #f0f0f0 63%
78
- );
79
- background-size: 1000px 100%;
80
- }
81
-
82
- /* Card content fade-in */
83
- .ant-card-body {
84
- animation: fadeIn 0.4s ease-out 0.2s forwards;
85
- }
86
-
87
- /* Header animation */
88
- .kb-page-header {
89
- animation: fadeInUp 0.5s ease-out;
90
- }
91
-
92
- /* Smooth scroll behavior */
93
- .ant-card-body {
94
- scroll-behavior: smooth;
95
- }
96
-
97
- /* Chart animations */
98
- .recharts-surface {
99
- animation: fadeIn 0.6s ease-out;
100
- }
101
-
102
- /* Table row animation */
103
- .ant-table-tbody > tr {
104
- animation: fadeIn 0.3s ease-out;
105
- animation-delay: calc(var(--row-index) * 0.03s);
106
- }
107
-
108
- /* Badge pulse animation */
109
- @keyframes badgePulse {
110
- 0%, 100% {
111
- opacity: 1;
112
- }
113
- 50% {
114
- opacity: 0.7;
115
- }
116
- }
117
-
118
- .ant-badge-count {
119
- animation: badgePulse 2s ease-in-out infinite;
120
- }
121
-
122
- /* Notification bell shake */
123
- @keyframes bellShake {
124
- 0%, 100% { transform: rotate(0deg); }
125
- 10%, 30%, 50%, 70%, 90% { transform: rotate(-10deg); }
126
- 20%, 40%, 60%, 80% { transform: rotate(10deg); }
127
- }
128
-
129
- .notification-bell-animated {
130
- animation: bellShake 0.5s ease-in-out;
131
- }
132
-
133
- /* Progress bar animation */
134
- .ant-progress-line {
135
- animation: fadeIn 0.5s ease-out;
136
- }
137
-
138
- /* Tag animation */
139
- .ant-tag {
140
- animation: fadeIn 0.3s ease-out;
141
- }
142
-
143
- /* Metric value count-up animation */
144
- @keyframes countUp {
145
- from {
146
- opacity: 0;
147
- transform: scale(0.8);
148
- }
149
- to {
150
- opacity: 1;
151
- transform: scale(1);
152
- }
153
- }
154
-
155
- .metric-value {
156
- animation: countUp 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
157
- }
158
-
159
- /* Sparkline draw animation */
160
- @keyframes drawLine {
161
- from {
162
- stroke-dashoffset: 1000;
163
- }
164
- to {
165
- stroke-dashoffset: 0;
166
- }
167
- }
168
-
169
- .sparkline-path {
170
- stroke-dasharray: 1000;
171
- animation: drawLine 1.5s ease-out forwards;
172
- }
173
-
174
- /* Hero card slide-in */
175
- @keyframes slideInRight {
176
- from {
177
- opacity: 0;
178
- transform: translateX(30px);
179
- }
180
- to {
181
- opacity: 1;
182
- transform: translateX(0);
183
- }
184
- }
185
-
186
- .hero-metric-card {
187
- animation: slideInRight 0.5s ease-out;
188
- animation-delay: calc(var(--card-index) * 0.1s);
189
- animation-fill-mode: backwards;
190
- }
191
-
192
- /* Glow effect for live indicators */
193
- @keyframes glow {
194
- 0%, 100% {
195
- box-shadow: 0 0 5px rgba(82, 196, 26, 0.5);
196
- }
197
- 50% {
198
- box-shadow: 0 0 20px rgba(82, 196, 26, 0.8);
199
- }
200
- }
201
-
202
- .live-indicator {
203
- animation: glow 2s ease-in-out infinite;
204
- }
205
-
206
- /* Alert pulse */
207
- @keyframes alertPulse {
208
- 0% {
209
- transform: scale(1);
210
- }
211
- 50% {
212
- transform: scale(1.02);
213
- }
214
- 100% {
215
- transform: scale(1);
216
- }
217
- }
218
-
219
- .ant-alert-warning {
220
- animation: alertPulse 2s ease-in-out infinite;
221
- }
222
-
223
- /* Topology node pulse */
224
- @keyframes nodePulse {
225
- 0%, 100% {
226
- opacity: 1;
227
- }
228
- 50% {
229
- opacity: 0.6;
230
- }
231
- }
232
-
233
- .react-flow__node {
234
- animation: fadeIn 0.5s ease-out;
235
- }
236
-
237
- .react-flow__edge {
238
- animation: fadeIn 0.7s ease-out 0.3s backwards;
239
- }
240
-
241
- /* Heatmap cell animation */
242
- @keyframes heatmapReveal {
243
- from {
244
- opacity: 0;
245
- transform: scale(0);
246
- }
247
- to {
248
- opacity: 1;
249
- transform: scale(1);
250
- }
251
- }
252
-
253
- .heatmap-cell {
254
- animation: heatmapReveal 0.3s ease-out;
255
- animation-delay: calc(var(--cell-index) * 0.01s);
256
- animation-fill-mode: backwards;
257
- }
258
-
259
- /* Modal entrance */
260
- .ant-modal {
261
- animation: fadeInUp 0.3s ease-out !important;
262
- }
263
-
264
- /* Tooltip smooth appearance */
265
- .ant-tooltip {
266
- animation: fadeIn 0.2s ease-out !important;
267
- }
268
-
269
- /* Loading spinner */
270
- @keyframes spin {
271
- from {
272
- transform: rotate(0deg);
273
- }
274
- to {
275
- transform: rotate(360deg);
276
- }
277
- }
278
-
279
- .loading-spinner {
280
- animation: spin 1s linear infinite;
281
- }
282
-
283
- /* Success checkmark animation */
284
- @keyframes checkmark {
285
- 0% {
286
- stroke-dashoffset: 100;
287
- }
288
- 100% {
289
- stroke-dashoffset: 0;
290
- }
291
- }
292
-
293
- .success-checkmark {
294
- stroke-dasharray: 100;
295
- animation: checkmark 0.5s ease-out forwards;
296
- }
297
-
298
- /* Responsive animations - disable on mobile for performance */
299
- @media (max-width: 768px) {
300
- .dashboard-widget,
301
- .hero-metric-card,
302
- .ant-table-tbody > tr {
303
- animation: none !important;
304
- opacity: 1 !important;
305
- }
306
- }
307
-
308
- /* Reduce motion for users who prefer it */
309
- @media (prefers-reduced-motion: reduce) {
310
- *,
311
- *::before,
312
- *::after {
313
- animation-duration: 0.01ms !important;
314
- animation-iteration-count: 1 !important;
315
- transition-duration: 0.01ms !important;
316
- }
317
- }
@@ -1,13 +0,0 @@
1
- import { HeroMetricsWidget } from '../components/HeroMetricsWidget';
2
- import { ActivityTimelineWidget } from '../components/ActivityTimelineWidget';
3
- import { SystemResourcesWidget } from '../components/SystemResourcesWidget';
4
-
5
- export function DashboardPage() {
6
- return (
7
- <div style={{ display: 'flex', flexDirection: 'column', gap: 24, paddingTop: 8 }}>
8
- <HeroMetricsWidget />
9
- <SystemResourcesWidget />
10
- <ActivityTimelineWidget />
11
- </div>
12
- );
13
- }
@@ -1,70 +0,0 @@
1
- /**
2
- * @module @kb-labs/studio-app/modules/dashboard/routes
3
- * Dashboard module routing configuration
4
- */
5
-
6
- import type { RouteObject } from 'react-router-dom';
7
- import { DashboardPage } from '../pages/dashboard-page';
8
- import { AIInsightsPage } from '../pages/ai-insights-page';
9
- import { DashboardLayout } from '../layouts/dashboard-layout';
10
- import { ErrorBoundary } from '../../../components/error-boundary';
11
- import { renderIcon } from '../../../routes/helpers';
12
- import type { NavigationItem } from '@/components/ui';
13
-
14
- // Route paths
15
- const PATHS = {
16
- ROOT: '/',
17
- INSIGHTS: '/insights',
18
- } as const;
19
-
20
- // Route keys
21
- const KEYS = {
22
- MODULE: 'dashboard',
23
- OVERVIEW: 'dashboard-overview',
24
- INSIGHTS: 'dashboard-insights',
25
- } as const;
26
-
27
- /**
28
- * Dashboard routes
29
- */
30
- export const dashboardRoutes: RouteObject[] = [
31
- {
32
- path: PATHS.ROOT,
33
- element: <DashboardLayout />,
34
- errorElement: <ErrorBoundary />,
35
- children: [
36
- {
37
- index: true,
38
- element: <DashboardPage />,
39
- },
40
- ],
41
- },
42
- {
43
- path: PATHS.INSIGHTS,
44
- element: <AIInsightsPage />,
45
- errorElement: <ErrorBoundary />,
46
- },
47
- ];
48
-
49
- /**
50
- * Dashboard navigation items for sidebar
51
- */
52
- export const dashboardNavigation: NavigationItem = {
53
- key: KEYS.MODULE,
54
- label: 'Dashboard',
55
- icon: renderIcon('DashboardOutlined'),
56
- children: [
57
- {
58
- key: KEYS.OVERVIEW,
59
- label: 'Overview',
60
- path: PATHS.ROOT,
61
- icon: renderIcon('DashboardOutlined'),
62
- },
63
- {
64
- key: KEYS.INSIGHTS,
65
- label: 'AI Insights',
66
- path: PATHS.INSIGHTS,
67
- icon: renderIcon('RobotOutlined'),
68
- },
69
- ],
70
- };
@@ -1,263 +0,0 @@
1
- import {
2
- UIRow,
3
- UICol,
4
- UITable,
5
- UICard,
6
- UIStatistic,
7
- UITag,
8
- UIAlert,
9
- UIProgress,
10
- UIIcon,
11
- } from '@kb-labs/studio-ui-kit';
12
- import { useDevKitHealth } from '@kb-labs/studio-data-client';
13
- import { useDataSources } from '../../../providers/data-sources-provider';
14
- import { UIPage, UIPageHeader } from '@kb-labs/studio-ui-kit';
15
-
16
- /**
17
- * Get color for health grade
18
- */
19
- function getGradeColor(grade: string): string {
20
- switch (grade) {
21
- case 'A':
22
- return 'success';
23
- case 'B':
24
- return 'processing';
25
- case 'C':
26
- return 'warning';
27
- case 'D':
28
- case 'F':
29
- return 'error';
30
- default:
31
- return 'default';
32
- }
33
- }
34
-
35
- /**
36
- * Get icon for health grade
37
- */
38
- function getGradeIcon(grade: string) {
39
- switch (grade) {
40
- case 'A':
41
- return <UIIcon name="CheckCircleOutlined" style={{ color: '#52c41a' }} />;
42
- case 'B':
43
- return <UIIcon name="CheckCircleOutlined" style={{ color: '#1890ff' }} />;
44
- case 'C':
45
- return <UIIcon name="WarningOutlined" style={{ color: '#faad14' }} />;
46
- case 'D':
47
- return <UIIcon name="ExclamationCircleOutlined" style={{ color: '#ff7a45' }} />;
48
- case 'F':
49
- return <UIIcon name="CloseCircleOutlined" style={{ color: '#ff4d4f' }} />;
50
- default:
51
- return <UIIcon name="ExclamationCircleOutlined" />;
52
- }
53
- }
54
-
55
- /**
56
- * Get status for health score progress bar
57
- */
58
- function getScoreStatus(score: number): 'success' | 'normal' | 'exception' {
59
- if (score >= 80) {return 'success';}
60
- if (score >= 60) {return 'normal';}
61
- return 'exception';
62
- }
63
-
64
- /**
65
- * Format issue key to human-readable label
66
- */
67
- function formatIssueLabel(key: string): string {
68
- return key
69
- .replace(/([A-Z])/g, ' $1')
70
- .replace(/^./, str => str.toUpperCase())
71
- .trim();
72
- }
73
-
74
- /**
75
- * DevKit Health Observability Page
76
- *
77
- * Shows monorepo health metrics from DevKit:
78
- * - Health score and grade
79
- * - Issues breakdown (duplicate deps, type errors, etc.)
80
- * - Package count and type coverage
81
- */
82
- export function DevKitPage() {
83
- const sources = useDataSources();
84
- const { data, isLoading, error, isError } = useDevKitHealth(sources.observability);
85
-
86
- if (isError) {
87
- return (
88
- <UIPage>
89
- <UIPageHeader
90
- title="DevKit Health"
91
- description="Monorepo health and quality metrics"
92
- />
93
- <UIAlert
94
- message="Failed to load DevKit health"
95
- description={error instanceof Error ? error.message : 'Unknown error. Make sure DevKit is installed and executable.'}
96
- variant="error"
97
- showIcon
98
- style={{ marginBottom: 24 }}
99
- />
100
- </UIPage>
101
- );
102
- }
103
-
104
- if (isLoading || !data) {
105
- return (
106
- <UIPage>
107
- <UIPageHeader
108
- title="DevKit Health"
109
- description="Monorepo health and quality metrics"
110
- />
111
- <div style={{ padding: '24px 0', textAlign: 'center' }}>
112
- Loading DevKit health check... (this may take up to 30 seconds)
113
- </div>
114
- </UIPage>
115
- );
116
- }
117
-
118
- const totalIssues = Object.values(data.issues).reduce((sum: number, count) => sum + (count ?? 0), 0);
119
-
120
- return (
121
- <UIPage width="full">
122
- <UIPageHeader
123
- title="DevKit Health"
124
- description="Monorepo health and quality metrics - Cached for 1 minute"
125
- />
126
-
127
- {/* Overview Stats */}
128
- <UIRow gutter={[16, 16]} style={{ marginBottom: 24 }}>
129
- <UICol xs={24} sm={12} lg={8}>
130
- <UICard>
131
- <UIStatistic
132
- title="Health Score"
133
- value={data.healthScore}
134
- suffix="/ 100"
135
- prefix={getGradeIcon(data.grade)}
136
- valueStyle={{
137
- color: data.healthScore >= 80 ? '#52c41a' :
138
- data.healthScore >= 60 ? '#1890ff' :
139
- '#ff4d4f'
140
- }}
141
- />
142
- <div style={{ marginTop: 8 }}>
143
- <UITag color={getGradeColor(data.grade)} style={{ fontSize: 14 }}>
144
- Grade {data.grade}
145
- </UITag>
146
- </div>
147
- </UICard>
148
- </UICol>
149
- <UICol xs={24} sm={12} lg={8}>
150
- <UICard>
151
- <UIStatistic
152
- title="Total Packages"
153
- value={data.packages}
154
- prefix={<UIIcon name="CodeOutlined" />}
155
- />
156
- </UICard>
157
- </UICol>
158
- <UICol xs={24} sm={12} lg={8}>
159
- <UICard>
160
- <UIStatistic
161
- title="Total Issues"
162
- value={totalIssues}
163
- prefix={<UIIcon name="WarningOutlined" />}
164
- valueStyle={{ color: totalIssues > 100 ? '#ff4d4f' : '#faad14' }}
165
- />
166
- </UICard>
167
- </UICol>
168
- </UIRow>
169
-
170
- {/* Health Score Progress */}
171
- <UICard title="Health Score Breakdown" style={{ marginBottom: 24 }}>
172
- <UIProgress
173
- percent={data.healthScore}
174
- status={getScoreStatus(data.healthScore)}
175
- strokeColor={
176
- data.healthScore >= 80 ? '#52c41a' :
177
- data.healthScore >= 60 ? '#1890ff' :
178
- '#ff4d4f'
179
- }
180
- />
181
- <div style={{ marginTop: 16, fontSize: 12, color: '#8c8c8c' }}>
182
- {data.healthScore >= 90 ? 'Excellent monorepo health!' :
183
- data.healthScore >= 80 ? 'Good health - minor improvements needed' :
184
- data.healthScore >= 70 ? 'Moderate health - some issues to address' :
185
- data.healthScore >= 60 ? 'Fair health - significant issues present' :
186
- 'Poor health - urgent attention required'}
187
- </div>
188
- </UICard>
189
-
190
- {/* Type Coverage (if available) */}
191
- {data.avgTypeCoverage !== undefined && (
192
- <UIRow gutter={[16, 16]} style={{ marginBottom: 24 }}>
193
- <UICol span={24}>
194
- <UICard title="TypeScript Type Coverage">
195
- <UIProgress
196
- percent={Math.round(data.avgTypeCoverage)}
197
- status={data.avgTypeCoverage >= 90 ? 'success' : data.avgTypeCoverage >= 70 ? 'normal' : 'exception'}
198
- strokeColor={data.avgTypeCoverage >= 90 ? '#52c41a' : data.avgTypeCoverage >= 70 ? '#1890ff' : '#faad14'}
199
- />
200
- <div style={{ marginTop: 8, fontSize: 12, color: '#8c8c8c' }}>
201
- Average type coverage across all packages
202
- </div>
203
- </UICard>
204
- </UICol>
205
- </UIRow>
206
- )}
207
-
208
- {/* Issues Breakdown Table */}
209
- <UICard title="Issues Breakdown">
210
- <UITable
211
- dataSource={Object.entries(data.issues)
212
- .map(([key, count]) => ({
213
- key,
214
- issue: formatIssueLabel(key),
215
- count: count ?? 0,
216
- severity: (count ?? 0) > 100 ? 'high' : (count ?? 0) > 10 ? 'medium' : 'low',
217
- }))
218
- .sort((a, b) => b.count - a.count)} // Sort by count descending
219
- columns={[
220
- {
221
- title: 'Issue Type',
222
- dataIndex: 'issue',
223
- key: 'issue',
224
- render: (issue: string) => <strong>{issue}</strong>,
225
- },
226
- {
227
- title: 'Count',
228
- dataIndex: 'count',
229
- key: 'count',
230
- align: 'right' as const,
231
- render: (count: number) => (
232
- <span style={{
233
- color: count > 100 ? '#ff4d4f' :
234
- count > 10 ? '#faad14' :
235
- '#52c41a'
236
- }}>
237
- {count.toLocaleString()}
238
- </span>
239
- ),
240
- },
241
- {
242
- title: 'Severity',
243
- dataIndex: 'severity',
244
- key: 'severity',
245
- align: 'center' as const,
246
- render: (severity: string) => {
247
- const config = {
248
- high: { color: 'error', label: 'High' },
249
- medium: { color: 'warning', label: 'Medium' },
250
- low: { color: 'success', label: 'Low' },
251
- }[severity] || { color: 'default', label: 'Unknown' };
252
-
253
- return <UITag color={config.color}>{config.label}</UITag>;
254
- },
255
- },
256
- ]}
257
- pagination={false}
258
- size="small"
259
- />
260
- </UICard>
261
- </UIPage>
262
- );
263
- }