@tpitre/story-ui 3.4.1 → 3.4.2
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/dist/mcp-server/index.js
CHANGED
|
@@ -146,7 +146,89 @@ app.get('/story-ui/frameworks/detect', detectCurrentFramework);
|
|
|
146
146
|
app.get('/story-ui/frameworks/:type', getFrameworkDetails);
|
|
147
147
|
app.post('/story-ui/frameworks/validate', validateStoryForFramework);
|
|
148
148
|
app.post('/story-ui/frameworks/post-process', postProcessStoryForFramework);
|
|
149
|
-
//
|
|
149
|
+
// List generated stories from file system
|
|
150
|
+
app.get('/story-ui/stories', async (req, res) => {
|
|
151
|
+
try {
|
|
152
|
+
const storiesPath = config.generatedStoriesPath;
|
|
153
|
+
console.log(`📋 Listing stories from: ${storiesPath}`);
|
|
154
|
+
if (!fs.existsSync(storiesPath)) {
|
|
155
|
+
return res.json({ stories: [] });
|
|
156
|
+
}
|
|
157
|
+
const files = fs.readdirSync(storiesPath);
|
|
158
|
+
const stories = files
|
|
159
|
+
.filter(file => file.endsWith('.stories.tsx'))
|
|
160
|
+
.map(file => {
|
|
161
|
+
const filePath = path.join(storiesPath, file);
|
|
162
|
+
const stats = fs.statSync(filePath);
|
|
163
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
164
|
+
// Extract title from story file
|
|
165
|
+
const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
|
|
166
|
+
const title = titleMatch ? titleMatch[1].replace('Generated/', '') : file.replace('.stories.tsx', '');
|
|
167
|
+
return {
|
|
168
|
+
id: file.replace('.stories.tsx', ''),
|
|
169
|
+
fileName: file,
|
|
170
|
+
title,
|
|
171
|
+
lastUpdated: stats.mtime.getTime(),
|
|
172
|
+
code: content
|
|
173
|
+
};
|
|
174
|
+
})
|
|
175
|
+
.sort((a, b) => b.lastUpdated - a.lastUpdated);
|
|
176
|
+
console.log(`✅ Found ${stories.length} stories`);
|
|
177
|
+
return res.json({ stories });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.error('Error listing stories:', error);
|
|
181
|
+
return res.status(500).json({ error: 'Failed to list stories' });
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// Save story to file system
|
|
185
|
+
app.post('/story-ui/stories', async (req, res) => {
|
|
186
|
+
try {
|
|
187
|
+
const { id, title, code } = req.body;
|
|
188
|
+
if (!id || !code) {
|
|
189
|
+
return res.status(400).json({ error: 'id and code are required' });
|
|
190
|
+
}
|
|
191
|
+
const storiesPath = config.generatedStoriesPath;
|
|
192
|
+
// Ensure stories directory exists
|
|
193
|
+
if (!fs.existsSync(storiesPath)) {
|
|
194
|
+
fs.mkdirSync(storiesPath, { recursive: true });
|
|
195
|
+
}
|
|
196
|
+
const fileName = `${id}.stories.tsx`;
|
|
197
|
+
const filePath = path.join(storiesPath, fileName);
|
|
198
|
+
fs.writeFileSync(filePath, code, 'utf-8');
|
|
199
|
+
console.log(`✅ Saved story: ${filePath}`);
|
|
200
|
+
return res.json({
|
|
201
|
+
success: true,
|
|
202
|
+
id,
|
|
203
|
+
fileName,
|
|
204
|
+
title
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error('Error saving story:', error);
|
|
209
|
+
return res.status(500).json({ error: 'Failed to save story' });
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
// Delete story by ID (RESTful endpoint)
|
|
213
|
+
app.delete('/story-ui/stories/:id', async (req, res) => {
|
|
214
|
+
try {
|
|
215
|
+
const { id } = req.params;
|
|
216
|
+
const storiesPath = config.generatedStoriesPath;
|
|
217
|
+
const fileName = id.endsWith('.stories.tsx') ? id : `${id}.stories.tsx`;
|
|
218
|
+
const filePath = path.join(storiesPath, fileName);
|
|
219
|
+
if (fs.existsSync(filePath)) {
|
|
220
|
+
fs.unlinkSync(filePath);
|
|
221
|
+
console.log(`✅ Deleted story: ${filePath}`);
|
|
222
|
+
return res.json({ success: true, message: 'Story deleted successfully' });
|
|
223
|
+
}
|
|
224
|
+
return res.status(404).json({ success: false, error: 'Story not found' });
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
console.error('Error deleting story:', error);
|
|
228
|
+
return res.status(500).json({ error: 'Failed to delete story' });
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
// Delete story from file system (legacy POST endpoint)
|
|
150
232
|
app.post('/story-ui/delete', async (req, res) => {
|
|
151
233
|
try {
|
|
152
234
|
const { chatId, storyId } = req.body;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StoryUIPanel.d.ts","sourceRoot":"","sources":["../../../templates/StoryUI/StoryUIPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StoryUIPanel.d.ts","sourceRoot":"","sources":["../../../templates/StoryUI/StoryUIPanel.tsx"],"names":[],"mappings":"AAiTA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,2BAA2B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtD;CACF;AA6oCD,iBAAS,YAAY,4CA8sCpB;AAED,eAAe,YAAY,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -82,10 +82,11 @@ const StatusIcons = {
|
|
|
82
82
|
// Priority order:
|
|
83
83
|
// 1. VITE_STORY_UI_EDGE_URL - Edge Worker URL for cloud deployments
|
|
84
84
|
// 2. window.__STORY_UI_EDGE_URL__ - Runtime override for edge URL
|
|
85
|
-
// 3.
|
|
86
|
-
// 4.
|
|
87
|
-
// 5. window.
|
|
88
|
-
// 6.
|
|
85
|
+
// 3. Production domains (railway.app, render.com, pages.dev) - use same origin
|
|
86
|
+
// 4. VITE_STORY_UI_PORT - Custom port for localhost
|
|
87
|
+
// 5. window.__STORY_UI_PORT__ - Legacy port override
|
|
88
|
+
// 6. window.STORY_UI_MCP_PORT - MCP port override
|
|
89
|
+
// 7. Default to localhost:4001
|
|
89
90
|
const getApiBaseUrl = () => {
|
|
90
91
|
// Check for Edge Worker URL (cloud deployment)
|
|
91
92
|
const edgeUrl = import.meta.env?.VITE_STORY_UI_EDGE_URL;
|
|
@@ -95,6 +96,15 @@ const getApiBaseUrl = () => {
|
|
|
95
96
|
const windowEdgeUrl = window.__STORY_UI_EDGE_URL__ || window.STORY_UI_EDGE_URL;
|
|
96
97
|
if (windowEdgeUrl)
|
|
97
98
|
return windowEdgeUrl.replace(/\/$/, '');
|
|
99
|
+
// Check if we're running on Railway production domain
|
|
100
|
+
// In this case, the MCP server is proxied through the same origin
|
|
101
|
+
if (typeof window !== 'undefined') {
|
|
102
|
+
const hostname = window.location.hostname;
|
|
103
|
+
if (hostname.includes('.railway.app')) {
|
|
104
|
+
// Use same-origin requests (empty string means relative URLs)
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
98
108
|
// Check for Vite port environment variable
|
|
99
109
|
const vitePort = import.meta.env?.VITE_STORY_UI_PORT;
|
|
100
110
|
if (vitePort)
|
package/package.json
CHANGED
|
@@ -249,10 +249,11 @@ interface ChatSession {
|
|
|
249
249
|
// Priority order:
|
|
250
250
|
// 1. VITE_STORY_UI_EDGE_URL - Edge Worker URL for cloud deployments
|
|
251
251
|
// 2. window.__STORY_UI_EDGE_URL__ - Runtime override for edge URL
|
|
252
|
-
// 3.
|
|
253
|
-
// 4.
|
|
254
|
-
// 5. window.
|
|
255
|
-
// 6.
|
|
252
|
+
// 3. Production domains (railway.app, render.com, pages.dev) - use same origin
|
|
253
|
+
// 4. VITE_STORY_UI_PORT - Custom port for localhost
|
|
254
|
+
// 5. window.__STORY_UI_PORT__ - Legacy port override
|
|
255
|
+
// 6. window.STORY_UI_MCP_PORT - MCP port override
|
|
256
|
+
// 7. Default to localhost:4001
|
|
256
257
|
const getApiBaseUrl = () => {
|
|
257
258
|
// Check for Edge Worker URL (cloud deployment)
|
|
258
259
|
const edgeUrl = (import.meta as any).env?.VITE_STORY_UI_EDGE_URL;
|
|
@@ -262,6 +263,16 @@ const getApiBaseUrl = () => {
|
|
|
262
263
|
const windowEdgeUrl = (window as any).__STORY_UI_EDGE_URL__ || (window as any).STORY_UI_EDGE_URL;
|
|
263
264
|
if (windowEdgeUrl) return windowEdgeUrl.replace(/\/$/, '');
|
|
264
265
|
|
|
266
|
+
// Check if we're running on Railway production domain
|
|
267
|
+
// In this case, the MCP server is proxied through the same origin
|
|
268
|
+
if (typeof window !== 'undefined') {
|
|
269
|
+
const hostname = window.location.hostname;
|
|
270
|
+
if (hostname.includes('.railway.app')) {
|
|
271
|
+
// Use same-origin requests (empty string means relative URLs)
|
|
272
|
+
return '';
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
265
276
|
// Check for Vite port environment variable
|
|
266
277
|
const vitePort = (import.meta as any).env?.VITE_STORY_UI_PORT;
|
|
267
278
|
if (vitePort) return `http://localhost:${vitePort}`;
|