@tpitre/story-ui 3.0.0 → 3.2.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 (281) hide show
  1. package/README.md +25 -72
  2. package/dist/cli/deploy.d.ts +0 -7
  3. package/dist/cli/deploy.d.ts.map +1 -1
  4. package/dist/cli/deploy.js +10 -421
  5. package/dist/cli/index.js +0 -0
  6. package/dist/mcp-server/index.js +7 -8
  7. package/dist/mcp-server/mcp-stdio-server.js +1 -2
  8. package/dist/mcp-server/routes/generateStory.d.ts.map +1 -1
  9. package/dist/mcp-server/routes/generateStory.js +3 -3
  10. package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -1
  11. package/dist/mcp-server/routes/generateStoryStream.js +3 -3
  12. package/dist/mcp-server/routes/hybridStories.d.ts +6 -6
  13. package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -1
  14. package/dist/mcp-server/routes/hybridStories.js +29 -27
  15. package/dist/mcp-server/routes/memoryStories.d.ts +7 -7
  16. package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -1
  17. package/dist/mcp-server/routes/memoryStories.js +37 -26
  18. package/dist/story-generator/postgresStoryService.d.ts +56 -0
  19. package/dist/story-generator/postgresStoryService.d.ts.map +1 -0
  20. package/dist/story-generator/postgresStoryService.js +240 -0
  21. package/dist/story-generator/storyServiceFactory.d.ts +22 -0
  22. package/dist/story-generator/storyServiceFactory.d.ts.map +1 -0
  23. package/dist/story-generator/storyServiceFactory.js +97 -0
  24. package/dist/story-generator/storyServiceInterface.d.ts +85 -0
  25. package/dist/story-generator/storyServiceInterface.d.ts.map +1 -0
  26. package/dist/story-generator/storyServiceInterface.js +5 -0
  27. package/dist/templates/StoryUI/StoryUIPanel.d.ts +5 -0
  28. package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -1
  29. package/dist/templates/StoryUI/StoryUIPanel.js +18 -3
  30. package/package.json +6 -6
  31. package/templates/StoryUI/StoryUIPanel.tsx +28 -3
  32. package/templates/StoryUI/manager.tsx +444 -213
  33. package/dist/cli/index.js.map +0 -1
  34. package/dist/cli/setup.js.map +0 -1
  35. package/dist/cloudflare-edge/src/mcp-session.js +0 -462
  36. package/dist/cloudflare-edge/src/types.js +0 -4
  37. package/dist/cloudflare-edge/src/worker.js +0 -106
  38. package/dist/cloudflare-pages/vite.config.js +0 -14
  39. package/dist/index.d.ts +0 -13
  40. package/dist/index.d.ts.map +0 -1
  41. package/dist/index.js +0 -12
  42. package/dist/index.js.map +0 -1
  43. package/dist/mcp-server/index.js.map +0 -1
  44. package/dist/mcp-server/mcp-stdio-server.js.map +0 -1
  45. package/dist/mcp-server/routes/claude.js.map +0 -1
  46. package/dist/mcp-server/routes/components.js.map +0 -1
  47. package/dist/mcp-server/routes/generateStory.js.map +0 -1
  48. package/dist/mcp-server/routes/hybridStories.js.map +0 -1
  49. package/dist/mcp-server/routes/memoryStories.js.map +0 -1
  50. package/dist/mcp-server/routes/storySync.js.map +0 -1
  51. package/dist/mcp-server/routes/updateStory.js +0 -246
  52. package/dist/mcp-server/sessionManager.js.map +0 -1
  53. package/dist/playground/components/AIAssistant/AIAssistant.d.ts +0 -6
  54. package/dist/playground/components/AIAssistant/AIAssistant.d.ts.map +0 -1
  55. package/dist/playground/components/AIAssistant/AIAssistant.js +0 -109
  56. package/dist/playground/components/AIAssistant/AIAssistant.js.map +0 -1
  57. package/dist/playground/components/AIAssistant/AIAssistant.module.css +0 -166
  58. package/dist/playground/components/Canvas/Canvas.d.ts +0 -9
  59. package/dist/playground/components/Canvas/Canvas.d.ts.map +0 -1
  60. package/dist/playground/components/Canvas/Canvas.js +0 -58
  61. package/dist/playground/components/Canvas/Canvas.js.map +0 -1
  62. package/dist/playground/components/Canvas/Canvas.module.css +0 -189
  63. package/dist/playground/components/Canvas/CanvasWithDnd.d.ts +0 -9
  64. package/dist/playground/components/Canvas/CanvasWithDnd.d.ts.map +0 -1
  65. package/dist/playground/components/Canvas/CanvasWithDnd.js +0 -158
  66. package/dist/playground/components/Canvas/CanvasWithDnd.js.map +0 -1
  67. package/dist/playground/components/Canvas/ComponentRenderer.d.ts +0 -15
  68. package/dist/playground/components/Canvas/ComponentRenderer.d.ts.map +0 -1
  69. package/dist/playground/components/Canvas/ComponentRenderer.js +0 -177
  70. package/dist/playground/components/Canvas/ComponentRenderer.js.map +0 -1
  71. package/dist/playground/components/Canvas/DraggableComponent.d.ts +0 -15
  72. package/dist/playground/components/Canvas/DraggableComponent.d.ts.map +0 -1
  73. package/dist/playground/components/Canvas/DraggableComponent.js +0 -49
  74. package/dist/playground/components/Canvas/DraggableComponent.js.map +0 -1
  75. package/dist/playground/components/Canvas/index.d.ts +0 -9
  76. package/dist/playground/components/Canvas/index.d.ts.map +0 -1
  77. package/dist/playground/components/Canvas/index.js +0 -5
  78. package/dist/playground/components/Canvas/index.js.map +0 -1
  79. package/dist/playground/components/CodeView/CodeView.d.ts +0 -12
  80. package/dist/playground/components/CodeView/CodeView.d.ts.map +0 -1
  81. package/dist/playground/components/CodeView/CodeView.js +0 -77
  82. package/dist/playground/components/CodeView/CodeView.js.map +0 -1
  83. package/dist/playground/components/CodeView/CodeView.module.css +0 -178
  84. package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts +0 -17
  85. package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts.map +0 -1
  86. package/dist/playground/components/ComponentPalette/ComponentPalette.js +0 -138
  87. package/dist/playground/components/ComponentPalette/ComponentPalette.js.map +0 -1
  88. package/dist/playground/components/ComponentPalette/ComponentPalette.module.css +0 -217
  89. package/dist/playground/components/ComponentPalette/index.d.ts +0 -3
  90. package/dist/playground/components/ComponentPalette/index.d.ts.map +0 -1
  91. package/dist/playground/components/ComponentPalette/index.js +0 -2
  92. package/dist/playground/components/ComponentPalette/index.js.map +0 -1
  93. package/dist/playground/components/DropZone/DropZone.d.ts +0 -17
  94. package/dist/playground/components/DropZone/DropZone.d.ts.map +0 -1
  95. package/dist/playground/components/DropZone/DropZone.js +0 -73
  96. package/dist/playground/components/DropZone/DropZone.js.map +0 -1
  97. package/dist/playground/components/DropZone/DropZone.module.css +0 -86
  98. package/dist/playground/components/ExportDialog/ExportDialog.d.ts +0 -10
  99. package/dist/playground/components/ExportDialog/ExportDialog.d.ts.map +0 -1
  100. package/dist/playground/components/ExportDialog/ExportDialog.js +0 -57
  101. package/dist/playground/components/ExportDialog/ExportDialog.js.map +0 -1
  102. package/dist/playground/components/ExportDialog/ExportDialog.module.css +0 -328
  103. package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts +0 -134
  104. package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts.map +0 -1
  105. package/dist/playground/components/LayoutHelpers/LayoutHelpers.js +0 -254
  106. package/dist/playground/components/LayoutHelpers/LayoutHelpers.js.map +0 -1
  107. package/dist/playground/components/LayoutHelpers/index.d.ts +0 -3
  108. package/dist/playground/components/LayoutHelpers/index.d.ts.map +0 -1
  109. package/dist/playground/components/LayoutHelpers/index.js +0 -2
  110. package/dist/playground/components/LayoutHelpers/index.js.map +0 -1
  111. package/dist/playground/components/Playground/Playground.d.ts +0 -10
  112. package/dist/playground/components/Playground/Playground.d.ts.map +0 -1
  113. package/dist/playground/components/Playground/Playground.js +0 -128
  114. package/dist/playground/components/Playground/Playground.js.map +0 -1
  115. package/dist/playground/components/Playground/Playground.module.css +0 -308
  116. package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts +0 -10
  117. package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts.map +0 -1
  118. package/dist/playground/components/PropertiesPanel/PropertiesPanel.js +0 -150
  119. package/dist/playground/components/PropertiesPanel/PropertiesPanel.js.map +0 -1
  120. package/dist/playground/components/PropertiesPanel/PropertiesPanel.module.css +0 -155
  121. package/dist/playground/components/PropertiesPanel/index.d.ts +0 -3
  122. package/dist/playground/components/PropertiesPanel/index.d.ts.map +0 -1
  123. package/dist/playground/components/PropertiesPanel/index.js +0 -2
  124. package/dist/playground/components/PropertiesPanel/index.js.map +0 -1
  125. package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts +0 -12
  126. package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts.map +0 -1
  127. package/dist/playground/components/PropertyEditors/BooleanEditor.js +0 -14
  128. package/dist/playground/components/PropertyEditors/BooleanEditor.js.map +0 -1
  129. package/dist/playground/components/PropertyEditors/ColorEditor.d.ts +0 -12
  130. package/dist/playground/components/PropertyEditors/ColorEditor.d.ts.map +0 -1
  131. package/dist/playground/components/PropertyEditors/ColorEditor.js +0 -62
  132. package/dist/playground/components/PropertyEditors/ColorEditor.js.map +0 -1
  133. package/dist/playground/components/PropertyEditors/IconEditor.d.ts +0 -12
  134. package/dist/playground/components/PropertyEditors/IconEditor.d.ts.map +0 -1
  135. package/dist/playground/components/PropertyEditors/IconEditor.js +0 -123
  136. package/dist/playground/components/PropertyEditors/IconEditor.js.map +0 -1
  137. package/dist/playground/components/PropertyEditors/NumberEditor.d.ts +0 -15
  138. package/dist/playground/components/PropertyEditors/NumberEditor.d.ts.map +0 -1
  139. package/dist/playground/components/PropertyEditors/NumberEditor.js +0 -46
  140. package/dist/playground/components/PropertyEditors/NumberEditor.js.map +0 -1
  141. package/dist/playground/components/PropertyEditors/PropertyEditors.module.css +0 -432
  142. package/dist/playground/components/PropertyEditors/SelectEditor.d.ts +0 -19
  143. package/dist/playground/components/PropertyEditors/SelectEditor.d.ts.map +0 -1
  144. package/dist/playground/components/PropertyEditors/SelectEditor.js +0 -17
  145. package/dist/playground/components/PropertyEditors/SelectEditor.js.map +0 -1
  146. package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts +0 -19
  147. package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts.map +0 -1
  148. package/dist/playground/components/PropertyEditors/SpacingEditor.js +0 -162
  149. package/dist/playground/components/PropertyEditors/SpacingEditor.js.map +0 -1
  150. package/dist/playground/components/PropertyEditors/SpacingEditor.module.css +0 -214
  151. package/dist/playground/components/PropertyEditors/TextEditor.d.ts +0 -14
  152. package/dist/playground/components/PropertyEditors/TextEditor.d.ts.map +0 -1
  153. package/dist/playground/components/PropertyEditors/TextEditor.js +0 -38
  154. package/dist/playground/components/PropertyEditors/TextEditor.js.map +0 -1
  155. package/dist/playground/components/PropertyEditors/TokenEditor.d.ts +0 -23
  156. package/dist/playground/components/PropertyEditors/TokenEditor.d.ts.map +0 -1
  157. package/dist/playground/components/PropertyEditors/TokenEditor.js +0 -50
  158. package/dist/playground/components/PropertyEditors/TokenEditor.js.map +0 -1
  159. package/dist/playground/components/PropertyEditors/index.d.ts +0 -20
  160. package/dist/playground/components/PropertyEditors/index.d.ts.map +0 -1
  161. package/dist/playground/components/PropertyEditors/index.js +0 -12
  162. package/dist/playground/components/PropertyEditors/index.js.map +0 -1
  163. package/dist/playground/components/TreeView/TreeView.d.ts +0 -10
  164. package/dist/playground/components/TreeView/TreeView.d.ts.map +0 -1
  165. package/dist/playground/components/TreeView/TreeView.js +0 -146
  166. package/dist/playground/components/TreeView/TreeView.js.map +0 -1
  167. package/dist/playground/components/TreeView/TreeView.module.css +0 -214
  168. package/dist/playground/components/TreeView/index.d.ts +0 -3
  169. package/dist/playground/components/TreeView/index.d.ts.map +0 -1
  170. package/dist/playground/components/TreeView/index.js +0 -2
  171. package/dist/playground/components/TreeView/index.js.map +0 -1
  172. package/dist/playground/config/propertyDefinitions.d.ts +0 -73
  173. package/dist/playground/config/propertyDefinitions.d.ts.map +0 -1
  174. package/dist/playground/config/propertyDefinitions.js +0 -809
  175. package/dist/playground/config/propertyDefinitions.js.map +0 -1
  176. package/dist/playground/hooks/useKeyboardShortcuts.d.ts +0 -38
  177. package/dist/playground/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  178. package/dist/playground/hooks/useKeyboardShortcuts.js +0 -191
  179. package/dist/playground/hooks/useKeyboardShortcuts.js.map +0 -1
  180. package/dist/playground/index.d.ts +0 -21
  181. package/dist/playground/index.d.ts.map +0 -1
  182. package/dist/playground/index.js +0 -23
  183. package/dist/playground/index.js.map +0 -1
  184. package/dist/playground/services/CodeGenerator.d.ts +0 -73
  185. package/dist/playground/services/CodeGenerator.d.ts.map +0 -1
  186. package/dist/playground/services/CodeGenerator.js +0 -359
  187. package/dist/playground/services/CodeGenerator.js.map +0 -1
  188. package/dist/playground/services/DragDropManager.d.ts +0 -95
  189. package/dist/playground/services/DragDropManager.d.ts.map +0 -1
  190. package/dist/playground/services/DragDropManager.js +0 -408
  191. package/dist/playground/services/DragDropManager.js.map +0 -1
  192. package/dist/playground/services/StoryParser.d.ts +0 -73
  193. package/dist/playground/services/StoryParser.d.ts.map +0 -1
  194. package/dist/playground/services/StoryParser.js +0 -419
  195. package/dist/playground/services/StoryParser.js.map +0 -1
  196. package/dist/playground/store/playgroundStore.d.ts +0 -86
  197. package/dist/playground/store/playgroundStore.d.ts.map +0 -1
  198. package/dist/playground/store/playgroundStore.js +0 -337
  199. package/dist/playground/store/playgroundStore.js.map +0 -1
  200. package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts +0 -13
  201. package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts.map +0 -1
  202. package/dist/playground/stories/PlaygroundDragDrop.stories.js +0 -227
  203. package/dist/playground/stories/PlaygroundDragDrop.stories.js.map +0 -1
  204. package/dist/playground/stories/PlaygroundPhase4.stories.d.ts +0 -13
  205. package/dist/playground/stories/PlaygroundPhase4.stories.d.ts.map +0 -1
  206. package/dist/playground/stories/PlaygroundPhase4.stories.js +0 -334
  207. package/dist/playground/stories/PlaygroundPhase4.stories.js.map +0 -1
  208. package/dist/playground/stories/PlaygroundPhase5.stories.d.ts +0 -14
  209. package/dist/playground/stories/PlaygroundPhase5.stories.d.ts.map +0 -1
  210. package/dist/playground/stories/PlaygroundPhase5.stories.js +0 -512
  211. package/dist/playground/stories/PlaygroundPhase5.stories.js.map +0 -1
  212. package/dist/playground/stories/PlaygroundProperties.stories.d.ts +0 -13
  213. package/dist/playground/stories/PlaygroundProperties.stories.d.ts.map +0 -1
  214. package/dist/playground/stories/PlaygroundProperties.stories.js +0 -342
  215. package/dist/playground/stories/PlaygroundProperties.stories.js.map +0 -1
  216. package/dist/playground/types/index.d.ts +0 -251
  217. package/dist/playground/types/index.d.ts.map +0 -1
  218. package/dist/playground/types/index.js +0 -5
  219. package/dist/playground/types/index.js.map +0 -1
  220. package/dist/scripts/verify-framework-adapters.js +0 -105
  221. package/dist/story-generator/componentBlacklist.js.map +0 -1
  222. package/dist/story-generator/componentDiscovery.js.map +0 -1
  223. package/dist/story-generator/configLoader.js.map +0 -1
  224. package/dist/story-generator/considerationsLoader.js.map +0 -1
  225. package/dist/story-generator/documentation-sources.js.map +0 -1
  226. package/dist/story-generator/documentationLoader.js.map +0 -1
  227. package/dist/story-generator/dynamicPackageDiscovery.js.map +0 -1
  228. package/dist/story-generator/enhancedComponentDiscovery.js.map +0 -1
  229. package/dist/story-generator/generateStory.js.map +0 -1
  230. package/dist/story-generator/gitignoreManager.js.map +0 -1
  231. package/dist/story-generator/inMemoryStoryService.js.map +0 -1
  232. package/dist/story-generator/logger.js.map +0 -1
  233. package/dist/story-generator/postProcessStory.js.map +0 -1
  234. package/dist/story-generator/productionGitignoreManager.js.map +0 -1
  235. package/dist/story-generator/promptGenerator.js.map +0 -1
  236. package/dist/story-generator/providerPresets.d.ts +0 -54
  237. package/dist/story-generator/providerPresets.d.ts.map +0 -1
  238. package/dist/story-generator/providerPresets.js +0 -214
  239. package/dist/story-generator/storyHistory.js.map +0 -1
  240. package/dist/story-generator/storySync.js.map +0 -1
  241. package/dist/story-generator/storyTracker.js.map +0 -1
  242. package/dist/story-generator/storyValidator.js.map +0 -1
  243. package/dist/story-generator/test_validation.d.ts +0 -2
  244. package/dist/story-generator/test_validation.d.ts.map +0 -1
  245. package/dist/story-generator/test_validation.js +0 -51
  246. package/dist/story-generator/universalDesignSystemAdapter.js.map +0 -1
  247. package/dist/story-generator/urlRedirectService.js.map +0 -1
  248. package/dist/story-generator/validateStory.js.map +0 -1
  249. package/dist/story-ui.config.js.map +0 -1
  250. package/dist/story-ui.config.loader.d.ts +0 -36
  251. package/dist/story-ui.config.loader.d.ts.map +0 -1
  252. package/dist/story-ui.config.loader.js +0 -205
  253. package/dist/story-ui.config.loader.js.map +0 -1
  254. package/dist/temp/package/templates/StoryUI/StoryUIPanel.js +0 -807
  255. package/dist/temp/package/templates/StoryUI/StoryUIPanel.stories.js +0 -37
  256. package/dist/temp/package/templates/StoryUI/index.js +0 -2
  257. package/dist/templates/StoryUI/StoryUIPanel.js.map +0 -1
  258. package/dist/templates/StoryUI/StoryUIPanel.stories.js.map +0 -1
  259. package/dist/templates/StoryUI/index.js.map +0 -1
  260. package/dist/templates/StoryUI/manager.d.ts +0 -14
  261. package/dist/templates/StoryUI/manager.d.ts.map +0 -1
  262. package/dist/templates/production-app/src/App.d.ts +0 -10
  263. package/dist/templates/production-app/src/App.d.ts.map +0 -1
  264. package/dist/templates/production-app/src/App.js +0 -653
  265. package/dist/templates/production-app/src/LivePreviewRenderer.d.ts +0 -24
  266. package/dist/templates/production-app/src/LivePreviewRenderer.d.ts.map +0 -1
  267. package/dist/templates/production-app/src/LivePreviewRenderer.js +0 -199
  268. package/dist/templates/production-app/src/componentRegistry.d.ts +0 -20
  269. package/dist/templates/production-app/src/componentRegistry.d.ts.map +0 -1
  270. package/dist/templates/production-app/src/componentRegistry.js +0 -316
  271. package/dist/templates/production-app/src/main.d.ts +0 -9
  272. package/dist/templates/production-app/src/main.d.ts.map +0 -1
  273. package/dist/templates/production-app/src/main.js +0 -18
  274. package/dist/templates/production-app/vite.config.d.ts +0 -3
  275. package/dist/templates/production-app/vite.config.d.ts.map +0 -1
  276. package/dist/templates/production-app/vite.config.js +0 -71
  277. package/dist/test-storybooks/angular-material-storybook/src/main.js +0 -66
  278. package/dist/test-storybooks/chakra-storybook/vite.config.js +0 -6
  279. package/dist/test-storybooks/mantine-storybook/vite.config.js +0 -93
  280. package/dist/test-storybooks/web-components-shoelace/vite.config.js +0 -9
  281. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,240 @@
