@tpitre/story-ui 2.2.0 → 2.3.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 (188) hide show
  1. package/.env.sample +82 -11
  2. package/README.md +89 -0
  3. package/dist/cli/deploy.d.ts +17 -0
  4. package/dist/cli/deploy.d.ts.map +1 -0
  5. package/dist/cli/deploy.js +696 -0
  6. package/dist/cli/index.d.ts +3 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +26 -2
  9. package/dist/cli/setup.d.ts +11 -0
  10. package/dist/cli/setup.d.ts.map +1 -0
  11. package/dist/cli/setup.js +437 -110
  12. package/dist/mcp-server/index.d.ts +2 -0
  13. package/dist/mcp-server/index.d.ts.map +1 -0
  14. package/dist/mcp-server/index.js +120 -2
  15. package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
  16. package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
  17. package/dist/mcp-server/mcp-stdio-server.js +8 -1
  18. package/dist/mcp-server/routes/claude.d.ts +3 -0
  19. package/dist/mcp-server/routes/claude.d.ts.map +1 -0
  20. package/dist/mcp-server/routes/claude.js +60 -23
  21. package/dist/mcp-server/routes/components.d.ts +4 -0
  22. package/dist/mcp-server/routes/components.d.ts.map +1 -0
  23. package/dist/mcp-server/routes/frameworks.d.ts +38 -0
  24. package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
  25. package/dist/mcp-server/routes/frameworks.js +183 -0
  26. package/dist/mcp-server/routes/generateStory.d.ts +3 -0
  27. package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
  28. package/dist/mcp-server/routes/generateStory.js +160 -76
  29. package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
  30. package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
  31. package/dist/mcp-server/routes/generateStoryStream.js +947 -0
  32. package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
  33. package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
  34. package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
  35. package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
  36. package/dist/mcp-server/routes/mcpRemote.js +489 -0
  37. package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
  38. package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
  39. package/dist/mcp-server/routes/providers.d.ts +89 -0
  40. package/dist/mcp-server/routes/providers.d.ts.map +1 -0
  41. package/dist/mcp-server/routes/providers.js +369 -0
  42. package/dist/mcp-server/routes/storySync.d.ts +26 -0
  43. package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
  44. package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
  45. package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
  46. package/dist/mcp-server/routes/streamTypes.js +18 -0
  47. package/dist/mcp-server/sessionManager.d.ts +50 -0
  48. package/dist/mcp-server/sessionManager.d.ts.map +1 -0
  49. package/dist/story-generator/componentBlacklist.d.ts +21 -0
  50. package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
  51. package/dist/story-generator/componentDiscovery.d.ts +28 -0
  52. package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
  53. package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
  54. package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
  55. package/dist/story-generator/componentRegistryGenerator.js +205 -0
  56. package/dist/story-generator/configLoader.d.ts +33 -0
  57. package/dist/story-generator/configLoader.d.ts.map +1 -0
  58. package/dist/story-generator/considerationsLoader.d.ts +32 -0
  59. package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
  60. package/dist/story-generator/documentation-sources.d.ts +28 -0
  61. package/dist/story-generator/documentation-sources.d.ts.map +1 -0
  62. package/dist/story-generator/documentationLoader.d.ts +64 -0
  63. package/dist/story-generator/documentationLoader.d.ts.map +1 -0
  64. package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
  65. package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
  66. package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
  67. package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
  68. package/dist/story-generator/enhancedComponentDiscovery.js +111 -11
  69. package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
  70. package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
  71. package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
  72. package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
  73. package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
  74. package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
  75. package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
  76. package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
  77. package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
  78. package/dist/story-generator/framework-adapters/index.d.ts +97 -0
  79. package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
  80. package/dist/story-generator/framework-adapters/index.js +198 -0
  81. package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
  82. package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
  83. package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
  84. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
  85. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
  86. package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
  87. package/dist/story-generator/framework-adapters/types.d.ts +182 -0
  88. package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
  89. package/dist/story-generator/framework-adapters/types.js +8 -0
  90. package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
  91. package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
  92. package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
  93. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
  94. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
  95. package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
  96. package/dist/story-generator/generateStory.d.ts +7 -0
  97. package/dist/story-generator/generateStory.d.ts.map +1 -0
  98. package/dist/story-generator/gitignoreManager.d.ts +50 -0
  99. package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
  100. package/dist/story-generator/imageProcessor.d.ts +80 -0
  101. package/dist/story-generator/imageProcessor.d.ts.map +1 -0
  102. package/dist/story-generator/imageProcessor.js +391 -0
  103. package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
  104. package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
  105. package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
  106. package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
  107. package/dist/story-generator/llm-providers/base-provider.js +135 -0
  108. package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
  109. package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
  110. package/dist/story-generator/llm-providers/claude-provider.js +414 -0
  111. package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
  112. package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
  113. package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
  114. package/dist/story-generator/llm-providers/index.d.ts +63 -0
  115. package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
  116. package/dist/story-generator/llm-providers/index.js +169 -0
  117. package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
  118. package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
  119. package/dist/story-generator/llm-providers/openai-provider.js +458 -0
  120. package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
  121. package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
  122. package/dist/story-generator/llm-providers/settings-manager.js +173 -0
  123. package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
  124. package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
  125. package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
  126. package/dist/story-generator/llm-providers/types.d.ts +153 -0
  127. package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
  128. package/dist/story-generator/llm-providers/types.js +8 -0
  129. package/dist/story-generator/logger.d.ts +14 -0
  130. package/dist/story-generator/logger.d.ts.map +1 -0
  131. package/dist/story-generator/logger.js +96 -29
  132. package/dist/story-generator/postProcessStory.d.ts +6 -0
  133. package/dist/story-generator/postProcessStory.d.ts.map +1 -0
  134. package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
  135. package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
  136. package/dist/story-generator/promptGenerator.d.ts +48 -0
  137. package/dist/story-generator/promptGenerator.d.ts.map +1 -0
  138. package/dist/story-generator/promptGenerator.js +186 -1
  139. package/dist/story-generator/storyHistory.d.ts +44 -0
  140. package/dist/story-generator/storyHistory.d.ts.map +1 -0
  141. package/dist/story-generator/storySync.d.ts +68 -0
  142. package/dist/story-generator/storySync.d.ts.map +1 -0
  143. package/dist/story-generator/storyTracker.d.ts +48 -0
  144. package/dist/story-generator/storyTracker.d.ts.map +1 -0
  145. package/dist/story-generator/storyValidator.d.ts +6 -0
  146. package/dist/story-generator/storyValidator.d.ts.map +1 -0
  147. package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
  148. package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
  149. package/dist/story-generator/universalDesignSystemAdapter.js +138 -1
  150. package/dist/story-generator/urlRedirectService.d.ts +21 -0
  151. package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
  152. package/dist/story-generator/validateStory.d.ts +19 -0
  153. package/dist/story-generator/validateStory.d.ts.map +1 -0
  154. package/dist/story-generator/validateStory.js +6 -2
  155. package/dist/story-generator/visionPrompts.d.ts +88 -0
  156. package/dist/story-generator/visionPrompts.d.ts.map +1 -0
  157. package/dist/story-generator/visionPrompts.js +462 -0
  158. package/dist/story-ui.config.d.ts +78 -0
  159. package/dist/story-ui.config.d.ts.map +1 -0
  160. package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
  161. package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
  162. package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
  163. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
  164. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
  165. package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
  166. package/dist/templates/StoryUI/index.d.ts +3 -0
  167. package/dist/templates/StoryUI/index.d.ts.map +1 -0
  168. package/dist/templates/StoryUI/index.js +2 -0
  169. package/package.json +17 -3
  170. package/templates/StoryUI/StoryUIPanel.tsx +1960 -384
  171. package/templates/StoryUI/index.tsx +1 -1
  172. package/templates/StoryUI/manager.tsx +264 -0
  173. package/templates/production-app/.env.example +11 -0
  174. package/templates/production-app/index.html +66 -0
  175. package/templates/production-app/package.json +30 -0
  176. package/templates/production-app/public/favicon.svg +5 -0
  177. package/templates/production-app/src/App.tsx +1157 -0
  178. package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
  179. package/templates/production-app/src/componentRegistry.ts +315 -0
  180. package/templates/production-app/src/considerations.ts +16 -0
  181. package/templates/production-app/src/index.css +284 -0
  182. package/templates/production-app/src/main.tsx +25 -0
  183. package/templates/production-app/tsconfig.json +32 -0
  184. package/templates/production-app/tsconfig.node.json +11 -0
  185. package/templates/production-app/vite.config.ts +83 -0
  186. package/templates/react-import-rule.json +2 -2
  187. package/dist/index.js +0 -12
  188. package/dist/story-ui.config.loader.js +0 -205
