@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
@@ -12,23 +12,76 @@ import cors from 'cors';
12
12
  import { getComponents, getProps } from './routes/components.js';
13
13
  import { claudeProxy } from './routes/claude.js';
14
14
  import { generateStoryFromPrompt } from './routes/generateStory.js';
15
+ import { generateStoryFromPromptStream } from './routes/generateStoryStream.js';
15
16
  import { clearAllStories, getMemoryStats } from './routes/memoryStories.js';
16
17
  import { getAllStories, getStoryById, getStoryContent, deleteStory } from './routes/hybridStories.js';
17
18
  import { getSyncedStories, deleteSyncedStory, clearAllSyncedStories, syncChatHistory, validateChatSession, getSyncedStoryById } from './routes/storySync.js';
18
19
  import { setupProductionGitignore } from '../story-generator/productionGitignoreManager.js';
19
20
  import { getInMemoryStoryService } from '../story-generator/inMemoryStoryService.js';
20
21
  import { loadUserConfig } from '../story-generator/configLoader.js';
22
+ import { loadConsiderations, considerationsToPrompt } from '../story-generator/considerationsLoader.js';
23
+ import { DocumentationLoader } from '../story-generator/documentationLoader.js';
21
24
  import fs from 'fs';
22
25
  import { UrlRedirectService } from '../story-generator/urlRedirectService.js';
26
+ import { getProviders, getModels, configureProviderRoute, validateApiKey, setDefaultProvider, setModel, getUISettings, applyUISettings, getSettingsConfig } from './routes/providers.js';
27
+ import { listFrameworks, detectCurrentFramework, getFrameworkDetails, validateStoryForFramework, postProcessStoryForFramework, } from './routes/frameworks.js';
28
+ import mcpRemoteRouter from './routes/mcpRemote.js';
23
29
  const app = express();
24
- app.use(cors());
25
- app.use(express.json());
30
+ // CORS configuration
31
+ // - Allow all origins for /story-ui/* routes (public API for production Storybooks)
32
+ // - Restrict to localhost + configured origins for other routes
33
+ const corsOptions = {
34
+ origin: (origin, callback) => {
35
+ // Allow requests with no origin (like mobile apps or curl)
36
+ if (!origin)
37
+ return callback(null, true);
38
+ // Allow localhost on any port (development)
39
+ const localhostPattern = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/;
40
+ if (localhostPattern.test(origin)) {
41
+ return callback(null, true);
42
+ }
43
+ // Allow Cloudflare Pages domains (*.pages.dev)
44
+ const cloudflarePattern = /^https:\/\/[a-z0-9-]+\.pages\.dev$/;
45
+ if (cloudflarePattern.test(origin)) {
46
+ return callback(null, true);
47
+ }
48
+ // Allow custom origins from environment
49
+ const allowedOrigins = process.env.STORY_UI_ALLOWED_ORIGINS?.split(',') || [];
50
+ if (allowedOrigins.includes(origin)) {
51
+ return callback(null, true);
52
+ }
53
+ // For production, allow any origin to access /story-ui/* endpoints
54
+ // These are public read-only endpoints for accessing generated stories
55
+ callback(null, true);
56
+ },
57
+ credentials: true,
58
+ };
59
+ app.use(cors(corsOptions));
60
+ app.use(express.json({ limit: '10mb' })); // Increased limit for file uploads
26
61
  // Component discovery routes
27
62
  app.get('/mcp/components', getComponents);
28
63
  app.get('/mcp/props', getProps);
29
64
  // AI generation routes
30
65
  app.post('/mcp/claude', claudeProxy);
31
66
  app.post('/mcp/generate-story', generateStoryFromPrompt);
