create-fluxstack 1.10.1 → 1.12.1

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 (257) hide show
  1. package/.dockerignore +1 -2
  2. package/Dockerfile +8 -8
  3. package/LLMD/INDEX.md +64 -0
  4. package/LLMD/MAINTENANCE.md +197 -0
  5. package/LLMD/MIGRATION.md +156 -0
  6. package/LLMD/config/.gitkeep +1 -0
  7. package/LLMD/config/declarative-system.md +268 -0
  8. package/LLMD/config/environment-vars.md +327 -0
  9. package/LLMD/config/runtime-reload.md +401 -0
  10. package/LLMD/core/.gitkeep +1 -0
  11. package/LLMD/core/build-system.md +599 -0
  12. package/LLMD/core/framework-lifecycle.md +229 -0
  13. package/LLMD/core/plugin-system.md +451 -0
  14. package/LLMD/patterns/.gitkeep +1 -0
  15. package/LLMD/patterns/anti-patterns.md +297 -0
  16. package/LLMD/patterns/project-structure.md +264 -0
  17. package/LLMD/patterns/type-safety.md +440 -0
  18. package/LLMD/reference/.gitkeep +1 -0
  19. package/LLMD/reference/cli-commands.md +250 -0
  20. package/LLMD/reference/plugin-hooks.md +357 -0
  21. package/LLMD/reference/routing.md +39 -0
  22. package/LLMD/reference/troubleshooting.md +364 -0
  23. package/LLMD/resources/.gitkeep +1 -0
  24. package/LLMD/resources/controllers.md +465 -0
  25. package/LLMD/resources/live-components.md +703 -0
  26. package/LLMD/resources/live-rooms.md +482 -0
  27. package/LLMD/resources/live-upload.md +130 -0
  28. package/LLMD/resources/plugins-external.md +617 -0
  29. package/LLMD/resources/routes-eden.md +254 -0
  30. package/README.md +37 -17
  31. package/app/client/index.html +0 -1
  32. package/app/client/src/App.tsx +107 -150
  33. package/app/client/src/components/AppLayout.tsx +68 -0
  34. package/app/client/src/components/BackButton.tsx +13 -0
  35. package/app/client/src/components/DemoPage.tsx +20 -0
  36. package/app/client/src/components/LiveUploadWidget.tsx +204 -0
  37. package/app/client/src/lib/eden-api.ts +85 -60
  38. package/app/client/src/live/ChatDemo.tsx +107 -0
  39. package/app/client/src/live/CounterDemo.tsx +206 -0
  40. package/app/client/src/live/FormDemo.tsx +119 -0
  41. package/app/client/src/live/RoomChatDemo.tsx +161 -0
  42. package/app/client/src/live/UploadDemo.tsx +21 -0
  43. package/app/client/src/main.tsx +4 -1
  44. package/app/client/src/pages/ApiTestPage.tsx +108 -0
  45. package/app/client/src/pages/HomePage.tsx +76 -0
  46. package/app/server/app.ts +1 -4
  47. package/app/server/controllers/users.controller.ts +36 -44
  48. package/app/server/index.ts +25 -35
  49. package/app/server/live/LiveChat.ts +77 -0
  50. package/app/server/live/LiveCounter.ts +67 -0
  51. package/app/server/live/LiveForm.ts +63 -0
  52. package/app/server/live/LiveLocalCounter.ts +32 -0
  53. package/app/server/live/LiveRoomChat.ts +127 -0
  54. package/app/server/live/LiveUpload.ts +81 -0
  55. package/app/server/routes/index.ts +3 -1
  56. package/app/server/routes/room.routes.ts +117 -0
  57. package/app/server/routes/users.routes.ts +35 -27
  58. package/app/shared/types/index.ts +14 -2
  59. package/config/app.config.ts +2 -62
  60. package/config/client.config.ts +2 -95
  61. package/config/database.config.ts +2 -99
  62. package/config/fluxstack.config.ts +25 -45
  63. package/config/index.ts +57 -38
  64. package/config/monitoring.config.ts +2 -114
  65. package/config/plugins.config.ts +2 -80
  66. package/config/server.config.ts +2 -68
  67. package/config/services.config.ts +2 -130
  68. package/config/system/app.config.ts +29 -0
  69. package/config/system/build.config.ts +49 -0
  70. package/config/system/client.config.ts +68 -0
  71. package/config/system/database.config.ts +17 -0
  72. package/config/system/fluxstack.config.ts +114 -0
  73. package/config/{logger.config.ts → system/logger.config.ts} +3 -1
  74. package/config/system/monitoring.config.ts +114 -0
  75. package/config/system/plugins.config.ts +84 -0
  76. package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
  77. package/config/system/server.config.ts +68 -0
  78. package/config/system/services.config.ts +46 -0
  79. package/config/{system.config.ts → system/system.config.ts} +1 -1
  80. package/core/build/flux-plugins-generator.ts +325 -325
  81. package/core/build/index.ts +39 -27
  82. package/core/build/live-components-generator.ts +3 -3
  83. package/core/build/optimizer.ts +235 -235
  84. package/core/cli/command-registry.ts +6 -4
  85. package/core/cli/commands/build.ts +79 -0
  86. package/core/cli/commands/create.ts +54 -0
  87. package/core/cli/commands/dev.ts +101 -0
  88. package/core/cli/commands/help.ts +34 -0
  89. package/core/cli/commands/index.ts +34 -0
  90. package/core/cli/commands/make-plugin.ts +90 -0
  91. package/core/cli/commands/plugin-add.ts +197 -0
  92. package/core/cli/commands/plugin-deps.ts +2 -2
  93. package/core/cli/commands/plugin-list.ts +208 -0
  94. package/core/cli/commands/plugin-remove.ts +170 -0
  95. package/core/cli/generators/component.ts +769 -769
  96. package/core/cli/generators/controller.ts +1 -1
  97. package/core/cli/generators/index.ts +146 -146
  98. package/core/cli/generators/interactive.ts +227 -227
  99. package/core/cli/generators/plugin.ts +2 -2
  100. package/core/cli/generators/prompts.ts +82 -82
  101. package/core/cli/generators/route.ts +6 -6
  102. package/core/cli/generators/service.ts +2 -2
  103. package/core/cli/generators/template-engine.ts +4 -3
  104. package/core/cli/generators/types.ts +2 -2
  105. package/core/cli/generators/utils.ts +191 -191
  106. package/core/cli/index.ts +115 -686
  107. package/core/cli/plugin-discovery.ts +2 -2
  108. package/core/client/LiveComponentsProvider.tsx +60 -8
  109. package/core/client/api/eden.ts +183 -0
  110. package/core/client/api/index.ts +11 -0
  111. package/core/client/components/Live.tsx +104 -0
  112. package/core/client/fluxstack.ts +1 -9
  113. package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
  114. package/core/client/hooks/state-validator.ts +1 -1
  115. package/core/client/hooks/useAuth.ts +48 -48
  116. package/core/client/hooks/useChunkedUpload.ts +85 -35
  117. package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
  118. package/core/client/hooks/useLiveComponent.ts +800 -0
  119. package/core/client/hooks/useLiveUpload.ts +71 -0
  120. package/core/client/hooks/useRoom.ts +409 -0
  121. package/core/client/hooks/useRoomProxy.ts +382 -0
  122. package/core/client/index.ts +17 -68
  123. package/core/client/standalone-entry.ts +8 -0
  124. package/core/client/standalone.ts +74 -53
  125. package/core/client/state/createStore.ts +192 -192
  126. package/core/client/state/index.ts +14 -14
  127. package/core/config/index.ts +70 -291
  128. package/core/config/schema.ts +42 -723
  129. package/core/framework/client.ts +131 -131
  130. package/core/framework/index.ts +7 -7
  131. package/core/framework/server.ts +47 -40
  132. package/core/framework/types.ts +2 -2
  133. package/core/index.ts +23 -4
  134. package/core/live/ComponentRegistry.ts +3 -3
  135. package/core/live/types.ts +77 -0
  136. package/core/plugins/built-in/index.ts +134 -134
  137. package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
  138. package/core/plugins/built-in/live-components/index.ts +1 -1
  139. package/core/plugins/built-in/monitoring/index.ts +111 -47
  140. package/core/plugins/built-in/static/index.ts +1 -1
  141. package/core/plugins/built-in/swagger/index.ts +68 -265
  142. package/core/plugins/built-in/vite/index.ts +85 -185
  143. package/core/plugins/built-in/vite/vite-dev.ts +10 -16
  144. package/core/plugins/config.ts +9 -7
  145. package/core/plugins/dependency-manager.ts +31 -1
  146. package/core/plugins/discovery.ts +19 -7
  147. package/core/plugins/executor.ts +2 -2
  148. package/core/plugins/index.ts +203 -203
  149. package/core/plugins/manager.ts +27 -39
  150. package/core/plugins/module-resolver.ts +19 -8
  151. package/core/plugins/registry.ts +255 -19
  152. package/core/plugins/types.ts +20 -53
  153. package/core/server/framework.ts +66 -43
  154. package/core/server/index.ts +15 -15
  155. package/core/server/live/ComponentRegistry.ts +78 -71
  156. package/core/server/live/FileUploadManager.ts +23 -10
  157. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  158. package/core/server/live/LiveRoomManager.ts +261 -0
  159. package/core/server/live/RoomEventBus.ts +234 -0
  160. package/core/server/live/RoomStateManager.ts +172 -0
  161. package/core/server/live/StateSignature.ts +643 -643
  162. package/core/server/live/WebSocketConnectionManager.ts +30 -19
  163. package/core/server/live/auto-generated-components.ts +21 -9
  164. package/core/server/live/index.ts +14 -0
  165. package/core/server/live/websocket-plugin.ts +214 -67
  166. package/core/server/middleware/elysia-helpers.ts +7 -2
  167. package/core/server/middleware/errorHandling.ts +1 -1
  168. package/core/server/middleware/index.ts +31 -31
  169. package/core/server/plugins/database.ts +180 -180
  170. package/core/server/plugins/static-files-plugin.ts +69 -69
  171. package/core/server/plugins/swagger.ts +1 -1
  172. package/core/server/rooms/RoomBroadcaster.ts +357 -0
  173. package/core/server/rooms/RoomSystem.ts +463 -0
  174. package/core/server/rooms/index.ts +13 -0
  175. package/core/server/services/BaseService.ts +1 -1
  176. package/core/server/services/ServiceContainer.ts +1 -1
  177. package/core/server/services/index.ts +8 -8
  178. package/core/templates/create-project.ts +12 -12
  179. package/core/testing/index.ts +9 -9
  180. package/core/testing/setup.ts +73 -73
  181. package/core/types/api.ts +168 -168
  182. package/core/types/build.ts +219 -219
  183. package/core/types/config.ts +56 -26
  184. package/core/types/index.ts +4 -4
  185. package/core/types/plugin.ts +107 -107
  186. package/core/types/types.ts +353 -14
  187. package/core/utils/build-logger.ts +324 -324
  188. package/core/utils/config-schema.ts +480 -480
  189. package/core/utils/env.ts +2 -8
  190. package/core/utils/errors/codes.ts +114 -114
  191. package/core/utils/errors/handlers.ts +36 -1
  192. package/core/utils/errors/index.ts +49 -5
  193. package/core/utils/errors/middleware.ts +113 -113
  194. package/core/utils/helpers.ts +6 -16
  195. package/core/utils/index.ts +17 -17
  196. package/core/utils/logger/colors.ts +114 -114
  197. package/core/utils/logger/config.ts +13 -9
  198. package/core/utils/logger/formatter.ts +82 -82
  199. package/core/utils/logger/group-logger.ts +101 -101
  200. package/core/utils/logger/index.ts +6 -1
  201. package/core/utils/logger/stack-trace.ts +3 -1
  202. package/core/utils/logger/startup-banner.ts +82 -82
  203. package/core/utils/logger/winston-logger.ts +152 -152
  204. package/core/utils/monitoring/index.ts +211 -211
  205. package/core/utils/sync-version.ts +66 -66
  206. package/core/utils/version.ts +1 -1
  207. package/create-fluxstack.ts +8 -7
  208. package/package.json +12 -13
  209. package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
  210. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  211. package/plugins/crypto-auth/client/components/index.ts +11 -11
  212. package/plugins/crypto-auth/client/index.ts +11 -11
  213. package/plugins/crypto-auth/config/index.ts +1 -1
  214. package/plugins/crypto-auth/index.ts +4 -4
  215. package/plugins/crypto-auth/package.json +65 -65
  216. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  217. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  218. package/plugins/crypto-auth/server/index.ts +21 -21
  219. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
  220. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
  221. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
  222. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
  223. package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
  224. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  225. package/tsconfig.api-strict.json +16 -0
  226. package/tsconfig.json +48 -52
  227. package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
  228. package/types/global.d.ts +29 -29
  229. package/types/vitest.d.ts +8 -8
  230. package/vite.config.ts +38 -62
  231. package/vitest.config.live.ts +10 -9
  232. package/vitest.config.ts +29 -17
  233. package/app/client/README.md +0 -69
  234. package/app/client/SIMPLIFICATION.md +0 -140
  235. package/app/client/frontend-only.ts +0 -12
  236. package/app/client/src/live/FileUploadExample.tsx +0 -359
  237. package/app/client/src/live/MinimalLiveClock.tsx +0 -47
  238. package/app/client/src/live/QuickUploadTest.tsx +0 -193
  239. package/app/client/tsconfig.app.json +0 -45
  240. package/app/client/tsconfig.json +0 -7
  241. package/app/client/zustand-setup.md +0 -65
  242. package/app/server/backend-only.ts +0 -18
  243. package/app/server/live/LiveClockComponent.ts +0 -215
  244. package/app/server/live/LiveFileUploadComponent.ts +0 -77
  245. package/app/server/routes/env-test.ts +0 -110
  246. package/core/client/hooks/index.ts +0 -7
  247. package/core/client/hooks/useHybridLiveComponent.ts +0 -685
  248. package/core/client/hooks/useTypedLiveComponent.ts +0 -133
  249. package/core/client/hooks/useWebSocket.ts +0 -361
  250. package/core/config/env.ts +0 -546
  251. package/core/config/loader.ts +0 -522
  252. package/core/config/runtime-config.ts +0 -327
  253. package/core/config/validator.ts +0 -540
  254. package/core/server/backend-entry.ts +0 -51
  255. package/core/server/standalone.ts +0 -106
  256. package/core/utils/regenerate-files.ts +0 -69
  257. package/fluxstack.config.ts +0 -354
