@iblai/mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +199 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +130 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/resources/data-layer.d.ts +8 -0
  7. package/dist/resources/data-layer.d.ts.map +1 -0
  8. package/dist/resources/data-layer.js +181 -0
  9. package/dist/resources/data-layer.js.map +1 -0
  10. package/dist/resources/guides-layout.d.ts +8 -0
  11. package/dist/resources/guides-layout.d.ts.map +1 -0
  12. package/dist/resources/guides-layout.js +235 -0
  13. package/dist/resources/guides-layout.js.map +1 -0
  14. package/dist/resources/guides-rbac.d.ts +8 -0
  15. package/dist/resources/guides-rbac.d.ts.map +1 -0
  16. package/dist/resources/guides-rbac.js +231 -0
  17. package/dist/resources/guides-rbac.js.map +1 -0
  18. package/dist/resources/guides-theme.d.ts +8 -0
  19. package/dist/resources/guides-theme.d.ts.map +1 -0
  20. package/dist/resources/guides-theme.js +183 -0
  21. package/dist/resources/guides-theme.js.map +1 -0
  22. package/dist/resources/index.d.ts +17 -0
  23. package/dist/resources/index.d.ts.map +1 -0
  24. package/dist/resources/index.js +18 -0
  25. package/dist/resources/index.js.map +1 -0
  26. package/dist/resources/packages-overview.d.ts +8 -0
  27. package/dist/resources/packages-overview.d.ts.map +1 -0
  28. package/dist/resources/packages-overview.js +53 -0
  29. package/dist/resources/packages-overview.js.map +1 -0
  30. package/dist/resources/web-containers.d.ts +8 -0
  31. package/dist/resources/web-containers.d.ts.map +1 -0
  32. package/dist/resources/web-containers.js +122 -0
  33. package/dist/resources/web-containers.js.map +1 -0
  34. package/dist/resources/web-utils.d.ts +8 -0
  35. package/dist/resources/web-utils.d.ts.map +1 -0
  36. package/dist/resources/web-utils.js +210 -0
  37. package/dist/resources/web-utils.js.map +1 -0
  38. package/dist/tools/api-query-info.d.ts +16 -0
  39. package/dist/tools/api-query-info.d.ts.map +1 -0
  40. package/dist/tools/api-query-info.js +2398 -0
  41. package/dist/tools/api-query-info.js.map +1 -0
  42. package/dist/tools/component-info.d.ts +16 -0
  43. package/dist/tools/component-info.d.ts.map +1 -0
  44. package/dist/tools/component-info.js +1323 -0
  45. package/dist/tools/component-info.js.map +1 -0
  46. package/dist/tools/hook-info.d.ts +16 -0
  47. package/dist/tools/hook-info.d.ts.map +1 -0
  48. package/dist/tools/hook-info.js +1988 -0
  49. package/dist/tools/hook-info.js.map +1 -0
  50. package/dist/tools/index.d.ts +68 -0
  51. package/dist/tools/index.d.ts.map +1 -0
  52. package/dist/tools/index.js +14 -0
  53. package/dist/tools/index.js.map +1 -0
  54. package/dist/tools/page-template.d.ts +28 -0
  55. package/dist/tools/page-template.d.ts.map +1 -0
  56. package/dist/tools/page-template.js +198 -0
  57. package/dist/tools/page-template.js.map +1 -0
  58. package/dist/tools/provider-setup.d.ts +24 -0
  59. package/dist/tools/provider-setup.d.ts.map +1 -0
  60. package/dist/tools/provider-setup.js +213 -0
  61. package/dist/tools/provider-setup.js.map +1 -0
  62. package/package.json +28 -0
