@kb-labs/studio-app 0.6.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.
- package/.env.example +10 -0
- package/README.md +74 -0
- package/UI-KIT-COMPONENTS.md +783 -0
- package/UI-KIT-PLAN.md +326 -0
- package/eslint-rules/no-direct-antd-import.js +151 -0
- package/eslint.config.ts +27 -0
- package/index.html +17 -0
- package/package.json +72 -0
- package/postcss.config.js +7 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +7 -0
- package/rspack.config.mjs +118 -0
- package/src/App.tsx +46 -0
- package/src/components/devtools/devtools-log-feed.module.css +165 -0
- package/src/components/devtools/devtools-log-feed.tsx +300 -0
- package/src/components/devtools/devtools-panel.module.css +121 -0
- package/src/components/devtools/devtools-panel.tsx +115 -0
- package/src/components/empty-state.tsx +28 -0
- package/src/components/error-boundary.tsx +210 -0
- package/src/components/health-banner.module.css +103 -0
- package/src/components/health-banner.tsx +134 -0
- package/src/components/health-indicator.tsx +12 -0
- package/src/components/page-header.tsx +49 -0
- package/src/components/page-transition.tsx +24 -0
- package/src/components/role-switcher.tsx +148 -0
- package/src/components/run-badge.tsx +13 -0
- package/src/components/ui/icons.tsx +509 -0
- package/src/components/ui/index.ts +25 -0
- package/src/components/ui/kb-config-provider.tsx +130 -0
- package/src/components/ui/kb-header.module.css +51 -0
- package/src/components/ui/kb-header.tsx +112 -0
- package/src/components/ui/kb-notification-bell.module.css +103 -0
- package/src/components/ui/kb-notification-bell.tsx +199 -0
- package/src/components/ui/kb-page-layout.tsx +66 -0
- package/src/components/ui/kb-quick-search.module.css +86 -0
- package/src/components/ui/kb-quick-search.tsx +196 -0
- package/src/components/ui/kb-sidebar.module.css +47 -0
- package/src/components/ui/kb-sidebar.tsx +196 -0
- package/src/components/ui/kb-stat-card.module.css +21 -0
- package/src/components/ui/kb-stat-card.tsx +22 -0
- package/src/components/ui/kb-stat-grid.tsx +22 -0
- package/src/components/ui/kb-status-bar.module.css +49 -0
- package/src/components/ui/kb-status-bar.tsx +145 -0
- package/src/components/ui/kb-system-health-indicator.tsx +229 -0
- package/src/components/ui/kb-theme-toggle.tsx +42 -0
- package/src/components/ui/theme-adapter.ts +812 -0
- package/src/components/ui/theme-transition-overlay.tsx +70 -0
- package/src/components/ui/utils.ts +6 -0
- package/src/components/widget-error-boundary.tsx +172 -0
- package/src/config/env.ts +5 -0
- package/src/config/feature-flags.ts +482 -0
- package/src/config/studio.config.schema.ts +88 -0
- package/src/config/studio.config.ts +84 -0
- package/src/env.d.ts +23 -0
- package/src/hooks/use-command-palette.ts +6 -0
- package/src/hooks/use-devtools-store.ts +25 -0
- package/src/hooks/use-feature-flags.ts +101 -0
- package/src/index.css +10 -0
- package/src/layouts/dashboard-grid.tsx +122 -0
- package/src/layouts/index.ts +12 -0
- package/src/layouts/two-pane.tsx +134 -0
- package/src/main.tsx +15 -0
- package/src/modules/analytics/components/analytics-daily-stats-chart.tsx +257 -0
- package/src/modules/analytics/components/analytics-date-range-picker.tsx +121 -0
- package/src/modules/analytics/pages/analytics-cache-page.tsx +285 -0
- package/src/modules/analytics/pages/analytics-embeddings-page.tsx +274 -0
- package/src/modules/analytics/pages/analytics-events-page.tsx +425 -0
- package/src/modules/analytics/pages/analytics-llm-page.tsx +434 -0
- package/src/modules/analytics/pages/analytics-overview-page.tsx +336 -0
- package/src/modules/analytics/pages/analytics-page.tsx +20 -0
- package/src/modules/analytics/pages/analytics-storage-page.tsx +344 -0
- package/src/modules/analytics/pages/analytics-vectorstore-page.tsx +279 -0
- package/src/modules/analytics/routes/index.tsx +133 -0
- package/src/modules/analytics/utils/formatters.test.ts +148 -0
- package/src/modules/analytics/utils/formatters.ts +100 -0
- package/src/modules/auth/pages/login-page.module.css +113 -0
- package/src/modules/auth/pages/login-page.tsx +80 -0
- package/src/modules/auth/routes/index.tsx +24 -0
- package/src/modules/dashboard/components/ActivityTimelineWidget.tsx +199 -0
- package/src/modules/dashboard/components/AiInsightsWidget.tsx +358 -0
- package/src/modules/dashboard/components/AnimatedMetricCard.css +88 -0
- package/src/modules/dashboard/components/AnimatedMetricCard.tsx +125 -0
- package/src/modules/dashboard/components/HeroMetricCard.css +114 -0
- package/src/modules/dashboard/components/HeroMetricCard.tsx +152 -0
- package/src/modules/dashboard/components/HeroMetricsWidget.tsx +146 -0
- package/src/modules/dashboard/components/SystemResourcesWidget.tsx +197 -0
- package/src/modules/dashboard/components/dashboard-empty.tsx +22 -0
- package/src/modules/dashboard/components/dashboard-kpis-widget.tsx +59 -0
- package/src/modules/dashboard/components/dashboard-kpis.tsx +13 -0
- package/src/modules/dashboard/components/dashboard-latency-percentiles-widget.tsx +85 -0
- package/src/modules/dashboard/components/dashboard-metrics-widget.tsx +78 -0
- package/src/modules/dashboard/components/dashboard-plugins-widget.tsx +67 -0
- package/src/modules/dashboard/components/dashboard-requests-widget.tsx +62 -0
- package/src/modules/dashboard/layouts/dashboard-layout.tsx +16 -0
- package/src/modules/dashboard/pages/ai-insights-page.tsx +563 -0
- package/src/modules/dashboard/pages/dashboard-animations.css +317 -0
- package/src/modules/dashboard/pages/dashboard-page.tsx +13 -0
- package/src/modules/dashboard/routes/index.tsx +70 -0
- package/src/modules/observability/pages/devkit-page.tsx +263 -0
- package/src/modules/observability/pages/incident-detail-page.tsx +571 -0
- package/src/modules/observability/pages/incidents-page.tsx +370 -0
- package/src/modules/observability/pages/log-detail-page.tsx +508 -0
- package/src/modules/observability/pages/logs-page.tsx +1129 -0
- package/src/modules/observability/pages/prometheus-metrics-page.tsx +486 -0
- package/src/modules/observability/pages/state-broker-page.tsx +229 -0
- package/src/modules/observability/pages/system-events-page.tsx +255 -0
- package/src/modules/observability/routes/index.tsx +133 -0
- package/src/modules/plugins/components/marketplace-card.tsx +153 -0
- package/src/modules/plugins/components/plugin-ai-assistant-modal.tsx +374 -0
- package/src/modules/plugins/components/plugin-card.tsx +136 -0
- package/src/modules/plugins/components/plugin-detail/capabilities-summary.tsx +101 -0
- package/src/modules/plugins/components/plugin-detail/cli-commands-table.tsx +101 -0
- package/src/modules/plugins/components/plugin-detail/index.ts +7 -0
- package/src/modules/plugins/components/plugin-detail/jobs-table.tsx +64 -0
- package/src/modules/plugins/components/plugin-detail/permissions/env-permissions.tsx +30 -0
- package/src/modules/plugins/components/plugin-detail/permissions/filesystem-permissions.tsx +68 -0
- package/src/modules/plugins/components/plugin-detail/permissions/index.ts +6 -0
- package/src/modules/plugins/components/plugin-detail/permissions/network-permissions.tsx +43 -0
- package/src/modules/plugins/components/plugin-detail/permissions/platform-services.tsx +242 -0
- package/src/modules/plugins/components/plugin-detail/permissions/resource-quotas.tsx +96 -0
- package/src/modules/plugins/components/plugin-detail/permissions/shell-permissions.tsx +55 -0
- package/src/modules/plugins/components/plugin-detail/permissions-view.tsx +47 -0
- package/src/modules/plugins/components/plugin-detail/plugin-header.tsx +169 -0
- package/src/modules/plugins/components/plugin-detail/rest-routes-table.tsx +159 -0
- package/src/modules/plugins/components/plugin-detail/workflows-table.tsx +40 -0
- package/src/modules/plugins/components/plugin-grid.tsx +20 -0
- package/src/modules/plugins/components/plugin-table.tsx +178 -0
- package/src/modules/plugins/pages/marketplace-page.tsx +200 -0
- package/src/modules/plugins/pages/plugin-detail-page.tsx +1145 -0
- package/src/modules/plugins/routes/index.tsx +48 -0
- package/src/modules/plugins/utils/index.ts +1 -0
- package/src/modules/plugins/utils/schema-helpers.ts +21 -0
- package/src/modules/settings/components/api-routes-viewer.tsx +415 -0
- package/src/modules/settings/components/appearance-settings.tsx +200 -0
- package/src/modules/settings/components/configuration-settings.tsx +321 -0
- package/src/modules/settings/components/data-privacy-settings.tsx +111 -0
- package/src/modules/settings/components/experimental-settings.tsx +243 -0
- package/src/modules/settings/components/navigation-settings.tsx +198 -0
- package/src/modules/settings/components/notifications-settings.tsx +40 -0
- package/src/modules/settings/pages/settings-page.tsx +298 -0
- package/src/modules/settings/routes/index.tsx +47 -0
- package/src/pages/README-assistant.md +91 -0
- package/src/pages/login-page.tsx +177 -0
- package/src/pages/not-found-page.tsx +85 -0
- package/src/providers/auth-provider.tsx +40 -0
- package/src/providers/command-palette-provider.tsx +193 -0
- package/src/providers/data-sources-provider.tsx +27 -0
- package/src/providers/devtools-provider.tsx +72 -0
- package/src/providers/navigation-items-provider.tsx +38 -0
- package/src/providers/registry-v2-provider.tsx +93 -0
- package/src/providers/settings-provider.tsx +158 -0
- package/src/router.tsx +302 -0
- package/src/routes/helpers.tsx +25 -0
- package/src/routes/plugin-page-v2.tsx +52 -0
- package/src/routes/types.ts +18 -0
- package/src/styles/antd-overrides.css +211 -0
- package/src/styles/base.css +190 -0
- package/src/styles/settings.css +75 -0
- package/src/styles/variables.css +94 -0
- package/src/utils/analytics.ts +183 -0
- package/src/utils/apply-navigation-categories.ts +83 -0
- package/src/utils/commands.ts +252 -0
- package/src/utils/export.ts +174 -0
- package/src/utils/format-date.ts +166 -0
- package/src/utils/logger.ts +110 -0
- package/tailwind.config.ts +13 -0
- package/tsconfig.json +13 -0
- package/vitest-setup.ts +1 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @kb-labs/studio-app/config/feature-flags
|
|
3
|
+
* Feature flags for experimental features
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type FeatureId =
|
|
7
|
+
// UI/UX Features
|
|
8
|
+
| 'command-palette'
|
|
9
|
+
| 'page-transitions'
|
|
10
|
+
| 'toast-notifications'
|
|
11
|
+
| 'bulk-actions'
|
|
12
|
+
| 'context-menu'
|
|
13
|
+
| 'drag-drop'
|
|
14
|
+
| 'keyboard-shortcuts-overlay'
|
|
15
|
+
| 'split-view'
|
|
16
|
+
| 'minimap'
|
|
17
|
+
| 'breadcrumb-history'
|
|
18
|
+
| 'floating-action-button'
|
|
19
|
+
// Developer Tools
|
|
20
|
+
| 'devtools-panel'
|
|
21
|
+
// Performance Features
|
|
22
|
+
| 'virtual-scrolling'
|
|
23
|
+
| 'lazy-loading'
|
|
24
|
+
| 'code-splitting'
|
|
25
|
+
| 'prefetching'
|
|
26
|
+
| 'service-worker'
|
|
27
|
+
| 'websocket-connection'
|
|
28
|
+
// AI Features
|
|
29
|
+
| 'ai-suggestions'
|
|
30
|
+
| 'natural-language-search'
|
|
31
|
+
| 'auto-complete'
|
|
32
|
+
| 'smart-insights'
|
|
33
|
+
// Data Features
|
|
34
|
+
| 'offline-mode'
|
|
35
|
+
| 'auto-save'
|
|
36
|
+
| 'collaborative-editing'
|
|
37
|
+
| 'version-history'
|
|
38
|
+
| 'real-time-sync';
|
|
39
|
+
|
|
40
|
+
export type FeatureGroup =
|
|
41
|
+
| 'ui-ux'
|
|
42
|
+
| 'performance'
|
|
43
|
+
| 'ai'
|
|
44
|
+
| 'data';
|
|
45
|
+
|
|
46
|
+
export type FeatureStatus = 'alpha' | 'beta' | 'stable' | 'deprecated';
|
|
47
|
+
|
|
48
|
+
export type FeatureRisk = 'low' | 'medium' | 'high';
|
|
49
|
+
|
|
50
|
+
export interface FeatureFlag {
|
|
51
|
+
id: FeatureId;
|
|
52
|
+
name: string;
|
|
53
|
+
description: string;
|
|
54
|
+
group: FeatureGroup;
|
|
55
|
+
status: FeatureStatus;
|
|
56
|
+
risk: FeatureRisk;
|
|
57
|
+
enabled: boolean;
|
|
58
|
+
/** Default value when no user preference is set */
|
|
59
|
+
defaultEnabled: boolean;
|
|
60
|
+
/** Long-form details shown in tooltip */
|
|
61
|
+
details?: string;
|
|
62
|
+
/** Related features that might affect this one */
|
|
63
|
+
dependencies?: FeatureId[];
|
|
64
|
+
/** When this feature was added (for "New" badge) */
|
|
65
|
+
addedAt?: string;
|
|
66
|
+
/** If deprecated, when it will be removed */
|
|
67
|
+
deprecatedAt?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const FEATURE_FLAGS: Record<FeatureId, FeatureFlag> = {
|
|
71
|
+
// UI/UX Features
|
|
72
|
+
'command-palette': {
|
|
73
|
+
id: 'command-palette',
|
|
74
|
+
name: 'Command Palette',
|
|
75
|
+
description: 'Quick actions via Cmd/Ctrl+K (like VS Code)',
|
|
76
|
+
details: 'Global keyboard shortcut (Cmd/Ctrl+K) to search and execute commands quickly. Includes fuzzy search, recent actions, and keyboard navigation.',
|
|
77
|
+
group: 'ui-ux',
|
|
78
|
+
status: 'alpha',
|
|
79
|
+
risk: 'low',
|
|
80
|
+
enabled: false,
|
|
81
|
+
defaultEnabled: false,
|
|
82
|
+
addedAt: '2025-12-31',
|
|
83
|
+
},
|
|
84
|
+
'page-transitions': {
|
|
85
|
+
id: 'page-transitions',
|
|
86
|
+
name: 'Page Transitions',
|
|
87
|
+
description: 'Smooth animations when switching between pages',
|
|
88
|
+
details: 'Subtle page transition animations (fade, slide) when navigating between routes. Can be customized or disabled in Dashboard settings.',
|
|
89
|
+
group: 'ui-ux',
|
|
90
|
+
status: 'beta',
|
|
91
|
+
risk: 'low',
|
|
92
|
+
enabled: false,
|
|
93
|
+
defaultEnabled: false,
|
|
94
|
+
addedAt: '2025-12-31',
|
|
95
|
+
},
|
|
96
|
+
'toast-notifications': {
|
|
97
|
+
id: 'toast-notifications',
|
|
98
|
+
name: 'Toast Notifications',
|
|
99
|
+
description: 'Non-blocking notifications for background tasks',
|
|
100
|
+
details: 'Lightweight toast notifications in the bottom-right corner. Better UX than blocking modals for non-critical events.',
|
|
101
|
+
group: 'ui-ux',
|
|
102
|
+
status: 'alpha',
|
|
103
|
+
risk: 'low',
|
|
104
|
+
enabled: false,
|
|
105
|
+
defaultEnabled: false,
|
|
106
|
+
addedAt: '2025-12-31',
|
|
107
|
+
},
|
|
108
|
+
'bulk-actions': {
|
|
109
|
+
id: 'bulk-actions',
|
|
110
|
+
name: 'Bulk Actions',
|
|
111
|
+
description: 'Select and act on multiple items at once',
|
|
112
|
+
details: 'Multi-select checkboxes in tables with bulk operations (delete, archive, export). Includes "Select All" and partial selection indicators.',
|
|
113
|
+
group: 'ui-ux',
|
|
114
|
+
status: 'alpha',
|
|
115
|
+
risk: 'medium',
|
|
116
|
+
enabled: false,
|
|
117
|
+
defaultEnabled: false,
|
|
118
|
+
addedAt: '2025-12-31',
|
|
119
|
+
},
|
|
120
|
+
'context-menu': {
|
|
121
|
+
id: 'context-menu',
|
|
122
|
+
name: 'Context Menu',
|
|
123
|
+
description: 'Right-click context menus for quick actions',
|
|
124
|
+
details: 'Right-click context menus throughout the app for contextual actions. Reduces clicks and improves discoverability.',
|
|
125
|
+
group: 'ui-ux',
|
|
126
|
+
status: 'alpha',
|
|
127
|
+
risk: 'low',
|
|
128
|
+
enabled: false,
|
|
129
|
+
defaultEnabled: false,
|
|
130
|
+
addedAt: '2025-12-31',
|
|
131
|
+
},
|
|
132
|
+
'drag-drop': {
|
|
133
|
+
id: 'drag-drop',
|
|
134
|
+
name: 'Drag & Drop',
|
|
135
|
+
description: 'Drag and drop for reordering and organizing',
|
|
136
|
+
details: 'Drag and drop support for reordering lists, moving items between sections, and file uploads. Uses react-dnd for accessibility.',
|
|
137
|
+
group: 'ui-ux',
|
|
138
|
+
status: 'beta',
|
|
139
|
+
risk: 'medium',
|
|
140
|
+
enabled: false,
|
|
141
|
+
defaultEnabled: false,
|
|
142
|
+
addedAt: '2025-12-31',
|
|
143
|
+
},
|
|
144
|
+
'keyboard-shortcuts-overlay': {
|
|
145
|
+
id: 'keyboard-shortcuts-overlay',
|
|
146
|
+
name: 'Keyboard Shortcuts Overlay',
|
|
147
|
+
description: 'Press "?" to see all keyboard shortcuts',
|
|
148
|
+
details: 'Modal overlay showing all available keyboard shortcuts, grouped by context. Searchable and includes visual key indicators.',
|
|
149
|
+
group: 'ui-ux',
|
|
150
|
+
status: 'alpha',
|
|
151
|
+
risk: 'low',
|
|
152
|
+
enabled: false,
|
|
153
|
+
defaultEnabled: false,
|
|
154
|
+
addedAt: '2025-12-31',
|
|
155
|
+
},
|
|
156
|
+
'split-view': {
|
|
157
|
+
id: 'split-view',
|
|
158
|
+
name: 'Split View',
|
|
159
|
+
description: 'View two pages side-by-side',
|
|
160
|
+
details: 'Split screen view to compare data, reference documentation, or work with multiple items simultaneously. Resizable panes.',
|
|
161
|
+
group: 'ui-ux',
|
|
162
|
+
status: 'beta',
|
|
163
|
+
risk: 'medium',
|
|
164
|
+
enabled: false,
|
|
165
|
+
defaultEnabled: false,
|
|
166
|
+
addedAt: '2025-12-31',
|
|
167
|
+
},
|
|
168
|
+
'minimap': {
|
|
169
|
+
id: 'minimap',
|
|
170
|
+
name: 'Minimap',
|
|
171
|
+
description: 'Code editor-style minimap for large pages',
|
|
172
|
+
details: 'Minimap overview for scrolling long pages (like VS Code). Shows current viewport position and allows quick navigation.',
|
|
173
|
+
group: 'ui-ux',
|
|
174
|
+
status: 'alpha',
|
|
175
|
+
risk: 'low',
|
|
176
|
+
enabled: false,
|
|
177
|
+
defaultEnabled: false,
|
|
178
|
+
addedAt: '2025-12-31',
|
|
179
|
+
},
|
|
180
|
+
'breadcrumb-history': {
|
|
181
|
+
id: 'breadcrumb-history',
|
|
182
|
+
name: 'Breadcrumb Navigation',
|
|
183
|
+
description: 'Enhanced breadcrumbs with dropdown history',
|
|
184
|
+
details: 'Breadcrumb navigation with clickable history dropdowns. Shows recent pages in each section for quick navigation.',
|
|
185
|
+
group: 'ui-ux',
|
|
186
|
+
status: 'beta',
|
|
187
|
+
risk: 'low',
|
|
188
|
+
enabled: false,
|
|
189
|
+
defaultEnabled: false,
|
|
190
|
+
addedAt: '2025-12-31',
|
|
191
|
+
},
|
|
192
|
+
'floating-action-button': {
|
|
193
|
+
id: 'floating-action-button',
|
|
194
|
+
name: 'Floating Action Button',
|
|
195
|
+
description: 'Quick access to primary actions',
|
|
196
|
+
details: 'Floating action button (FAB) in the bottom-right for quick access to primary actions like "Create", "Upload", etc.',
|
|
197
|
+
group: 'ui-ux',
|
|
198
|
+
status: 'alpha',
|
|
199
|
+
risk: 'low',
|
|
200
|
+
enabled: false,
|
|
201
|
+
defaultEnabled: false,
|
|
202
|
+
addedAt: '2025-12-31',
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
// Developer Tools
|
|
206
|
+
'devtools-panel': {
|
|
207
|
+
id: 'devtools-panel',
|
|
208
|
+
name: 'DevTools Panel',
|
|
209
|
+
description: 'Developer debug panel in Settings → Developer tab',
|
|
210
|
+
details: 'Captures Module Federation loading events (including missing default exports) and EventBus events. Only useful during plugin development.',
|
|
211
|
+
group: 'performance',
|
|
212
|
+
status: 'alpha',
|
|
213
|
+
risk: 'low',
|
|
214
|
+
enabled: false,
|
|
215
|
+
defaultEnabled: false,
|
|
216
|
+
addedAt: '2026-04-02',
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
// Performance Features
|
|
220
|
+
'virtual-scrolling': {
|
|
221
|
+
id: 'virtual-scrolling',
|
|
222
|
+
name: 'Virtual Scrolling',
|
|
223
|
+
description: 'Render only visible items in large lists (10,000+ items)',
|
|
224
|
+
details: 'Virtual scrolling for large tables and lists. Only renders visible rows, dramatically improving performance for datasets with 10,000+ items.',
|
|
225
|
+
group: 'performance',
|
|
226
|
+
status: 'beta',
|
|
227
|
+
risk: 'medium',
|
|
228
|
+
enabled: false,
|
|
229
|
+
defaultEnabled: false,
|
|
230
|
+
addedAt: '2025-12-31',
|
|
231
|
+
},
|
|
232
|
+
'lazy-loading': {
|
|
233
|
+
id: 'lazy-loading',
|
|
234
|
+
name: 'Lazy Loading',
|
|
235
|
+
description: 'Load images and components on demand',
|
|
236
|
+
details: 'Lazy load images and heavy components only when they enter the viewport. Reduces initial page load time and bandwidth usage.',
|
|
237
|
+
group: 'performance',
|
|
238
|
+
status: 'beta',
|
|
239
|
+
risk: 'low',
|
|
240
|
+
enabled: false,
|
|
241
|
+
defaultEnabled: false,
|
|
242
|
+
addedAt: '2025-12-31',
|
|
243
|
+
},
|
|
244
|
+
'code-splitting': {
|
|
245
|
+
id: 'code-splitting',
|
|
246
|
+
name: 'Code Splitting',
|
|
247
|
+
description: 'Load JavaScript code on demand per route',
|
|
248
|
+
details: 'Dynamic imports and code splitting to reduce initial bundle size. Routes load their JS only when visited.',
|
|
249
|
+
group: 'performance',
|
|
250
|
+
status: 'stable',
|
|
251
|
+
risk: 'low',
|
|
252
|
+
enabled: false,
|
|
253
|
+
defaultEnabled: false,
|
|
254
|
+
addedAt: '2025-12-31',
|
|
255
|
+
},
|
|
256
|
+
'prefetching': {
|
|
257
|
+
id: 'prefetching',
|
|
258
|
+
name: 'Smart Prefetching',
|
|
259
|
+
description: 'Prefetch data for likely next pages',
|
|
260
|
+
details: 'Intelligently prefetch data for pages you are likely to visit next (based on hover, navigation patterns). Makes navigation instant.',
|
|
261
|
+
group: 'performance',
|
|
262
|
+
status: 'alpha',
|
|
263
|
+
risk: 'medium',
|
|
264
|
+
enabled: false,
|
|
265
|
+
defaultEnabled: false,
|
|
266
|
+
addedAt: '2025-12-31',
|
|
267
|
+
},
|
|
268
|
+
'service-worker': {
|
|
269
|
+
id: 'service-worker',
|
|
270
|
+
name: 'Service Worker',
|
|
271
|
+
description: 'Offline support and faster repeat visits',
|
|
272
|
+
details: 'Service worker for offline support, background sync, and caching. Enables Progressive Web App (PWA) features.',
|
|
273
|
+
group: 'performance',
|
|
274
|
+
status: 'alpha',
|
|
275
|
+
risk: 'high',
|
|
276
|
+
enabled: false,
|
|
277
|
+
defaultEnabled: false,
|
|
278
|
+
addedAt: '2025-12-31',
|
|
279
|
+
dependencies: ['offline-mode'],
|
|
280
|
+
},
|
|
281
|
+
'websocket-connection': {
|
|
282
|
+
id: 'websocket-connection',
|
|
283
|
+
name: 'WebSocket Connection',
|
|
284
|
+
description: 'Real-time updates via WebSocket instead of polling',
|
|
285
|
+
details: 'Replace polling with WebSocket connection for real-time updates. Lower latency, reduced server load, but requires backend support.',
|
|
286
|
+
group: 'performance',
|
|
287
|
+
status: 'alpha',
|
|
288
|
+
risk: 'high',
|
|
289
|
+
enabled: false,
|
|
290
|
+
defaultEnabled: false,
|
|
291
|
+
addedAt: '2025-12-31',
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
// AI Features
|
|
295
|
+
'ai-suggestions': {
|
|
296
|
+
id: 'ai-suggestions',
|
|
297
|
+
name: 'AI Suggestions',
|
|
298
|
+
description: 'AI-powered suggestions and auto-completion',
|
|
299
|
+
details: 'AI-powered suggestions for forms, queries, and actions. Uses LLM to predict what you want to do next.',
|
|
300
|
+
group: 'ai',
|
|
301
|
+
status: 'alpha',
|
|
302
|
+
risk: 'high',
|
|
303
|
+
enabled: false,
|
|
304
|
+
defaultEnabled: false,
|
|
305
|
+
addedAt: '2025-12-31',
|
|
306
|
+
},
|
|
307
|
+
'natural-language-search': {
|
|
308
|
+
id: 'natural-language-search',
|
|
309
|
+
name: 'Natural Language Search',
|
|
310
|
+
description: 'Search using natural language queries',
|
|
311
|
+
details: 'Search using plain English instead of filters. Example: "Show me workflows that failed last week" instead of complex filter UI.',
|
|
312
|
+
group: 'ai',
|
|
313
|
+
status: 'alpha',
|
|
314
|
+
risk: 'medium',
|
|
315
|
+
enabled: false,
|
|
316
|
+
defaultEnabled: false,
|
|
317
|
+
addedAt: '2025-12-31',
|
|
318
|
+
},
|
|
319
|
+
'auto-complete': {
|
|
320
|
+
id: 'auto-complete',
|
|
321
|
+
name: 'Smart Auto-Complete',
|
|
322
|
+
description: 'Context-aware auto-completion',
|
|
323
|
+
details: 'Intelligent auto-completion for search, filters, and forms. Learns from your usage patterns.',
|
|
324
|
+
group: 'ai',
|
|
325
|
+
status: 'beta',
|
|
326
|
+
risk: 'medium',
|
|
327
|
+
enabled: false,
|
|
328
|
+
defaultEnabled: false,
|
|
329
|
+
addedAt: '2025-12-31',
|
|
330
|
+
},
|
|
331
|
+
'smart-insights': {
|
|
332
|
+
id: 'smart-insights',
|
|
333
|
+
name: 'Smart Insights',
|
|
334
|
+
description: 'AI-generated insights and recommendations',
|
|
335
|
+
details: 'AI-generated insights about your data, trends, and anomalies. Proactive recommendations for optimization.',
|
|
336
|
+
group: 'ai',
|
|
337
|
+
status: 'alpha',
|
|
338
|
+
risk: 'high',
|
|
339
|
+
enabled: false,
|
|
340
|
+
defaultEnabled: false,
|
|
341
|
+
addedAt: '2025-12-31',
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
// Data Features
|
|
345
|
+
'offline-mode': {
|
|
346
|
+
id: 'offline-mode',
|
|
347
|
+
name: 'Offline Mode',
|
|
348
|
+
description: 'Work offline and sync when back online',
|
|
349
|
+
details: 'Full offline support with background sync. Continue working without internet and changes sync automatically when reconnected.',
|
|
350
|
+
group: 'data',
|
|
351
|
+
status: 'alpha',
|
|
352
|
+
risk: 'high',
|
|
353
|
+
enabled: false,
|
|
354
|
+
defaultEnabled: false,
|
|
355
|
+
addedAt: '2025-12-31',
|
|
356
|
+
dependencies: ['service-worker'],
|
|
357
|
+
},
|
|
358
|
+
'auto-save': {
|
|
359
|
+
id: 'auto-save',
|
|
360
|
+
name: 'Auto-Save',
|
|
361
|
+
description: 'Automatically save changes every few seconds',
|
|
362
|
+
details: 'Auto-save form changes every 3 seconds. Never lose work due to browser crashes or accidental navigation.',
|
|
363
|
+
group: 'data',
|
|
364
|
+
status: 'beta',
|
|
365
|
+
risk: 'medium',
|
|
366
|
+
enabled: false,
|
|
367
|
+
defaultEnabled: false,
|
|
368
|
+
addedAt: '2025-12-31',
|
|
369
|
+
},
|
|
370
|
+
'collaborative-editing': {
|
|
371
|
+
id: 'collaborative-editing',
|
|
372
|
+
name: 'Collaborative Editing',
|
|
373
|
+
description: 'Real-time collaboration with other users',
|
|
374
|
+
details: 'See who else is viewing/editing the same data in real-time. Prevents conflicts and enables teamwork.',
|
|
375
|
+
group: 'data',
|
|
376
|
+
status: 'alpha',
|
|
377
|
+
risk: 'high',
|
|
378
|
+
enabled: false,
|
|
379
|
+
defaultEnabled: false,
|
|
380
|
+
addedAt: '2025-12-31',
|
|
381
|
+
dependencies: ['websocket-connection'],
|
|
382
|
+
},
|
|
383
|
+
'version-history': {
|
|
384
|
+
id: 'version-history',
|
|
385
|
+
name: 'Version History',
|
|
386
|
+
description: 'View and restore previous versions',
|
|
387
|
+
details: 'Complete version history for all entities. View changes over time, compare versions, and restore previous states.',
|
|
388
|
+
group: 'data',
|
|
389
|
+
status: 'beta',
|
|
390
|
+
risk: 'medium',
|
|
391
|
+
enabled: false,
|
|
392
|
+
defaultEnabled: false,
|
|
393
|
+
addedAt: '2025-12-31',
|
|
394
|
+
},
|
|
395
|
+
'real-time-sync': {
|
|
396
|
+
id: 'real-time-sync',
|
|
397
|
+
name: 'Real-Time Sync',
|
|
398
|
+
description: 'Sync changes instantly across all devices',
|
|
399
|
+
details: 'Real-time synchronization across all your devices. Changes appear instantly everywhere.',
|
|
400
|
+
group: 'data',
|
|
401
|
+
status: 'alpha',
|
|
402
|
+
risk: 'high',
|
|
403
|
+
enabled: false,
|
|
404
|
+
defaultEnabled: false,
|
|
405
|
+
addedAt: '2025-12-31',
|
|
406
|
+
dependencies: ['websocket-connection'],
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
export const FEATURE_GROUPS: Record<FeatureGroup, { name: string; description: string; icon: string }> = {
|
|
411
|
+
'ui-ux': {
|
|
412
|
+
name: 'UI & UX',
|
|
413
|
+
description: 'User interface and experience enhancements',
|
|
414
|
+
icon: 'BgColorsOutlined',
|
|
415
|
+
},
|
|
416
|
+
performance: {
|
|
417
|
+
name: 'Performance',
|
|
418
|
+
description: 'Speed and efficiency improvements',
|
|
419
|
+
icon: 'ThunderboltOutlined',
|
|
420
|
+
},
|
|
421
|
+
ai: {
|
|
422
|
+
name: 'AI Features',
|
|
423
|
+
description: 'AI-powered capabilities and intelligence',
|
|
424
|
+
icon: 'RobotOutlined',
|
|
425
|
+
},
|
|
426
|
+
data: {
|
|
427
|
+
name: 'Data & Sync',
|
|
428
|
+
description: 'Data management and synchronization',
|
|
429
|
+
icon: 'DatabaseOutlined',
|
|
430
|
+
},
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
/** Get features grouped by category */
|
|
434
|
+
export function getFeaturesByGroup(): Record<FeatureGroup, FeatureFlag[]> {
|
|
435
|
+
const grouped: Record<FeatureGroup, FeatureFlag[]> = {
|
|
436
|
+
'ui-ux': [],
|
|
437
|
+
performance: [],
|
|
438
|
+
ai: [],
|
|
439
|
+
data: [],
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
Object.values(FEATURE_FLAGS).forEach((flag) => {
|
|
443
|
+
grouped[flag.group].push(flag);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
return grouped;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/** Check if a feature is enabled based on user preferences */
|
|
450
|
+
export function isFeatureEnabled(
|
|
451
|
+
featureId: FeatureId,
|
|
452
|
+
userPreferences?: Record<FeatureId, boolean>
|
|
453
|
+
): boolean {
|
|
454
|
+
const flag = FEATURE_FLAGS[featureId];
|
|
455
|
+
if (!flag) {return false;}
|
|
456
|
+
|
|
457
|
+
// If user has explicit preference, use that
|
|
458
|
+
if (userPreferences && featureId in userPreferences) {
|
|
459
|
+
return userPreferences[featureId];
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Otherwise use default
|
|
463
|
+
return flag.defaultEnabled;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/** Get all enabled features */
|
|
467
|
+
export function getEnabledFeatures(userPreferences?: Record<FeatureId, boolean>): FeatureId[] {
|
|
468
|
+
return Object.keys(FEATURE_FLAGS).filter((id) =>
|
|
469
|
+
isFeatureEnabled(id as FeatureId, userPreferences)
|
|
470
|
+
) as FeatureId[];
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Check if feature has dependencies and all are enabled */
|
|
474
|
+
export function areDependenciesMet(
|
|
475
|
+
featureId: FeatureId,
|
|
476
|
+
userPreferences?: Record<FeatureId, boolean>
|
|
477
|
+
): boolean {
|
|
478
|
+
const flag = FEATURE_FLAGS[featureId];
|
|
479
|
+
if (!flag.dependencies || flag.dependencies.length === 0) {return true;}
|
|
480
|
+
|
|
481
|
+
return flag.dependencies.every((dep) => isFeatureEnabled(dep, userPreferences));
|
|
482
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @kb-labs/studio-app/config/schema
|
|
3
|
+
* Zod validation schema for Studio configuration
|
|
4
|
+
*
|
|
5
|
+
* This provides runtime validation of environment variables and configuration.
|
|
6
|
+
* Ensures that invalid config fails fast at startup instead of causing runtime errors.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Data source mode schema
|
|
13
|
+
*/
|
|
14
|
+
const DataSourceModeSchema = z.enum(['mock', 'http'], {
|
|
15
|
+
errorMap: () => ({ message: 'dataSourceMode must be either "mock" or "http"' }),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Features configuration schema
|
|
20
|
+
*/
|
|
21
|
+
const FeaturesSchema = z.object({
|
|
22
|
+
enableDevlink: z.boolean(),
|
|
23
|
+
enableMind: z.boolean(),
|
|
24
|
+
enableAnalytics: z.boolean(),
|
|
25
|
+
sse: z.boolean(),
|
|
26
|
+
analytics: z.boolean(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Events configuration schema
|
|
31
|
+
*/
|
|
32
|
+
const EventsSchema = z.object({
|
|
33
|
+
baseUrl: z.string(),
|
|
34
|
+
registryPath: z.string(),
|
|
35
|
+
registryUrl: z.string().url().or(z.string().startsWith('/')),
|
|
36
|
+
retryDelays: z.array(z.number().int().positive()).min(1),
|
|
37
|
+
token: z.string().optional(),
|
|
38
|
+
headers: z.record(z.string()).optional(),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Complete Studio configuration schema
|
|
43
|
+
*/
|
|
44
|
+
export const StudioConfigSchema = z.object({
|
|
45
|
+
dataSourceMode: DataSourceModeSchema,
|
|
46
|
+
apiBaseUrl: z.string().min(1, 'apiBaseUrl is required'),
|
|
47
|
+
/** Bearer token sent to Gateway on every request. Optional — omit when connecting directly to REST API. */
|
|
48
|
+
gatewayToken: z.string().optional(),
|
|
49
|
+
features: FeaturesSchema,
|
|
50
|
+
events: EventsSchema,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* TypeScript type inferred from schema
|
|
55
|
+
*/
|
|
56
|
+
export type StudioConfig = z.infer<typeof StudioConfigSchema>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Validates studio configuration at runtime
|
|
60
|
+
* Throws ZodError if configuration is invalid
|
|
61
|
+
*
|
|
62
|
+
* @param config - Raw configuration object
|
|
63
|
+
* @returns Validated and typed configuration
|
|
64
|
+
* @throws {z.ZodError} If configuration is invalid
|
|
65
|
+
*/
|
|
66
|
+
export function validateStudioConfig(config: unknown): StudioConfig {
|
|
67
|
+
return StudioConfigSchema.parse(config);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Validates studio configuration and returns safe result
|
|
72
|
+
*
|
|
73
|
+
* @param config - Raw configuration object
|
|
74
|
+
* @returns Validation result with typed data or error
|
|
75
|
+
*/
|
|
76
|
+
export function safeValidateStudioConfig(config: unknown): {
|
|
77
|
+
success: boolean;
|
|
78
|
+
data?: StudioConfig;
|
|
79
|
+
error?: z.ZodError;
|
|
80
|
+
} {
|
|
81
|
+
const result = StudioConfigSchema.safeParse(config);
|
|
82
|
+
|
|
83
|
+
if (result.success) {
|
|
84
|
+
return { success: true, data: result.data };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { success: false, error: result.error };
|
|
88
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio configuration
|
|
3
|
+
*
|
|
4
|
+
* Environment variables:
|
|
5
|
+
* - KB_API_BASE_URL: API base URL (default: '/api/v1' — proxied through rspack devServer to Gateway :4000, which routes /api/v1/* to REST API :5050)
|
|
6
|
+
* - KB_GATEWAY_TOKEN: Bearer token for Gateway auth (dev: 'dev-studio-token')
|
|
7
|
+
* - KB_DATA_SOURCE_MODE: 'mock' | 'http' (default: 'http')
|
|
8
|
+
* - KB_EVENTS_BASE_URL: SSE base URL (default: same as KB_API_BASE_URL)
|
|
9
|
+
* - KB_EVENTS_REGISTRY_PATH: SSE registry path (default: '/events/registry')
|
|
10
|
+
* - KB_EVENTS_AUTH_TOKEN: SSE auth token (default: same as KB_GATEWAY_TOKEN)
|
|
11
|
+
* - KB_EVENTS_HEADERS: SSE extra headers as JSON string
|
|
12
|
+
*
|
|
13
|
+
* All traffic flows through Gateway (:4000). rspack devServer proxies /api and /plugins to Gateway.
|
|
14
|
+
*/
|
|
15
|
+
import { validateStudioConfig } from './studio.config.schema';
|
|
16
|
+
import { getStudioEnv } from './env';
|
|
17
|
+
|
|
18
|
+
function resolveUrl(base: string, path: string): string {
|
|
19
|
+
if (!path) {
|
|
20
|
+
return base;
|
|
21
|
+
}
|
|
22
|
+
if (/^https?:\/\//i.test(path)) {
|
|
23
|
+
return path;
|
|
24
|
+
}
|
|
25
|
+
if (path.startsWith('/')) {
|
|
26
|
+
return `${base.replace(/\/$/, '')}${path}`;
|
|
27
|
+
}
|
|
28
|
+
return `${base.replace(/\/$/, '')}/${path}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const env = getStudioEnv();
|
|
32
|
+
const apiBaseUrl = env.KB_API_BASE_URL || '/api/v1';
|
|
33
|
+
const gatewayTokenEnv = env.KB_GATEWAY_TOKEN;
|
|
34
|
+
const eventsBaseUrlEnv = env.KB_EVENTS_BASE_URL || apiBaseUrl;
|
|
35
|
+
const registryEventsPath = env.KB_EVENTS_REGISTRY_PATH || '/events/registry';
|
|
36
|
+
const eventsAuthTokenEnv = env.KB_EVENTS_AUTH_TOKEN;
|
|
37
|
+
const eventsHeadersEnv = env.KB_EVENTS_HEADERS;
|
|
38
|
+
|
|
39
|
+
function parseHeaders(value: string | undefined): Record<string, string> | undefined {
|
|
40
|
+
if (!value) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(value);
|
|
45
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
46
|
+
return Object.fromEntries(
|
|
47
|
+
Object.entries(parsed).map(([key, val]) => [String(key), String(val)])
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
// fall through
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Raw configuration object (before validation)
|
|
57
|
+
const rawConfig = {
|
|
58
|
+
dataSourceMode: (env.KB_DATA_SOURCE_MODE || 'http') as 'mock' | 'http',
|
|
59
|
+
apiBaseUrl,
|
|
60
|
+
gatewayToken: gatewayTokenEnv,
|
|
61
|
+
features: {
|
|
62
|
+
enableDevlink: false,
|
|
63
|
+
enableMind: false,
|
|
64
|
+
enableAnalytics: false,
|
|
65
|
+
sse: true,
|
|
66
|
+
analytics: true,
|
|
67
|
+
},
|
|
68
|
+
events: {
|
|
69
|
+
baseUrl: eventsBaseUrlEnv,
|
|
70
|
+
registryPath: registryEventsPath,
|
|
71
|
+
registryUrl: resolveUrl(eventsBaseUrlEnv, registryEventsPath),
|
|
72
|
+
retryDelays: [250, 1_000, 2_000, 5_000],
|
|
73
|
+
// KB_EVENTS_AUTH_TOKEN takes precedence; fall back to gateway token so
|
|
74
|
+
// a single KB_GATEWAY_TOKEN covers both REST and SSE connections.
|
|
75
|
+
token: eventsAuthTokenEnv ?? gatewayTokenEnv,
|
|
76
|
+
headers: parseHeaders(eventsHeadersEnv),
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validated studio configuration
|
|
82
|
+
* This will throw ZodError with clear error messages if config is malformed
|
|
83
|
+
*/
|
|
84
|
+
export const studioConfig = validateStudioConfig(rawConfig);
|
package/src/env.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
declare module '*.module.css' {
|
|
4
|
+
const classes: Record<string, string>;
|
|
5
|
+
export default classes;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface ImportMetaEnv {
|
|
9
|
+
readonly KB_API_BASE_URL?: string;
|
|
10
|
+
readonly KB_GATEWAY_TOKEN?: string;
|
|
11
|
+
readonly KB_DATA_SOURCE_MODE?: string;
|
|
12
|
+
readonly KB_EVENTS_BASE_URL?: string;
|
|
13
|
+
readonly KB_EVENTS_REGISTRY_PATH?: string;
|
|
14
|
+
readonly KB_EVENTS_AUTH_TOKEN?: string;
|
|
15
|
+
readonly KB_EVENTS_HEADERS?: string;
|
|
16
|
+
readonly MODE: string;
|
|
17
|
+
readonly DEV: boolean;
|
|
18
|
+
readonly PROD: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ImportMeta {
|
|
22
|
+
readonly env: ImportMetaEnv;
|
|
23
|
+
}
|