create-lego-one 2.0.10 → 2.0.13

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 (242) hide show
  1. package/dist/index.cjs +179 -0
  2. package/dist/index.cjs.map +1 -1
  3. package/package.json +5 -3
  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/e2e/auth.spec.ts +38 -0
  70. package/template/host/e2e/layout.spec.ts +38 -0
  71. package/template/host/modern.config.ts +19 -0
  72. package/template/host/package.json +71 -0
  73. package/template/host/playwright.config.ts +34 -0
  74. package/template/host/postcss.config.mjs +6 -0
  75. package/template/host/src/App.tsx +6 -0
  76. package/template/host/src/bootstrap.tsx +74 -0
  77. package/template/host/src/global.css +59 -0
  78. package/template/host/src/index.ts +2 -0
  79. package/template/host/src/kernel/__tests__/lib-utils.test.ts +32 -0
  80. package/template/host/src/kernel/__tests__/rbac-hooks.test.tsx +114 -0
  81. package/template/host/src/kernel/__tests__/rbac-utils.test.ts +108 -0
  82. package/template/host/src/kernel/auth/ProtectedRoute.tsx +41 -0
  83. package/template/host/src/kernel/auth/components/LoginForm.tsx +97 -0
  84. package/template/host/src/kernel/auth/components/LogoutButton.tsx +79 -0
  85. package/template/host/src/kernel/auth/hooks.ts +174 -0
  86. package/template/host/src/kernel/auth/index.ts +5 -0
  87. package/template/host/src/kernel/auth/schemas.ts +27 -0
  88. package/template/host/src/kernel/auth/service.ts +197 -0
  89. package/template/host/src/kernel/auth/types.ts +36 -0
  90. package/template/host/src/kernel/channels/ChannelBus.ts +181 -0
  91. package/template/host/src/kernel/channels/ChannelProvider.tsx +57 -0
  92. package/template/host/src/kernel/channels/events.ts +27 -0
  93. package/template/host/src/kernel/channels/hooks.ts +168 -0
  94. package/template/host/src/kernel/channels/index.ts +6 -0
  95. package/template/host/src/kernel/channels/integrations/ToastIntegration.tsx +60 -0
  96. package/template/host/src/kernel/channels/plugin-hooks.ts +72 -0
  97. package/template/host/src/kernel/channels/types.ts +112 -0
  98. package/template/host/src/kernel/components/__tests__/Badge.test.tsx +35 -0
  99. package/template/host/src/kernel/components/__tests__/Button.test.tsx +63 -0
  100. package/template/host/src/kernel/components/__tests__/Input.test.tsx +64 -0
  101. package/template/host/src/kernel/components/index.ts +32 -0
  102. package/template/host/src/kernel/components/ui/alert.tsx +58 -0
  103. package/template/host/src/kernel/components/ui/avatar.tsx +47 -0
  104. package/template/host/src/kernel/components/ui/badge.tsx +35 -0
  105. package/template/host/src/kernel/components/ui/button.tsx +50 -0
  106. package/template/host/src/kernel/components/ui/card.tsx +78 -0
  107. package/template/host/src/kernel/components/ui/dialog.tsx +116 -0
  108. package/template/host/src/kernel/components/ui/dropdown-menu.tsx +192 -0
  109. package/template/host/src/kernel/components/ui/index.ts +7 -0
  110. package/template/host/src/kernel/components/ui/input.tsx +24 -0
  111. package/template/host/src/kernel/components/ui/label.tsx +21 -0
  112. package/template/host/src/kernel/components/ui/popover.tsx +28 -0
  113. package/template/host/src/kernel/components/ui/progress.tsx +25 -0
  114. package/template/host/src/kernel/components/ui/scroll-area.tsx +45 -0
  115. package/template/host/src/kernel/components/ui/select.tsx +155 -0
  116. package/template/host/src/kernel/components/ui/separator.tsx +28 -0
  117. package/template/host/src/kernel/components/ui/skeleton.tsx +15 -0
  118. package/template/host/src/kernel/components/ui/switch.tsx +26 -0
  119. package/template/host/src/kernel/components/ui/table.tsx +116 -0
  120. package/template/host/src/kernel/components/ui/tabs.tsx +52 -0
  121. package/template/host/src/kernel/components/ui/toast.tsx +126 -0
  122. package/template/host/src/kernel/components/ui/toaster.tsx +34 -0
  123. package/template/host/src/kernel/components/ui/tooltip.tsx +27 -0
  124. package/template/host/src/kernel/components/ui/use-toast.ts +183 -0
  125. package/template/host/src/kernel/index.ts +48 -0
  126. package/template/host/src/kernel/lib/cn.ts +1 -0
  127. package/template/host/src/kernel/lib/utils.ts +36 -0
  128. package/template/host/src/kernel/plugins/Slot.tsx +41 -0
  129. package/template/host/src/kernel/plugins/SlotProvider.tsx +88 -0
  130. package/template/host/src/kernel/plugins/index.ts +23 -0
  131. package/template/host/src/kernel/plugins/loader.ts +122 -0
  132. package/template/host/src/kernel/plugins/schemas.ts +54 -0
  133. package/template/host/src/kernel/plugins/store.ts +185 -0
  134. package/template/host/src/kernel/plugins/types.ts +103 -0
  135. package/template/host/src/kernel/providers/PocketBaseProvider.tsx +70 -0
  136. package/template/host/src/kernel/providers/QueryProvider.tsx +28 -0
  137. package/template/host/src/kernel/providers/ThemeProvider.tsx +25 -0
  138. package/template/host/src/kernel/providers/index.ts +3 -0
  139. package/template/host/src/kernel/rbac/components/OrganizationSelector.tsx +69 -0
  140. package/template/host/src/kernel/rbac/components/PermissionGate.tsx +43 -0
  141. package/template/host/src/kernel/rbac/hooks.ts +379 -0
  142. package/template/host/src/kernel/rbac/index.ts +6 -0
  143. package/template/host/src/kernel/rbac/service.ts +504 -0
  144. package/template/host/src/kernel/rbac/types.ts +164 -0
  145. package/template/host/src/kernel/rbac/utils.ts +34 -0
  146. package/template/host/src/kernel/shared-state/bridge.ts +31 -0
  147. package/template/host/src/kernel/shared-state/index.ts +3 -0
  148. package/template/host/src/kernel/shared-state/store.ts +62 -0
  149. package/template/host/src/kernel/shared-state/types.ts +60 -0
  150. package/template/host/src/kernel/use-migrations.ts +72 -0
  151. package/template/host/src/layout/MobileMenu.tsx +61 -0
  152. package/template/host/src/layout/Shell.tsx +42 -0
  153. package/template/host/src/layout/Sidebar.tsx +178 -0
  154. package/template/host/src/layout/Topbar.tsx +50 -0
  155. package/template/host/src/layout/index.ts +4 -0
  156. package/template/host/src/lib/pocketbase/client.ts +38 -0
  157. package/template/host/src/lib/pocketbase/collections/audit_logs.ts +87 -0
  158. package/template/host/src/lib/pocketbase/collections/index.ts +19 -0
  159. package/template/host/src/lib/pocketbase/collections/organizations.ts +63 -0
  160. package/template/host/src/lib/pocketbase/collections/permissions.ts +57 -0
  161. package/template/host/src/lib/pocketbase/collections/roles.ts +55 -0
  162. package/template/host/src/lib/pocketbase/collections/todos.ts +74 -0
  163. package/template/host/src/lib/pocketbase/collections/user_roles.ts +57 -0
  164. package/template/host/src/lib/pocketbase/collections/users.ts +43 -0
  165. package/template/host/src/lib/pocketbase/index.ts +5 -0
  166. package/template/host/src/lib/pocketbase/migrations.ts +44 -0
  167. package/template/host/src/lib/pocketbase/seed/permissions.ts +8 -0
  168. package/template/host/src/lib/pocketbase/seed/roles.ts +22 -0
  169. package/template/host/src/lib/pocketbase/seed.ts +113 -0
  170. package/template/host/src/lib/pocketbase/types.ts +102 -0
  171. package/template/host/src/modern.runtime.ts +26 -0
  172. package/template/host/src/plugins.d.ts +9 -0
  173. package/template/host/src/providers/PocketBaseProvider.tsx +30 -0
  174. package/template/host/src/routes/_.tsx +6 -0
  175. package/template/host/src/routes/dashboard._.tsx +41 -0
  176. package/template/host/src/routes/index.tsx +93 -0
  177. package/template/host/src/routes/login.tsx +36 -0
  178. package/template/host/src/saas.config.ts +52 -0
  179. package/template/host/src/test/setup.ts +65 -0
  180. package/template/host/src/test/utils.tsx +69 -0
  181. package/template/host/src/test/vitest-globals.d.ts +19 -0
  182. package/template/host/src/vite-env.d.ts +16 -0
  183. package/template/host/tailwind.config.ts +77 -0
  184. package/template/host/tsconfig.json +19 -0
  185. package/template/host/vitest.config.ts +30 -0
  186. package/template/nginx.conf +72 -0
  187. package/template/package.json +44 -0
  188. package/template/packages/plugins/@lego/plugin-dashboard/modern.config.ts +19 -0
  189. package/template/packages/plugins/@lego/plugin-dashboard/package.json +35 -0
  190. package/template/packages/plugins/@lego/plugin-dashboard/postcss.config.mjs +6 -0
  191. package/template/packages/plugins/@lego/plugin-dashboard/src/App.tsx +27 -0
  192. package/template/packages/plugins/@lego/plugin-dashboard/src/components/ActivityFeed.tsx +63 -0
  193. package/template/packages/plugins/@lego/plugin-dashboard/src/components/QuickActionSlot.tsx +11 -0
  194. package/template/packages/plugins/@lego/plugin-dashboard/src/components/QuickActions.tsx +68 -0
  195. package/template/packages/plugins/@lego/plugin-dashboard/src/components/SidebarWidget.tsx +35 -0
  196. package/template/packages/plugins/@lego/plugin-dashboard/src/components/StatCard.tsx +47 -0
  197. package/template/packages/plugins/@lego/plugin-dashboard/src/global.css +24 -0
  198. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useChannelIntegration.ts +43 -0
  199. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useDashboardStats.ts +65 -0
  200. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/usePocketBase.ts +47 -0
  201. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useRecentActivity.ts +55 -0
  202. package/template/packages/plugins/@lego/plugin-dashboard/src/lib/utils.ts +6 -0
  203. package/template/packages/plugins/@lego/plugin-dashboard/src/pages/DashboardPage.tsx +105 -0
  204. package/template/packages/plugins/@lego/plugin-dashboard/src/plugin.config.ts +121 -0
  205. package/template/packages/plugins/@lego/plugin-dashboard/src/plugin.ts +18 -0
  206. package/template/packages/plugins/@lego/plugin-dashboard/src/vite-env.d.ts +32 -0
  207. package/template/packages/plugins/@lego/plugin-dashboard/tailwind.config.ts +35 -0
  208. package/template/packages/plugins/@lego/plugin-dashboard/tsconfig.json +18 -0
  209. package/template/packages/plugins/@lego/plugin-todo/modern.config.ts +18 -0
  210. package/template/packages/plugins/@lego/plugin-todo/package.json +41 -0
  211. package/template/packages/plugins/@lego/plugin-todo/postcss.config.mjs +6 -0
  212. package/template/packages/plugins/@lego/plugin-todo/src/App.tsx +12 -0
  213. package/template/packages/plugins/@lego/plugin-todo/src/components/SidebarWidget.tsx +16 -0
  214. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoDialog.tsx +55 -0
  215. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoFilters.tsx +79 -0
  216. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoForm.tsx +94 -0
  217. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoItem.tsx +121 -0
  218. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoList.tsx +41 -0
  219. package/template/packages/plugins/@lego/plugin-todo/src/components/index.ts +6 -0
  220. package/template/packages/plugins/@lego/plugin-todo/src/global.css +59 -0
  221. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useCreateTodo.ts +62 -0
  222. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useDeleteTodo.ts +46 -0
  223. package/template/packages/plugins/@lego/plugin-todo/src/hooks/usePocketBase.ts +38 -0
  224. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useTodos.ts +64 -0
  225. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useUpdateTodo.ts +35 -0
  226. package/template/packages/plugins/@lego/plugin-todo/src/index.tsx +5 -0
  227. package/template/packages/plugins/@lego/plugin-todo/src/lib/utils.ts +20 -0
  228. package/template/packages/plugins/@lego/plugin-todo/src/pages/TodoPage.tsx +89 -0
  229. package/template/packages/plugins/@lego/plugin-todo/src/plugin.config.ts +104 -0
  230. package/template/packages/plugins/@lego/plugin-todo/src/plugin.ts +13 -0
  231. package/template/packages/plugins/@lego/plugin-todo/src/schemas.ts +37 -0
  232. package/template/packages/plugins/@lego/plugin-todo/src/types.ts +42 -0
  233. package/template/packages/plugins/@lego/plugin-todo/src/vite-env.d.ts +31 -0
  234. package/template/packages/plugins/@lego/plugin-todo/tailwind.config.ts +51 -0
  235. package/template/packages/plugins/@lego/plugin-todo/tsconfig.json +18 -0
  236. package/template/pnpm-workspace.yaml +4 -0
  237. package/template/pocketbase/CHANGELOG.md +911 -0
  238. package/template/pocketbase/LICENSE.md +17 -0
  239. package/template/scripts/create-plugin.js +221 -0
  240. package/template/scripts/deploy.sh +56 -0
  241. package/template/tsconfig.base.json +26 -0
  242. package/template/tsconfig.json +8 -0