@@ -0,0 +1,235 @@
1
+ export const guidesLayout = {
2
+ uri: 'ibl://guides/layout',
3
+ name: 'Layout Rules and Patterns',
4
+ description: 'How to structure layouts for IBL apps',
5
+ mimeType: 'text/markdown',
6
+ content: `# IBL Layout Rules and Patterns
7
+
8
+ ## Root Layout Structure
9
+
10
+ Every IBL app follows this root layout pattern:
11
+
12
+ \`\`\`typescript
13
+ // app/layout.tsx
14
+ import { StoreProvider } from '@/providers/store-provider';
15
+ import { Providers } from '@/providers';
16
+ import { ClientLayout } from '@/components/client-layout';
17
+
18
+ export default function RootLayout({ children }) {
19
+ return (
20
+ <html lang="en" suppressHydrationWarning>
21
+ <head>
22
+ <script src="/env.js" />
23
+ </head>
24
+ <body>
25
+ <StoreProvider>
26
+ <Providers>
27
+ <ClientLayout>
28
+ {children}
29
+ </ClientLayout>
30
+ </Providers>
31
+ </StoreProvider>
32
+ </body>
33
+ </html>
34
+ );
35
+ }
36
+ \`\`\`
37
+
38
+ ## StoreProvider Pattern
39
+
40
+ \`\`\`typescript
41
+ // providers/store-provider.tsx
42
+ 'use client';
43
+
44
+ import { useRef } from 'react';
45
+ import { Provider } from 'react-redux';
46
+ import { makeStore, AppStore } from '@/lib/store';
47
+
48
+ export function StoreProvider({ children }) {
49
+ const storeRef = useRef<AppStore | null>(null);
50
+
51
+ if (!storeRef.current) {
52
+ storeRef.current = makeStore();
53
+ }
54
+
55
+ return <Provider store={storeRef.current}>{children}</Provider>;
56
+ }
57
+ \`\`\`
58
+
59
+ ## Providers Component
60
+
61
+ \`\`\`typescript
62
+ // providers/index.tsx
63
+ 'use client';
64
+
65
+ import { AuthProvider, TenantProvider } from '@iblai/web-utils';
66
+ import { getTenant, getUsername, redirectToAuthSpa } from '@/lib/utils';
67
+
68
+ export function Providers({ children }) {
69
+ return (
70
+ <AuthProvider
71
+ skip={shouldSkipAuth(pathname)}
72
+ username={getUsername()}
73
+ token={getToken()}
74
+ redirectToAuthSpa={redirectToAuthSpa}
75
+ hasNonExpiredAuthToken={hasNonExpiredAuthToken}
76
+ >
77
+ <TenantProvider
78
+ currentTenant={getTenant()}
79
+ requestedTenant={getRequestedTenant()}
80
+ handleTenantSwitch={handleTenantSwitch}
81
+ onLoadPlatformPermissions={handlePermissions}
82
+ >
83
+ {children}
84
+ </TenantProvider>
85
+ </AuthProvider>
86
+ );
87
+ }
88
+ \`\`\`
89
+
90
+ ## ClientLayout for Theming
91
+
92
+ \`\`\`typescript
93
+ // components/client-layout.tsx
94
+ 'use client';
95
+
96
+ import { ThemeProvider } from 'next-themes';
97
+ import { Toaster } from '@iblai/web-containers';
98
+
99
+ export function ClientLayout({ children }) {
100
+ return (
101
+ <ThemeProvider attribute="class" defaultTheme="light">
102
+ {children}
103
+ <Toaster />
104
+ </ThemeProvider>
105
+ );
106
+ }
107
+ \`\`\`
108
+
109
+ ## Page Layout Components
110
+
111
+ ### AppLayout (with Navigation)
112
+
113
+ \`\`\`typescript
114
+ // app/_components/app-layout.tsx
115
+ 'use client';
116
+
117
+ import { NavBar } from '@/components/nav-bar';
118
+ import { Footer } from '@/components/footer';
119
+
120
+ const NON_AUTH_PAGES = ['/sso-login', '/version', '/error'];
121
+
122
+ export function AppLayout({ children }) {
123
+ const pathname = usePathname();
124
+
125
+ if (NON_AUTH_PAGES.some(p => pathname.startsWith(p))) {
126
+ return <>{children}</>;
127
+ }
128
+
129
+ return (
130
+ <div className="flex min-h-screen flex-col">
131
+ <NavBar />
132
+ <main className="flex-1">{children}</main>
133
+ <Footer />
134
+ </div>
135
+ );
136
+ }
137
+ \`\`\`
138
+
139
+ ### For Mentor App with Sidebar
140
+
141
+ \`\`\`typescript
142
+ import { SidebarProvider, SidebarInset } from '@iblai/web-containers';
143
+
144
+ <SidebarProvider>
145
+ <AppSidebar />
146
+ <SidebarInset>
147
+ <NavBar />
148
+ <main>{children}</main>
149
+ </SidebarInset>
150
+ </SidebarProvider>
151
+ \`\`\`
152
+
153
+ ## Page Structure
154
+
155
+ \`\`\`typescript
156
+ // app/dashboard/page.tsx
157
+ import { AppLayout } from '@/app/_components/app-layout';
158
+
159
+ export default function DashboardPage() {
160
+ return (
161
+ <AppLayout>
162
+ <div className="container mx-auto px-4 py-8">
163
+ <h1 className="text-2xl font-bold">Dashboard</h1>
164
+ {/* Page content */}
165
+ </div>
166
+ </AppLayout>
167
+ );
168
+ }
169
+ \`\`\`
170
+
171
+ ## Dynamic Routes
172
+
173
+ \`\`\`typescript
174
+ // app/platform/[tenantKey]/[mentorId]/page.tsx
175
+ interface PageProps {
176
+ params: Promise<{
177
+ tenantKey: string;
178
+ mentorId: string;
179
+ }>;
180
+ }
181
+
182
+ export default async function MentorPage({ params }: PageProps) {
183
+ const { tenantKey, mentorId } = await params;
184
+
185
+ return <MentorChat tenantKey={tenantKey} mentorId={mentorId} />;
186
+ }
187
+ \`\`\`
188
+
189
+ ## Route Groups
190
+
191
+ Use route groups for organization without affecting URL:
192
+
193
+ \`\`\`
194
+ app/
195
+ ├── (authenticated)/
196
+ │ ├── layout.tsx # Auth required layout
197
+ │ ├── dashboard/
198
+ │ └── settings/
199
+ ├── (public)/
200
+ │ ├── layout.tsx # No auth required
201
+ │ └── about/
202
+ └── layout.tsx # Root layout
203
+ \`\`\`
204
+
205
+ ## Loading States
206
+
207
+ \`\`\`typescript
208
+ // app/dashboard/loading.tsx
209
+ import { Skeleton } from '@iblai/web-containers';
210
+
211
+ export default function Loading() {
212
+ return (
213
+ <div className="container mx-auto px-4 py-8">
214
+ <Skeleton className="h-8 w-48 mb-4" />
215
+ <Skeleton className="h-64 w-full" />
216
+ </div>
217
+ );
218
+ }
219
+ \`\`\`
220
+
221
+ ## Error Boundaries
222
+
223
+ \`\`\`typescript
224
+ // app/error.tsx
225
+ 'use client';
226
+
227
+ import { ClientErrorPage } from '@iblai/web-containers/next';
228
+
229
+ export default function Error({ error, reset }) {
230
+ return <ClientErrorPage error={error} reset={reset} />;
231
+ }
232
+ \`\`\`
233
+ `,
234
+ };
235
+ //# sourceMappingURL=guides-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides-layout.js","sourceRoot":"","sources":["../../src/resources/guides-layout.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,EAAE,qBAAqB;IAC1B,IAAI,EAAE,2BAA2B;IACjC,WAAW,EAAE,uCAAuC;IACpD,QAAQ,EAAE,eAAe;IACzB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmOV;CACA,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const guidesRbac: {
2
+ uri: string;
3
+ name: string;
4
+ description: string;
5
+ mimeType: string;
6
+ content: string;
7
+ };
8
+ //# sourceMappingURL=guides-rbac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides-rbac.d.ts","sourceRoot":"","sources":["../../src/resources/guides-rbac.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;CAqOtB,CAAC"}
@@ -0,0 +1,231 @@
1
+ export const guidesRbac = {
2
+ uri: 'ibl://guides/rbac',
3
+ name: 'RBAC Patterns',
4
+ description: 'Role-Based Access Control patterns',
5
+ mimeType: 'text/markdown',
6
+ content: `# RBAC (Role-Based Access Control) Patterns
7
+
8
+ ## Overview
9
+
10
+ IBL uses a resource-based RBAC system where permissions are associated with specific resources.
11
+
12
+ ## Permission Resource Format
13
+
14
+ \`\`\`
15
+ /platforms/{tenantKey}/#permission_name
16
+ /mentors/{mentorId}/#permission_name
17
+ \`\`\`
18
+
19
+ ## Redux RBAC Slice
20
+
21
+ \`\`\`typescript
22
+ // features/rbac/rbac-slice.ts
23
+ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
24
+
25
+ export interface RbacPermissions {
26
+ mentors?: Record<string, unknown>;
27
+ mentor?: Record<string, unknown>;
28
+ skills?: Record<string, unknown>;
29
+ }
30
+
31
+ interface RbacState {
32
+ rbacPermissions: RbacPermissions;
33
+ }
34
+
35
+ const initialState: RbacState = {
36
+ rbacPermissions: {},
37
+ };
38
+
39
+ const rbacSlice = createSlice({
40
+ name: 'rbac',
41
+ initialState,
42
+ reducers: {
43
+ updateRbacPermissions: (state, action: PayloadAction<RbacPermissions>) => {
44
+ state.rbacPermissions = {
45
+ ...state.rbacPermissions,
46
+ ...action.payload,
47
+ };
48
+ },
49
+ },
50
+ });
51
+
52
+ export const { updateRbacPermissions } = rbacSlice.actions;
53
+ export const selectRbacPermissions = (state) => state.rbac.rbacPermissions;
54
+ export default rbacSlice.reducer;
55
+ \`\`\`
56
+
57
+ ## WithPermissions HOC
58
+
59
+ \`\`\`typescript
60
+ // hoc/withPermissions.tsx
61
+ import { WithPermissions as BaseWithPermissions, checkRbacPermission } from '@iblai/web-utils';
62
+ import { useAppSelector } from '@/lib/hooks';
63
+ import { selectRbacPermissions } from '@/features/rbac';
64
+ import { config } from '@/lib/config';
65
+
66
+ interface WithPermissionsProps {
67
+ rbacResource: string;
68
+ children: ({ hasPermission }: { hasPermission: boolean }) => React.ReactNode;
69
+ }
70
+
71
+ export function WithPermissions({ rbacResource, children }: WithPermissionsProps) {
72
+ const rbacPermissions = useAppSelector(selectRbacPermissions);
73
+
74
+ // Skip RBAC if disabled in config
75
+ if (!config.settings.enableRBAC()) {
76
+ return <>{children({ hasPermission: true })}</>;
77
+ }
78
+
79
+ return (
80
+ <BaseWithPermissions
81
+ rbacResource={rbacResource}
82
+ rbacPermissions={rbacPermissions}
83
+ >
84
+ {children}
85
+ </BaseWithPermissions>
86
+ );
87
+ }
88
+
89
+ // For form field-level permissions
90
+ export function WithFormPermissions(props) {
91
+ const rbacPermissions = useAppSelector(selectRbacPermissions);
92
+ return (
93
+ <BaseWithFormPermissions
94
+ {...props}
95
+ rbacPermissions={rbacPermissions}
96
+ enableRBAC={config.settings.enableRBAC()}
97
+ />
98
+ );
99
+ }
100
+ \`\`\`
101
+
102
+ ## Usage Examples
103
+
104
+ ### Conditional UI Rendering
105
+
106
+ \`\`\`typescript
107
+ import { WithPermissions } from '@/hoc/withPermissions';
108
+
109
+ function NavBar() {
110
+ return (
111
+ <nav>
112
+ <WithPermissions rbacResource={\`/platforms/\${tenantKey}/#can_view_analytics\`}>
113
+ {({ hasPermission }) =>
114
+ hasPermission && (
115
+ <Link href="/analytics">Analytics</Link>
116
+ )
117
+ }
118
+ </WithPermissions>
119
+
120
+ <WithPermissions rbacResource={\`/mentors/\${mentorId}/#show_settings\`}>
121
+ {({ hasPermission }) =>
122
+ hasPermission && (
123
+ <Button onClick={openSettings}>Settings</Button>
124
+ )
125
+ }
126
+ </WithPermissions>
127
+ </nav>
128
+ );
129
+ }
130
+ \`\`\`
131
+
132
+ ### Programmatic Permission Check
133
+
134
+ \`\`\`typescript
135
+ import { checkRbacPermission } from '@iblai/web-utils';
136
+ import { useAppSelector } from '@/lib/hooks';
137
+ import { selectRbacPermissions } from '@/features/rbac';
138
+
139
+ function MentorActions({ mentorId }) {
140
+ const rbacPermissions = useAppSelector(selectRbacPermissions);
141
+
142
+ const canEdit = checkRbacPermission(
143
+ rbacPermissions,
144
+ \`/mentors/\${mentorId}/#can_edit\`
145
+ );
146
+
147
+ const canDelete = checkRbacPermission(
148
+ rbacPermissions,
149
+ \`/mentors/\${mentorId}/#can_delete\`
150
+ );
151
+
152
+ return (
153
+ <div>
154
+ {canEdit && <Button onClick={handleEdit}>Edit</Button>}
155
+ {canDelete && <Button onClick={handleDelete}>Delete</Button>}
156
+ </div>
157
+ );
158
+ }
159
+ \`\`\`
160
+
161
+ ### Loading Permissions from Provider
162
+
163
+ \`\`\`typescript
164
+ // In your Providers component
165
+ <TenantProvider
166
+ onLoadPlatformPermissions={(permissions) => {
167
+ dispatch(updateRbacPermissions(permissions));
168
+ }}
169
+ >
170
+ {children}
171
+ </TenantProvider>
172
+
173
+ // In MentorProvider (for mentor app)
174
+ <MentorProvider
175
+ onLoadMentorsPermissions={(permissions) => {
176
+ dispatch(updateRbacPermissions(permissions));
177
+ }}
178
+ >
179
+ {children}
180
+ </MentorProvider>
181
+ \`\`\`
182
+
183
+ ## Common Permission Resources
184
+
185
+ ### Platform Level
186
+ - \`/platforms/{tenantKey}/#can_view_analytics\`
187
+ - \`/platforms/{tenantKey}/#can_manage_users\`
188
+ - \`/platforms/{tenantKey}/#can_invite_users\`
189
+ - \`/platforms/{tenantKey}/#can_manage_groups\`
190
+
191
+ ### Mentor Level
192
+ - \`/mentors/{mentorId}/#can_edit\`
193
+ - \`/mentors/{mentorId}/#can_delete\`
194
+ - \`/mentors/{mentorId}/#show_settings\`
195
+ - \`/mentors/{mentorId}/#mentor_name\`
196
+ - \`/mentors/{mentorId}/#profile_image\`
197
+
198
+ ### Field-Level Permissions
199
+
200
+ For forms, use WithFormPermissions:
201
+
202
+ \`\`\`typescript
203
+ <WithFormPermissions
204
+ fieldName="mentor_name"
205
+ mentorSettings={mentorSettings}
206
+ >
207
+ {({ isEditable }) => (
208
+ <Input
209
+ disabled={!isEditable}
210
+ value={mentorName}
211
+ onChange={handleChange}
212
+ />
213
+ )}
214
+ </WithFormPermissions>
215
+ \`\`\`
216
+
217
+ ## User Type Checks
218
+
219
+ Additional to RBAC, check user types:
220
+
221
+ \`\`\`typescript
222
+ const isAdmin = currentTenant?.is_admin;
223
+ const isStudent = !isAdmin;
224
+ const isAnonymous = username === ANONYMOUS_USERNAME;
225
+
226
+ // Combine with RBAC
227
+ const canAccessFeature = isAdmin && hasRbacPermission;
228
+ \`\`\`
229
+ `,
230
+ };
231
+ //# sourceMappingURL=guides-rbac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides-rbac.js","sourceRoot":"","sources":["../../src/resources/guides-rbac.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,mBAAmB;IACxB,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,oCAAoC;IACjD,QAAQ,EAAE,eAAe;IACzB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+NV;CACA,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const guidesTheme: {
2
+ uri: string;
3
+ name: string;
4
+ description: string;
5
+ mimeType: string;
6
+ content: string;
7
+ };
8
+ //# sourceMappingURL=guides-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides-theme.d.ts","sourceRoot":"","sources":["../../src/resources/guides-theme.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;;CAqLvB,CAAC"}
@@ -0,0 +1,183 @@
1
+ export const guidesTheme = {
2
+ uri: 'ibl://guides/theme',
3
+ name: 'IBL Theme Configuration',
4
+ description: 'Theme and styling patterns',
5
+ mimeType: 'text/markdown',
6
+ content: `# IBL Theme Configuration
7
+
8
+ ## CSS Custom Properties
9
+
10
+ Import the base theme in your app:
11
+
12
+ \`\`\`typescript
13
+ // In your root layout or global CSS
14
+ import '@iblai/web-containers/styles/base.css';
15
+ \`\`\`
16
+
17
+ ## Theme Variables
18
+
19
+ \`\`\`css
20
+ :root {
21
+ /* Primary Colors */
22
+ --primary: #0058cc;
23
+ --primary-light: #00b0ef;
24
+ --primary-dark: #004499;
25
+ --primary-foreground: #ffffff;
26
+
27
+ /* Secondary Colors */
28
+ --secondary: #f4f4f5;
29
+ --secondary-foreground: #18181b;
30
+
31
+ /* Text Colors */
32
+ --text-primary: #616a76;
33
+ --text-secondary: #71717a;
34
+ --text-muted: #9ca3af;
35
+
36
+ /* Status Colors */
37
+ --success: #22c55e;
38
+ --warning: #f59e0b;
39
+ --error: #ef4444;
40
+ --info: #3b82f6;
41
+
42
+ /* Background Colors */
43
+ --background: #ffffff;
44
+ --foreground: #0a0a0a;
45
+ --card: #ffffff;
46
+ --card-foreground: #0a0a0a;
47
+ --muted: #f4f4f5;
48
+ --muted-foreground: #71717a;
49
+
50
+ /* Border Colors */
51
+ --border: #e4e4e7;
52
+ --input: #e4e4e7;
53
+ --ring: #0058cc;
54
+
55
+ /* Border Radius */
56
+ --radius: 0.5rem;
57
+ }
58
+
59
+ /* Dark Mode */
60
+ .dark {
61
+ --background: #0a0a0a;
62
+ --foreground: #fafafa;
63
+ --card: #0a0a0a;
64
+ --card-foreground: #fafafa;
65
+ --muted: #27272a;
66
+ --muted-foreground: #a1a1aa;
67
+ --border: #27272a;
68
+ }
69
+ \`\`\`
70
+
71
+ ## Using Theme with Next-Themes
72
+
73
+ \`\`\`typescript
74
+ // components/client-layout.tsx
75
+ 'use client';
76
+
77
+ import { ThemeProvider } from 'next-themes';
78
+
79
+ export function ClientLayout({ children }) {
80
+ return (
81
+ <ThemeProvider
82
+ attribute="class"
83
+ defaultTheme="light"
84
+ enableSystem
85
+ disableTransitionOnChange
86
+ >
87
+ {children}
88
+ </ThemeProvider>
89
+ );
90
+ }
91
+ \`\`\`
92
+
93
+ ## Theme Toggle
94
+
95
+ \`\`\`typescript
96
+ import { useTheme } from 'next-themes';
97
+ import { Sun, Moon } from 'lucide-react';
98
+ import { Button } from '@iblai/web-containers';
99
+
100
+ export function ThemeToggle() {
101
+ const { theme, setTheme } = useTheme();
102
+
103
+ return (
104
+ <Button
105
+ variant="ghost"
106
+ size="icon"
107
+ onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
108
+ >
109
+ <Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
110
+ <Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
111
+ </Button>
112
+ );
113
+ }
114
+ \`\`\`
115
+
116
+ ## Tenant-Specific Theming
117
+
118
+ Tenants can customize CSS through metadata:
119
+
120
+ \`\`\`typescript
121
+ // Load tenant CSS dynamically
122
+ const { metadata } = useTenantMetadata(tenantKey);
123
+
124
+ useEffect(() => {
125
+ if (metadata?.skills_advanced_css) {
126
+ const style = document.createElement('style');
127
+ style.textContent = sanitizeCss(metadata.skills_advanced_css);
128
+ document.head.appendChild(style);
129
+ return () => style.remove();
130
+ }
131
+ }, [metadata]);
132
+ \`\`\`
133
+
134
+ ## Button Variants
135
+
136
+ \`\`\`typescript
137
+ import { Button } from '@iblai/web-containers';
138
+
139
+ // Available variants
140
+ <Button variant="default">Primary</Button>
141
+ <Button variant="destructive">Delete</Button>
142
+ <Button variant="outline">Outline</Button>
143
+ <Button variant="secondary">Secondary</Button>
144
+ <Button variant="ghost">Ghost</Button>
145
+ <Button variant="link">Link</Button>
146
+
147
+ // Sizes
148
+ <Button size="sm">Small</Button>
149
+ <Button size="default">Default</Button>
150
+ <Button size="lg">Large</Button>
151
+ <Button size="icon"><Icon /></Button>
152
+ \`\`\`
153
+
154
+ ## Class Merging Utility
155
+
156
+ \`\`\`typescript
157
+ import { cn } from '@iblai/web-containers';
158
+
159
+ // Merge classes with conflict resolution
160
+ <div className={cn(
161
+ 'base-class',
162
+ isActive && 'active-class',
163
+ variant === 'primary' ? 'bg-primary' : 'bg-secondary'
164
+ )} />
165
+ \`\`\`
166
+
167
+ ## Gradient Patterns
168
+
169
+ \`\`\`css
170
+ /* IBL gradient pattern */
171
+ .ibl-gradient {
172
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
173
+ }
174
+
175
+ .ibl-text-gradient {
176
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
177
+ -webkit-background-clip: text;
178
+ -webkit-text-fill-color: transparent;
179
+ }
180
+ \`\`\`
181
+ `,
182
+ };
183
+ //# sourceMappingURL=guides-theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guides-theme.js","sourceRoot":"","sources":["../../src/resources/guides-theme.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,GAAG,EAAE,oBAAoB;IACzB,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE,4BAA4B;IACzC,QAAQ,EAAE,eAAe;IACzB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+KV;CACA,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { packagesOverview } from './packages-overview.js';
2
+ import { webContainers } from './web-containers.js';
3
+ import { webUtils } from './web-utils.js';
4
+ import { dataLayer } from './data-layer.js';
5
+ import { guidesLayout } from './guides-layout.js';
6
+ import { guidesRbac } from './guides-rbac.js';
7
+ import { guidesTheme } from './guides-theme.js';
8
+ export interface Resource {
9
+ uri: string;
10
+ name: string;
11
+ description: string;
12
+ mimeType: string;
13
+ content: string;
14
+ }
15
+ export declare const RESOURCES: Record<string, Resource>;
16
+ export { packagesOverview, webContainers, webUtils, dataLayer, guidesLayout, guidesRbac, guidesTheme, };
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAQ9C,CAAC;AAEF,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,WAAW,GACZ,CAAC"}