@@ -0,0 +1,369 @@
1
+ /**
2
+ * LLM Provider Management Routes
3
+ *
4
+ * API endpoints for managing LLM providers, API keys, and model selection.
5
+ */
6
+ import { getProviderRegistry, } from '../../story-generator/llm-providers/index.js';
7
+ import { getAvailableProviders, getProviderInfo, configureProvider, validateProviderKey, } from '../../story-generator/llm-providers/story-llm-service.js';
8
+ import { getSettingsForUI, applyUserSettings, loadSettingsConfig, } from '../../story-generator/llm-providers/settings-manager.js';
9
+ import { logger } from '../../story-generator/logger.js';
10
+ /**
11
+ * GET /mcp/providers
12
+ * Returns list of available providers and their configuration status
13
+ */
14
+ export function getProviders(req, res) {
15
+ try {
16
+ const providers = getAvailableProviders();
17
+ const currentInfo = getProviderInfo();
18
+ res.json({
19
+ providers,
20
+ current: {
21
+ provider: currentInfo.currentProvider,
22
+ model: currentInfo.currentModel,
23
+ supportsVision: currentInfo.supportsVision,
24
+ supportsStreaming: currentInfo.supportsStreaming,
25
+ },
26
+ });
27
+ }
28
+ catch (error) {
29
+ logger.error('Error fetching providers', { error });
30
+ res.status(500).json({
31
+ error: 'Failed to fetch providers',
32
+ message: error instanceof Error ? error.message : 'Unknown error',
33
+ });
34
+ }
35
+ }
36
+ /**
37
+ * GET /mcp/providers/models
38
+ * Returns all available models across all providers
39
+ */
40
+ export function getModels(req, res) {
41
+ try {
42
+ const registry = getProviderRegistry();
43
+ const models = registry.getAvailableModels();
44
+ // Group models by provider for easier display
45
+ const groupedModels = {};
46
+ for (const model of models) {
47
+ const provider = model.provider;
48
+ if (!groupedModels[provider]) {
49
+ groupedModels[provider] = [];
50
+ }
51
+ groupedModels[provider].push(model);
52
+ }
53
+ res.json({
54
+ models,
55
+ grouped: groupedModels,
56
+ });
57
+ }
58
+ catch (error) {
59
+ logger.error('Error fetching models', { error });
60
+ res.status(500).json({
61
+ error: 'Failed to fetch models',
62
+ message: error instanceof Error ? error.message : 'Unknown error',
63
+ });
64
+ }
65
+ }
66
+ /**
67
+ * POST /mcp/providers/configure
68
+ * Configure a provider with API key and optional model
69
+ *
70
+ * Body: {
71
+ * provider: 'claude' | 'openai' | 'gemini',
72
+ * apiKey: string,
73
+ * model?: string,
74
+ * setAsDefault?: boolean
75
+ * }
76
+ */
77
+ export async function configureProviderRoute(req, res) {
78
+ try {
79
+ const { provider, apiKey, model, setAsDefault } = req.body;
80
+ if (!provider) {
81
+ return res.status(400).json({ error: 'Provider type is required' });
82
+ }
83
+ if (!apiKey) {
84
+ return res.status(400).json({ error: 'API key is required' });
85
+ }
86
+ const validProviders = ['claude', 'openai', 'gemini', 'ollama', 'custom'];
87
+ if (!validProviders.includes(provider)) {
88
+ return res.status(400).json({
89
+ error: 'Invalid provider type',
90
+ validProviders,
91
+ });
92
+ }
93
+ // Configure the provider
94
+ const success = configureProvider(provider, apiKey, model);
95
+ if (!success) {
96
+ return res.status(500).json({ error: 'Failed to configure provider' });
97
+ }
98
+ // Set as default if requested
99
+ if (setAsDefault) {
100
+ const registry = getProviderRegistry();
101
+ registry.setDefault(provider);
102
+ }
103
+ const currentInfo = getProviderInfo();
104
+ res.json({
105
+ success: true,
106
+ message: `${provider} provider configured successfully`,
107
+ current: {
108
+ provider: currentInfo.currentProvider,
109
+ model: currentInfo.currentModel,
110
+ },
111
+ });
112
+ }
113
+ catch (error) {
114
+ logger.error('Error configuring provider', { error });
115
+ res.status(500).json({
116
+ error: 'Failed to configure provider',
117
+ message: error instanceof Error ? error.message : 'Unknown error',
118
+ });
119
+ }
120
+ }
121
+ /**
122
+ * POST /mcp/providers/validate
123
+ * Validate an API key for a provider without saving it
124
+ *
125
+ * Body: {
126
+ * provider: 'claude' | 'openai' | 'gemini',
127
+ * apiKey: string
128
+ * }
129
+ */
130
+ export async function validateApiKey(req, res) {
131
+ try {
132
+ const { provider, apiKey } = req.body;
133
+ if (!provider) {
134
+ return res.status(400).json({ error: 'Provider type is required' });
135
+ }
136
+ if (!apiKey) {
137
+ return res.status(400).json({ error: 'API key is required' });
138
+ }
139
+ const validProviders = ['claude', 'openai', 'gemini'];
140
+ if (!validProviders.includes(provider)) {
141
+ return res.status(400).json({
142
+ error: 'Invalid provider type',
143
+ validProviders,
144
+ });
145
+ }
146
+ const result = await validateProviderKey(provider, apiKey);
147
+ res.json({
148
+ valid: result.valid,
149
+ error: result.error,
150
+ provider,
151
+ });
152
+ }
153
+ catch (error) {
154
+ logger.error('Error validating API key', { error });
155
+ res.status(500).json({
156
+ error: 'Failed to validate API key',
157
+ message: error instanceof Error ? error.message : 'Unknown error',
158
+ });
159
+ }
160
+ }
161
+ /**
162
+ * POST /mcp/providers/default
163
+ * Set the default provider
164
+ *
165
+ * Body: {
166
+ * provider: 'claude' | 'openai' | 'gemini'
167
+ * }
168
+ */
169
+ export function setDefaultProvider(req, res) {
170
+ try {
171
+ const { provider } = req.body;
172
+ if (!provider) {
173
+ return res.status(400).json({ error: 'Provider type is required' });
174
+ }
175
+ const registry = getProviderRegistry();
176
+ const providerInstance = registry.get(provider);
177
+ if (!providerInstance) {
178
+ return res.status(400).json({ error: `Provider '${provider}' not found` });
179
+ }
180
+ if (!providerInstance.isConfigured()) {
181
+ return res.status(400).json({
182
+ error: `Provider '${provider}' is not configured. Please set an API key first.`,
183
+ });
184
+ }
185
+ registry.setDefault(provider);
186
+ const currentInfo = getProviderInfo();
187
+ res.json({
188
+ success: true,
189
+ message: `Default provider set to ${provider}`,
190
+ current: {
191
+ provider: currentInfo.currentProvider,
192
+ model: currentInfo.currentModel,
193
+ },
194
+ });
195
+ }
196
+ catch (error) {
197
+ logger.error('Error setting default provider', { error });
198
+ res.status(500).json({
199
+ error: 'Failed to set default provider',
200
+ message: error instanceof Error ? error.message : 'Unknown error',
201
+ });
202
+ }
203
+ }
204
+ /**
205
+ * POST /mcp/providers/model
206
+ * Set the model for a provider
207
+ *
208
+ * Body: {
209
+ * provider?: 'claude' | 'openai' | 'gemini', // defaults to current provider
210
+ * model: string
211
+ * }
212
+ */
213
+ export function setModel(req, res) {
214
+ try {
215
+ const { provider, model } = req.body;
216
+ if (!model) {
217
+ return res.status(400).json({ error: 'Model is required' });
218
+ }
219
+ const registry = getProviderRegistry();
220
+ // If provider specified, use that; otherwise use default
221
+ const targetProvider = provider
222
+ ? registry.get(provider)
223
+ : registry.getDefault();
224
+ if (!targetProvider) {
225
+ return res.status(400).json({
226
+ error: provider ? `Provider '${provider}' not found` : 'No default provider configured',
227
+ });
228
+ }
229
+ // Validate model is supported
230
+ const supportedModels = targetProvider.supportedModels;
231
+ const modelInfo = supportedModels.find(m => m.id === model);
232
+ if (!modelInfo) {
233
+ return res.status(400).json({
234
+ error: `Model '${model}' is not supported by ${targetProvider.name}`,
235
+ supportedModels: supportedModels.map(m => m.id),
236
+ });
237
+ }
238
+ // Update the provider's model
239
+ const currentConfig = targetProvider.getConfig();
240
+ targetProvider.configure({
241
+ ...currentConfig,
242
+ model,
243
+ });
244
+ const currentInfo = getProviderInfo();
245
+ res.json({
246
+ success: true,
247
+ message: `Model set to ${model}`,
248
+ current: {
249
+ provider: currentInfo.currentProvider,
250
+ model: currentInfo.currentModel,
251
+ },
252
+ });
253
+ }
254
+ catch (error) {
255
+ logger.error('Error setting model', { error });
256
+ res.status(500).json({
257
+ error: 'Failed to set model',
258
+ message: error instanceof Error ? error.message : 'Unknown error',
259
+ });
260
+ }
261
+ }
262
+ /**
263
+ * GET /mcp/providers/settings
264
+ * Get UI settings configuration with available providers/models
265
+ *
266
+ * This endpoint is designed for non-technical users to select
267
+ * from pre-approved providers and models configured by DevOps.
268
+ *
269
+ * Query params:
270
+ * provider?: current selected provider
271
+ * model?: current selected model
272
+ */
273
+ export function getUISettings(req, res) {
274
+ try {
275
+ const currentProvider = req.query.provider;
276
+ const currentModel = req.query.model;
277
+ const settings = getSettingsForUI(currentProvider, currentModel);
278
+ res.json({
279
+ success: true,
280
+ ...settings,
281
+ });
282
+ }
283
+ catch (error) {
284
+ logger.error('Error fetching UI settings', { error });
285
+ res.status(500).json({
286
+ error: 'Failed to fetch settings',
287
+ message: error instanceof Error ? error.message : 'Unknown error',
288
+ });
289
+ }
290
+ }
291
+ /**
292
+ * POST /mcp/providers/settings
293
+ * Apply user's provider/model selection
294
+ *
295
+ * Body: {
296
+ * provider?: 'claude' | 'openai' | 'gemini',
297
+ * model?: string
298
+ * }
299
+ *
300
+ * Returns effective settings (may fall back to defaults if invalid)
301
+ */
302
+ export function applyUISettings(req, res) {
303
+ try {
304
+ const { provider, model } = req.body;
305
+ const result = applyUserSettings({
306
+ selectedProvider: provider,
307
+ selectedModel: model,
308
+ });
309
+ // If settings were applied, also update the actual provider config
310
+ if (result.applied) {
311
+ const registry = getProviderRegistry();
312
+ // Set the default provider
313
+ registry.setDefault(result.provider);
314
+ // Update model for the provider
315
+ const providerInstance = registry.get(result.provider);
316
+ if (providerInstance) {
317
+ const currentConfig = providerInstance.getConfig();
318
+ providerInstance.configure({
319
+ ...currentConfig,
320
+ model: result.model,
321
+ });
322
+ }
323
+ }
324
+ res.json({
325
+ success: true,
326
+ applied: result.applied,
327
+ provider: result.provider,
328
+ model: result.model,
329
+ fallbackReason: result.fallbackReason,
330
+ });
331
+ }
332
+ catch (error) {
333
+ logger.error('Error applying UI settings', { error });
334
+ res.status(500).json({
335
+ error: 'Failed to apply settings',
336
+ message: error instanceof Error ? error.message : 'Unknown error',
337
+ });
338
+ }
339
+ }
340
+ /**
341
+ * GET /mcp/providers/config
342
+ * Get current environment configuration (for admin/debugging)
343
+ *
344
+ * This reveals which restrictions are in place.
345
+ */
346
+ export function getSettingsConfig(req, res) {
347
+ try {
348
+ const config = loadSettingsConfig();
349
+ res.json({
350
+ success: true,
351
+ config: {
352
+ defaultProvider: config.defaultProvider,
353
+ defaultModel: config.defaultModel,
354
+ allowedProviders: config.allowedProviders,
355
+ allowedModels: config.allowedModels.length > 0
356
+ ? config.allowedModels
357
+ : 'all', // Show 'all' if no restrictions
358
+ singleProviderMode: config.singleProviderMode,
359
+ },
360
+ });
361
+ }
362
+ catch (error) {
363
+ logger.error('Error fetching settings config', { error });
364
+ res.status(500).json({
365
+ error: 'Failed to fetch config',
366
+ message: error instanceof Error ? error.message : 'Unknown error',
367
+ });
368
+ }
369
+ }
@@ -0,0 +1,26 @@
1
+ import { Request, Response } from 'express';
2
+ /**
3
+ * Get all synchronized stories (from both file system and memory)
4
+ */
5
+ export declare function getSyncedStories(req: Request, res: Response): Promise<void>;
6
+ /**
7
+ * Delete a story from both file system and memory
8
+ */
9
+ export declare function deleteSyncedStory(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
10
+ /**
11
+ * Clear all stories from both file system and memory
12
+ */
13
+ export declare function clearAllSyncedStories(req: Request, res: Response): Promise<void>;
14
+ /**
15
+ * Sync chat history with actual stories
16
+ */
17
+ export declare function syncChatHistory(req: Request, res: Response): Promise<void>;
18
+ /**
19
+ * Validate that a chat session corresponds to an actual story
20
+ */
21
+ export declare function validateChatSession(req: Request, res: Response): Promise<void>;
22
+ /**
23
+ * Get a specific synced story by ID
24
+ */
25
+ export declare function getSyncedStoryById(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
26
+ //# sourceMappingURL=storySync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storySync.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/storySync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI5C;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,iBAyBjE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAwBlE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,iBAgBtE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,iBAgBhE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,iBAkBpE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAwBnE"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Stream Types for Two-Way Chat Communication
3
+ *
4
+ * These types define the event structure for Server-Sent Events (SSE)
5
+ * that enable real-time feedback during story generation.
6
+ */
7
+ export type StreamEventType = 'intent' | 'progress' | 'validation' | 'retry' | 'completion' | 'error';
8
+ export interface IntentPreview {
9
+ requestType: 'new' | 'modification';
10
+ framework: string;
11
+ detectedDesignSystem: string | null;
12
+ strategy: string;
13
+ estimatedComponents: string[];
14
+ promptAnalysis: {
15
+ hasVisionInput: boolean;
16
+ hasConversationContext: boolean;
17
+ hasPreviousCode: boolean;
18
+ };
19
+ }
20
+ export interface ProgressUpdate {
21
+ step: number;
22
+ totalSteps: number;
23
+ phase: 'config_loaded' | 'components_discovered' | 'prompt_built' | 'llm_thinking' | 'code_extracted' | 'validating' | 'post_processing' | 'saving';
24
+ message: string;
25
+ details?: Record<string, unknown>;
26
+ }
27
+ export interface ValidationFeedback {
28
+ isValid: boolean;
29
+ errors: string[];
30
+ warnings: string[];
31
+ autoFixApplied: boolean;
32
+ fixDetails?: string[];
33
+ }
34
+ export interface RetryInfo {
35
+ attempt: number;
36
+ maxAttempts: number;
37
+ reason: string;
38
+ errors: string[];
39
+ }
40
+ export interface CompletionFeedback {
41
+ success: boolean;
42
+ title: string;
43
+ fileName: string;
44
+ storyId: string;
45
+ summary: {
46
+ action: 'created' | 'updated' | 'failed';
47
+ description: string;
48
+ };
49
+ componentsUsed: {
50
+ name: string;
51
+ reason?: string;
52
+ }[];
53
+ layoutChoices: {
54
+ pattern: string;
55
+ reason: string;
56
+ }[];
57
+ styleChoices: {
58
+ property: string;
59
+ value: string;
60
+ reason?: string;
61
+ }[];
62
+ suggestions?: string[];
63
+ validation: ValidationFeedback;
64
+ code: string;
65
+ metrics: {
66
+ totalTimeMs: number;
67
+ llmCallsCount: number;
68
+ tokensUsed?: number;
69
+ };
70
+ }
71
+ export interface ErrorFeedback {
72
+ code: string;
73
+ message: string;
74
+ details?: string;
75
+ recoverable: boolean;
76
+ suggestion?: string;
77
+ }
78
+ export interface StreamEvent {
79
+ type: StreamEventType;
80
+ timestamp: number;
81
+ data: IntentPreview | ProgressUpdate | ValidationFeedback | RetryInfo | CompletionFeedback | ErrorFeedback;
82
+ }
83
+ export interface StreamGenerateRequest {
84
+ prompt: string;
85
+ fileName?: string;
86
+ conversation?: Array<{
87
+ role: 'user' | 'assistant';
88
+ content: string;
89
+ }>;
90
+ isUpdate?: boolean;
91
+ originalTitle?: string;
92
+ storyId?: string;
93
+ framework?: string;
94
+ autoDetectFramework?: boolean;
95
+ images?: Array<{
96
+ type: 'base64' | 'url' | 'file';
97
+ data?: string;
98
+ url?: string;
99
+ path?: string;
100
+ mediaType?: string;
101
+ }>;
102
+ visionMode?: string;
103
+ designSystem?: string;
104
+ provider?: string;
105
+ model?: string;
106
+ considerations?: string;
107
+ }
108
+ export declare function formatSSE(event: StreamEvent): string;
109
+ export declare function createStreamEvent<T extends StreamEvent['data']>(type: StreamEventType, data: T): StreamEvent;
110
+ //# sourceMappingURL=streamTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamTypes.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/streamTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Stream Types for Two-Way Chat Communication
3
+ *
4
+ * These types define the event structure for Server-Sent Events (SSE)
5
+ * that enable real-time feedback during story generation.
6
+ */
7
+ // Helper to create SSE-formatted message
8
+ export function formatSSE(event) {
9
+ return `event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
10
+ }
11
+ // Helper to create event objects
12
+ export function createStreamEvent(type, data) {
13
+ return {
14
+ type,
15
+ timestamp: Date.now(),
16
+ data
17
+ };
18
+ }
@@ -0,0 +1,50 @@
1
+ interface SessionStory {
2
+ id: string;
3
+ fileName: string;
4
+ title: string;
5
+ prompt: string;
6
+ timestamp: Date;
7
+ keywords: string[];
8
+ }
9
+ export declare class SessionManager {
10
+ private static instance;
11
+ private sessions;
12
+ private currentStoryId;
13
+ private constructor();
14
+ static getInstance(): SessionManager;
15
+ /**
16
+ * Track a newly generated story in the current session
17
+ */
18
+ trackStory(sessionId: string, story: {
19
+ id: string;
20
+ fileName: string;
21
+ title: string;
22
+ prompt: string;
23
+ }): void;
24
+ /**
25
+ * Get the current story being discussed
26
+ */
27
+ getCurrentStory(sessionId: string): SessionStory | null;
28
+ /**
29
+ * Find a story by context (keywords in the user's message)
30
+ */
31
+ findStoryByContext(sessionId: string, userMessage: string): SessionStory | null;
32
+ /**
33
+ * Get all stories in the current session
34
+ */
35
+ getSessionStories(sessionId: string): SessionStory[];
36
+ /**
37
+ * Set the current story being discussed
38
+ */
39
+ setCurrentStory(sessionId: string, storyId: string): void;
40
+ /**
41
+ * Clear session data (for cleanup)
42
+ */
43
+ clearSession(sessionId: string): void;
44
+ /**
45
+ * Extract meaningful keywords from text
46
+ */
47
+ private extractKeywords;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=sessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.d.ts","sourceRoot":"","sources":["../../mcp-server/sessionManager.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,cAAc,CAAuB;IAE7C,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,cAAc;IAOpC;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QACnC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB;IAmBD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IASvD;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAiC/E;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE;IAIpD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAQlD;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM;IAO9B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkCxB"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Blacklist of component names that AI commonly mistakes for real components
3
+ * These are often story export names or made-up components that don't exist
4
+ */
5
+ export declare const BLACKLISTED_COMPONENTS: (string | RegExp)[];
6
+ export declare function isBlacklistedComponent(componentName: string, validComponents: Set<string>, importPath?: string): boolean;
7
+ /**
8
+ * Common icon name mistakes - maps incorrect names to correct ones
9
+ */
10
+ export declare const ICON_CORRECTIONS: Record<string, string>;
11
+ export declare function isBlacklistedIcon(iconName: string, allowedIcons: Set<string>): boolean;
12
+ export declare function validateImports(imports: string[], allowedComponents: Set<string>): {
13
+ valid: string[];
14
+ invalid: string[];
15
+ suggestions: Map<string, string[]>;
16
+ };
17
+ /**
18
+ * Get helpful error message for blacklisted component
19
+ */
20
+ export declare function getBlacklistErrorMessage(componentName: string, importPath?: string): string;
21
+ //# sourceMappingURL=componentBlacklist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentBlacklist.d.ts","sourceRoot":"","sources":["../../story-generator/componentBlacklist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,sBAAsB,qBA2BlC,CAAC;AAOF,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAqCxH;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAwBnD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAuBtF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG;IAClF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACpC,CAsBA;AAkCD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB3F"}
@@ -0,0 +1,28 @@
1
+ import { StoryUIConfig } from '../story-ui.config.js';
2
+ export interface DiscoveredComponent {
3
+ name: string;
4
+ filePath: string;
5
+ props: string[];
6
+ description: string;
7
+ category: 'layout' | 'content' | 'form' | 'navigation' | 'feedback' | 'other';
8
+ slots?: string[];
9
+ examples?: string[];
10
+ __componentPath?: string;
11
+ }
12
+ /**
13
+ * Discovers components from a directory structure
14
+ */
15
+ export declare function discoverComponentsFromDirectory(componentsPath: string, componentPrefix?: string): DiscoveredComponent[];
16
+ /**
17
+ * Discovers components from custom-elements.json (Web Components)
18
+ */
19
+ export declare function discoverComponentsFromCustomElements(customElementsPath: string, componentPrefix?: string): DiscoveredComponent[];
20
+ /**
21
+ * Discovers components from package.json exports or index files
22
+ */
23
+ export declare function discoverComponentsFromPackage(packagePath: string, componentPrefix?: string): DiscoveredComponent[];
24
+ /**
25
+ * Main discovery function that tries multiple methods
26
+ */
27
+ export declare function discoverComponents(config: StoryUIConfig): DiscoveredComponent[];
28
+ //# sourceMappingURL=componentDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentDiscovery.d.ts","sourceRoot":"","sources":["../../story-generator/componentDiscovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,cAAc,EAAE,MAAM,EACtB,eAAe,GAAE,MAAW,GAC3B,mBAAmB,EAAE,CA2DvB;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,kBAAkB,EAAE,MAAM,EAC1B,eAAe,GAAE,MAAW,GAC3B,mBAAmB,EAAE,CAwCvB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,MAAM,EACnB,eAAe,GAAE,MAAW,GAC3B,mBAAmB,EAAE,CA8DvB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,mBAAmB,EAAE,CAmB/E"}