@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.
Files changed (168) hide show
  1. package/.env.example +10 -0
  2. package/README.md +74 -0
  3. package/UI-KIT-COMPONENTS.md +783 -0
  4. package/UI-KIT-PLAN.md +326 -0
  5. package/eslint-rules/no-direct-antd-import.js +151 -0
  6. package/eslint.config.ts +27 -0
  7. package/index.html +17 -0
  8. package/package.json +72 -0
  9. package/postcss.config.js +7 -0
  10. package/public/favicon.ico +0 -0
  11. package/public/favicon.svg +7 -0
  12. package/rspack.config.mjs +118 -0
  13. package/src/App.tsx +46 -0
  14. package/src/components/devtools/devtools-log-feed.module.css +165 -0
  15. package/src/components/devtools/devtools-log-feed.tsx +300 -0
  16. package/src/components/devtools/devtools-panel.module.css +121 -0
  17. package/src/components/devtools/devtools-panel.tsx +115 -0
  18. package/src/components/empty-state.tsx +28 -0
  19. package/src/components/error-boundary.tsx +210 -0
  20. package/src/components/health-banner.module.css +103 -0
  21. package/src/components/health-banner.tsx +134 -0
  22. package/src/components/health-indicator.tsx +12 -0
  23. package/src/components/page-header.tsx +49 -0
  24. package/src/components/page-transition.tsx +24 -0
  25. package/src/components/role-switcher.tsx +148 -0
  26. package/src/components/run-badge.tsx +13 -0
  27. package/src/components/ui/icons.tsx +509 -0
  28. package/src/components/ui/index.ts +25 -0
  29. package/src/components/ui/kb-config-provider.tsx +130 -0
  30. package/src/components/ui/kb-header.module.css +51 -0
  31. package/src/components/ui/kb-header.tsx +112 -0
  32. package/src/components/ui/kb-notification-bell.module.css +103 -0
  33. package/src/components/ui/kb-notification-bell.tsx +199 -0
  34. package/src/components/ui/kb-page-layout.tsx +66 -0
  35. package/src/components/ui/kb-quick-search.module.css +86 -0
  36. package/src/components/ui/kb-quick-search.tsx +196 -0
  37. package/src/components/ui/kb-sidebar.module.css +47 -0
  38. package/src/components/ui/kb-sidebar.tsx +196 -0
  39. package/src/components/ui/kb-stat-card.module.css +21 -0
  40. package/src/components/ui/kb-stat-card.tsx +22 -0
  41. package/src/components/ui/kb-stat-grid.tsx +22 -0
  42. package/src/components/ui/kb-status-bar.module.css +49 -0
  43. package/src/components/ui/kb-status-bar.tsx +145 -0
  44. package/src/components/ui/kb-system-health-indicator.tsx +229 -0
  45. package/src/components/ui/kb-theme-toggle.tsx +42 -0
  46. package/src/components/ui/theme-adapter.ts +812 -0
  47. package/src/components/ui/theme-transition-overlay.tsx +70 -0
  48. package/src/components/ui/utils.ts +6 -0
  49. package/src/components/widget-error-boundary.tsx +172 -0
  50. package/src/config/env.ts +5 -0
  51. package/src/config/feature-flags.ts +482 -0
  52. package/src/config/studio.config.schema.ts +88 -0
  53. package/src/config/studio.config.ts +84 -0
  54. package/src/env.d.ts +23 -0
  55. package/src/hooks/use-command-palette.ts +6 -0
  56. package/src/hooks/use-devtools-store.ts +25 -0
  57. package/src/hooks/use-feature-flags.ts +101 -0
  58. package/src/index.css +10 -0
  59. package/src/layouts/dashboard-grid.tsx +122 -0
  60. package/src/layouts/index.ts +12 -0
  61. package/src/layouts/two-pane.tsx +134 -0
  62. package/src/main.tsx +15 -0
  63. package/src/modules/analytics/components/analytics-daily-stats-chart.tsx +257 -0
  64. package/src/modules/analytics/components/analytics-date-range-picker.tsx +121 -0
  65. package/src/modules/analytics/pages/analytics-cache-page.tsx +285 -0
  66. package/src/modules/analytics/pages/analytics-embeddings-page.tsx +274 -0
  67. package/src/modules/analytics/pages/analytics-events-page.tsx +425 -0
  68. package/src/modules/analytics/pages/analytics-llm-page.tsx +434 -0
  69. package/src/modules/analytics/pages/analytics-overview-page.tsx +336 -0
  70. package/src/modules/analytics/pages/analytics-page.tsx +20 -0
  71. package/src/modules/analytics/pages/analytics-storage-page.tsx +344 -0
  72. package/src/modules/analytics/pages/analytics-vectorstore-page.tsx +279 -0
  73. package/src/modules/analytics/routes/index.tsx +133 -0
  74. package/src/modules/analytics/utils/formatters.test.ts +148 -0
  75. package/src/modules/analytics/utils/formatters.ts +100 -0
  76. package/src/modules/auth/pages/login-page.module.css +113 -0
  77. package/src/modules/auth/pages/login-page.tsx +80 -0
  78. package/src/modules/auth/routes/index.tsx +24 -0
  79. package/src/modules/dashboard/components/ActivityTimelineWidget.tsx +199 -0
  80. package/src/modules/dashboard/components/AiInsightsWidget.tsx +358 -0
  81. package/src/modules/dashboard/components/AnimatedMetricCard.css +88 -0
  82. package/src/modules/dashboard/components/AnimatedMetricCard.tsx +125 -0
  83. package/src/modules/dashboard/components/HeroMetricCard.css +114 -0
  84. package/src/modules/dashboard/components/HeroMetricCard.tsx +152 -0
  85. package/src/modules/dashboard/components/HeroMetricsWidget.tsx +146 -0
  86. package/src/modules/dashboard/components/SystemResourcesWidget.tsx +197 -0
  87. package/src/modules/dashboard/components/dashboard-empty.tsx +22 -0
  88. package/src/modules/dashboard/components/dashboard-kpis-widget.tsx +59 -0
  89. package/src/modules/dashboard/components/dashboard-kpis.tsx +13 -0
  90. package/src/modules/dashboard/components/dashboard-latency-percentiles-widget.tsx +85 -0
  91. package/src/modules/dashboard/components/dashboard-metrics-widget.tsx +78 -0
  92. package/src/modules/dashboard/components/dashboard-plugins-widget.tsx +67 -0
  93. package/src/modules/dashboard/components/dashboard-requests-widget.tsx +62 -0
  94. package/src/modules/dashboard/layouts/dashboard-layout.tsx +16 -0
  95. package/src/modules/dashboard/pages/ai-insights-page.tsx +563 -0
  96. package/src/modules/dashboard/pages/dashboard-animations.css +317 -0
  97. package/src/modules/dashboard/pages/dashboard-page.tsx +13 -0
  98. package/src/modules/dashboard/routes/index.tsx +70 -0
  99. package/src/modules/observability/pages/devkit-page.tsx +263 -0
  100. package/src/modules/observability/pages/incident-detail-page.tsx +571 -0
  101. package/src/modules/observability/pages/incidents-page.tsx +370 -0
  102. package/src/modules/observability/pages/log-detail-page.tsx +508 -0
  103. package/src/modules/observability/pages/logs-page.tsx +1129 -0
  104. package/src/modules/observability/pages/prometheus-metrics-page.tsx +486 -0
  105. package/src/modules/observability/pages/state-broker-page.tsx +229 -0
  106. package/src/modules/observability/pages/system-events-page.tsx +255 -0
  107. package/src/modules/observability/routes/index.tsx +133 -0
  108. package/src/modules/plugins/components/marketplace-card.tsx +153 -0
  109. package/src/modules/plugins/components/plugin-ai-assistant-modal.tsx +374 -0
  110. package/src/modules/plugins/components/plugin-card.tsx +136 -0
  111. package/src/modules/plugins/components/plugin-detail/capabilities-summary.tsx +101 -0
  112. package/src/modules/plugins/components/plugin-detail/cli-commands-table.tsx +101 -0
  113. package/src/modules/plugins/components/plugin-detail/index.ts +7 -0
  114. package/src/modules/plugins/components/plugin-detail/jobs-table.tsx +64 -0
  115. package/src/modules/plugins/components/plugin-detail/permissions/env-permissions.tsx +30 -0
  116. package/src/modules/plugins/components/plugin-detail/permissions/filesystem-permissions.tsx +68 -0
  117. package/src/modules/plugins/components/plugin-detail/permissions/index.ts +6 -0
  118. package/src/modules/plugins/components/plugin-detail/permissions/network-permissions.tsx +43 -0
  119. package/src/modules/plugins/components/plugin-detail/permissions/platform-services.tsx +242 -0
  120. package/src/modules/plugins/components/plugin-detail/permissions/resource-quotas.tsx +96 -0
  121. package/src/modules/plugins/components/plugin-detail/permissions/shell-permissions.tsx +55 -0
  122. package/src/modules/plugins/components/plugin-detail/permissions-view.tsx +47 -0
  123. package/src/modules/plugins/components/plugin-detail/plugin-header.tsx +169 -0
  124. package/src/modules/plugins/components/plugin-detail/rest-routes-table.tsx +159 -0
  125. package/src/modules/plugins/components/plugin-detail/workflows-table.tsx +40 -0
  126. package/src/modules/plugins/components/plugin-grid.tsx +20 -0
  127. package/src/modules/plugins/components/plugin-table.tsx +178 -0
  128. package/src/modules/plugins/pages/marketplace-page.tsx +200 -0
  129. package/src/modules/plugins/pages/plugin-detail-page.tsx +1145 -0
  130. package/src/modules/plugins/routes/index.tsx +48 -0
  131. package/src/modules/plugins/utils/index.ts +1 -0
  132. package/src/modules/plugins/utils/schema-helpers.ts +21 -0
  133. package/src/modules/settings/components/api-routes-viewer.tsx +415 -0
  134. package/src/modules/settings/components/appearance-settings.tsx +200 -0
  135. package/src/modules/settings/components/configuration-settings.tsx +321 -0
  136. package/src/modules/settings/components/data-privacy-settings.tsx +111 -0
  137. package/src/modules/settings/components/experimental-settings.tsx +243 -0
  138. package/src/modules/settings/components/navigation-settings.tsx +198 -0
  139. package/src/modules/settings/components/notifications-settings.tsx +40 -0
  140. package/src/modules/settings/pages/settings-page.tsx +298 -0
  141. package/src/modules/settings/routes/index.tsx +47 -0
  142. package/src/pages/README-assistant.md +91 -0
  143. package/src/pages/login-page.tsx +177 -0
  144. package/src/pages/not-found-page.tsx +85 -0
  145. package/src/providers/auth-provider.tsx +40 -0
  146. package/src/providers/command-palette-provider.tsx +193 -0
  147. package/src/providers/data-sources-provider.tsx +27 -0
  148. package/src/providers/devtools-provider.tsx +72 -0
  149. package/src/providers/navigation-items-provider.tsx +38 -0
  150. package/src/providers/registry-v2-provider.tsx +93 -0
  151. package/src/providers/settings-provider.tsx +158 -0
  152. package/src/router.tsx +302 -0
  153. package/src/routes/helpers.tsx +25 -0
  154. package/src/routes/plugin-page-v2.tsx +52 -0
  155. package/src/routes/types.ts +18 -0
  156. package/src/styles/antd-overrides.css +211 -0
  157. package/src/styles/base.css +190 -0
  158. package/src/styles/settings.css +75 -0
  159. package/src/styles/variables.css +94 -0
  160. package/src/utils/analytics.ts +183 -0
  161. package/src/utils/apply-navigation-categories.ts +83 -0
  162. package/src/utils/commands.ts +252 -0
  163. package/src/utils/export.ts +174 -0
  164. package/src/utils/format-date.ts +166 -0
  165. package/src/utils/logger.ts +110 -0
  166. package/tailwind.config.ts +13 -0
  167. package/tsconfig.json +13 -0
  168. package/vitest-setup.ts +1 -0
