create-lego-one 2.0.12 → 2.0.14

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 (78) hide show
  1. package/dist/index.cjs +150 -15
  2. package/dist/index.cjs.map +1 -1
  3. package/package.json +1 -1
  4. package/template/.cursor/rules/rules.mdc +639 -0
  5. package/template/.dockerignore +58 -0
  6. package/template/.env.example +18 -0
  7. package/template/.eslintignore +5 -0
  8. package/template/.eslintrc.js +28 -0
  9. package/template/.prettierignore +6 -0
  10. package/template/.prettierrc +11 -0
  11. package/template/CLAUDE.md +634 -0
  12. package/template/Dockerfile +67 -0
  13. package/template/PROMPT.md +457 -0
  14. package/template/README.md +325 -0
  15. package/template/docker-compose.yml +48 -0
  16. package/template/docker-entrypoint.sh +23 -0
  17. package/template/docs/checkpoints/.template.md +64 -0
  18. package/template/docs/checkpoints/framework/01-infrastructure-setup.md +132 -0
  19. package/template/docs/checkpoints/framework/02-pocketbase-setup.md +155 -0
  20. package/template/docs/checkpoints/framework/03-host-kernel.md +170 -0
  21. package/template/docs/checkpoints/framework/04-auth-system.md +163 -0
  22. package/template/docs/checkpoints/framework/phase-05-multitenancy-rbac.md +223 -0
  23. package/template/docs/checkpoints/framework/phase-06-ui-components.md +260 -0
  24. package/template/docs/checkpoints/framework/phase-07-communication-system.md +276 -0
  25. package/template/docs/checkpoints/framework/phase-08-plugin-system.md +91 -0
  26. package/template/docs/checkpoints/framework/phase-09-dashboard-plugin.md +111 -0
  27. package/template/docs/checkpoints/framework/phase-10-todo-plugin.md +169 -0
  28. package/template/docs/checkpoints/framework/phase-11-testing.md +264 -0
  29. package/template/docs/checkpoints/framework/phase-12-deployment.md +294 -0
  30. package/template/docs/checkpoints/framework/phase-13-documentation.md +312 -0
  31. package/template/docs/framework/plans/00-index.md +164 -0
  32. package/template/docs/framework/plans/01-infrastructure-setup.md +855 -0
  33. package/template/docs/framework/plans/02-pocketbase-setup.md +1374 -0
  34. package/template/docs/framework/plans/03-host-kernel.md +1518 -0
  35. package/template/docs/framework/plans/04-auth-system.md +1466 -0
  36. package/template/docs/framework/plans/05-multitenancy-rbac.md +1527 -0
  37. package/template/docs/framework/plans/06-ui-components.md +1478 -0
  38. package/template/docs/framework/plans/07-communication-system.md +1106 -0
  39. package/template/docs/framework/plans/08-plugin-system.md +1179 -0
  40. package/template/docs/framework/plans/09-dashboard-plugin.md +1137 -0
  41. package/template/docs/framework/plans/10-todo-plugin.md +1343 -0
  42. package/template/docs/framework/plans/11-testing.md +935 -0
  43. package/template/docs/framework/plans/12-deployment.md +896 -0
  44. package/template/docs/framework/prompts/0-boilerplate-modernjs.md +151 -0
  45. package/template/docs/framework/research/00-modernjs-audit.md +488 -0
  46. package/template/docs/framework/research/01-system-blueprint.md +721 -0
  47. package/template/docs/framework/research/02-data-migration-protocol.md +699 -0
  48. package/template/docs/framework/research/03-host-setup.md +714 -0
  49. package/template/docs/framework/research/04-plugin-architecture.md +645 -0
  50. package/template/docs/framework/research/05-slot-injection-pattern.md +671 -0
  51. package/template/docs/framework/research/06-cli-strategy.md +615 -0
  52. package/template/docs/framework/research/07-deployment.md +629 -0
  53. package/template/docs/framework/research/README.md +282 -0
  54. package/template/docs/framework/setup/00-index.md +210 -0
  55. package/template/docs/framework/setup/01-framework-structure.md +308 -0
  56. package/template/docs/framework/setup/02-development-workflow.md +405 -0
  57. package/template/docs/framework/setup/03-environment-setup.md +215 -0
  58. package/template/docs/framework/setup/04-kernel-architecture.md +499 -0
  59. package/template/docs/framework/setup/05-plugin-system.md +620 -0
  60. package/template/docs/framework/setup/06-communication-patterns.md +451 -0
  61. package/template/docs/framework/setup/07-plugin-development.md +582 -0
  62. package/template/docs/framework/setup/08-component-library.md +658 -0
  63. package/template/docs/framework/setup/09-data-integration.md +609 -0
  64. package/template/docs/framework/setup/10-auth-rbac.md +497 -0
  65. package/template/docs/framework/setup/11-hooks-api.md +393 -0
  66. package/template/docs/framework/setup/12-components-api.md +665 -0
  67. package/template/docs/framework/setup/13-deployment-guide.md +566 -0
  68. package/template/docs/framework/setup/README.md +548 -0
  69. package/template/host/package.json +1 -1
  70. package/template/nginx.conf +72 -0
  71. package/template/package.json +1 -1
  72. package/template/packages/plugins/@lego/plugin-dashboard/package.json +1 -1
  73. package/template/packages/plugins/@lego/plugin-todo/package.json +1 -1
  74. package/template/pocketbase/CHANGELOG.md +911 -0
  75. package/template/pocketbase/LICENSE.md +17 -0
  76. package/template/scripts/create-plugin.js +221 -0
  77. package/template/scripts/deploy.sh +56 -0
  78. package/template/tsconfig.base.json +26 -0
