@tpitre/story-ui 2.2.0 → 2.3.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.
- package/.env.sample +82 -11
- package/README.md +89 -0
- package/dist/cli/deploy.d.ts +17 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +696 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +26 -2
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +437 -110
- package/dist/mcp-server/index.d.ts +2 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +120 -2
- package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
- package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
- package/dist/mcp-server/mcp-stdio-server.js +8 -1
- package/dist/mcp-server/routes/claude.d.ts +3 -0
- package/dist/mcp-server/routes/claude.d.ts.map +1 -0
- package/dist/mcp-server/routes/claude.js +60 -23
- package/dist/mcp-server/routes/components.d.ts +4 -0
- package/dist/mcp-server/routes/components.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.d.ts +38 -0
- package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.js +183 -0
- package/dist/mcp-server/routes/generateStory.d.ts +3 -0
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStory.js +160 -76
- package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStoryStream.js +947 -0
- package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
- package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.js +489 -0
- package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
- package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.d.ts +89 -0
- package/dist/mcp-server/routes/providers.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.js +369 -0
- package/dist/mcp-server/routes/storySync.d.ts +26 -0
- package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
- package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.js +18 -0
- package/dist/mcp-server/sessionManager.d.ts +50 -0
- package/dist/mcp-server/sessionManager.d.ts.map +1 -0
- package/dist/story-generator/componentBlacklist.d.ts +21 -0
- package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
- package/dist/story-generator/componentDiscovery.d.ts +28 -0
- package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.js +205 -0
- package/dist/story-generator/configLoader.d.ts +33 -0
- package/dist/story-generator/configLoader.d.ts.map +1 -0
- package/dist/story-generator/considerationsLoader.d.ts +32 -0
- package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
- package/dist/story-generator/documentation-sources.d.ts +28 -0
- package/dist/story-generator/documentation-sources.d.ts.map +1 -0
- package/dist/story-generator/documentationLoader.d.ts +64 -0
- package/dist/story-generator/documentationLoader.d.ts.map +1 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.js +111 -11
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
- package/dist/story-generator/framework-adapters/index.d.ts +97 -0
- package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/index.js +198 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
- package/dist/story-generator/framework-adapters/types.d.ts +182 -0
- package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/types.js +8 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
- package/dist/story-generator/generateStory.d.ts +7 -0
- package/dist/story-generator/generateStory.d.ts.map +1 -0
- package/dist/story-generator/gitignoreManager.d.ts +50 -0
- package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.d.ts +80 -0
- package/dist/story-generator/imageProcessor.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.js +391 -0
- package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
- package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.js +135 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/claude-provider.js +414 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
- package/dist/story-generator/llm-providers/index.d.ts +63 -0
- package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/index.js +169 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/openai-provider.js +458 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/settings-manager.js +173 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
- package/dist/story-generator/llm-providers/types.d.ts +153 -0
- package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/types.js +8 -0
- package/dist/story-generator/logger.d.ts +14 -0
- package/dist/story-generator/logger.d.ts.map +1 -0
- package/dist/story-generator/logger.js +96 -29
- package/dist/story-generator/postProcessStory.d.ts +6 -0
- package/dist/story-generator/postProcessStory.d.ts.map +1 -0
- package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
- package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.d.ts +48 -0
- package/dist/story-generator/promptGenerator.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.js +186 -1
- package/dist/story-generator/storyHistory.d.ts +44 -0
- package/dist/story-generator/storyHistory.d.ts.map +1 -0
- package/dist/story-generator/storySync.d.ts +68 -0
- package/dist/story-generator/storySync.d.ts.map +1 -0
- package/dist/story-generator/storyTracker.d.ts +48 -0
- package/dist/story-generator/storyTracker.d.ts.map +1 -0
- package/dist/story-generator/storyValidator.d.ts +6 -0
- package/dist/story-generator/storyValidator.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.js +138 -1
- package/dist/story-generator/urlRedirectService.d.ts +21 -0
- package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
- package/dist/story-generator/validateStory.d.ts +19 -0
- package/dist/story-generator/validateStory.d.ts.map +1 -0
- package/dist/story-generator/validateStory.js +6 -2
- package/dist/story-generator/visionPrompts.d.ts +88 -0
- package/dist/story-generator/visionPrompts.d.ts.map +1 -0
- package/dist/story-generator/visionPrompts.js +462 -0
- package/dist/story-ui.config.d.ts +78 -0
- package/dist/story-ui.config.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
- package/dist/templates/StoryUI/index.d.ts +3 -0
- package/dist/templates/StoryUI/index.d.ts.map +1 -0
- package/dist/templates/StoryUI/index.js +2 -0
- package/package.json +17 -3
- package/templates/StoryUI/StoryUIPanel.tsx +1960 -384
- package/templates/StoryUI/index.tsx +1 -1
- package/templates/StoryUI/manager.tsx +264 -0
- package/templates/production-app/.env.example +11 -0
- package/templates/production-app/index.html +66 -0
- package/templates/production-app/package.json +30 -0
- package/templates/production-app/public/favicon.svg +5 -0
- package/templates/production-app/src/App.tsx +1560 -0
- package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
- package/templates/production-app/src/componentRegistry.ts +315 -0
- package/templates/production-app/src/considerations.ts +16 -0
- package/templates/production-app/src/index.css +284 -0
- package/templates/production-app/src/main.tsx +25 -0
- package/templates/production-app/tsconfig.json +32 -0
- package/templates/production-app/tsconfig.node.json +11 -0
- package/templates/production-app/vite.config.ts +83 -0
- package/templates/react-import-rule.json +2 -2
- package/dist/index.js +0 -12
- package/dist/story-ui.config.loader.js +0 -205
package/dist/mcp-server/index.js
CHANGED
|
@@ -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
|
-
|
|
25
|
-
|
|
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 @@
|
|
|
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:
|
|
44
|
+
version: PACKAGE_VERSION,
|
|
38
45
|
}, {
|
|
39
46
|
capabilities: {
|
|
40
47
|
tools: {},
|
|
@@ -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
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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 @@
|
|
|
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"}
|