@@ -0,0 +1,101 @@
1
+ import { UISpace, UIAlert, UICard, UITag, UIIcon } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface CapabilitiesSummaryProps {
4
+ cliCommands: any[];
5
+ restRoutes: any[];
6
+ workflowHandlers: any[];
7
+ jobs: any[];
8
+ permissions?: any;
9
+ platformReqs?: {
10
+ requires?: string[];
11
+ };
12
+ }
13
+
14
+ export function CapabilitiesSummary({
15
+ cliCommands,
16
+ restRoutes,
17
+ workflowHandlers,
18
+ jobs,
19
+ permissions,
20
+ platformReqs,
21
+ }: CapabilitiesSummaryProps) {
22
+ return (
23
+ <UICard title="Capabilities">
24
+ <UISpace direction="vertical" size="middle" style={{ width: '100%' }}>
25
+ <UISpace wrap size="large">
26
+ {cliCommands.length > 0 && (
27
+ <div>
28
+ <UITag
29
+ icon={<UIIcon name="CodeOutlined" />}
30
+ color="blue"
31
+ style={{ fontSize: 14, padding: '4px 12px' }}
32
+ >
33
+ {cliCommands.length} CLI Command{cliCommands.length > 1 ? 's' : ''}
34
+ </UITag>
35
+ </div>
36
+ )}
37
+ {restRoutes.length > 0 && (
38
+ <div>
39
+ <UITag
40
+ icon={<UIIcon name="ApiOutlined" />}
41
+ color="green"
42
+ style={{ fontSize: 14, padding: '4px 12px' }}
43
+ >
44
+ {restRoutes.length} REST Route{restRoutes.length > 1 ? 's' : ''}
45
+ </UITag>
46
+ </div>
47
+ )}
48
+ {workflowHandlers.length > 0 && (
49
+ <div>
50
+ <UITag
51
+ icon={<UIIcon name="NodeIndexOutlined" />}
52
+ color="purple"
53
+ style={{ fontSize: 14, padding: '4px 12px' }}
54
+ >
55
+ {workflowHandlers.length} Workflow{workflowHandlers.length > 1 ? 's' : ''}
56
+ </UITag>
57
+ </div>
58
+ )}
59
+ {jobs.length > 0 && (
60
+ <div>
61
+ <UITag
62
+ icon={<UIIcon name="ClockCircleOutlined" />}
63
+ color="orange"
64
+ style={{ fontSize: 14, padding: '4px 12px' }}
65
+ >
66
+ {jobs.length} Scheduled Job{jobs.length > 1 ? 's' : ''}
67
+ </UITag>
68
+ </div>
69
+ )}
70
+ </UISpace>
71
+
72
+ {permissions && (
73
+ <UIAlert
74
+ icon={<UIIcon name="LockOutlined" />}
75
+ variant="warning"
76
+ message="This plugin requires permissions"
77
+ description="See Permissions tab for details"
78
+ showIcon
79
+ />
80
+ )}
81
+ {platformReqs?.requires && platformReqs.requires.length > 0 && (
82
+ <UIAlert
83
+ icon={<UIIcon name="DatabaseOutlined" />}
84
+ variant="info"
85
+ message="Platform Requirements"
86
+ description={
87
+ <UISpace wrap>
88
+ {platformReqs.requires.map((req) => (
89
+ <UITag key={req} color="cyan">
90
+ {req}
91
+ </UITag>
92
+ ))}
93
+ </UISpace>
94
+ }
95
+ showIcon
96
+ />
97
+ )}
98
+ </UISpace>
99
+ </UICard>
100
+ );
101
+ }
@@ -0,0 +1,101 @@
1
+ import { UITable, UISpace, UICard, UIText, UITag, UITitle, useUITheme, type UITableColumn } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface CLICommandsTableProps {
4
+ commands: any[];
5
+ }
6
+
7
+ export function CLICommandsTable({ commands }: CLICommandsTableProps) {
8
+ const { token } = useUITheme();
9
+
10
+ const columns: UITableColumn<any>[] = [
11
+ {
12
+ title: 'Command',
13
+ dataIndex: 'id',
14
+ key: 'id',
15
+ render: (id, record) => (
16
+ <div>
17
+ <UIText weight="semibold" style={{ fontFamily: token.fontFamilyCode }}>
18
+ {record.group ? `${record.group}:${id}` : id}
19
+ </UIText>
20
+ </div>
21
+ ),
22
+ },
23
+ {
24
+ title: 'Description',
25
+ dataIndex: 'describe',
26
+ key: 'describe',
27
+ render: (desc) => (typeof desc === 'string' ? desc : desc ? JSON.stringify(desc) : '--'),
28
+ },
29
+ {
30
+ title: 'Flags',
31
+ dataIndex: 'flags',
32
+ key: 'flags',
33
+ render: (flags) => {
34
+ return flags?.length > 0 ? (
35
+ <UISpace wrap>
36
+ {flags.map((flag: any) => (
37
+ <UITag key={flag.name}>
38
+ --{flag.name}
39
+ {flag.required && <UIText color="error">*</UIText>}
40
+ </UITag>
41
+ ))}
42
+ </UISpace>
43
+ ) : (
44
+ <UIText color="secondary">None</UIText>
45
+ );
46
+ },
47
+ },
48
+ {
49
+ title: 'Handler',
50
+ dataIndex: 'handler',
51
+ key: 'handler',
52
+ render: (handler) => (
53
+ <UIText style={{ fontSize: 11, fontFamily: token.fontFamilyCode }}>
54
+ {handler}
55
+ </UIText>
56
+ ),
57
+ },
58
+ ];
59
+
60
+ return (
61
+ <UICard>
62
+ <UITable
63
+ columns={columns}
64
+ dataSource={commands}
65
+ rowKey="id"
66
+ pagination={false}
67
+ expandable={{
68
+ expandedRowRender: (record) =>
69
+ record.flags && record.flags.length > 0 ? (
70
+ <div style={{ margin: 0, paddingLeft: 48 }}>
71
+ <UITitle level={5}>Flags</UITitle>
72
+ {record.flags.map((flag: any) => (
73
+ <div key={flag.name} style={{ marginBottom: 8 }}>
74
+ <UIText style={{ fontFamily: token.fontFamilyCode }}>
75
+ --{flag.name}
76
+ </UIText>
77
+ {flag.alias && <UIText color="secondary"> (-{flag.alias})</UIText>}
78
+ {flag.required && <UITag color="red">Required</UITag>}
79
+ <UITag>{flag.type}</UITag>
80
+ {flag.default !== undefined && (
81
+ <UITag color="blue">
82
+ Default: {typeof flag.default === 'object' ? JSON.stringify(flag.default) : String(flag.default)}
83
+ </UITag>
84
+ )}
85
+ {flag.choices && flag.choices.length > 0 && (
86
+ <UITag color="cyan">
87
+ Choices: {flag.choices.join(', ')}
88
+ </UITag>
89
+ )}
90
+ <div>
91
+ <UIText color="secondary">{flag.description || '--'}</UIText>
92
+ </div>
93
+ </div>
94
+ ))}
95
+ </div>
96
+ ) : null,
97
+ }}
98
+ />
99
+ </UICard>
100
+ );
101
+ }
@@ -0,0 +1,7 @@
1
+ export { PluginHeader } from './plugin-header';
2
+ export { CapabilitiesSummary } from './capabilities-summary';
3
+ export { CLICommandsTable } from './cli-commands-table';
4
+ export { RestRoutesTable } from './rest-routes-table';
5
+ export { WorkflowsTable } from './workflows-table';
6
+ export { JobsTable } from './jobs-table';
7
+ export { PermissionsView } from './permissions-view';
@@ -0,0 +1,64 @@
1
+ import { UITable, UICard, UIText, UITag, useUITheme, type UITableColumn } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface JobsTableProps {
4
+ jobs: any[];
5
+ }
6
+
7
+ export function JobsTable({ jobs }: JobsTableProps) {
8
+ const { token } = useUITheme();
9
+
10
+ const columns: UITableColumn<any>[] = [
11
+ {
12
+ title: 'ID',
13
+ dataIndex: 'id',
14
+ key: 'id',
15
+ render: (id) => <UIText style={{ fontFamily: token.fontFamilyCode }}>{id}</UIText>,
16
+ },
17
+ {
18
+ title: 'Description',
19
+ dataIndex: 'describe',
20
+ key: 'describe',
21
+ render: (desc) => (typeof desc === 'string' ? desc : desc ? JSON.stringify(desc) : '--'),
22
+ },
23
+ {
24
+ title: 'Schedule',
25
+ dataIndex: 'schedule',
26
+ key: 'schedule',
27
+ render: (schedule) =>
28
+ schedule ? (
29
+ <UITag color="orange">{schedule}</UITag>
30
+ ) : (
31
+ <UIText color="secondary">Manual</UIText>
32
+ ),
33
+ },
34
+ {
35
+ title: 'Enabled',
36
+ dataIndex: 'enabled',
37
+ key: 'enabled',
38
+ render: (enabled) =>
39
+ enabled !== false ? <UITag color="green">Yes</UITag> : <UITag color="red">No</UITag>,
40
+ },
41
+ {
42
+ title: 'Priority',
43
+ dataIndex: 'priority',
44
+ key: 'priority',
45
+ render: (priority) => priority || 5,
46
+ },
47
+ {
48
+ title: 'Handler',
49
+ dataIndex: 'handler',
50
+ key: 'handler',
51
+ render: (handler) => (
52
+ <UIText style={{ fontSize: 11, fontFamily: token.fontFamilyCode }}>
53
+ {handler}
54
+ </UIText>
55
+ ),
56
+ },
57
+ ];
58
+
59
+ return (
60
+ <UICard>
61
+ <UITable columns={columns} dataSource={jobs} rowKey="id" pagination={false} />
62
+ </UICard>
63
+ );
64
+ }
@@ -0,0 +1,30 @@
1
+ import { UISpace, UICard, UIText, UITag } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface EnvPermissionsProps {
4
+ permissions: {
5
+ read: string[];
6
+ };
7
+ }
8
+
9
+ export function EnvPermissions({ permissions }: EnvPermissionsProps) {
10
+ return (
11
+ <UICard title="Environment Variables">
12
+ <UIText color="secondary" style={{ marginBottom: 16, display: 'block' }}>
13
+ System environment variables that this plugin can access. Used for configuration and
14
+ secrets management.
15
+ </UIText>
16
+ <div>
17
+ <UIText weight="bold">Read Access:</UIText>
18
+ <div style={{ marginTop: 8 }}>
19
+ <UISpace wrap>
20
+ {permissions.read.map((env: string, idx: number) => (
21
+ <UITag key={idx} color="cyan">
22
+ {env}
23
+ </UITag>
24
+ ))}
25
+ </UISpace>
26
+ </div>
27
+ </div>
28
+ </UICard>
29
+ );
30
+ }
@@ -0,0 +1,68 @@
1
+ import { UISpace, UICard, UIText, UIIcon, useUITheme } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface FilesystemPermissionsProps {
4
+ permissions: {
5
+ read?: string[];
6
+ write?: string[];
7
+ };
8
+ }
9
+
10
+ export function FilesystemPermissions({ permissions }: FilesystemPermissionsProps) {
11
+ const { token } = useUITheme();
12
+
13
+ return (
14
+ <UICard
15
+ title={
16
+ <UISpace>
17
+ <UIIcon name="LockOutlined" />
18
+ <span>Filesystem Permissions</span>
19
+ </UISpace>
20
+ }
21
+ >
22
+ <UIText color="secondary" style={{ marginBottom: 16, display: 'block' }}>
23
+ File and directory access patterns that this plugin is allowed to use. Read access allows
24
+ viewing files, write access allows creating or modifying files.
25
+ </UIText>
26
+ <UISpace direction="vertical" size="middle" style={{ width: '100%' }}>
27
+ {permissions.read && permissions.read.length > 0 && (
28
+ <div>
29
+ <UIText weight="semibold">Read Access:</UIText>
30
+ <div style={{ marginTop: 8 }}>
31
+ {permissions.read.map((path: string, idx: number) => (
32
+ <div key={idx} style={{ marginBottom: 4 }}>
33
+ <UIText
34
+ style={{
35
+ fontSize: token.fontSizeSM,
36
+ fontFamily: token.fontFamilyCode,
37
+ }}
38
+ >
39
+ {path}
40
+ </UIText>
41
+ </div>
42
+ ))}
43
+ </div>
44
+ </div>
45
+ )}
46
+ {permissions.write && permissions.write.length > 0 && (
47
+ <div>
48
+ <UIText weight="semibold">Write Access:</UIText>
49
+ <div style={{ marginTop: 8 }}>
50
+ {permissions.write.map((path: string, idx: number) => (
51
+ <div key={idx} style={{ marginBottom: 4 }}>
52
+ <UIText
53
+ style={{
54
+ fontSize: token.fontSizeSM,
55
+ fontFamily: token.fontFamilyCode,
56
+ }}
57
+ >
58
+ {path}
59
+ </UIText>
60
+ </div>
61
+ ))}
62
+ </div>
63
+ </div>
64
+ )}
65
+ </UISpace>
66
+ </UICard>
67
+ );
68
+ }
@@ -0,0 +1,6 @@
1
+ export { FilesystemPermissions } from './filesystem-permissions';
2
+ export { NetworkPermissions } from './network-permissions';
3
+ export { EnvPermissions } from './env-permissions';
4
+ export { ShellPermissions } from './shell-permissions';
5
+ export { PlatformServices } from './platform-services';
6
+ export { ResourceQuotas } from './resource-quotas';
@@ -0,0 +1,43 @@
1
+ import { UISpace, UICard, UIText, UIIcon, useUITheme } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface NetworkPermissionsProps {
4
+ permissions: {
5
+ fetch: string[];
6
+ };
7
+ }
8
+
9
+ export function NetworkPermissions({ permissions }: NetworkPermissionsProps) {
10
+ const { token } = useUITheme();
11
+
12
+ return (
13
+ <UICard
14
+ title={
15
+ <UISpace>
16
+ <UIIcon name="GlobalOutlined" />
17
+ <span>Network Permissions</span>
18
+ </UISpace>
19
+ }
20
+ >
21
+ <UIText color="secondary" style={{ marginBottom: 16, display: 'block' }}>
22
+ External hosts and APIs that this plugin can communicate with over the network.
23
+ </UIText>
24
+ <div>
25
+ <UIText weight="semibold">Allowed Hosts:</UIText>
26
+ <div style={{ marginTop: 8 }}>
27
+ {permissions.fetch.map((host: string, idx: number) => (
28
+ <div key={idx} style={{ marginBottom: 4 }}>
29
+ <UIText
30
+ style={{
31
+ fontSize: token.fontSizeSM,
32
+ fontFamily: token.fontFamilyCode,
33
+ }}
34
+ >
35
+ {host}
36
+ </UIText>
37
+ </div>
38
+ ))}
39
+ </div>
40
+ </div>
41
+ </UICard>
42
+ );
43
+ }
@@ -0,0 +1,242 @@
1
+ import { UISpace, UICard, UIText, UITag, UIIcon, useUITheme } from '@kb-labs/studio-ui-kit';
2
+
3
+ interface PlatformServicesProps {
4
+ permissions: any;
5
+ }
6
+
7
+ export function PlatformServices({ permissions }: PlatformServicesProps) {
8
+ const { token } = useUITheme();
9
+
10
+ return (
11
+ <UICard
12
+ title={
13
+ <UISpace>
14
+ <UIIcon name="DatabaseOutlined" />
15
+ <span>Platform Services</span>
16
+ </UISpace>
17
+ }
18
+ >
19
+ <UIText color="secondary" style={{ marginBottom: 16, display: 'block' }}>
20
+ Access to KB Labs platform services like LLM, vector store, cache, and analytics.
21
+ </UIText>
22
+ <UISpace direction="vertical" size="middle" style={{ width: '100%' }}>
23
+ <div
24
+ style={{
25
+ display: 'grid',
26
+ gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
27
+ gap: 12,
28
+ }}
29
+ >
30
+ {/* LLM Service */}
31
+ {permissions.llm !== undefined && (
32
+ <UICard size="small">
33
+ <UISpace direction="vertical" size="small">
34
+ <UISpace>
35
+ {permissions.llm ? (
36
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
37
+ ) : (
38
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
39
+ )}
40
+ <UIText weight="semibold">LLM Service</UIText>
41
+ </UISpace>
42
+ {typeof permissions.llm === 'object' && permissions.llm.models && (
43
+ <div>
44
+ <UIText color="secondary" style={{ fontSize: token.fontSizeSM }}>
45
+ Models:
46
+ </UIText>
47
+ <div style={{ marginTop: 4 }}>
48
+ <UISpace wrap size="small">
49
+ {permissions.llm.models.map((model: string, idx: number) => (
50
+ <UITag key={idx} color="blue" style={{ fontSize: 11 }}>
51
+ {model}
52
+ </UITag>
53
+ ))}
54
+ </UISpace>
55
+ </div>
56
+ </div>
57
+ )}
58
+ </UISpace>
59
+ </UICard>
60
+ )}
61
+
62
+ {/* Vector Store */}
63
+ {permissions.vectorStore !== undefined && (
64
+ <UICard size="small">
65
+ <UISpace direction="vertical" size="small">
66
+ <UISpace>
67
+ {permissions.vectorStore ? (
68
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
69
+ ) : (
70
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
71
+ )}
72
+ <UIText weight="semibold">Vector Store</UIText>
73
+ </UISpace>
74
+ {typeof permissions.vectorStore === 'object' &&
75
+ permissions.vectorStore.collections && (
76
+ <div>
77
+ <UIText color="secondary" style={{ fontSize: token.fontSizeSM }}>
78
+ Collections:
79
+ </UIText>
80
+ <div style={{ marginTop: 4 }}>
81
+ <UISpace wrap size="small">
82
+ {permissions.vectorStore.collections.map((col: string, idx: number) => (
83
+ <UITag key={idx} color="purple" style={{ fontSize: 11 }}>
84
+ {col}
85
+ </UITag>
86
+ ))}
87
+ </UISpace>
88
+ </div>
89
+ </div>
90
+ )}
91
+ </UISpace>
92
+ </UICard>
93
+ )}
94
+
95
+ {/* Cache */}
96
+ {permissions.cache !== undefined && (
97
+ <UICard size="small">
98
+ <UISpace direction="vertical" size="small">
99
+ <UISpace>
100
+ {permissions.cache ? (
101
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
102
+ ) : (
103
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
104
+ )}
105
+ <UIText weight="semibold">Cache</UIText>
106
+ </UISpace>
107
+ {typeof permissions.cache === 'object' && permissions.cache.namespaces && (
108
+ <div>
109
+ <UIText color="secondary" style={{ fontSize: token.fontSizeSM }}>
110
+ Namespaces:
111
+ </UIText>
112
+ <div style={{ marginTop: 4 }}>
113
+ <UISpace wrap size="small">
114
+ {permissions.cache.namespaces.map((ns: string, idx: number) => (
115
+ <UITag key={idx} color="cyan" style={{ fontSize: 11 }}>
116
+ {ns}
117
+ </UITag>
118
+ ))}
119
+ </UISpace>
120
+ </div>
121
+ </div>
122
+ )}
123
+ </UISpace>
124
+ </UICard>
125
+ )}
126
+
127
+ {/* Storage */}
128
+ {permissions.storage !== undefined && (
129
+ <UICard size="small">
130
+ <UISpace direction="vertical" size="small">
131
+ <UISpace>
132
+ {permissions.storage ? (
133
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
134
+ ) : (
135
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
136
+ )}
137
+ <UIText weight="semibold">Storage</UIText>
138
+ </UISpace>
139
+ {typeof permissions.storage === 'object' && permissions.storage.paths && (
140
+ <div>
141
+ <UIText color="secondary" style={{ fontSize: token.fontSizeSM }}>
142
+ Paths:
143
+ </UIText>
144
+ <div style={{ marginTop: 4 }}>
145
+ <UISpace wrap size="small">
146
+ {permissions.storage.paths.map((path: string, idx: number) => (
147
+ <UITag key={idx} color="orange" style={{ fontSize: 11 }}>
148
+ {path}
149
+ </UITag>
150
+ ))}
151
+ </UISpace>
152
+ </div>
153
+ </div>
154
+ )}
155
+ </UISpace>
156
+ </UICard>
157
+ )}
158
+
159
+ {/* Analytics */}
160
+ {permissions.analytics !== undefined && (
161
+ <UICard size="small">
162
+ <UISpace>
163
+ {permissions.analytics ? (
164
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
165
+ ) : (
166
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
167
+ )}
168
+ <UIText weight="semibold">Analytics</UIText>
169
+ </UISpace>
170
+ </UICard>
171
+ )}
172
+
173
+ {/* Embeddings */}
174
+ {permissions.embeddings !== undefined && (
175
+ <UICard size="small">
176
+ <UISpace>
177
+ {permissions.embeddings ? (
178
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
179
+ ) : (
180
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
181
+ )}
182
+ <UIText weight="semibold">Embeddings</UIText>
183
+ </UISpace>
184
+ </UICard>
185
+ )}
186
+
187
+ {/* Events */}
188
+ {permissions.events !== undefined && (
189
+ <UICard size="small">
190
+ <UISpace direction="vertical" size="small">
191
+ <UISpace>
192
+ {permissions.events ? (
193
+ <UIIcon name="CheckCircleOutlined" style={{ color: token.colorSuccess }} />
194
+ ) : (
195
+ <UIIcon name="WarningOutlined" style={{ color: token.colorTextDisabled }} />
196
+ )}
197
+ <UIText weight="semibold">Event Bus</UIText>
198
+ </UISpace>
199
+ {typeof permissions.events === 'object' && (
200
+ <div>
201
+ {permissions.events.publish && permissions.events.publish.length > 0 && (
202
+ <div style={{ marginBottom: 8 }}>
203
+ <UIText color="secondary" style={{ fontSize: token.fontSizeSM }}>
204
+ Publish:
205
+ </UIText>
206
+ <div style={{ marginTop: 4 }}>
207
+ <UISpace wrap size="small">
208
+ {permissions.events.publish.map((evt: string, idx: number) => (
209
+ <UITag key={idx} color="green" style={{ fontSize: 11 }}>
210
+ {evt}
211
+ </UITag>
212
+ ))}
213
+ </UISpace>
214
+ </div>
215
+ </div>
216
+ )}
217
+ {permissions.events.subscribe && permissions.events.subscribe.length > 0 && (
218
+ <div>
219
+ <UIText color="secondary" style={{ fontSize: token.fontSizeSM }}>
220
+ Subscribe:
221
+ </UIText>
222
+ <div style={{ marginTop: 4 }}>
223
+ <UISpace wrap size="small">
224
+ {permissions.events.subscribe.map((evt: string, idx: number) => (
225
+ <UITag key={idx} color="blue" style={{ fontSize: 11 }}>
226
+ {evt}
227
+ </UITag>
228
+ ))}
229
+ </UISpace>
230
+ </div>
231
+ </div>
232
+ )}
233
+ </div>
234
+ )}
235
+ </UISpace>
236
+ </UICard>
237
+ )}
238
+ </div>
239
+ </UISpace>
240
+ </UICard>
241
+ );
242
+ }