@@ -0,0 +1,620 @@
1
+ # Plugin System
2
+
3
+ **Plugin Architecture, Loading, and Slot Injection**
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ The Lego-One plugin system enables modular feature development through Garfish micro-frontends. Plugins register slots, inject UI, and communicate with the host via channels.
10
+
11
+ ---
12
+
13
+ ## Plugin Architecture
14
+
15
+ ```
16
+ ┌─────────────────────────────────────────────────────────────────────┐
17
+ │ HOST KERNEL │
18
+ │ ┌────────────────────────────────────────────────────────────────┐ │
19
+ │ │ PLUGIN MANAGER │ │
20
+ │ │ • Plugin Loader (dynamic loading) │ │
21
+ │ │ • Plugin Store (state management) │ │
22
+ │ │ • Slot Registry (UI injection) │ │
23
+ │ └────────────────────────────────────────────────────────────────┘ │
24
+ │ │ │
25
+ │ ═══════════════════════════════ │
26
+ │ GARFISH PLUGIN BOUNDARY │
27
+ │ ═══════════════════════════════ │
28
+ │ │ │
29
+ │ ┌──────────────┬──────────────┬──────────────┬──────────────┐ │
30
+ │ │ Plugin 1 │ Plugin 2 │ Plugin 3 │ Plugin N │ │
31
+ │ │ Dashboard │ Todo │ Custom │ Future │ │
32
+ │ ├──────────────┼──────────────┼──────────────┼──────────────┤ │
33
+ │ │ plugin.config│ plugin.config│ plugin.config│ plugin.config│ │
34
+ │ │ Slot: nav │ Slot: nav │ Slot: widgets│ Slot: ??? │ │
35
+ │ │ Route: /dash │ Route: /todos│ Route: /custom│ Route: ??? │ │
36
+ │ └──────────────┴──────────────┴──────────────┴──────────────┘ │
37
+ └─────────────────────────────────────────────────────────────────────┘
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Plugin Structure
43
+
44
+ ### Standard Plugin File Layout
45
+
46
+ ```
47
+ packages/plugins/@lego/plugin-<name>/
48
+ ├── package.json # Plugin package configuration
49
+ ├── tsconfig.json # TypeScript configuration
50
+ ├── modern.config.ts # Modern.js + Garfish config
51
+ ├── tailwind.config.ts # Tailwind CSS configuration
52
+ ├── postcss.config.mjs # PostCSS configuration
53
+
54
+ └── src/
55
+ ├── global.css # Global plugin styles
56
+ ├── plugin.config.ts # Plugin manifest & configuration
57
+ ├── plugin.ts # Garfish entry point
58
+ ├── App.tsx # Root component with routing
59
+ ├── types.ts # TypeScript types
60
+ ├── schemas.ts # Zod validation schemas
61
+
62
+ ├── pages/ # Page components
63
+ │ └── <Plugin>Page.tsx
64
+
65
+ ├── components/ # React components
66
+ │ └── slots/ # Slot injection components
67
+ │ └── SidebarWidget.tsx
68
+
69
+ ├── hooks/ # Custom React hooks
70
+ │ ├── usePocketBase.ts
71
+ │ └── use<Feature>Data.ts
72
+
73
+ └── vite-env.d.ts # Vite type declarations
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Plugin Configuration
79
+
80
+ ### plugin.config.ts
81
+
82
+ **Location:** `packages/plugins/@lego/plugin-<name>/src/plugin.config.ts`
83
+
84
+ This file defines the plugin's metadata, slots, routes, and settings.
85
+
86
+ ```typescript
87
+ import type { PluginConfig } from '@lego/kernel/plugins';
88
+ import { SidebarWidget } from './components/slots/SidebarWidget';
89
+ import { DashboardPage } from './pages/DashboardPage';
90
+
91
+ export const pluginConfig: PluginConfig = {
92
+ // ==================== MANIFEST ====================
93
+ manifest: {
94
+ name: '@lego/plugin-dashboard',
95
+ version: '1.0.0',
96
+ displayName: 'Dashboard',
97
+ description: 'Organization statistics and activity feed',
98
+ author: 'Lego-One',
99
+ permissions: ['dashboard.read'],
100
+ },
101
+
102
+ // ==================== ENABLED STATE ====================
103
+ enabled: true,
104
+
105
+ // ==================== SLOT INJECTIONS ====================
106
+ slots: [
107
+ {
108
+ slot: 'sidebar:nav',
109
+ component: () => import('./components/slots/SidebarWidget').then(m => m.default),
110
+ order: 100,
111
+ props: {},
112
+ condition: undefined,
113
+ },
114
+ {
115
+ slot: 'dashboard:widgets',
116
+ component: () => import('./components/StatsCard').then(m => m.default),
117
+ order: 50,
118
+ },
119
+ ],
120
+
121
+ // ==================== ROUTES ====================
122
+ routes: [
123
+ {
124
+ path: '/dashboard',
125
+ component: () => import('./pages/DashboardPage').then(m => m.default),
126
+ protected: true,
127
+ permissions: ['dashboard.read'],
128
+ },
129
+ ],
130
+
131
+ // ==================== SETTINGS ====================
132
+ settings: [
133
+ {
134
+ key: 'showActivityFeed',
135
+ type: 'boolean',
136
+ label: 'Show Activity Feed',
137
+ description: 'Display recent activity on dashboard',
138
+ defaultValue: true,
139
+ },
140
+ {
141
+ key: 'refreshInterval',
142
+ type: 'number',
143
+ label: 'Refresh Interval (seconds)',
144
+ description: 'How often to refresh dashboard data',
145
+ defaultValue: 30,
146
+ },
147
+ ],
148
+ };
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Slot System
154
+
155
+ ### Available Slots
156
+
157
+ | Slot Name | Location | Purpose | Example Use |
158
+ |-----------|----------|---------|-------------|
159
+ | `sidebar:top` | Top of sidebar | Logo, branding | Plugin logo |
160
+ | `sidebar:nav` | Main navigation area | Navigation links | Plugin nav link |
161
+ | `sidebar:bottom` | Bottom of sidebar | Logout, settings | Settings link |
162
+ | `topbar:left` | Left side of header | Breadcrumbs, back button | Parent nav |
163
+ | `topbar:center` | Center of header | Page title, search | Search bar |
164
+ | `topbar:right` | Right side of header | Notifications, user menu | Notification icon |
165
+ | `dashboard:widgets` | Dashboard page | Statistics, activity | Stats cards |
166
+ | `settings:menu` | Settings page | Settings sections | Plugin settings |
167
+
168
+ ### Slot Injection Example
169
+
170
+ **File:** `packages/plugins/@lego/plugin-dashboard/src/components/slots/SidebarWidget.tsx`
171
+
172
+ ```typescript
173
+ import { NavLink } from '@modern-js/runtime/router';
174
+ import { LayoutDashboard } from 'lucide-react';
175
+
176
+ export function SidebarWidget() {
177
+ return (
178
+ <NavLink
179
+ to="/dashboard"
180
+ className={({ isActive }) =>
181
+ `flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors ${
182
+ isActive
183
+ ? 'bg-primary text-primary-foreground'
184
+ : 'text-muted-foreground hover:bg-muted hover:text-foreground'
185
+ }`
186
+ }
187
+ >
188
+ <LayoutDashboard className="h-5 w-5" />
189
+ <span>Dashboard</span>
190
+ </NavLink>
191
+ );
192
+ }
193
+
194
+ export default SidebarWidget;
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Plugin Loading
200
+
201
+ ### Dev Mode (Separate Servers)
202
+
203
+ ```bash
204
+ # Each plugin runs independently
205
+ pnpm run dev:all
206
+
207
+ # Results in:
208
+ # Host: http://localhost:8080
209
+ # Dashboard: http://localhost:3001
210
+ # Todo: http://localhost:3002
211
+ ```
212
+
213
+ **modern.runtime.ts (dev entries):**
214
+ ```typescript
215
+ {
216
+ name: '@lego/plugin-dashboard',
217
+ entry: 'http://localhost:3001', // Dev: separate server
218
+ activeWhen: '/dashboard',
219
+ }
220
+ ```
221
+
222
+ ### Production Mode (Bundled)
223
+
224
+ ```bash
225
+ pnpm run build
226
+
227
+ # All plugins bundled into host/dist/
228
+ ```
229
+
230
+ **modern.runtime.ts (prod entries):**
231
+ ```typescript
232
+ {
233
+ name: '@lego/plugin-dashboard',
234
+ entry: () => import('@lego/plugin-dashboard'), // Prod: dynamic import
235
+ activeWhen: '/dashboard',
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Plugin Enable/Disable
242
+
243
+ ### Via Config File
244
+
245
+ **File:** `host/src/saas.config.ts`
246
+
247
+ ```typescript
248
+ export const saasConfig = {
249
+ plugins: [
250
+ { name: '@lego/plugin-dashboard', enabled: true },
251
+ { name: '@lego/plugin-todo', enabled: false }, // Disabled
252
+ ],
253
+ };
254
+ ```
255
+
256
+ ### Via Plugin Store (Runtime)
257
+
258
+ ```typescript
259
+ import { usePluginStore } from '@lego/kernel/plugins';
260
+
261
+ function PluginManager() {
262
+ const { plugins, enablePlugin, disablePlugin } = usePluginStore();
263
+
264
+ return (
265
+ <div>
266
+ {Object.values(plugins).map((plugin) => (
267
+ <div key={plugin.id}>
268
+ <span>{plugin.manifest.displayName}</span>
269
+ <button
270
+ onClick={() => plugin.enabled
271
+ ? disablePlugin(plugin.id)
272
+ : enablePlugin(plugin.id)
273
+ }
274
+ >
275
+ {plugin.enabled ? 'Disable' : 'Enable'}
276
+ </button>
277
+ </div>
278
+ ))}
279
+ </div>
280
+ );
281
+ }
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Plugin Routes
287
+
288
+ ### Route Registration
289
+
290
+ Routes are registered in `plugin.config.ts` and automatically loaded by Garfish.
291
+
292
+ ```typescript
293
+ routes: [
294
+ {
295
+ path: '/my-plugin',
296
+ component: () => import('./pages/MyPluginPage').then(m => m.default),
297
+ protected: true, // Requires authentication
298
+ permissions: ['plugin.read'], // Requires specific permission
299
+ },
300
+ ]
301
+ ```
302
+
303
+ ### Protected Routes
304
+
305
+ Routes with `protected: true` will redirect unauthenticated users to sign-in.
306
+
307
+ ### Permission-Gated Routes
308
+
309
+ Routes with `permissions` require the user to have the specified permissions.
310
+
311
+ **Host handles this automatically** - plugins just declare requirements.
312
+
313
+ ---
314
+
315
+ ## Plugin Communication
316
+
317
+ ### Using Channel Bus
318
+
319
+ **File:** `packages/plugins/@lego/plugin-todo/src/hooks/useToast.ts`
320
+
321
+ ```typescript
322
+ export function useNotifySuccess() {
323
+ return (title: string, description?: string) => {
324
+ // Publish to channel bus
325
+ window.__LEGO_CHANNEL_BUS__?.publish('lego:toast', {
326
+ type: 'success',
327
+ title,
328
+ description,
329
+ });
330
+ };
331
+ }
332
+
333
+ // Usage
334
+ const notifySuccess = useNotifySuccess();
335
+ notifySuccess('Todo created', 'Your todo was created successfully');
336
+ ```
337
+
338
+ ### Reading Kernel State
339
+
340
+ **File:** `packages/plugins/@lego/plugin-todo/src/hooks/useOrganization.ts`
341
+
342
+ ```typescript
343
+ export function useCurrentOrganization() {
344
+ const kernelState = window.__LEGO_KERNEL_STATE__?.useGlobalKernelState?.getState();
345
+
346
+ return kernelState?.organization || null;
347
+ }
348
+
349
+ // Usage
350
+ const organization = useCurrentOrganization();
351
+ const orgId = organization?.id;
352
+ ```
353
+
354
+ ### Subscribing to Events
355
+
356
+ ```typescript
357
+ useEffect(() => {
358
+ const channelBus = window.__LEGO_CHANNEL_BUS__;
359
+ if (!channelBus) return;
360
+
361
+ // Listen for auth changes
362
+ const unsubscribe = channelBus.subscribe('lego:auth:change', (data) => {
363
+ console.log('Auth changed:', data);
364
+ if (data.isAuthenticated) {
365
+ // Refresh data
366
+ } else {
367
+ // Clear data
368
+ }
369
+ });
370
+
371
+ return unsubscribe;
372
+ }, []);
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Plugin Settings
378
+
379
+ ### Defining Settings
380
+
381
+ **In plugin.config.ts:**
382
+ ```typescript
383
+ settings: [
384
+ {
385
+ key: 'featureEnabled',
386
+ type: 'boolean',
387
+ label: 'Enable Feature',
388
+ defaultValue: true,
389
+ },
390
+ {
391
+ key: 'apiKey',
392
+ type: 'string',
393
+ label: 'API Key',
394
+ description: 'External service API key',
395
+ },
396
+ {
397
+ key: 'refreshRate',
398
+ type: 'select',
399
+ label: 'Refresh Rate',
400
+ options: [
401
+ { label: 'Slow (60s)', value: '60' },
402
+ { label: 'Fast (10s)', value: '10' },
403
+ ],
404
+ defaultValue: '30',
405
+ },
406
+ ]
407
+ ```
408
+
409
+ ### Reading Settings
410
+
411
+ Settings are stored in the plugin store and can be accessed via the store.
412
+
413
+ ```typescript
414
+ import { usePluginStore } from '@lego/kernel/plugins';
415
+
416
+ function MyPluginComponent() {
417
+ const pluginState = usePluginStore((state) => state.plugins['@lego/plugin-my-plugin']);
418
+
419
+ const settings = pluginState?.settings || {};
420
+
421
+ return (
422
+ <div>
423
+ <p>Feature Enabled: {settings.featureEnabled}</p>
424
+ <p>Refresh Rate: {settings.refreshRate}s</p>
425
+ </div>
426
+ );
427
+ }
428
+ ```
429
+
430
+ ---
431
+
432
+ ## Creating a New Plugin
433
+
434
+ ### Quick Method (CLI)
435
+
436
+ ```bash
437
+ pnpm run create-plugin my-new-plugin
438
+ ```
439
+
440
+ ### Manual Method
441
+
442
+ 1. **Create directory:**
443
+ ```bash
444
+ mkdir -p packages/plugins/@lego/plugin-my-new-plugin
445
+ cd packages/plugins/@lego/plugin-my-new-plugin
446
+ ```
447
+
448
+ 2. **Create package.json**
449
+ 3. **Create modern.config.ts**
450
+ 4. **Create src/plugin.config.ts**
451
+ 5. **Create src/plugin.ts**
452
+ 6. **Create src/App.tsx**
453
+ 7. **Create src/pages/MyPluginPage.tsx**
454
+ 8. **Create src/components/slots/SidebarWidget.tsx**
455
+
456
+ See [`07-plugin-development.md`](./07-plugin-development.md) for complete step-by-step guide.
457
+
458
+ ---
459
+
460
+ ## Plugin Development Patterns
461
+
462
+ ### CRUD Plugin Pattern (Like Todo)
463
+
464
+ ```
465
+ types.ts → Data interfaces
466
+ schemas.ts → Zod validation
467
+ hooks/ → Data fetching (usePocketBase, useItems, useCreate, etc.)
468
+ components/ → List, Item, Form, Dialog components
469
+ pages/ → Main page with filters
470
+ ```
471
+
472
+ ### Display Plugin Pattern (Like Dashboard)
473
+
474
+ ```
475
+ hooks/ → Stats queries, activity feed
476
+ components/ → Stat cards, activity feed, quick actions
477
+ pages/ → Dashboard overview
478
+ ```
479
+
480
+ ### Calculation Plugin Pattern
481
+
482
+ ```
483
+ types.ts → Input/Output types
484
+ hooks/ → Pure calculation functions
485
+ components/ → Input form, result display
486
+ pages/ → Calculator page
487
+ ```
488
+
489
+ ---
490
+
491
+ ## Multi-Tenancy in Plugins
492
+
493
+ **ALL plugin data MUST be scoped to organization:**
494
+
495
+ ```typescript
496
+ // ✅ CORRECT - Filter by organization
497
+ const result = await pb.collection('my_items').getList(1, 50, {
498
+ filter: `organizationId = "${orgId}"`,
499
+ });
500
+
501
+ // ❌ WRONG - No organization filter
502
+ const result = await pb.collection('my_items').getList(1, 50);
503
+ ```
504
+
505
+ **PocketBase collections MUST include:**
506
+ - `organizationId` field (relation to organizations)
507
+ - `ownerId` field (relation to users)
508
+ - API rules with organization filtering
509
+
510
+ ---
511
+
512
+ ## Plugin Best Practices
513
+
514
+ ### DO ✅
515
+
516
+ 1. **Follow the standard structure** - Copy from Dashboard/Todo plugins
517
+ 2. **Use window bridge** for host communication
518
+ 3. **Scope all data** to organization
519
+ 4. **Handle loading/error states**
520
+ 5. **Show toast notifications** for user feedback
521
+ 6. **Use existing UI components** from kernel
522
+ 7. **Write TypeScript types** for all data
523
+ 8. **Validate with Zod schemas**
524
+
525
+ ### DON'T ❌
526
+
527
+ 1. **Don't import from host** - Use window bridge instead
528
+ 2. **Don't skip organization filtering** - Always scope data
529
+ 3. **Don't ignore error states** - Handle failures gracefully
530
+ 4. **Don't create circular dependencies** - Plugin → Host OK, Host → Plugin bad
531
+ 5. **Don't hardcode URLs** - Use environment variables
532
+ 6. **Don't forget TypeScript strict mode** - All code must type-check
533
+ 7. **Don't skip testing** - Write tests for hooks and components
534
+
535
+ ---
536
+
537
+ ## Plugin Registry
538
+
539
+ ### How Plugins Are Registered
540
+
541
+ **1. In saas.config.ts (Host config):**
542
+ ```typescript
543
+ plugins: [
544
+ { name: '@lego/plugin-dashboard', enabled: true },
545
+ ]
546
+ ```
547
+
548
+ **2. In modern.runtime.ts (Garfish config):**
549
+ ```typescript
550
+ apps: [
551
+ {
552
+ name: '@lego/plugin-dashboard',
553
+ entry: isDev ? 'http://localhost:3001' : () => import('@lego/plugin-dashboard'),
554
+ activeWhen: '/dashboard',
555
+ },
556
+ ]
557
+ ```
558
+
559
+ **3. In plugin's plugin.config.ts (Plugin manifest):**
560
+ ```typescript
561
+ export const pluginConfig: PluginConfig = {
562
+ manifest: { name: '@lego/plugin-dashboard', ... },
563
+ slots: [...],
564
+ routes: [...],
565
+ };
566
+ ```
567
+
568
+ ---
569
+
570
+ ## Plugin Lifecycle
571
+
572
+ ```
573
+ ┌─────────────────────────────────────────────────────────────────┐
574
+ │ 1. REGISTRATION │
575
+ │ • Plugin added to saas.config.ts │
576
+ │ • Plugin added to modern.runtime.ts │
577
+ └─────────────────────────────────────────────────────────────────┘
578
+
579
+ v
580
+ ┌─────────────────────────────────────────────────────────────────┐
581
+ │ 2. INITIALIZATION │
582
+ │ • Plugin loader reads plugin.config.ts │
583
+ │ • Plugin store creates plugin state │
584
+ │ • Slots registered in slot registry │
585
+ └─────────────────────────────────────────────────────────────────┘
586
+
587
+ v
588
+ ┌─────────────────────────────────────────────────────────────────┐
589
+ │ 3. LOADING (Dev) │
590
+ │ • Plugin starts on dev server (:3001, :3002, etc.) │
591
+ │ • Garfish connects to plugin URL │
592
+ └─────────────────────────────────────────────────────────────────┘
593
+
594
+ v
595
+ ┌─────────────────────────────────────────────────────────────────┐
596
+ │ 4. LOADING (Production) │
597
+ │ • Plugin bundled into host build │
598
+ │ • Garfish dynamically imports plugin │
599
+ └─────────────────────────────────────────────────────────────────┘
600
+
601
+ v
602
+ ┌─────────────────────────────────────────────────────────────────┐
603
+ │ 5. MOUNTING │
604
+ │ • User navigates to plugin route │
605
+ │ • Garfish mounts plugin App component │
606
+ │ • Plugin renders in host layout │
607
+ └─────────────────────────────────────────────────────────────────┘
608
+
609
+ v
610
+ ┌─────────────────────────────────────────────────────────────────┐
611
+ │ 6. ACTIVE │
612
+ │ • Plugin can use host services via channels │
613
+ │ • Plugin slots render in host layout │
614
+ │ • Plugin routes accessible │
615
+ └─────────────────────────────────────────────────────────────────┘
616
+ ```
617
+
618
+ ---
619
+
620
+ **Next:** Read [`06-communication-patterns.md`](./06-communication-patterns.md) for inter-plugin communication details.