67
+ app.post('/mcp/generate-story-stream', generateStoryFromPromptStream);
68
+ // LLM Provider management routes
69
+ app.get('/mcp/providers', getProviders);
70
+ app.get('/mcp/providers/models', getModels);
71
+ app.post('/mcp/providers/configure', configureProviderRoute);
72
+ app.post('/mcp/providers/validate', validateApiKey);
73
+ app.post('/mcp/providers/default', setDefaultProvider);
74
+ app.post('/mcp/providers/model', setModel);
75
+ // UI Settings routes (hybrid model selection for non-technical users)
76
+ app.get('/mcp/providers/settings', getUISettings);
77
+ app.post('/mcp/providers/settings', applyUISettings);
78
+ app.get('/mcp/providers/config', getSettingsConfig);
79
+ // Framework detection and adapter routes
80
+ app.get('/mcp/frameworks', listFrameworks);
81
+ app.get('/mcp/frameworks/detect', detectCurrentFramework);
82
+ app.get('/mcp/frameworks/:type', getFrameworkDetails);
83
+ app.post('/mcp/frameworks/validate', validateStoryForFramework);
84
+ app.post('/mcp/frameworks/post-process', postProcessStoryForFramework);
32
85
  // Hybrid story management routes (works in both dev and production)
33
86
  app.get('/mcp/stories', getAllStories);
34
87
  app.get('/mcp/stories/:id', getStoryById);
@@ -50,10 +103,71 @@ app.get('/story-ui/stories/:id/content', getStoryContent);
50
103
  app.delete('/story-ui/stories/:id', deleteStory);
51
104
  app.delete('/story-ui/stories', clearAllStories);
52
105
  app.post('/story-ui/generate', generateStoryFromPrompt);
106
+ app.post('/story-ui/generate-stream', generateStoryFromPromptStream);
53
107
  app.post('/story-ui/claude', claudeProxy);
54
108
  app.get('/story-ui/components', getComponents);
55
109
  app.get('/story-ui/props', getProps);
56
110
  app.get('/story-ui/memory-stats', getMemoryStats);
111
+ // Design system considerations endpoint - serves considerations for environment parity
112
+ app.get('/story-ui/considerations', async (req, res) => {
113
+ try {
114
+ const projectRoot = process.cwd();
115
+ // First try directory-based documentation (story-ui-docs/)
116
+ const docLoader = new DocumentationLoader(projectRoot);
117
+ if (docLoader.hasDocumentation()) {
118
+ const docs = await docLoader.loadDocumentation();
119
+ // Use the formatForPrompt method to properly format all documentation
120
+ const considerationsText = docLoader.formatForPrompt(docs);
121
+ return res.json({
122
+ hasConsiderations: considerationsText.length > 0,
123
+ source: 'story-ui-docs',
124
+ considerations: considerationsText
125
+ });
126
+ }
127
+ // Fall back to legacy single-file considerations
128
+ const considerations = loadConsiderations(config.considerationsPath);
129
+ if (considerations) {
130
+ const considerationsText = considerationsToPrompt(considerations);
131
+ return res.json({
132
+ hasConsiderations: true,
133
+ source: 'story-ui-considerations',
134
+ considerations: considerationsText
135
+ });
136
+ }
137
+ // No considerations found
138
+ return res.json({
139
+ hasConsiderations: false,
140
+ source: null,
141
+ considerations: ''
142
+ });
143
+ }
144
+ catch (error) {
145
+ console.error('Error loading considerations:', error);
146
+ return res.json({
147
+ hasConsiderations: false,
148
+ source: null,
149
+ considerations: '',
150
+ error: error instanceof Error ? error.message : 'Unknown error'
151
+ });
152
+ }
153
+ });
154
+ // Provider management proxy routes
155
+ app.get('/story-ui/providers', getProviders);
156
+ app.get('/story-ui/providers/models', getModels);
157
+ app.post('/story-ui/providers/configure', configureProviderRoute);
158
+ app.post('/story-ui/providers/validate', validateApiKey);
159
+ app.post('/story-ui/providers/default', setDefaultProvider);
160
+ app.post('/story-ui/providers/model', setModel);
161
+ // UI Settings proxy routes (for non-technical users)
162
+ app.get('/story-ui/providers/settings', getUISettings);
163
+ app.post('/story-ui/providers/settings', applyUISettings);
164
+ app.get('/story-ui/providers/config', getSettingsConfig);
165
+ // Framework management proxy routes
166
+ app.get('/story-ui/frameworks', listFrameworks);
167
+ app.get('/story-ui/frameworks/detect', detectCurrentFramework);
168
+ app.get('/story-ui/frameworks/:type', getFrameworkDetails);
169
+ app.post('/story-ui/frameworks/validate', validateStoryForFramework);
170
+ app.post('/story-ui/frameworks/post-process', postProcessStoryForFramework);
57
171
  // Legacy delete route for backwards compatibility