@@ -0,0 +1,617 @@
1
+ # External Plugins
2
+
3
+ **Version:** 1.11.0 | **Updated:** 2025-02-08
4
+
5
+ ## Quick Facts
6
+
7
+ - Plugins extend FluxStack with custom functionality
8
+ - Located in `plugins/[plugin-name]/` directory
9
+ - Use lifecycle hooks for integration
10
+ - Support declarative configuration system
11
+ - Can add CLI commands, routes, and middleware
12
+ - Auto-discovered and loaded at startup
13
+
14
+ ## Plugin Structure
15
+
16
+ ```
17
+ plugins/my-plugin/
18
+ ├── index.ts # Main plugin file (required)
19
+ ├── package.json # Plugin metadata
20
+ ├── config/
21
+ │ └── index.ts # Plugin configuration
22
+ ├── server/
23
+ │ ├── index.ts # Server-side code
24
+ │ └── middleware.ts # Middleware
25
+ ├── client/
26
+ │ └── index.ts # Client-side code
27
+ └── cli/
28
+ └── commands.ts # CLI commands
29
+ ```
30
+
31
+ ## Basic Plugin Template
32
+
33
+ ```typescript
34
+ // plugins/my-plugin/index.ts
35
+ import type { FluxStack, PluginContext } from "@core/plugins/types"
36
+ import { Elysia } from "elysia"
37
+
38
+ export const myPlugin: FluxStack.Plugin = {
39
+ name: "my-plugin",
40
+ version: "1.0.0",
41
+ description: "My custom plugin",
42
+ author: "Your Name",
43
+ priority: 100,
44
+ category: "utility",
45
+ tags: ["custom", "utility"],
46
+ dependencies: [],
47
+
48
+ setup: async (context: PluginContext) => {
49
+ context.logger.info('My plugin initialized')
50
+
51
+ // Initialize plugin services
52
+ // Register middleware
53
+ // Setup database connections
54
+ },
55
+
56
+ onServerStart: async (context: PluginContext) => {
57
+ context.logger.info('Server started with my plugin')
58
+ },
59
+
60
+ onRequest: async (requestContext) => {
61
+ // Process incoming requests
62
+ },
63
+
64
+ onResponse: async (responseContext) => {
65
+ // Process outgoing responses
66
+ }
67
+ }
68
+
69
+ export default myPlugin
70
+ ```
71
+
72
+ ## Plugin Interface
73
+
74
+ ```typescript
75
+ interface Plugin {
76
+ // Metadata
77
+ name: string
78
+ version?: string
79
+ description?: string
80
+ author?: string
81
+ dependencies?: string[]
82
+ priority?: number | 'highest' | 'high' | 'normal' | 'low' | 'lowest'
83
+ category?: string
84
+ tags?: string[]
85
+
86
+ // Lifecycle hooks
87
+ setup?: (context: PluginContext) => void | Promise<void>
88
+ onConfigLoad?: (context: ConfigLoadContext) => void | Promise<void>
89
+ onBeforeServerStart?: (context: PluginContext) => void | Promise<void>
90
+ onServerStart?: (context: PluginContext) => void | Promise<void>
91
+ onAfterServerStart?: (context: PluginContext) => void | Promise<void>
92
+ onBeforeServerStop?: (context: PluginContext) => void | Promise<void>
93
+ onServerStop?: (context: PluginContext) => void | Promise<void>
94
+
95
+ // Request/Response hooks
96
+ onRequest?: (context: RequestContext) => void | Promise<void>
97
+ onBeforeRoute?: (context: RequestContext) => void | Promise<void>
98
+ onAfterRoute?: (context: RouteContext) => void | Promise<void>
99
+ onBeforeResponse?: (context: ResponseContext) => void | Promise<void>
100
+ onResponse?: (context: ResponseContext) => void | Promise<void>
101
+ onRequestValidation?: (context: ValidationContext) => void | Promise<void>
102
+ onResponseTransform?: (context: TransformContext) => void | Promise<void>
103
+
104
+ // Error handling
105
+ onError?: (context: ErrorContext) => void | Promise<void>
106
+
107
+ // Build hooks
108
+ onBeforeBuild?: (context: BuildContext) => void | Promise<void>
109
+ onBuild?: (context: BuildContext) => void | Promise<void>
110
+ onBuildComplete?: (context: BuildContext) => void | Promise<void>
111
+ onBuildError?: (context: BuildErrorContext) => void | Promise<void>
112
+
113
+ // CLI commands
114
+ commands?: CliCommand[]
115
+ }
116
+ ```
117
+
118
+ ## Lifecycle Hooks
119
+
120
+ ### setup
121
+
122
+ Called during plugin initialization, before server starts:
123
+
124
+ ```typescript
125
+ setup: async (context: PluginContext) => {
126
+ // Initialize services
127
+ const service = new MyService(context.config)
128
+
129
+ // Store in global for access in other hooks
130
+ ;(global as any).myService = service
131
+
132
+ // Register with plugin registry
133
+ context.logger.info('Plugin initialized')
134
+ }
135
+ ```
136
+
137
+ ### onServerStart
138
+
139
+ Called when server starts:
140
+
141
+ ```typescript
142
+ onServerStart: async (context: PluginContext) => {
143
+ context.logger.info('Server started')
144
+
145
+ // Start background tasks
146
+ // Connect to external services
147
+ // Initialize monitoring
148
+ }
149
+ ```
150
+
151
+ ### onRequest
152
+
153
+ Process incoming requests:
154
+
155
+ ```typescript
156
+ onRequest: async (requestContext) => {
157
+ // Log request
158
+ console.log(`${requestContext.method} ${requestContext.path}`)
159
+
160
+ // Add custom headers
161
+ requestContext.headers['x-custom'] = 'value'
162
+
163
+ // Authenticate user
164
+ const user = await authenticateRequest(requestContext)
165
+ requestContext.user = user
166
+ }
167
+ ```
168
+
169
+ ### onResponse
170
+
171
+ Process outgoing responses:
172
+
173
+ ```typescript
174
+ onResponse: async (responseContext) => {
175
+ // Log response
176
+ console.log(`${responseContext.statusCode} - ${responseContext.duration}ms`)
177
+
178
+ // Track metrics
179
+ if (responseContext.user) {
180
+ trackUserActivity(responseContext.user, responseContext.path)
181
+ }
182
+ }
183
+ ```
184
+
185
+ ### onError
186
+
187
+ Handle errors:
188
+
189
+ ```typescript
190
+ onError: async (errorContext) => {
191
+ // Log error
192
+ console.error('Request error:', errorContext.error)
193
+
194
+ // Send to error tracking service
195
+ await sendToSentry(errorContext.error)
196
+
197
+ // Mark as handled to prevent default error handler
198
+ errorContext.handled = true
199
+ }
200
+ ```
201
+
202
+ ## Plugin Configuration
203
+
204
+ Use declarative config system:
205
+
206
+ ```typescript
207
+ // plugins/my-plugin/config/index.ts
208
+ import { defineConfig, config } from '@core/utils/config-schema'
209
+
210
+ const myPluginConfigSchema = {
211
+ enabled: config.boolean('MY_PLUGIN_ENABLED', true),
212
+ apiKey: config.string('MY_PLUGIN_API_KEY', '', true), // required
213
+ timeout: config.number('MY_PLUGIN_TIMEOUT', 5000, false),
214
+ features: config.array('MY_PLUGIN_FEATURES', ['feature1', 'feature2'])
215
+ }
216
+
217
+ export const myPluginConfig = defineConfig(myPluginConfigSchema)
218
+ export type MyPluginConfig = typeof myPluginConfig
219
+ export default myPluginConfig
220
+ ```
221
+
222
+ Use in plugin:
223
+
224
+ ```typescript
225
+ // plugins/my-plugin/index.ts
226
+ import { myPluginConfig } from "./config"
227
+
228
+ export const myPlugin: FluxStack.Plugin = {
229
+ name: "my-plugin",
230
+
231
+ setup: async (context) => {
232
+ if (!myPluginConfig.enabled) {
233
+ context.logger.info('Plugin disabled')
234
+ return
235
+ }
236
+
237
+ const service = new MyService({
238
+ apiKey: myPluginConfig.apiKey,
239
+ timeout: myPluginConfig.timeout
240
+ })
241
+ }
242
+ }
243
+ ```
244
+
245
+ ## Adding Routes (Elysia Plugin)
246
+
247
+ Plugins can add routes using Elysia:
248
+
249
+ ```typescript
250
+ import { Elysia, t } from "elysia"
251
+
252
+ export const myPlugin: FluxStack.Plugin = {
253
+ name: "my-plugin",
254
+
255
+ // @ts-ignore - plugin property supported but not in official types
256
+ plugin: new Elysia({ prefix: "/api/my-plugin", tags: ['MyPlugin'] })
257
+ .get("/status", () => ({
258
+ status: "ok",
259
+ version: "1.0.0"
260
+ }), {
261
+ response: t.Object({
262
+ status: t.String(),
263
+ version: t.String()
264
+ }),
265
+ detail: {
266
+ summary: 'Plugin Status',
267
+ description: 'Returns plugin status information'
268
+ }
269
+ })
270
+
271
+ .post("/action", async ({ body }) => {
272
+ // Handle action
273
+ return { success: true }
274
+ }, {
275
+ body: t.Object({
276
+ data: t.String()
277
+ }),
278
+ response: t.Object({
279
+ success: t.Boolean()
280
+ })
281
+ })
282
+ }
283
+ ```
284
+
285
+ ## Adding CLI Commands
286
+
287
+ ```typescript
288
+ // plugins/my-plugin/cli/my-command.ts
289
+ import type { CliCommand } from "@core/plugins/types"
290
+
291
+ export const myCommand: CliCommand = {
292
+ name: "my:command",
293
+ description: "Does something useful",
294
+ usage: "flux my:command [options]",
295
+ examples: [
296
+ "flux my:command --option value"
297
+ ],
298
+ options: [
299
+ {
300
+ name: "option",
301
+ alias: "o",
302
+ description: "An option",
303
+ type: "string",
304
+ required: false
305
+ }
306
+ ],
307
+ handler: async (args, options, context) => {
308
+ context.logger.info('Running my command')
309
+
310
+ // Access config
311
+ const config = context.config
312
+
313
+ // Perform action
314
+ console.log('Option value:', options.option)
315
+ }
316
+ }
317
+ ```
318
+
319
+ Register in plugin:
320
+
321
+ ```typescript
322
+ import { myCommand } from "./cli/my-command"
323
+
324
+ export const myPlugin: FluxStack.Plugin = {
325
+ name: "my-plugin",
326
+ commands: [myCommand]
327
+ }
328
+ ```
329
+
330
+ ## Middleware Pattern
331
+
332
+ Create reusable middleware:
333
+
334
+ ```typescript
335
+ // plugins/my-plugin/server/middleware.ts
336
+ export class MyMiddleware {
337
+ constructor(private config: any) {}
338
+
339
+ async handle(requestContext: RequestContext) {
340
+ // Validate request
341
+ if (!this.validateRequest(requestContext)) {
342
+ throw new Error('Invalid request')
343
+ }
344
+
345
+ // Add data to context
346
+ requestContext.user = await this.getUser(requestContext)
347
+ }
348
+
349
+ private validateRequest(context: RequestContext): boolean {
350
+ // Validation logic
351
+ return true
352
+ }
353
+
354
+ private async getUser(context: RequestContext) {
355
+ // Get user from headers
356
+ return { id: 1, name: 'User' }
357
+ }
358
+ }
359
+ ```
360
+
361
+ Use in plugin:
362
+
363
+ ```typescript
364
+ import { MyMiddleware } from "./server/middleware"
365
+
366
+ export const myPlugin: FluxStack.Plugin = {
367
+ name: "my-plugin",
368
+
369
+ setup: async (context) => {
370
+ const middleware = new MyMiddleware(myPluginConfig)
371
+ ;(global as any).myMiddleware = middleware
372
+ },
373
+
374
+ onRequest: async (requestContext) => {
375
+ const middleware = (global as any).myMiddleware
376
+ await middleware.handle(requestContext)
377
+ }
378
+ }
379
+ ```
380
+
381
+ ## Package.json Metadata
382
+
383
+ ```json
384
+ {
385
+ "name": "@fluxstack/my-plugin",
386
+ "version": "1.0.0",
387
+ "description": "My FluxStack plugin",
388
+ "main": "index.ts",
389
+ "types": "index.ts",
390
+ "exports": {
391
+ ".": {
392
+ "import": "./index.ts",
393
+ "types": "./index.ts"
394
+ },
395
+ "./server": {
396
+ "import": "./server/index.ts",
397
+ "types": "./server/index.ts"
398
+ },
399
+ "./client": {
400
+ "import": "./client/index.ts",
401
+ "types": "./client/index.ts"
402
+ }
403
+ },
404
+ "keywords": [
405
+ "fluxstack",
406
+ "plugin"
407
+ ],
408
+ "author": "Your Name",
409
+ "license": "MIT",
410
+ "dependencies": {},
411
+ "fluxstack": {
412
+ "plugin": true,
413
+ "version": "^1.0.0",
414
+ "hooks": [
415
+ "setup",
416
+ "onServerStart",
417
+ "onRequest"
418
+ ],
419
+ "category": "utility",
420
+ "tags": ["custom"]
421
+ }
422
+ }
423
+ ```
424
+
425
+ ## Plugin Dependencies
426
+
427
+ Declare dependencies on other plugins:
428
+
429
+ ```typescript
430
+ export const myPlugin: FluxStack.Plugin = {
431
+ name: "my-plugin",
432
+ dependencies: ["crypto-auth", "database"],
433
+
434
+ setup: async (context) => {
435
+ // Dependencies are loaded first
436
+ // Access other plugin services
437
+ const authService = (global as any).cryptoAuthService
438
+ }
439
+ }
440
+ ```
441
+
442
+ ## Plugin Priority
443
+
444
+ Control load order with priority:
445
+
446
+ ```typescript
447
+ export const myPlugin: FluxStack.Plugin = {
448
+ name: "my-plugin",
449
+ priority: 100, // Higher = loads first
450
+ // or use named priorities:
451
+ // priority: 'highest' | 'high' | 'normal' | 'low' | 'lowest'
452
+ }
453
+ ```
454
+
455
+ Load order:
456
+ 1. Highest priority (or 1000+)
457
+ 2. High priority (or 500-999)
458
+ 3. Normal priority (or 100-499) - default
459
+ 4. Low priority (or 50-99)
460
+ 5. Lowest priority (or 0-49)
461
+
462
+ ## Security Considerations
463
+
464
+ ### Plugin Whitelist
465
+
466
+ Only whitelisted plugins are loaded:
467
+
468
+ ```typescript
469
+ // config/system/plugins.config.ts
470
+ export const pluginsConfig = defineConfig({
471
+ whitelist: config.array('PLUGINS_WHITELIST', [
472
+ 'crypto-auth',
473
+ 'my-plugin'
474
+ ])
475
+ })
476
+ ```
477
+
478
+ ### Validate Input
479
+
480
+ Always validate user input in plugin routes:
481
+
482
+ ```typescript
483
+ .post("/action", async ({ body, set }) => {
484
+ if (!body.data || typeof body.data !== 'string') {
485
+ set.status = 400
486
+ return { error: 'Invalid data' }
487
+ }
488
+
489
+ // Process validated data
490
+ }, {
491
+ body: t.Object({
492
+ data: t.String({ minLength: 1, maxLength: 1000 })
493
+ })
494
+ })
495
+ ```
496
+
497
+ ### Secure Configuration
498
+
499
+ Never expose sensitive config in responses:
500
+
501
+ ```typescript
502
+ // ❌ BAD
503
+ .get("/config", () => myPluginConfig)
504
+
505
+ // ✅ GOOD
506
+ .get("/config", () => ({
507
+ enabled: myPluginConfig.enabled,
508
+ features: myPluginConfig.features
509
+ // Don't expose apiKey or secrets
510
+ }))
511
+ ```
512
+
513
+ ## Testing Plugins
514
+
515
+ ```typescript
516
+ // plugins/my-plugin/__tests__/plugin.test.ts
517
+ import { describe, it, expect, beforeAll } from 'vitest'
518
+ import { myPlugin } from '../index'
519
+
520
+ describe('MyPlugin', () => {
521
+ it('should have correct metadata', () => {
522
+ expect(myPlugin.name).toBe('my-plugin')
523
+ expect(myPlugin.version).toBe('1.0.0')
524
+ })
525
+
526
+ it('should initialize correctly', async () => {
527
+ const mockContext = {
528
+ config: {},
529
+ logger: { info: vi.fn() },
530
+ app: {},
531
+ utils: {}
532
+ }
533
+
534
+ await myPlugin.setup?.(mockContext)
535
+
536
+ expect(mockContext.logger.info).toHaveBeenCalled()
537
+ })
538
+ })
539
+ ```
540
+
541
+ ## Example: Crypto Auth Plugin
542
+
543
+ Reference implementation in `plugins/crypto-auth/`:
544
+
545
+ ```typescript
546
+ export const cryptoAuthPlugin: FluxStack.Plugin = {
547
+ name: "crypto-auth",
548
+ version: "1.0.0",
549
+ description: "Ed25519 cryptographic authentication",
550
+ priority: 100,
551
+ category: "auth",
552
+ tags: ["authentication", "ed25519", "security"],
553
+ dependencies: [],
554
+
555
+ setup: async (context) => {
556
+ if (!cryptoAuthConfig.enabled) return
557
+
558
+ const authService = new CryptoAuthService({
559
+ maxTimeDrift: cryptoAuthConfig.maxTimeDrift,
560
+ adminKeys: cryptoAuthConfig.adminKeys,
561
+ logger: context.logger
562
+ })
563
+
564
+ ;(global as any).cryptoAuthService = authService
565
+ },
566
+
567
+ plugin: new Elysia({ prefix: "/api/auth" })
568
+ .get("/info", () => ({
569
+ name: "FluxStack Crypto Auth",
570
+ version: "1.0.0"
571
+ })),
572
+
573
+ onResponse: async (context) => {
574
+ if (!cryptoAuthConfig.enableMetrics) return
575
+
576
+ // Log authentication metrics
577
+ if (context.user) {
578
+ console.debug("Authenticated request", {
579
+ publicKey: context.user.publicKey,
580
+ path: context.path
581
+ })
582
+ }
583
+ }
584
+ }
585
+ ```
586
+
587
+ ## Plugin Discovery
588
+
589
+ Plugins are auto-discovered from:
590
+
591
+ 1. `plugins/` directory (project plugins)
592
+ 2. `node_modules/@fluxstack/*-plugin` (npm plugins)
593
+ 3. Whitelisted in `config/system/plugins.config.ts`
594
+
595
+ ## Critical Rules
596
+
597
+ **ALWAYS:**
598
+ - Export plugin as default export
599
+ - Use declarative config system
600
+ - Validate all user input
601
+ - Handle errors gracefully
602
+ - Document plugin hooks and dependencies
603
+ - Test plugin functionality
604
+
605
+ **NEVER:**
606
+ - Modify core framework files
607
+ - Expose sensitive configuration
608
+ - Block server startup in setup hook
609
+ - Ignore security best practices
610
+ - Forget to cleanup in onServerStop
611
+
612
+ ## Related
613
+
614
+ - [Plugin System](../core/plugin-system.md)
615
+ - [Plugin Hooks Reference](../reference/plugin-hooks.md)
616
+ - [Configuration System](../config/declarative-system.md)
617
+ - [CLI Commands](../reference/cli-commands.md)