1
+ import pg from 'pg';
2
+ const { Pool } = pg;
3
+ /**
4
+ * PostgreSQL Story Service
5
+ * Persistent story storage using PostgreSQL database
6
+ * Designed for Railway PostgreSQL deployments
7
+ */
8
+ export class PostgresStoryService {
9
+ constructor(connectionString) {
10
+ this.initialized = false;
11
+ this.pool = new Pool({
12
+ connectionString,
13
+ ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
14
+ max: 10,
15
+ idleTimeoutMillis: 30000,
16
+ connectionTimeoutMillis: 10000,
17
+ });
18
+ }
19
+ /**
20
+ * Initialize database schema
21
+ */
22
+ async initialize() {
23
+ if (this.initialized)
24
+ return;
25
+ const client = await this.pool.connect();
26
+ try {
27
+ await client.query(`
28
+ CREATE TABLE IF NOT EXISTS stories (
29
+ id VARCHAR(255) PRIMARY KEY,
30
+ title VARCHAR(500) NOT NULL,
31
+ description TEXT,
32
+ content TEXT NOT NULL,
33
+ prompt TEXT,
34
+ components TEXT[],
35
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
36
+ last_accessed TIMESTAMP WITH TIME ZONE DEFAULT NOW()
37
+ );
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_stories_created_at ON stories(created_at DESC);
40
+ CREATE INDEX IF NOT EXISTS idx_stories_last_accessed ON stories(last_accessed DESC);
41
+ `);
42
+ this.initialized = true;
43
+ console.log('✅ PostgreSQL story service initialized');
44
+ }
45
+ finally {
46
+ client.release();
47
+ }
48
+ }
49
+ /**
50
+ * Store a generated story
51
+ */
52
+ async storeStory(story) {
53
+ await this.initialize();
54
+ const client = await this.pool.connect();
55
+ try {
56
+ await client.query(`INSERT INTO stories (id, title, description, content, prompt, components, created_at, last_accessed)
57
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
58
+ ON CONFLICT (id) DO UPDATE SET
59
+ title = EXCLUDED.title,
60
+ description = EXCLUDED.description,
61
+ content = EXCLUDED.content,
62
+ prompt = EXCLUDED.prompt,
63
+ components = EXCLUDED.components,
64
+ last_accessed = EXCLUDED.last_accessed`, [
65
+ story.id,
66
+ story.title,
67
+ story.description,
68
+ story.content,
69
+ story.prompt || null,
70
+ story.components || [],
71
+ story.createdAt || new Date(),
72
+ new Date()
73
+ ]);
74
+ console.log(`✅ Stored story in PostgreSQL: ${story.id}`);
75
+ }
76
+ finally {
77
+ client.release();
78
+ }
79
+ }
80
+ /**
81
+ * Retrieve a story by ID
82
+ */
83
+ async getStory(id) {
84
+ await this.initialize();
85
+ const client = await this.pool.connect();
86
+ try {
87
+ // Update last_accessed and return the story
88
+ const result = await client.query(`UPDATE stories SET last_accessed = NOW()
89
+ WHERE id = $1
90
+ RETURNING id, title, description, content, prompt, components, created_at, last_accessed`, [id]);
91
+ if (result.rows.length === 0) {
92
+ return null;
93
+ }
94
+ const row = result.rows[0];
95
+ return {
96
+ id: row.id,
97
+ title: row.title,
98
+ description: row.description,
99
+ content: row.content,
100
+ prompt: row.prompt,
101
+ components: row.components || [],
102
+ createdAt: new Date(row.created_at),
103
+ lastAccessed: new Date(row.last_accessed)
104
+ };
105
+ }
106
+ finally {
107
+ client.release();
108
+ }
109
+ }
110
+ /**
111
+ * Get all stored stories
112
+ */
113
+ async getAllStories() {
114
+ await this.initialize();
115
+ const client = await this.pool.connect();
116
+ try {
117
+ const result = await client.query(`SELECT id, title, description, content, prompt, components, created_at, last_accessed
118
+ FROM stories
119
+ ORDER BY created_at DESC`);
120
+ return result.rows.map(row => ({
121
+ id: row.id,
122
+ title: row.title,
123
+ description: row.description,
124
+ content: row.content,
125
+ prompt: row.prompt,
126
+ components: row.components || [],
127
+ createdAt: new Date(row.created_at),
128
+ lastAccessed: new Date(row.last_accessed)
129
+ }));
130
+ }
131
+ finally {
132
+ client.release();
133
+ }
134
+ }
135
+ /**
136
+ * Delete a story by ID
137
+ */
138
+ async deleteStory(id) {
139
+ await this.initialize();
140
+ const client = await this.pool.connect();
141
+ try {
142
+ const result = await client.query(`DELETE FROM stories WHERE id = $1 RETURNING id`, [id]);
143
+ const deleted = result.rowCount !== null && result.rowCount > 0;
144
+ if (deleted) {
145
+ console.log(`✅ Deleted story from PostgreSQL: ${id}`);
146
+ }
147
+ return deleted;
148
+ }
149
+ finally {
150
+ client.release();
151
+ }
152
+ }
153
+ /**
154
+ * Clear all stories
155
+ */
156
+ async clearAllStories() {
157
+ await this.initialize();
158
+ const client = await this.pool.connect();
159
+ try {
160
+ await client.query('TRUNCATE TABLE stories');
161
+ console.log('✅ Cleared all stories from PostgreSQL');
162
+ }
163
+ finally {
164
+ client.release();
165
+ }
166
+ }
167
+ /**
168
+ * Get story content for Storybook integration
169
+ */
170
+ async getStoryContent(id) {
171
+ const story = await this.getStory(id);
172
+ return story ? story.content : null;
173
+ }
174
+ /**
175
+ * Get story metadata for listing
176
+ */
177
+ async getStoryMetadata() {
178
+ await this.initialize();
179
+ const client = await this.pool.connect();
180
+ try {
181
+ const result = await client.query(`SELECT id, title, description, content, created_at, last_accessed
182
+ FROM stories
183
+ ORDER BY created_at DESC`);
184
+ return result.rows.map(row => ({
185
+ id: row.id,
186
+ title: row.title,
187
+ description: row.description,
188
+ createdAt: new Date(row.created_at),
189
+ lastAccessed: new Date(row.last_accessed),
190
+ componentCount: this.countComponents(row.content)
191
+ }));
192
+ }
193
+ finally {
194
+ client.release();
195
+ }
196
+ }
197
+ /**
198
+ * Get storage usage statistics
199
+ */
200
+ async getStorageStats() {
201
+ await this.initialize();
202
+ const client = await this.pool.connect();
203
+ try {
204
+ const result = await client.query(`
205
+ SELECT
206
+ COUNT(*)::int as story_count,
207
+ COALESCE(SUM(LENGTH(content)), 0)::bigint as total_size,
208
+ COALESCE(AVG(LENGTH(content)), 0)::int as avg_size,
209
+ MIN(created_at) as oldest,
210
+ MAX(created_at) as newest
211
+ FROM stories
212
+ `);
213
+ const row = result.rows[0];
214
+ return {
215
+ storyCount: row.story_count,
216
+ totalSizeBytes: parseInt(row.total_size) || 0,
217
+ averageSizeBytes: row.avg_size || 0,
218
+ oldestStory: row.oldest ? new Date(row.oldest) : null,
219
+ newestStory: row.newest ? new Date(row.newest) : null
220
+ };
221
+ }
222
+ finally {
223
+ client.release();
224
+ }
225
+ }
226
+ /**
227
+ * Count unique components in story content
228
+ */
229
+ countComponents(content) {
230
+ const componentMatches = content.match(/<[A-Z][A-Za-z0-9]*\s/g);
231
+ return componentMatches ? new Set(componentMatches).size : 0;
232
+ }
233
+ /**
234
+ * Close the connection pool
235
+ */
236
+ async close() {
237
+ await this.pool.end();
238
+ console.log('PostgreSQL connection pool closed');
239
+ }
240
+ }
@@ -0,0 +1,22 @@
1
+ import type { IStoryService } from './storyServiceInterface.js';
2
+ import { StoryUIConfig } from '../story-ui.config.js';
3
+ /**
4
+ * Get or create the story service based on environment configuration
5
+ *
6
+ * - If DATABASE_URL is set, uses PostgreSQL for persistent storage
7
+ * - Otherwise, falls back to in-memory storage
8
+ */
9
+ export declare function getStoryService(config: StoryUIConfig): Promise<IStoryService>;
10
+ /**
11
+ * Check if PostgreSQL storage is configured
12
+ */
13
+ export declare function isPostgresConfigured(): boolean;
14
+ /**
15
+ * Get storage type description
16
+ */
17
+ export declare function getStorageType(): 'postgresql' | 'memory';
18
+ /**
19
+ * Reset the global service (for testing)
20
+ */
21
+ export declare function resetStoryService(): Promise<void>;
22
+ //# sourceMappingURL=storyServiceFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyServiceFactory.d.ts","sourceRoot":"","sources":["../../story-generator/storyServiceFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAA+C,MAAM,4BAA4B,CAAC;AAG7G,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAkEtD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAmBnF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,YAAY,GAAG,QAAQ,CAExD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKvD"}
@@ -0,0 +1,97 @@
1
+ import { getInMemoryStoryService } from './inMemoryStoryService.js';
2
+ import { PostgresStoryService } from './postgresStoryService.js';
3
+ /**
4
+ * Async wrapper for InMemoryStoryService
5
+ * Makes the synchronous in-memory service conform to the async IStoryService interface
6
+ */
7
+ class AsyncInMemoryStoryService {
8
+ constructor(config) {
9
+ this.innerService = getInMemoryStoryService(config);
10
+ }
11
+ async initialize() {
12
+ // No-op for in-memory
13
+ }
14
+ async storeStory(story) {
15
+ this.innerService.storeStory(story);
16
+ }
17
+ async getStory(id) {
18
+ return this.innerService.getStory(id);
19
+ }
20
+ async getAllStories() {
21
+ return this.innerService.getAllStories();
22
+ }
23
+ async deleteStory(id) {
24
+ return this.innerService.deleteStory(id);
25
+ }
26
+ async clearAllStories() {
27
+ this.innerService.clearAllStories();
28
+ }
29
+ async getStoryContent(id) {
30
+ return this.innerService.getStoryContent(id);
31
+ }
32
+ async getStoryMetadata() {
33
+ return this.innerService.getStoryMetadata();
34
+ }
35
+ async getStorageStats() {
36
+ const stats = this.innerService.getMemoryStats();
37
+ return {
38
+ storyCount: stats.storyCount,
39
+ totalSizeBytes: stats.totalSizeBytes,
40
+ averageSizeBytes: stats.averageSizeBytes,
41
+ oldestStory: stats.oldestStory,
42
+ newestStory: stats.newestStory
43
+ };
44
+ }
45
+ async close() {
46
+ // No-op for in-memory
47
+ }
48
+ }
49
+ /**
50
+ * Global story service instance
51
+ */
52
+ let globalStoryService = null;
53
+ /**
54
+ * Get or create the story service based on environment configuration
55
+ *
56
+ * - If DATABASE_URL is set, uses PostgreSQL for persistent storage
57
+ * - Otherwise, falls back to in-memory storage
58
+ */
59
+ export async function getStoryService(config) {
60
+ if (globalStoryService) {
61
+ return globalStoryService;
62
+ }
63
+ const databaseUrl = process.env.DATABASE_URL;
64
+ if (databaseUrl) {
65
+ console.log('🗄️ Using PostgreSQL for story persistence');
66
+ const pgService = new PostgresStoryService(databaseUrl);
67
+ await pgService.initialize();
68
+ globalStoryService = pgService;
69
+ }
70
+ else {
71
+ console.log('💾 Using in-memory storage (no DATABASE_URL configured)');
72
+ globalStoryService = new AsyncInMemoryStoryService(config);
73
+ await globalStoryService.initialize();
74
+ }
75
+ return globalStoryService;
76
+ }
77
+ /**
78
+ * Check if PostgreSQL storage is configured
79
+ */
80
+ export function isPostgresConfigured() {
81
+ return !!process.env.DATABASE_URL;
82
+ }
83
+ /**
84
+ * Get storage type description
85
+ */
86
+ export function getStorageType() {
87
+ return process.env.DATABASE_URL ? 'postgresql' : 'memory';
88
+ }
89
+ /**
90
+ * Reset the global service (for testing)
91
+ */
92
+ export async function resetStoryService() {
93
+ if (globalStoryService) {
94
+ await globalStoryService.close();
95
+ globalStoryService = null;
96
+ }
97
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Story Service Interface
3
+ * Common interface for both in-memory and PostgreSQL story storage
4
+ */
5
+ /**
6
+ * Generated story interface
7
+ */
8
+ export interface GeneratedStory {
9
+ id: string;
10
+ title: string;
11
+ description: string;
12
+ content: string;
13
+ createdAt: Date;
14
+ lastAccessed: Date;
15
+ prompt?: string;
16
+ components?: string[];
17
+ }
18
+ /**
19
+ * Story metadata for listing
20
+ */
21
+ export interface StoryMetadata {
22
+ id: string;
23
+ title: string;
24
+ description: string;
25
+ createdAt: Date;
26
+ lastAccessed: Date;
27
+ componentCount: number;
28
+ }
29
+ /**
30
+ * Memory/storage usage statistics
31
+ */
32
+ export interface StorageStats {
33
+ storyCount: number;
34
+ totalSizeBytes: number;
35
+ averageSizeBytes: number;
36
+ oldestStory: Date | null;
37
+ newestStory: Date | null;
38
+ }
39
+ /**
40
+ * Story Service Interface
41
+ * All methods are async to support both in-memory and database backends
42
+ */
43
+ export interface IStoryService {
44
+ /**
45
+ * Initialize the service (create tables, etc.)
46
+ */
47
+ initialize(): Promise<void>;
48
+ /**
49
+ * Store a generated story
50
+ */
51
+ storeStory(story: GeneratedStory): Promise<void>;
52
+ /**
53
+ * Retrieve a story by ID
54
+ */
55
+ getStory(id: string): Promise<GeneratedStory | null>;
56
+ /**
57
+ * Get all stored stories
58
+ */
59
+ getAllStories(): Promise<GeneratedStory[]>;
60
+ /**
61
+ * Delete a story by ID
62
+ */
63
+ deleteStory(id: string): Promise<boolean>;
64
+ /**
65
+ * Clear all stories
66
+ */
67
+ clearAllStories(): Promise<void>;
68
+ /**
69
+ * Get story content for Storybook integration
70
+ */
71
+ getStoryContent(id: string): Promise<string | null>;
72
+ /**
73
+ * Get story metadata for listing
74
+ */
75
+ getStoryMetadata(): Promise<StoryMetadata[]>;
76
+ /**
77
+ * Get storage usage statistics
78
+ */
79
+ getStorageStats(): Promise<StorageStats>;
80
+ /**
81
+ * Close any connections (for cleanup)
82
+ */
83
+ close(): Promise<void>;
84
+ }
85
+ //# sourceMappingURL=storyServiceInterface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyServiceInterface.d.ts","sourceRoot":"","sources":["../../story-generator/storyServiceInterface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAErD;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAE3C;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1C;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEpD;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAE7C;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Story Service Interface
3
+ * Common interface for both in-memory and PostgreSQL story storage
4
+ */
5
+ export {};
@@ -1,3 +1,8 @@
1
+ declare global {
2
+ interface Window {
3
+ __STORY_UI_GENERATED_CODE__?: Record<string, string>;
4
+ }
5
+ }
1
6
  declare function StoryUIPanel(): import("react/jsx-runtime").JSX.Element;
2
7
  export default StoryUIPanel;
3
8
  export { StoryUIPanel };
@@ -1 +1 @@
1
- {"version":3,"file":"StoryUIPanel.d.ts","sourceRoot":"","sources":["../../../templates/StoryUI/StoryUIPanel.tsx"],"names":[],"mappings":"AA85CA,iBAAS,YAAY,4CA8sCpB;AAED,eAAe,YAAY,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"StoryUIPanel.d.ts","sourceRoot":"","sources":["../../../templates/StoryUI/StoryUIPanel.tsx"],"names":[],"mappings":"AAsSA,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"}
@@ -121,12 +121,27 @@ const titleToStoryPath = (title) => {
121
121
  const kebabTitle = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
122
122
  return `generated-${kebabTitle}--default`;
123
123
  };
124
+ // Helper to store generated code for the Source Code panel to display
125
+ const storeGeneratedCode = (title, code) => {
126
+ const storyPath = titleToStoryPath(title);
127
+ const topWindow = window.top || window;
128
+ // Store code in the top window so it's accessible from manager frame
129
+ if (!topWindow.__STORY_UI_GENERATED_CODE__) {
130
+ topWindow.__STORY_UI_GENERATED_CODE__ = {};
131
+ }
132
+ topWindow.__STORY_UI_GENERATED_CODE__[storyPath] = code;
133
+ console.log(`[Story UI] Stored code for story "${storyPath}" in window cache`);
134
+ };
124
135
  // Helper to navigate to a newly created story after generation completes
125
136
  // In dev mode with HMR, this prevents the "Couldn't find story after HMR" error
126
137
  // In all modes, this provides a better UX by auto-navigating to the new story
127
- const navigateToNewStory = (title, delayMs = 4000) => {
138
+ const navigateToNewStory = (title, code, delayMs = 1500) => {
128
139
  const storyPath = titleToStoryPath(title);
129
140
  console.log(`[Story UI] Will navigate to story "${storyPath}" in ${delayMs}ms...`);
141
+ // Store the code for the Source Code panel if provided
142
+ if (code) {
143
+ storeGeneratedCode(title, code);
144
+ }
130
145
  setTimeout(() => {
131
146
  // Navigate the TOP window (parent Storybook UI), not the iframe
132
147
  // The Story UI panel runs inside an iframe, so we need window.top to escape it
@@ -1438,7 +1453,7 @@ function StoryUIPanel() {
1438
1453
  // Auto-navigate to the newly created story after HMR processes the file
1439
1454
  // This prevents the "Couldn't find story after HMR" error by refreshing
1440
1455
  // after the file system has been updated and HMR has processed the change
1441
- navigateToNewStory(chatTitle);
1456
+ navigateToNewStory(chatTitle, completion.code);
1442
1457
  }
1443
1458
  }, [activeChatId, activeTitle, conversation.length]);
1444
1459
  const handleSend = async (e) => {
@@ -1631,7 +1646,7 @@ function StoryUIPanel() {
1631
1646
  saveChats(chats);
1632
1647
  setRecentChats(chats);
1633
1648
  // Auto-navigate to the newly created story
1634
- navigateToNewStory(chatTitle);
1649
+ navigateToNewStory(chatTitle, data.code);
1635
1650
  }
1636
1651
  }
1637
1652
  catch (fallbackErr) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpitre/story-ui",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "AI-powered Storybook story generator with dynamic component discovery",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,9 +36,7 @@
36
36
  "release:dry-run": "semantic-release --dry-run",
37
37
  "commit": "cz",
38
38
  "prepare": "husky",
39
- "story-ui": "story-ui start --port 4001",
40
- "deploy:edge": "./scripts/deploy-edge.sh",
41
- "deploy:edge:dry-run": "./scripts/deploy-edge.sh --dry-run"
39
+ "story-ui": "story-ui start --port 4001"
42
40
  },
43
41
  "keywords": [
44
42
  "storybook",
@@ -78,6 +76,7 @@
78
76
  "@emotion/styled": "^11.14.1",
79
77
  "@modelcontextprotocol/sdk": "^0.5.0",
80
78
  "@mui/material": "^7.2.0",
79
+ "@types/pg": "^8.15.6",
81
80
  "chalk": "^5.3.0",
82
81
  "commander": "^11.0.0",
83
82
  "cors": "^2.8.5",
@@ -86,6 +85,7 @@
86
85
  "glob": "^11.0.3",
87
86
  "inquirer": "^9.2.0",
88
87
  "node-fetch": "^2.6.7",
88
+ "pg": "^8.16.3",
89
89
  "typescript": "^5.8.3",
90
90
  "zod": "^3.22.4"
91
91
  },
@@ -105,11 +105,11 @@
105
105
  "@types/node": "^20.4.2",
106
106
  "@types/node-fetch": "^2.6.12",
107
107
  "commitizen": "^4.3.1",
108
+ "concurrently": "^8.2.0",
108
109
  "cz-conventional-changelog": "^3.3.0",
109
110
  "husky": "^9.1.7",
110
111
  "semantic-release": "^24.2.0",
111
- "ts-node": "^10.9.2",
112
- "concurrently": "^8.2.0"
112
+ "ts-node": "^10.9.2"
113
113
  },
114
114
  "peerDependencies": {
115
115
  "@storybook/react": ">=6.0.0",
@@ -291,13 +291,38 @@ const titleToStoryPath = (title: string): string => {
291
291
  return `generated-${kebabTitle}--default`;
292
292
  };
293
293
 
294
+ // Extend window to include our code cache for the Source Code panel
295
+ declare global {
296
+ interface Window {
297
+ __STORY_UI_GENERATED_CODE__?: Record<string, string>;
298
+ }
299
+ }
300
+
301
+ // Helper to store generated code for the Source Code panel to display
302
+ const storeGeneratedCode = (title: string, code: string) => {
303
+ const storyPath = titleToStoryPath(title);
304
+ const topWindow = window.top || window;
305
+
306
+ // Store code in the top window so it's accessible from manager frame
307
+ if (!topWindow.__STORY_UI_GENERATED_CODE__) {
308
+ topWindow.__STORY_UI_GENERATED_CODE__ = {};
309
+ }
310
+ topWindow.__STORY_UI_GENERATED_CODE__[storyPath] = code;
311
+ console.log(`[Story UI] Stored code for story "${storyPath}" in window cache`);
312
+ };
313
+
294
314
  // Helper to navigate to a newly created story after generation completes
295
315
  // In dev mode with HMR, this prevents the "Couldn't find story after HMR" error
296
316
  // In all modes, this provides a better UX by auto-navigating to the new story
297
- const navigateToNewStory = (title: string, delayMs: number = 4000) => {
317
+ const navigateToNewStory = (title: string, code?: string, delayMs: number = 1500) => {
298
318
  const storyPath = titleToStoryPath(title);
299
319
  console.log(`[Story UI] Will navigate to story "${storyPath}" in ${delayMs}ms...`);
300
320
 
321
+ // Store the code for the Source Code panel if provided
322
+ if (code) {
323
+ storeGeneratedCode(title, code);
324
+ }
325
+
301
326
  setTimeout(() => {
302
327
  // Navigate the TOP window (parent Storybook UI), not the iframe
303
328
  // The Story UI panel runs inside an iframe, so we need window.top to escape it
@@ -1927,7 +1952,7 @@ function StoryUIPanel() {
1927
1952
  // Auto-navigate to the newly created story after HMR processes the file
1928
1953
  // This prevents the "Couldn't find story after HMR" error by refreshing
1929
1954
  // after the file system has been updated and HMR has processed the change
1930
- navigateToNewStory(chatTitle);
1955
+ navigateToNewStory(chatTitle, completion.code);
1931
1956
  }
1932
1957
  }, [activeChatId, activeTitle, conversation.length]);
1933
1958
 
@@ -2137,7 +2162,7 @@ function StoryUIPanel() {
2137
2162
  setRecentChats(chats);
2138
2163
 
2139
2164
  // Auto-navigate to the newly created story
2140
- navigateToNewStory(chatTitle);
2165
+ navigateToNewStory(chatTitle, data.code);
2141
2166
  }
2142
2167
  } catch (fallbackErr: unknown) {
2143
2168
  const errorMessage = fallbackErr instanceof Error ? fallbackErr.message : 'Unknown error';