58
172
  app.post('/story-ui/delete', async (req, res) => {
59
173
  try {
@@ -109,6 +223,10 @@ app.delete('/story-ui/sync/stories/:id', deleteSyncedStory);
109
223
  app.delete('/story-ui/sync/stories', clearAllSyncedStories);
110
224
  app.get('/story-ui/sync/chat-history', syncChatHistory);
111
225
  app.get('/story-ui/sync/validate/:id', validateChatSession);
226
+ // MCP Remote HTTP transport routes (for Claude Desktop remote connections)
227
+ // Provides Streamable HTTP and legacy SSE endpoints for remote MCP access
228
+ app.use('/mcp-remote', mcpRemoteRouter);
229
+ app.use('/story-ui/mcp-remote', mcpRemoteRouter); // Also available at story-ui prefix
112
230
  // Redirect service endpoint
113
231
  app.get('/mcp/redirects.js', (req, res) => {
114
232
  res.set('Content-Type', 'application/javascript');
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=mcp-stdio-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-stdio-server.d.ts","sourceRoot":"","sources":["../../mcp-server/mcp-stdio-server.ts"],"names":[],"mappings":""}
@@ -11,6 +11,13 @@ import dotenv from 'dotenv';
11
11
  import path from 'path';
12
12
  import fs from 'fs';
13
13
  import crypto from 'crypto';
14
+ import { fileURLToPath } from 'url';
15
+ // Get package version dynamically
16
+ const __filename_mcp = fileURLToPath(import.meta.url);
17
+ const __dirname_mcp = path.dirname(__filename_mcp);
18
+ const packageJsonPath = path.resolve(__dirname_mcp, '../package.json');
19
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
20
+ const PACKAGE_VERSION = packageJson.version;
14
21
  // Check for working directory override from environment or command line
15
22
  const workingDir = process.env.STORY_UI_CWD || process.argv.find(arg => arg.startsWith('--cwd='))?.split('=')[1];
16
23
  if (workingDir) {
@@ -34,7 +41,7 @@ console.error(`[MCP] Session ID: ${sessionId}`);
34
41
  // Create MCP server instance
35
42
  const server = new Server({
36
43
  name: "story-ui",
37
- version: "2.1.5",
44
+ version: PACKAGE_VERSION,
38
45
  }, {
39
46
  capabilities: {
40
47
  tools: {},
@@ -0,0 +1,3 @@
1
+ import { Request, Response } from 'express';
2
+ export declare function claudeProxy(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
3
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI5C,wBAAsB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAwE5D"}
@@ -1,30 +1,67 @@
1
- import fetch from 'node-fetch';
1
+ import { chatCompletion, isProviderConfigured, getProviderInfo } from '../../story-generator/llm-providers/story-llm-service.js';
2
+ import { logger } from '../../story-generator/logger.js';
2
3
  export async function claudeProxy(req, res) {
3
- const { prompt } = req.body;
4
- if (!prompt)
5
- return res.status(400).json({ error: 'Missing prompt' });
6
- const apiKey = process.env.CLAUDE_API_KEY;
7
- if (!apiKey)
8
- return res.status(500).json({ error: 'Claude API key not set' });
4
+ const { prompt, messages, model, maxTokens, systemPrompt, prefillAssistant } = req.body;
5
+ // Support both single prompt and messages array
6
+ if (!prompt && (!messages || messages.length === 0)) {
7
+ return res.status(400).json({ error: 'Missing prompt or messages' });
8
+ }
9
+ // Check if any provider is configured
10
+ if (!isProviderConfigured()) {
11
+ return res.status(500).json({
12
+ error: 'No LLM provider configured',
13
+ message: 'Please set CLAUDE_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY in your environment'
14
+ });
15
+ }
9
16
  try {
10
- // Example Claude API call (adjust endpoint/model as needed)
11
- const response = await fetch('https://api.anthropic.com/v1/messages', {
12
- method: 'POST',
13
- headers: {
14
- 'x-api-key': apiKey,
15
- 'content-type': 'application/json',
16
- 'anthropic-version': '2023-06-01',
17
- },
18
- body: JSON.stringify({
19
- model: process.env.CLAUDE_MODEL || 'claude-sonnet-4-20250514',
20
- max_tokens: 4096,
21
- messages: [{ role: 'user', content: prompt }],
22
- }),
17
+ const providerInfo = getProviderInfo();
18
+ logger.debug('LLM proxy request', {
19
+ provider: providerInfo.currentProvider,
20
+ model: providerInfo.currentModel,
21
+ hasPrompt: !!prompt,
22
+ messageCount: messages?.length || 1,
23
+ hasPrefill: !!prefillAssistant
24
+ });
25
+ // Convert single prompt to messages format if needed
26
+ // Handle both undefined messages and empty array
27
+ let chatMessages = (messages && messages.length > 0)
28
+ ? messages
29
+ : [{ role: 'user', content: prompt }];
30
+ // Prepend system prompt as a system message if provided
31
+ if (systemPrompt) {
32
+ chatMessages = [
33
+ { role: 'system', content: systemPrompt },
34
+ ...chatMessages
35
+ ];
36
+ }
37
+ // Add assistant prefill if provided (forces Claude to continue from this point)
38
+ // This is a powerful technique to control output format
39
+ if (prefillAssistant) {
40
+ chatMessages = [
41
+ ...chatMessages,
42
+ { role: 'assistant', content: prefillAssistant }
43
+ ];
44
+ }
45
+ const response = await chatCompletion(chatMessages, {
46
+ model,
47
+ maxTokens: maxTokens || 4096
48
+ });
49
+ // If we used a prefill, prepend it to the response so the client gets the full output
50
+ const fullResponse = prefillAssistant ? prefillAssistant + response : response;
51
+ // Return response in a format compatible with the old Claude API
52
+ res.json({
53
+ content: [{ type: 'text', text: fullResponse }],
54
+ provider: providerInfo.currentProvider,
55
+ model: providerInfo.currentModel
23
56
  });
24
- const data = await response.json();
25
- res.json(data);
26
57
  }
27
58
  catch (err) {
28
- res.status(500).json({ error: 'Claude API error', details: err });
59
+ logger.error('LLM proxy error', {
60
+ error: err instanceof Error ? err.message : String(err)
61
+ });
62
+ res.status(500).json({
63
+ error: 'LLM API error',
64
+ message: err instanceof Error ? err.message : 'An unexpected error occurred'
65
+ });
29
66
  }
30
67
  }
@@ -0,0 +1,4 @@
1
+ import { Request, Response } from 'express';
2
+ export declare function getComponents(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
3
+ export declare function getProps(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
4
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAW5C,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAkC9D;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DA8CzD"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Framework Management Routes
3
+ *
4
+ * API endpoints for framework detection and adapter management.
5
+ * Supports multi-framework story generation.
6
+ */
7
+ import { Request, Response } from 'express';
8
+ /**
9
+ * GET /mcp/frameworks
10
+ *
11
+ * List all available frameworks and their adapters.
12
+ */
13
+ export declare function listFrameworks(req: Request, res: Response): Promise<void>;
14
+ /**
15
+ * GET /mcp/frameworks/detect
16
+ *
17
+ * Auto-detect the framework used in the current project.
18
+ */
19
+ export declare function detectCurrentFramework(req: Request, res: Response): Promise<void>;
20
+ /**
21
+ * GET /mcp/frameworks/:type
22
+ *
23
+ * Get details about a specific framework adapter.
24
+ */
25
+ export declare function getFrameworkDetails(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
26
+ /**
27
+ * POST /mcp/frameworks/validate
28
+ *
29
+ * Validate generated story content against framework rules.
30
+ */
31
+ export declare function validateStoryForFramework(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
32
+ /**
33
+ * POST /mcp/frameworks/post-process
34
+ *
35
+ * Post-process generated story content for a specific framework.
36
+ */
37
+ export declare function postProcessStoryForFramework(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
38
+ //# sourceMappingURL=frameworks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frameworks.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/frameworks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAS5C;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,iBA0B/D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,iBAwBvE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DA+BpE;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAsC1E;AAED;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAmC7E"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Framework Management Routes
3
+ *
4
+ * API endpoints for framework detection and adapter management.
5
+ * Supports multi-framework story generation.
6
+ */
7
+ import { getAvailableFrameworks, getFrameworkAdapter, } from '../../story-generator/promptGenerator.js';
8
+ import { detectFramework } from '../../story-generator/framework-adapters/index.js';
9
+ import { logger } from '../../story-generator/logger.js';
10
+ /**
11
+ * GET /mcp/frameworks
12
+ *
13
+ * List all available frameworks and their adapters.
14
+ */
15
+ export async function listFrameworks(req, res) {
16
+ try {
17
+ const frameworks = getAvailableFrameworks();
18
+ const frameworkDetails = frameworks.map(framework => {
19
+ const adapter = getFrameworkAdapter(framework);
20
+ return {
21
+ type: framework,
22
+ name: adapter.name,
23
+ supportedStoryFrameworks: adapter.supportedStoryFrameworks,
24
+ defaultExtension: adapter.defaultExtension,
25
+ };
26
+ });
27
+ res.json({
28
+ success: true,
29
+ frameworks: frameworkDetails,
30
+ count: frameworks.length,
31
+ });
32
+ }
33
+ catch (error) {
34
+ logger.error('Failed to list frameworks', { error: error.message });
35
+ res.status(500).json({
36
+ error: 'Failed to list frameworks',
37
+ message: error.message,
38
+ });
39
+ }
40
+ }
41
+ /**
42
+ * GET /mcp/frameworks/detect
43
+ *
44
+ * Auto-detect the framework used in the current project.
45
+ */
46
+ export async function detectCurrentFramework(req, res) {
47
+ try {
48
+ const projectRoot = req.query.path || process.cwd();
49
+ const result = await detectFramework(projectRoot);
50
+ res.json({
51
+ success: true,
52
+ detected: {
53
+ primary: result.primary,
54
+ alternatives: result.frameworks.slice(1),
55
+ },
56
+ projectInfo: {
57
+ dependencies: result.dependencies,
58
+ configFiles: result.configFiles,
59
+ },
60
+ });
61
+ }
62
+ catch (error) {
63
+ logger.error('Failed to detect framework', { error: error.message });
64
+ res.status(500).json({
65
+ error: 'Failed to detect framework',
66
+ message: error.message,
67
+ });
68
+ }
69
+ }
70
+ /**
71
+ * GET /mcp/frameworks/:type
72
+ *
73
+ * Get details about a specific framework adapter.
74
+ */
75
+ export async function getFrameworkDetails(req, res) {
76
+ try {
77
+ const { type } = req.params;
78
+ const availableFrameworks = getAvailableFrameworks();
79
+ if (!availableFrameworks.includes(type)) {
80
+ return res.status(404).json({
81
+ error: 'Framework not found',
82
+ message: `Framework "${type}" is not supported`,
83
+ available: availableFrameworks,
84
+ });
85
+ }
86
+ const adapter = getFrameworkAdapter(type);
87
+ res.json({
88
+ success: true,
89
+ framework: {
90
+ type: adapter.type,
91
+ name: adapter.name,
92
+ supportedStoryFrameworks: adapter.supportedStoryFrameworks,
93
+ defaultExtension: adapter.defaultExtension,
94
+ },
95
+ });
96
+ }
97
+ catch (error) {
98
+ logger.error('Failed to get framework details', { error: error.message });
99
+ res.status(500).json({
100
+ error: 'Failed to get framework details',
101
+ message: error.message,
102
+ });
103
+ }
104
+ }
105
+ /**
106
+ * POST /mcp/frameworks/validate
107
+ *
108
+ * Validate generated story content against framework rules.
109
+ */
110
+ export async function validateStoryForFramework(req, res) {
111
+ try {
112
+ const { framework, content } = req.body;
113
+ if (!framework || !content) {
114
+ return res.status(400).json({
115
+ error: 'Missing required fields',
116
+ message: 'Both "framework" and "content" are required',
117
+ });
118
+ }
119
+ const availableFrameworks = getAvailableFrameworks();
120
+ if (!availableFrameworks.includes(framework)) {
121
+ return res.status(400).json({
122
+ error: 'Invalid framework',
123
+ message: `Framework "${framework}" is not supported`,
124
+ available: availableFrameworks,
125
+ });
126
+ }
127
+ const adapter = getFrameworkAdapter(framework);
128
+ const validation = adapter.validate(content);
129
+ res.json({
130
+ success: true,
131
+ validation: {
132
+ isValid: validation.valid,
133
+ errors: validation.errors,
134
+ framework: adapter.type,
135
+ },
136
+ });
137
+ }
138
+ catch (error) {
139
+ logger.error('Failed to validate story', { error: error.message });
140
+ res.status(500).json({
141
+ error: 'Failed to validate story',
142
+ message: error.message,
143
+ });
144
+ }
145
+ }
146
+ /**
147
+ * POST /mcp/frameworks/post-process
148
+ *
149
+ * Post-process generated story content for a specific framework.
150
+ */
151
+ export async function postProcessStoryForFramework(req, res) {
152
+ try {
153
+ const { framework, content } = req.body;
154
+ if (!framework || !content) {
155
+ return res.status(400).json({
156
+ error: 'Missing required fields',
157
+ message: 'Both "framework" and "content" are required',
158
+ });
159
+ }
160
+ const availableFrameworks = getAvailableFrameworks();
161
+ if (!availableFrameworks.includes(framework)) {
162
+ return res.status(400).json({
163
+ error: 'Invalid framework',
164
+ message: `Framework "${framework}" is not supported`,
165
+ available: availableFrameworks,
166
+ });
167
+ }
168
+ const adapter = getFrameworkAdapter(framework);
169
+ const processed = adapter.postProcess(content);
170
+ res.json({
171
+ success: true,
172
+ content: processed,
173
+ framework: adapter.type,
174
+ });
175
+ }
176
+ catch (error) {
177
+ logger.error('Failed to post-process story', { error: error.message });
178
+ res.status(500).json({
179
+ error: 'Failed to post-process story',
180
+ message: error.message,
181
+ });
182
+ }
183
+ }
@@ -0,0 +1,3 @@
1
+ import { Request, Response } from 'express';
2
+ export declare function generateStoryFromPrompt(req: Request, res: Response): Promise<Response<any, Record<string, any>> | undefined>;
3
+ //# sourceMappingURL=generateStory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateStory.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/generateStory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAuZ5C,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAigBxE"}