@@ -0,0 +1,645 @@
1
+ # Plugin Architecture: Hello World & Registration
2
+
3
+ **Project:** Lego-One (Modern.js SaaS OS)
4
+ **Document:** 04 - Plugin Architecture
5
+ **Status:** Research Phase
6
+
7
+ ## Executive Summary
8
+
9
+ This document explains how to create a "Hello World" plugin as a standalone Modern.js sub-app and register it with the Host (Kernel). Plugins are independently deployable Modern.js applications that can run standalone or be loaded by the host.
10
+
11
+ ---
12
+
13
+ ## 1. Plugin Structure Overview
14
+
15
+ ### 1.1 Directory Structure
16
+
17
+ ```
18
+ lego-one/
19
+ ├── host/ # Kernel application
20
+ ├── packages/
21
+ │ └── plugins/
22
+ │ └── @lego/
23
+ │ └── plugin-hello/ # Hello World plugin
24
+ │ ├── modern.config.ts
25
+ │ ├── package.json
26
+ │ ├── plugin.config.ts
27
+ │ ├── tsconfig.json
28
+ │ └── src/
29
+ │ ├── App.tsx
30
+ │ ├── main.tsx
31
+ │ ├── pages/
32
+ │ │ └── HelloPage.tsx
33
+ │ ├── components/
34
+ │ │ └── Greeting.tsx
35
+ │ ├── hooks/
36
+ │ │ ├── useKernelState.ts
37
+ │ │ └── useKernelBus.ts
38
+ │ └── lib/
39
+ │ └── utils.ts
40
+ ```
41
+
42
+ ### 1.2 Plugin Types
43
+
44
+ | Type | Description | Example |
45
+ |------|-------------|---------|
46
+ | **Feature Plugin** | Standalone business functionality | Loan Calculator, Inventory |
47
+ | **Integration Plugin** | Third-party service integration | Stripe, Snowflake, SendGrid |
48
+ | **UI Extension** | Extends host UI (slots) | Dashboard widget, Sidebar link |
49
+
50
+ ---
51
+
52
+ ## 2. Create Hello World Plugin
53
+
54
+ ### 2.1 Initialize Plugin Project
55
+
56
+ ```bash
57
+ cd lego-one/packages/plugins/@lego
58
+
59
+ # Create plugin using Modern.js
60
+ npx @modern-js/create@latest plugin-hello
61
+
62
+ cd plugin-hello
63
+
64
+ # Enable Micro Frontend
65
+ pnpm run new
66
+ # Select: Enable features -> Micro Front-end Feature
67
+ ```
68
+
69
+ ### 2.2 Configure Package.json
70
+
71
+ **File:** `packages/plugins/@lego/plugin-hello/package.json`
72
+
73
+ ```json
74
+ {
75
+ "name": "@lego/plugin-hello",
76
+ "version": "1.0.0",
77
+ "private": true,
78
+ "type": "module",
79
+ "exports": {
80
+ ".": "./src/main.tsx",
81
+ "./plugin.config": "./plugin.config.ts"
82
+ },
83
+ "scripts": {
84
+ "dev": "modern dev",
85
+ "build": "modern build",
86
+ "preview": "modern preview",
87
+ "lint": "modern lint"
88
+ },
89
+ "dependencies": {
90
+ "@modern-js/runtime": "^2.0.0",
91
+ "react": "^18.3.0",
92
+ "react-dom": "^18.3.0"
93
+ },
94
+ "devDependencies": {
95
+ "@modern-js/app-tools": "^2.0.0",
96
+ "@modern-js/plugin-garfish": "^2.0.0",
97
+ "@types/react": "^18.3.0",
98
+ "@types/react-dom": "^18.3.0",
99
+ "typescript": "^5.5.0"
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### 2.3 Configure Modern.js
105
+
106
+ **File:** `packages/plugins/@lego/plugin-hello/modern.config.ts`
107
+
108
+ ```typescript
109
+ import { appTools, defineConfig } from '@modern-js/app-tools';
110
+ import { garfishPlugin } from '@modern-js/plugin-garfish';
111
+
112
+ export default defineConfig({
113
+ // Unique dev port for each plugin
114
+ dev: {
115
+ port: 3001,
116
+ },
117
+
118
+ // Enable routing
119
+ runtime: {
120
+ router: true,
121
+ },
122
+
123
+ // CRITICAL: Mark as micro-frontend sub-app
124
+ deploy: {
125
+ microFrontend: true,
126
+ },
127
+
128
+ plugins: [appTools(), garfishPlugin()],
129
+
130
+ // Path aliases
131
+ source: {
132
+ alias: {
133
+ '@': './src',
134
+ },
135
+ },
136
+ });
137
+ ```
138
+
139
+ ### 2.4 Create Plugin Config
140
+
141
+ **File:** `packages/plugins/@lego/plugin-hello/plugin.config.ts`
142
+
143
+ ```typescript
144
+ import { definePluginConfig } from '@lego/kernel/plugin-config';
145
+
146
+ export default definePluginConfig({
147
+ name: '@lego/plugin-hello',
148
+ version: '1.0.0',
149
+ displayName: 'Hello World',
150
+ description: 'A simple Hello World plugin for demonstration',
151
+
152
+ // Plugin exports available to host
153
+ exports: {
154
+ components: {
155
+ Greeting: './src/components/Greeting',
156
+ },
157
+ hooks: {
158
+ useHello: './src/hooks/useHello',
159
+ },
160
+ },
161
+
162
+ // Slot injections
163
+ slots: {
164
+ 'sidebar:nav': {
165
+ component: './src/components/SidebarLink',
166
+ order: 100,
167
+ },
168
+ },
169
+
170
+ // Routes this plugin handles
171
+ routes: {
172
+ basePath: '/hello',
173
+ children: ['/', '/greeting'],
174
+ },
175
+ });
176
+ ```
177
+
178
+ ### 2.5 Create Plugin Entry Point
179
+
180
+ **File:** `packages/plugins/@lego/plugin-hello/src/App.tsx`
181
+
182
+ ```typescript
183
+ import { BrowserRouter, Routes, Route } from '@modern-js/runtime/router';
184
+ import { useGarfish } from '@garfish/hooks';
185
+ import { useEffect, useState } from 'react';
186
+ import { HelloPage } from './pages/HelloPage';
187
+ import { GreetingPage } from './pages/GreetingPage';
188
+ import pluginConfig from '../../plugin.config';
189
+ import { registerSlots } from './lib/slot-registration';
190
+
191
+ interface PluginProps {
192
+ basename?: string;
193
+ }
194
+
195
+ export default function PluginApp(props: PluginProps) {
196
+ const { appInfo } = useGarfish();
197
+ const basename = props.basename || '/hello';
198
+
199
+ useEffect(() => {
200
+ console.log(`[${pluginConfig.name}] Plugin loaded with appInfo:`, appInfo);
201
+
202
+ // Register slot injections with host
203
+ registerSlots(pluginConfig.slots);
204
+ }, [appInfo]);
205
+
206
+ return (
207
+ <BrowserRouter basename={basename}>
208
+ <Routes>
209
+ <Route index element={<HelloPage />} />
210
+ <Route path="greeting" element={<GreetingPage />} />
211
+ </Routes>
212
+ </BrowserRouter>
213
+ );
214
+ }
215
+ ```
216
+
217
+ ### 2.6 Create Pages
218
+
219
+ **File:** `packages/plugins/@lego/plugin-hello/src/pages/HelloPage.tsx`
220
+
221
+ ```typescript
222
+ import { useKernelState } from '../hooks/useKernelState';
223
+ import { useKernelBus } from '../hooks/useKernelBus';
224
+ import { Button } from '../components/ui/button';
225
+
226
+ export function HelloPage() {
227
+ const kernelState = useKernelState();
228
+ const bus = useKernelBus();
229
+
230
+ const handleGreet = () => {
231
+ // Emit event to host for toast notification
232
+ bus.emit({
233
+ type: 'toast:show',
234
+ payload: { message: 'Hello from the plugin!', variant: 'success' },
235
+ });
236
+ };
237
+
238
+ return (
239
+ <div className="p-8">
240
+ <h1 className="text-3xl font-bold mb-4">Hello World Plugin</h1>
241
+
242
+ <div className="space-y-4">
243
+ <p className="text-muted-foreground">
244
+ This is a standalone Modern.js application running as a micro-frontend.
245
+ </p>
246
+
247
+ <div className="bg-muted p-4 rounded-lg">
248
+ <h2 className="font-semibold mb-2">Shared State from Kernel:</h2>
249
+ <ul className="list-disc list-inside space-y-1">
250
+ <li>Theme: {kernelState?.theme}</li>
251
+ <li>Sidebar: {kernelState?.sidebarOpen ? 'Open' : 'Closed'}</li>
252
+ <li>User: {kernelState?.currentUser?.email || 'Not authenticated'}</li>
253
+ </ul>
254
+ </div>
255
+
256
+ <Button onClick={handleGreet}>Show Greeting</Button>
257
+ </div>
258
+ </div>
259
+ );
260
+ }
261
+ ```
262
+
263
+ **File:** `packages/plugins/@lego/plugin-hello/src/pages/GreetingPage.tsx`
264
+
265
+ ```typescript
266
+ import { Greeting } from '../components/Greeting';
267
+
268
+ export function GreetingPage() {
269
+ return (
270
+ <div className="p-8">
271
+ <h1 className="text-3xl font-bold mb-4">Greeting Page</h1>
272
+ <Greeting name="Developer" />
273
+ </div>
274
+ );
275
+ }
276
+ ```
277
+
278
+ ### 2.7 Create Components
279
+
280
+ **File:** `packages/plugins/@lego/plugin-hello/src/components/Greeting.tsx`
281
+
282
+ ```typescript
283
+ import { useState } from 'react';
284
+
285
+ interface GreetingProps {
286
+ name: string;
287
+ }
288
+
289
+ export function Greeting({ name }: GreetingProps) {
290
+ const [count, setCount] = useState(0);
291
+
292
+ return (
293
+ <div className="bg-card p-6 rounded-lg border">
294
+ <p className="text-lg">
295
+ Hello, <span className="font-semibold text-primary">{name}</span>!
296
+ </p>
297
+ <p className="text-muted-foreground mt-2">
298
+ You've clicked the button {count} times.
299
+ </p>
300
+ <button
301
+ onClick={() => setCount((c) => c + 1)}
302
+ className="mt-4 px-4 py-2 bg-primary text-primary-foreground rounded-md"
303
+ >
304
+ Click Me
305
+ </button>
306
+ </div>
307
+ );
308
+ }
309
+ ```
310
+
311
+ **File:** `packages/plugins/@lego/plugin-hello/src/components/SidebarLink.tsx`
312
+
313
+ ```typescript
314
+ import { Link } from '@modern-js/runtime/router';
315
+ import { Hand } from 'lucide-react';
316
+
317
+ export function SidebarLink() {
318
+ return (
319
+ <Link
320
+ to="/hello"
321
+ className="flex items-center gap-2 px-3 py-2 text-sm rounded-md hover:bg-accent hover:text-accent-foreground"
322
+ >
323
+ <Hand className="h-4 w-4" />
324
+ <span>Hello Plugin</span>
325
+ </Link>
326
+ );
327
+ }
328
+ ```
329
+
330
+ ### 2.8 Create Hooks
331
+
332
+ **File:** `packages/plugins/@lego/plugin-hello/src/hooks/useKernelState.ts`
333
+
334
+ ```typescript
335
+ import { useEffect, useState } from 'react';
336
+
337
+ interface KernelState {
338
+ currentUser: { id: string; email: string; role: string } | null;
339
+ theme: 'light' | 'dark';
340
+ sidebarOpen: boolean;
341
+ }
342
+
343
+ export function useKernelState() {
344
+ const [state, setState] = useState<KernelState | null>(null);
345
+
346
+ useEffect(() => {
347
+ // Access shared state bridge from host
348
+ const kernelBridge = (window as any).__LEGO_KERNEL_STATE__;
349
+
350
+ if (kernelBridge?.useGlobalKernelState) {
351
+ // Subscribe to state changes
352
+ const unsubscribe = kernelBridge.useGlobalKernelState.subscribe(
353
+ (newState: KernelState) => {
354
+ setState({ ...newState });
355
+ }
356
+ );
357
+
358
+ // Initialize with current state
359
+ setState(kernelBridge.useGlobalKernelState.getState());
360
+
361
+ return () => unsubscribe?.();
362
+ }
363
+ }, []);
364
+
365
+ return state;
366
+ }
367
+ ```
368
+
369
+ **File:** `packages/plugins/@lego/plugin-hello/src/hooks/useKernelBus.ts`
370
+
371
+ ```typescript
372
+ import { Garfish } from 'garfish';
373
+
374
+ type BusEvent =
375
+ | { type: 'toast:show'; payload: { message: string; variant: 'success' | 'error' } }
376
+ | { type: 'navigation:goto'; payload: { path: string } };
377
+
378
+ export function useKernelBus() {
379
+ const channel = Garfish.channel;
380
+
381
+ return {
382
+ emit: (event: BusEvent) => {
383
+ channel.emit(event.type, event.payload);
384
+ },
385
+ on: (eventType: BusEvent['type'], handler: (payload: any) => void) => {
386
+ channel.on(eventType, handler);
387
+ },
388
+ off: (eventType: BusEvent['type'], handler: (payload: any) => void) => {
389
+ channel.off(eventType, handler);
390
+ },
391
+ };
392
+ }
393
+ ```
394
+
395
+ ### 2.9 Create Slot Registration Helper
396
+
397
+ **File:** `packages/plugins/@lego/plugin-hello/src/lib/slot-registration.ts`
398
+
399
+ ```typescript
400
+ interface SlotConfig {
401
+ component: string;
402
+ order: number;
403
+ isVisible?: () => boolean;
404
+ }
405
+
406
+ interface SlotsConfig {
407
+ [slotName: string]: SlotConfig;
408
+ }
409
+
410
+ export async function registerSlots(slots: SlotsConfig) {
411
+ const slotRegistry = (window as any).__LEGO_SLOT_REGISTRY__;
412
+
413
+ if (!slotRegistry) {
414
+ console.warn('Slot registry not found. Host may not be initialized.');
415
+ return;
416
+ }
417
+
418
+ for (const [slotName, slotConfig] of Object.entries(slots)) {
419
+ try {
420
+ const module = await import(/* @vite-ignore */ slotConfig.component);
421
+ const Component = module.default;
422
+
423
+ slotRegistry.register(slotName, {
424
+ id: `${slotName}-${Date.now()}`,
425
+ pluginName: '@lego/plugin-hello',
426
+ component: Component,
427
+ order: slotConfig.order,
428
+ isVisible: slotConfig.isVisible || (() => true),
429
+ });
430
+
431
+ console.log(`[Slot] Registered "${slotName}" for @lego/plugin-hello`);
432
+ } catch (error) {
433
+ console.error(`[Slot] Failed to register "${slotName}":`, error);
434
+ }
435
+ }
436
+ }
437
+ ```
438
+
439
+ ---
440
+
441
+ ## 3. Register Plugin with Host
442
+
443
+ ### 3.1 Update Host Configuration
444
+
445
+ **File:** `host/src/modern.runtime.ts`
446
+
447
+ ```typescript
448
+ import { defineRuntimeConfig } from '@modern-js/runtime';
449
+
450
+ export default defineRuntimeConfig({
451
+ masterApp: {
452
+ apps: [
453
+ {
454
+ name: '@lego/plugin-hello',
455
+ entry: 'http://localhost:3001',
456
+ activeWhen: '/hello',
457
+ },
458
+ ],
459
+ },
460
+ });
461
+ ```
462
+
463
+ ### 3.2 Create Plugin Route in Host
464
+
465
+ **File:** `host/src/routes/hello/$.tsx`
466
+
467
+ ```typescript
468
+ import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
469
+
470
+ export default function HelloRoute() {
471
+ const { Hello } = useModuleApps();
472
+
473
+ return <Hello />;
474
+ }
475
+ ```
476
+
477
+ ### 3.3 Update Host saas.config.ts
478
+
479
+ **File:** `host/saas.config.ts`
480
+
481
+ ```typescript
482
+ import { defineConfig } from '@lego/kernel/config';
483
+
484
+ export default defineConfig({
485
+ plugins: [
486
+ {
487
+ name: '@lego/plugin-hello',
488
+ enabled: true,
489
+ },
490
+ ],
491
+ });
492
+ ```
493
+
494
+ ---
495
+
496
+ ## 4. Development Workflow
497
+
498
+ ### 4.1 Start Host and Plugin
499
+
500
+ Open two terminal windows:
501
+
502
+ ```bash
503
+ # Terminal 1: Start Host
504
+ cd host
505
+ pnpm run dev
506
+ # Runs on http://localhost:8080
507
+ ```
508
+
509
+ ```bash
510
+ # Terminal 2: Start Plugin
511
+ cd packages/plugins/@lego/plugin-hello
512
+ pnpm run dev
513
+ # Runs on http://localhost:3001
514
+ ```
515
+
516
+ ### 4.2 Test Plugin
517
+
518
+ Navigate to `http://localhost:8080/hello`
519
+
520
+ **Expected behavior:**
521
+ 1. Host loads the Hello plugin at the `/hello` route
522
+ 2. Plugin displays "Hello World Plugin" header
523
+ 3. Shared kernel state (theme, user, sidebar) is displayed
524
+ 4. "Show Greeting" button triggers toast in host app
525
+ 5. Sidebar shows "Hello Plugin" link (if slot injection works)
526
+
527
+ ---
528
+
529
+ ## 5. Plugin Lifecycle
530
+
531
+ ```
532
+ ┌─────────────────────────────────────────────────────────────────────────┐
533
+ │ Plugin Lifecycle │
534
+ ├─────────────────────────────────────────────────────────────────────────┤
535
+ │ │
536
+ │ 1. REGISTRATION │
537
+ │ - Plugin listed in saas.config.ts │
538
+ │ - Host reads plugin config on startup │
539
+ │ │
540
+ │ 2. LOADING │
541
+ │ - User navigates to plugin route (/hello) │
542
+ │ - Garfish.loadApp() fetches plugin entry │
543
+ │ - Plugin JavaScript executes │
544
+ │ │
545
+ │ 3. MOUNTING │
546
+ │ - Plugin App.tsx receives basename prop │
547
+ │ - Plugin registers slots with host │
548
+ │ - Plugin subscribes to kernel bus events │
549
+ │ - Plugin ReactDOM.render into container │
550
+ │ │
551
+ │ 4. ACTIVE STATE │
552
+ │ - Plugin handles its own routing │
553
+ │ - Plugin communicates with host via bus │
554
+ │ - Plugin accesses shared state via window bridge │
555
+ │ │
556
+ │ 5. UNMOUNTING │
557
+ │ - User navigates away from plugin route │
558
+ │ - Plugin cleanup functions run │
559
+ │ - Garfish unloads plugin resources │
560
+ │ │
561
+ └─────────────────────────────────────────────────────────────────────────┘
562
+ ```
563
+
564
+ ---
565
+
566
+ ## 6. Standalone Development
567
+
568
+ Plugins can run independently for development:
569
+
570
+ ```bash
571
+ cd packages/plugins/@lego/plugin-hello
572
+ pnpm run dev
573
+ # Access at http://localhost:3001
574
+ ```
575
+
576
+ **Standalone App.tsx:**
577
+
578
+ ```typescript
579
+ // For standalone development, provide a default basename
580
+ export default function PluginApp(props: PluginProps) {
581
+ const basename = props.basename || '/hello';
582
+ // ... rest of component
583
+ }
584
+ ```
585
+
586
+ ---
587
+
588
+ ## 7. Plugin Best Practices
589
+
590
+ | Practice | Description |
591
+ |----------|-------------|
592
+ | **Unique Ports** | Each plugin needs a unique dev port |
593
+ | **Isolated State** | Don't rely on host state for core functionality |
594
+ | **Error Boundaries** | Wrap plugin in error boundary |
595
+ | **Type Safety** | Export types from plugin.config.ts |
596
+ | **Testing** | Test plugin standalone and integrated |
597
+ | **Documentation** | Document slots, events, and exports |
598
+
599
+ ---
600
+
601
+ ## 8. Troubleshooting
602
+
603
+ ### 8.1 Plugin Not Loading
604
+
605
+ **Symptoms:** Blank page at plugin route
606
+
607
+ **Solutions:**
608
+ 1. Check plugin dev server is running
609
+ 2. Verify `activeWhen` matches route
610
+ 3. Check browser console for errors
611
+ 4. Verify `deploy.microFrontend: true` in plugin config
612
+
613
+ ### 8.2 Shared State Undefined
614
+
615
+ **Symptoms:** `useKernelState()` returns null
616
+
617
+ **Solutions:**
618
+ 1. Verify host has called `registerSharedState()`
619
+ 2. Check `window.__LEGO_KERNEL_STATE__` exists
620
+ 3. Ensure host loads before plugin
621
+
622
+ ### 8.3 Route Mismatch
623
+
624
+ **Symptoms:** 404 when navigating to plugin
625
+
626
+ **Solutions:**
627
+ 1. Check `$.tsx` file exists in host routes
628
+ 2. Verify `basename` prop is passed correctly
629
+ 3. Check for conflicts with other routes
630
+
631
+ ---
632
+
633
+ ## 9. Next Steps
634
+
635
+ 1. **`05-slot-injection-pattern.md`**: Advanced slot injection patterns
636
+ 2. **`06-cli-strategy.md`**: Automate plugin creation with CLI
637
+ 3. **`07-deployment.md`**: Deploy plugins to production
638
+
639
+ ---
640
+
641
+ ## References
642
+
643
+ - [Modern.js Micro Frontend Development](https://modernjs.dev/guides/topic-detail/micro-frontend/c02-development)
644
+ - [Garfish Documentation](https://www.garfishjs.org/)
645
+ - [Garfish.setExternal API](https://www.garfishjs.org/api/setExternal.html)