@tpitre/story-ui 2.6.1 → 2.7.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.
Files changed (295) hide show
  1. package/README.md +36 -37
  2. package/dist/cli/deploy.d.ts +4 -3
  3. package/dist/cli/deploy.d.ts.map +1 -1
  4. package/dist/cli/deploy.js +542 -46
  5. package/dist/cli/index.js +17 -14
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/cli/setup.d.ts.map +1 -1
  8. package/dist/cli/setup.js +4 -110
  9. package/dist/cli/setup.js.map +1 -0
  10. package/dist/cloudflare-edge/src/mcp-session.js +462 -0
  11. package/dist/cloudflare-edge/src/types.js +4 -0
  12. package/dist/cloudflare-edge/src/worker.js +106 -0
  13. package/dist/cloudflare-pages/vite.config.js +14 -0
  14. package/dist/index.d.ts +13 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +12 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/mcp-server/index.js.map +1 -0
  19. package/dist/mcp-server/mcp-stdio-server.js.map +1 -0
  20. package/dist/mcp-server/routes/claude.js.map +1 -0
  21. package/dist/mcp-server/routes/components.js.map +1 -0
  22. package/dist/mcp-server/routes/generateStory.js.map +1 -0
  23. package/dist/mcp-server/routes/hybridStories.js.map +1 -0
  24. package/dist/mcp-server/routes/memoryStories.js.map +1 -0
  25. package/dist/mcp-server/routes/storySync.js.map +1 -0
  26. package/dist/mcp-server/routes/updateStory.js +246 -0
  27. package/dist/mcp-server/sessionManager.js.map +1 -0
  28. package/dist/playground/components/AIAssistant/AIAssistant.d.ts +6 -0
  29. package/dist/playground/components/AIAssistant/AIAssistant.d.ts.map +1 -0
  30. package/dist/playground/components/AIAssistant/AIAssistant.js +109 -0
  31. package/dist/playground/components/AIAssistant/AIAssistant.js.map +1 -0
  32. package/dist/playground/components/AIAssistant/AIAssistant.module.css +166 -0
  33. package/dist/playground/components/Canvas/Canvas.d.ts +9 -0
  34. package/dist/playground/components/Canvas/Canvas.d.ts.map +1 -0
  35. package/dist/playground/components/Canvas/Canvas.js +58 -0
  36. package/dist/playground/components/Canvas/Canvas.js.map +1 -0
  37. package/dist/playground/components/Canvas/Canvas.module.css +189 -0
  38. package/dist/playground/components/Canvas/CanvasWithDnd.d.ts +9 -0
  39. package/dist/playground/components/Canvas/CanvasWithDnd.d.ts.map +1 -0
  40. package/dist/playground/components/Canvas/CanvasWithDnd.js +158 -0
  41. package/dist/playground/components/Canvas/CanvasWithDnd.js.map +1 -0
  42. package/dist/playground/components/Canvas/ComponentRenderer.d.ts +15 -0
  43. package/dist/playground/components/Canvas/ComponentRenderer.d.ts.map +1 -0
  44. package/dist/playground/components/Canvas/ComponentRenderer.js +177 -0
  45. package/dist/playground/components/Canvas/ComponentRenderer.js.map +1 -0
  46. package/dist/playground/components/Canvas/DraggableComponent.d.ts +15 -0
  47. package/dist/playground/components/Canvas/DraggableComponent.d.ts.map +1 -0
  48. package/dist/playground/components/Canvas/DraggableComponent.js +49 -0
  49. package/dist/playground/components/Canvas/DraggableComponent.js.map +1 -0
  50. package/dist/playground/components/Canvas/index.d.ts +9 -0
  51. package/dist/playground/components/Canvas/index.d.ts.map +1 -0
  52. package/dist/playground/components/Canvas/index.js +5 -0
  53. package/dist/playground/components/Canvas/index.js.map +1 -0
  54. package/dist/playground/components/CodeView/CodeView.d.ts +12 -0
  55. package/dist/playground/components/CodeView/CodeView.d.ts.map +1 -0
  56. package/dist/playground/components/CodeView/CodeView.js +77 -0
  57. package/dist/playground/components/CodeView/CodeView.js.map +1 -0
  58. package/dist/playground/components/CodeView/CodeView.module.css +178 -0
  59. package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts +17 -0
  60. package/dist/playground/components/ComponentPalette/ComponentPalette.d.ts.map +1 -0
  61. package/dist/playground/components/ComponentPalette/ComponentPalette.js +138 -0
  62. package/dist/playground/components/ComponentPalette/ComponentPalette.js.map +1 -0
  63. package/dist/playground/components/ComponentPalette/ComponentPalette.module.css +217 -0
  64. package/dist/playground/components/ComponentPalette/index.d.ts +3 -0
  65. package/dist/playground/components/ComponentPalette/index.d.ts.map +1 -0
  66. package/dist/playground/components/ComponentPalette/index.js +2 -0
  67. package/dist/playground/components/ComponentPalette/index.js.map +1 -0
  68. package/dist/playground/components/DropZone/DropZone.d.ts +17 -0
  69. package/dist/playground/components/DropZone/DropZone.d.ts.map +1 -0
  70. package/dist/playground/components/DropZone/DropZone.js +73 -0
  71. package/dist/playground/components/DropZone/DropZone.js.map +1 -0
  72. package/dist/playground/components/DropZone/DropZone.module.css +86 -0
  73. package/dist/playground/components/ExportDialog/ExportDialog.d.ts +10 -0
  74. package/dist/playground/components/ExportDialog/ExportDialog.d.ts.map +1 -0
  75. package/dist/playground/components/ExportDialog/ExportDialog.js +57 -0
  76. package/dist/playground/components/ExportDialog/ExportDialog.js.map +1 -0
  77. package/dist/playground/components/ExportDialog/ExportDialog.module.css +328 -0
  78. package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts +134 -0
  79. package/dist/playground/components/LayoutHelpers/LayoutHelpers.d.ts.map +1 -0
  80. package/dist/playground/components/LayoutHelpers/LayoutHelpers.js +254 -0
  81. package/dist/playground/components/LayoutHelpers/LayoutHelpers.js.map +1 -0
  82. package/dist/playground/components/LayoutHelpers/index.d.ts +3 -0
  83. package/dist/playground/components/LayoutHelpers/index.d.ts.map +1 -0
  84. package/dist/playground/components/LayoutHelpers/index.js +2 -0
  85. package/dist/playground/components/LayoutHelpers/index.js.map +1 -0
  86. package/dist/playground/components/Playground/Playground.d.ts +10 -0
  87. package/dist/playground/components/Playground/Playground.d.ts.map +1 -0
  88. package/dist/playground/components/Playground/Playground.js +128 -0
  89. package/dist/playground/components/Playground/Playground.js.map +1 -0
  90. package/dist/playground/components/Playground/Playground.module.css +308 -0
  91. package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts +10 -0
  92. package/dist/playground/components/PropertiesPanel/PropertiesPanel.d.ts.map +1 -0
  93. package/dist/playground/components/PropertiesPanel/PropertiesPanel.js +150 -0
  94. package/dist/playground/components/PropertiesPanel/PropertiesPanel.js.map +1 -0
  95. package/dist/playground/components/PropertiesPanel/PropertiesPanel.module.css +155 -0
  96. package/dist/playground/components/PropertiesPanel/index.d.ts +3 -0
  97. package/dist/playground/components/PropertiesPanel/index.d.ts.map +1 -0
  98. package/dist/playground/components/PropertiesPanel/index.js +2 -0
  99. package/dist/playground/components/PropertiesPanel/index.js.map +1 -0
  100. package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts +12 -0
  101. package/dist/playground/components/PropertyEditors/BooleanEditor.d.ts.map +1 -0
  102. package/dist/playground/components/PropertyEditors/BooleanEditor.js +14 -0
  103. package/dist/playground/components/PropertyEditors/BooleanEditor.js.map +1 -0
  104. package/dist/playground/components/PropertyEditors/ColorEditor.d.ts +12 -0
  105. package/dist/playground/components/PropertyEditors/ColorEditor.d.ts.map +1 -0
  106. package/dist/playground/components/PropertyEditors/ColorEditor.js +62 -0
  107. package/dist/playground/components/PropertyEditors/ColorEditor.js.map +1 -0
  108. package/dist/playground/components/PropertyEditors/IconEditor.d.ts +12 -0
  109. package/dist/playground/components/PropertyEditors/IconEditor.d.ts.map +1 -0
  110. package/dist/playground/components/PropertyEditors/IconEditor.js +123 -0
  111. package/dist/playground/components/PropertyEditors/IconEditor.js.map +1 -0
  112. package/dist/playground/components/PropertyEditors/NumberEditor.d.ts +15 -0
  113. package/dist/playground/components/PropertyEditors/NumberEditor.d.ts.map +1 -0
  114. package/dist/playground/components/PropertyEditors/NumberEditor.js +46 -0
  115. package/dist/playground/components/PropertyEditors/NumberEditor.js.map +1 -0
  116. package/dist/playground/components/PropertyEditors/PropertyEditors.module.css +432 -0
  117. package/dist/playground/components/PropertyEditors/SelectEditor.d.ts +19 -0
  118. package/dist/playground/components/PropertyEditors/SelectEditor.d.ts.map +1 -0
  119. package/dist/playground/components/PropertyEditors/SelectEditor.js +17 -0
  120. package/dist/playground/components/PropertyEditors/SelectEditor.js.map +1 -0
  121. package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts +19 -0
  122. package/dist/playground/components/PropertyEditors/SpacingEditor.d.ts.map +1 -0
  123. package/dist/playground/components/PropertyEditors/SpacingEditor.js +162 -0
  124. package/dist/playground/components/PropertyEditors/SpacingEditor.js.map +1 -0
  125. package/dist/playground/components/PropertyEditors/SpacingEditor.module.css +214 -0
  126. package/dist/playground/components/PropertyEditors/TextEditor.d.ts +14 -0
  127. package/dist/playground/components/PropertyEditors/TextEditor.d.ts.map +1 -0
  128. package/dist/playground/components/PropertyEditors/TextEditor.js +38 -0
  129. package/dist/playground/components/PropertyEditors/TextEditor.js.map +1 -0
  130. package/dist/playground/components/PropertyEditors/TokenEditor.d.ts +23 -0
  131. package/dist/playground/components/PropertyEditors/TokenEditor.d.ts.map +1 -0
  132. package/dist/playground/components/PropertyEditors/TokenEditor.js +50 -0
  133. package/dist/playground/components/PropertyEditors/TokenEditor.js.map +1 -0
  134. package/dist/playground/components/PropertyEditors/index.d.ts +20 -0
  135. package/dist/playground/components/PropertyEditors/index.d.ts.map +1 -0
  136. package/dist/playground/components/PropertyEditors/index.js +12 -0
  137. package/dist/playground/components/PropertyEditors/index.js.map +1 -0
  138. package/dist/playground/components/TreeView/TreeView.d.ts +10 -0
  139. package/dist/playground/components/TreeView/TreeView.d.ts.map +1 -0
  140. package/dist/playground/components/TreeView/TreeView.js +146 -0
  141. package/dist/playground/components/TreeView/TreeView.js.map +1 -0
  142. package/dist/playground/components/TreeView/TreeView.module.css +214 -0
  143. package/dist/playground/components/TreeView/index.d.ts +3 -0
  144. package/dist/playground/components/TreeView/index.d.ts.map +1 -0
  145. package/dist/playground/components/TreeView/index.js +2 -0
  146. package/dist/playground/components/TreeView/index.js.map +1 -0
  147. package/dist/playground/config/propertyDefinitions.d.ts +73 -0
  148. package/dist/playground/config/propertyDefinitions.d.ts.map +1 -0
  149. package/dist/playground/config/propertyDefinitions.js +809 -0
  150. package/dist/playground/config/propertyDefinitions.js.map +1 -0
  151. package/dist/playground/hooks/useKeyboardShortcuts.d.ts +38 -0
  152. package/dist/playground/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  153. package/dist/playground/hooks/useKeyboardShortcuts.js +191 -0
  154. package/dist/playground/hooks/useKeyboardShortcuts.js.map +1 -0
  155. package/dist/playground/index.d.ts +21 -0
  156. package/dist/playground/index.d.ts.map +1 -0
  157. package/dist/playground/index.js +23 -0
  158. package/dist/playground/index.js.map +1 -0
  159. package/dist/playground/services/CodeGenerator.d.ts +73 -0
  160. package/dist/playground/services/CodeGenerator.d.ts.map +1 -0
  161. package/dist/playground/services/CodeGenerator.js +359 -0
  162. package/dist/playground/services/CodeGenerator.js.map +1 -0
  163. package/dist/playground/services/DragDropManager.d.ts +95 -0
  164. package/dist/playground/services/DragDropManager.d.ts.map +1 -0
  165. package/dist/playground/services/DragDropManager.js +408 -0
  166. package/dist/playground/services/DragDropManager.js.map +1 -0
  167. package/dist/playground/services/StoryParser.d.ts +73 -0
  168. package/dist/playground/services/StoryParser.d.ts.map +1 -0
  169. package/dist/playground/services/StoryParser.js +419 -0
  170. package/dist/playground/services/StoryParser.js.map +1 -0
  171. package/dist/playground/store/playgroundStore.d.ts +86 -0
  172. package/dist/playground/store/playgroundStore.d.ts.map +1 -0
  173. package/dist/playground/store/playgroundStore.js +337 -0
  174. package/dist/playground/store/playgroundStore.js.map +1 -0
  175. package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts +13 -0
  176. package/dist/playground/stories/PlaygroundDragDrop.stories.d.ts.map +1 -0
  177. package/dist/playground/stories/PlaygroundDragDrop.stories.js +227 -0
  178. package/dist/playground/stories/PlaygroundDragDrop.stories.js.map +1 -0
  179. package/dist/playground/stories/PlaygroundPhase4.stories.d.ts +13 -0
  180. package/dist/playground/stories/PlaygroundPhase4.stories.d.ts.map +1 -0
  181. package/dist/playground/stories/PlaygroundPhase4.stories.js +334 -0
  182. package/dist/playground/stories/PlaygroundPhase4.stories.js.map +1 -0
  183. package/dist/playground/stories/PlaygroundPhase5.stories.d.ts +14 -0
  184. package/dist/playground/stories/PlaygroundPhase5.stories.d.ts.map +1 -0
  185. package/dist/playground/stories/PlaygroundPhase5.stories.js +512 -0
  186. package/dist/playground/stories/PlaygroundPhase5.stories.js.map +1 -0
  187. package/dist/playground/stories/PlaygroundProperties.stories.d.ts +13 -0
  188. package/dist/playground/stories/PlaygroundProperties.stories.d.ts.map +1 -0
  189. package/dist/playground/stories/PlaygroundProperties.stories.js +342 -0
  190. package/dist/playground/stories/PlaygroundProperties.stories.js.map +1 -0
  191. package/dist/playground/types/index.d.ts +251 -0
  192. package/dist/playground/types/index.d.ts.map +1 -0
  193. package/dist/playground/types/index.js +5 -0
  194. package/dist/playground/types/index.js.map +1 -0
  195. package/dist/scripts/verify-framework-adapters.js +105 -0
  196. package/dist/story-generator/componentBlacklist.js.map +1 -0
  197. package/dist/story-generator/componentDiscovery.js.map +1 -0
  198. package/dist/story-generator/configLoader.js.map +1 -0
  199. package/dist/story-generator/considerationsLoader.js.map +1 -0
  200. package/dist/story-generator/documentation-sources.js.map +1 -0
  201. package/dist/story-generator/documentationLoader.js.map +1 -0
  202. package/dist/story-generator/dynamicPackageDiscovery.js.map +1 -0
  203. package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -1
  204. package/dist/story-generator/enhancedComponentDiscovery.js +4 -6
  205. package/dist/story-generator/enhancedComponentDiscovery.js.map +1 -0
  206. package/dist/story-generator/generateStory.js.map +1 -0
  207. package/dist/story-generator/gitignoreManager.js.map +1 -0
  208. package/dist/story-generator/inMemoryStoryService.js.map +1 -0
  209. package/dist/story-generator/llm-providers/settings-manager.js +4 -4
  210. package/dist/story-generator/logger.js.map +1 -0
  211. package/dist/story-generator/postProcessStory.js.map +1 -0
  212. package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -1
  213. package/dist/story-generator/productionGitignoreManager.js +6 -0
  214. package/dist/story-generator/productionGitignoreManager.js.map +1 -0
  215. package/dist/story-generator/promptGenerator.js.map +1 -0
  216. package/dist/story-generator/providerPresets.d.ts +54 -0
  217. package/dist/story-generator/providerPresets.d.ts.map +1 -0
  218. package/dist/story-generator/providerPresets.js +214 -0
  219. package/dist/story-generator/storyHistory.js.map +1 -0
  220. package/dist/story-generator/storySync.js.map +1 -0
  221. package/dist/story-generator/storyTracker.js.map +1 -0
  222. package/dist/story-generator/storyValidator.js.map +1 -0
  223. package/dist/story-generator/test_validation.d.ts +2 -0
  224. package/dist/story-generator/test_validation.d.ts.map +1 -0
  225. package/dist/story-generator/test_validation.js +51 -0
  226. package/dist/story-generator/universalDesignSystemAdapter.js.map +1 -0
  227. package/dist/story-generator/urlRedirectService.js.map +1 -0
  228. package/dist/story-generator/validateStory.js.map +1 -0
  229. package/dist/story-ui.config.js.map +1 -0
  230. package/dist/story-ui.config.loader.d.ts +36 -0
  231. package/dist/story-ui.config.loader.d.ts.map +1 -0
  232. package/dist/story-ui.config.loader.js +205 -0
  233. package/dist/story-ui.config.loader.js.map +1 -0
  234. package/dist/temp/package/templates/StoryUI/StoryUIPanel.js +807 -0
  235. package/dist/temp/package/templates/StoryUI/StoryUIPanel.stories.js +37 -0
  236. package/dist/temp/package/templates/StoryUI/index.js +2 -0
  237. package/dist/templates/StoryUI/StoryUIPanel.js.map +1 -0
  238. package/dist/templates/StoryUI/StoryUIPanel.stories.js.map +1 -0
  239. package/dist/templates/StoryUI/index.js.map +1 -0
  240. package/dist/templates/StoryUI/manager.d.ts +14 -0
  241. package/dist/templates/StoryUI/manager.d.ts.map +1 -0
  242. package/dist/templates/production-app/src/App.d.ts +10 -0
  243. package/dist/templates/production-app/src/App.d.ts.map +1 -0
  244. package/dist/templates/production-app/src/App.js +653 -0
  245. package/dist/templates/production-app/src/LivePreviewRenderer.d.ts +24 -0
  246. package/dist/templates/production-app/src/LivePreviewRenderer.d.ts.map +1 -0
  247. package/dist/templates/production-app/src/LivePreviewRenderer.js +199 -0
  248. package/dist/templates/production-app/src/componentRegistry.d.ts +20 -0
  249. package/dist/templates/production-app/src/componentRegistry.d.ts.map +1 -0
  250. package/dist/templates/production-app/src/componentRegistry.js +316 -0
  251. package/dist/templates/production-app/src/main.d.ts +9 -0
  252. package/dist/templates/production-app/src/main.d.ts.map +1 -0
  253. package/dist/templates/production-app/src/main.js +18 -0
  254. package/dist/templates/production-app/vite.config.d.ts +3 -0
  255. package/dist/templates/production-app/vite.config.d.ts.map +1 -0
  256. package/dist/templates/production-app/vite.config.js +71 -0
  257. package/dist/test-storybooks/angular-material-storybook/src/main.js +66 -0
  258. package/dist/test-storybooks/chakra-storybook/vite.config.js +6 -0
  259. package/dist/test-storybooks/mantine-storybook/vite.config.js +93 -0
  260. package/dist/test-storybooks/web-components-shoelace/vite.config.js +9 -0
  261. package/dist/tsconfig.tsbuildinfo +1 -0
  262. package/dist/visual-builder/components/Canvas/Canvas.js +70 -0
  263. package/dist/visual-builder/components/Canvas/ComponentRenderer.js +545 -0
  264. package/dist/visual-builder/components/CodeExporter/CodeExporter.js +25 -0
  265. package/dist/visual-builder/components/CodeExporter/codeGenerator.js +99 -0
  266. package/dist/visual-builder/components/ComponentPalette/ComponentPalette.js +8 -0
  267. package/dist/visual-builder/components/ComponentPalette/ComponentPaletteItem.js +51 -0
  268. package/dist/visual-builder/components/EmbeddedVisualBuilder.js +107 -0
  269. package/dist/visual-builder/components/PropertyEditor/PropertyEditor.js +16 -0
  270. package/dist/visual-builder/components/PropertyEditor/PropertyForm.js +88 -0
  271. package/dist/visual-builder/components/PropertyEditor/SpacingControl.js +145 -0
  272. package/dist/visual-builder/components/PropertyEditor/SpacingEditor.js +32 -0
  273. package/dist/visual-builder/components/StoryManager/SaveOnlyManager.js +94 -0
  274. package/dist/visual-builder/components/StoryManager/StoryManager.js +68 -0
  275. package/dist/visual-builder/components/StoryManager/index.js +1 -0
  276. package/dist/visual-builder/components/VisualBuilder.js +256 -0
  277. package/dist/visual-builder/config/componentRegistry.js +1758 -0
  278. package/dist/visual-builder/decorators/VisualBuilderDecorator.js +184 -0
  279. package/dist/visual-builder/example-integration.js +59 -0
  280. package/dist/visual-builder/example.js +23 -0
  281. package/dist/visual-builder/hooks/useDragAndDrop.js +137 -0
  282. package/dist/visual-builder/hooks/useSelection.js +27 -0
  283. package/dist/visual-builder/index.js +7 -0
  284. package/dist/visual-builder/store/visualBuilderStore.js +305 -0
  285. package/dist/visual-builder/types/index.js +1 -0
  286. package/dist/visual-builder/utils/__tests__/storyFileUpdater.test.js +145 -0
  287. package/dist/visual-builder/utils/aiParser.js +336 -0
  288. package/dist/visual-builder/utils/componentTreeUtils.js +111 -0
  289. package/dist/visual-builder/utils/parserValidation.js +122 -0
  290. package/dist/visual-builder/utils/storyFileManager.js +73 -0
  291. package/dist/visual-builder/utils/storyFileUpdater.js +326 -0
  292. package/dist/visual-builder/utils/storyNameExtraction.test.js +211 -0
  293. package/dist/visual-builder/utils/storyPersistence.js +180 -0
  294. package/dist/visual-builder/utils/storyToBuilder.js +813 -0
  295. package/package.json +1 -1
@@ -0,0 +1,336 @@
1
+ import { getComponentConfig } from '../config/componentRegistry';
2
+ /**
3
+ * Parse AI-generated JSX code into Visual Builder component definitions
4
+ */
5
+ export const parseAIGeneratedCode = (code) => {
6
+ const result = {
7
+ components: [],
8
+ errors: [],
9
+ warnings: []
10
+ };
11
+ try {
12
+ // Clean and extract the component JSX
13
+ const jsxContent = extractJSXContent(code);
14
+ if (!jsxContent) {
15
+ result.errors.push('No JSX content found in the provided code');
16
+ return result;
17
+ }
18
+ // Parse the JSX into component definitions
19
+ const parsedComponents = parseJSXToComponents(jsxContent);
20
+ result.components = parsedComponents;
21
+ // Validate components against registry
22
+ validateComponents(result.components, result);
23
+ }
24
+ catch (error) {
25
+ result.errors.push(`Failed to parse code: ${error instanceof Error ? error.message : 'Unknown error'}`);
26
+ }
27
+ return result;
28
+ };
29
+ /**
30
+ * Extract JSX content from the AI-generated code
31
+ */
32
+ const extractJSXContent = (code) => {
33
+ // Remove imports and exports to focus on JSX
34
+ const lines = code.split('\n');
35
+ const jsxLines = [];
36
+ let inJSX = false;
37
+ let bracketCount = 0;
38
+ let parenthesesCount = 0;
39
+ for (const line of lines) {
40
+ const trimmed = line.trim();
41
+ // Skip import statements
42
+ if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) {
43
+ continue;
44
+ }
45
+ // Skip function declaration lines
46
+ if (trimmed.includes('= () => {') || trimmed.includes('function ') || trimmed === '{' || trimmed === '}') {
47
+ continue;
48
+ }
49
+ // Skip return statement
50
+ if (trimmed.startsWith('return (') || trimmed.startsWith('return')) {
51
+ inJSX = true;
52
+ if (trimmed.includes('(')) {
53
+ parenthesesCount += (trimmed.match(/\(/g) || []).length;
54
+ parenthesesCount -= (trimmed.match(/\)/g) || []).length;
55
+ }
56
+ continue;
57
+ }
58
+ if (inJSX) {
59
+ // Track brackets and parentheses
60
+ bracketCount += (line.match(/</g) || []).length;
61
+ bracketCount -= (line.match(/>/g) || []).length;
62
+ parenthesesCount += (line.match(/\(/g) || []).length;
63
+ parenthesesCount -= (line.match(/\)/g) || []).length;
64
+ // Add line if it contains actual JSX content
65
+ if (trimmed && !trimmed.startsWith('//') && trimmed !== ';') {
66
+ jsxLines.push(line);
67
+ }
68
+ // Stop when we've closed all parentheses (end of return statement)
69
+ if (parenthesesCount <= 0 && bracketCount <= 0) {
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ return jsxLines.length > 0 ? jsxLines.join('\n') : null;
75
+ };
76
+ /**
77
+ * Parse JSX string into component definitions
78
+ */
79
+ const parseJSXToComponents = (jsx) => {
80
+ const components = [];
81
+ // Simple regex-based parsing for common patterns
82
+ // This is a basic implementation - in production, you'd want a proper JSX parser
83
+ // Remove extra whitespace and normalize
84
+ const cleanJSX = jsx.replace(/\s+/g, ' ').trim();
85
+ // Parse top-level components
86
+ const topLevelComponents = extractTopLevelComponents(cleanJSX);
87
+ topLevelComponents.forEach((componentString, index) => {
88
+ const parsed = parseComponentString(componentString, index);
89
+ if (parsed) {
90
+ components.push(parsed);
91
+ }
92
+ });
93
+ return components;
94
+ };
95
+ /**
96
+ * Extract top-level components from JSX string
97
+ */
98
+ const extractTopLevelComponents = (jsx) => {
99
+ const components = [];
100
+ let currentComponent = '';
101
+ let depth = 0;
102
+ let i = 0;
103
+ while (i < jsx.length) {
104
+ const char = jsx[i];
105
+ if (char === '<') {
106
+ const nextChar = jsx[i + 1];
107
+ if (nextChar === '/') {
108
+ // Closing tag
109
+ depth--;
110
+ currentComponent += char;
111
+ }
112
+ else if (nextChar === '!') {
113
+ // Comment or doctype, skip
114
+ const endComment = jsx.indexOf('>', i);
115
+ i = endComment;
116
+ continue;
117
+ }
118
+ else {
119
+ // Opening tag
120
+ depth++;
121
+ currentComponent += char;
122
+ }
123
+ }
124
+ else {
125
+ currentComponent += char;
126
+ }
127
+ // If we've closed all tags and have content, we have a complete component
128
+ if (depth === 0 && currentComponent.trim()) {
129
+ const trimmed = currentComponent.trim();
130
+ if (trimmed.startsWith('<') && (trimmed.endsWith('>') || trimmed.endsWith('/>'))) {
131
+ components.push(trimmed);
132
+ currentComponent = '';
133
+ }
134
+ }
135
+ i++;
136
+ }
137
+ // Add any remaining component
138
+ if (currentComponent.trim()) {
139
+ components.push(currentComponent.trim());
140
+ }
141
+ return components;
142
+ };
143
+ /**
144
+ * Parse individual component string into ComponentDefinition
145
+ */
146
+ const parseComponentString = (componentString, index) => {
147
+ // Extract component type
148
+ const typeMatch = componentString.match(/<(\w+)/);
149
+ if (!typeMatch)
150
+ return null;
151
+ const type = typeMatch[1];
152
+ const config = getComponentConfig(type);
153
+ if (!config) {
154
+ // Return a basic definition even for unknown components
155
+ return {
156
+ id: `${type.toLowerCase()}-${Date.now()}-${index}`,
157
+ type,
158
+ displayName: type,
159
+ category: 'Unknown',
160
+ props: {},
161
+ children: []
162
+ };
163
+ }
164
+ // Extract props
165
+ const props = extractProps(componentString, config.defaultProps);
166
+ // Extract children
167
+ const children = extractChildren(componentString, index);
168
+ return {
169
+ id: `${type.toLowerCase()}-${Date.now()}-${index}`,
170
+ type,
171
+ displayName: config.displayName,
172
+ category: config.category,
173
+ props,
174
+ children
175
+ };
176
+ };
177
+ /**
178
+ * Extract props from component string
179
+ */
180
+ const extractProps = (componentString, defaultProps) => {
181
+ const props = { ...defaultProps };
182
+ // Extract attributes using regex
183
+ const attrRegex = /(\w+)=(?:"([^"]*)"|{([^}]*)}|(\w+))/g;
184
+ let match;
185
+ while ((match = attrRegex.exec(componentString)) !== null) {
186
+ const [, propName, stringValue, jsValue, boolValue] = match;
187
+ if (stringValue !== undefined) {
188
+ props[propName] = stringValue;
189
+ }
190
+ else if (jsValue !== undefined) {
191
+ // Try to parse JavaScript value
192
+ try {
193
+ props[propName] = JSON.parse(jsValue);
194
+ }
195
+ catch {
196
+ // If parsing fails, treat as string
197
+ props[propName] = jsValue;
198
+ }
199
+ }
200
+ else if (boolValue !== undefined) {
201
+ props[propName] = true;
202
+ }
203
+ }
204
+ // Extract text content for components that support it
205
+ const textContentMatch = componentString.match(/>([^<]+)</);
206
+ if (textContentMatch && textContentMatch[1].trim()) {
207
+ const textContent = textContentMatch[1].trim();
208
+ if (!textContent.startsWith('<')) {
209
+ props.children = textContent;
210
+ }
211
+ }
212
+ return props;
213
+ };
214
+ /**
215
+ * Extract children components
216
+ */
217
+ const extractChildren = (componentString, parentIndex) => {
218
+ // Check if component is self-closing
219
+ if (componentString.endsWith('/>')) {
220
+ return [];
221
+ }
222
+ // Extract content between opening and closing tags
223
+ const contentMatch = componentString.match(/>(.+)</s);
224
+ if (!contentMatch)
225
+ return [];
226
+ const content = contentMatch[1];
227
+ // If content doesn't contain tags, it's just text
228
+ if (!content.includes('<')) {
229
+ return [];
230
+ }
231
+ // Recursively parse child components
232
+ const childComponents = extractTopLevelComponents(content);
233
+ const children = [];
234
+ childComponents.forEach((childString, index) => {
235
+ const parsed = parseComponentString(childString, parentIndex * 100 + index);
236
+ if (parsed) {
237
+ children.push(parsed);
238
+ }
239
+ });
240
+ return children;
241
+ };
242
+ /**
243
+ * Validate components against the registry and collect warnings
244
+ */
245
+ const validateComponents = (components, result) => {
246
+ const validateComponent = (component) => {
247
+ const config = getComponentConfig(component.type);
248
+ if (!config) {
249
+ result.warnings.push(`Component "${component.type}" is not in the Mantine component registry`);
250
+ return;
251
+ }
252
+ // Validate props
253
+ Object.keys(component.props).forEach(propName => {
254
+ const propConfig = config.properties.find(p => p.name === propName);
255
+ if (!propConfig) {
256
+ result.warnings.push(`Property "${propName}" is not defined for ${component.type}`);
257
+ }
258
+ });
259
+ // Recursively validate children
260
+ if (component.children) {
261
+ component.children.forEach(validateComponent);
262
+ }
263
+ };
264
+ components.forEach(validateComponent);
265
+ };
266
+ /**
267
+ * Create a simplified component structure for basic layouts
268
+ */
269
+ export const createBasicLayout = (description) => {
270
+ // This can be enhanced to create basic layouts based on keywords
271
+ const lowerDesc = description.toLowerCase();
272
+ if (lowerDesc.includes('button')) {
273
+ return [{
274
+ id: `button-${Date.now()}`,
275
+ type: 'Button',
276
+ displayName: 'Button',
277
+ category: 'Inputs',
278
+ props: {
279
+ children: 'Click me',
280
+ variant: 'filled',
281
+ size: 'sm'
282
+ }
283
+ }];
284
+ }
285
+ if (lowerDesc.includes('form')) {
286
+ return [
287
+ {
288
+ id: `stack-${Date.now()}`,
289
+ type: 'Stack',
290
+ displayName: 'Stack',
291
+ category: 'Layout',
292
+ props: { gap: 'md' },
293
+ children: [
294
+ {
295
+ id: `textinput-${Date.now()}`,
296
+ type: 'TextInput',
297
+ displayName: 'Text Input',
298
+ category: 'Inputs',
299
+ props: {
300
+ placeholder: 'Enter text...',
301
+ label: 'Input Label'
302
+ }
303
+ },
304
+ {
305
+ id: `button-${Date.now()}`,
306
+ type: 'Button',
307
+ displayName: 'Button',
308
+ category: 'Inputs',
309
+ props: {
310
+ children: 'Submit',
311
+ variant: 'filled'
312
+ }
313
+ }
314
+ ]
315
+ }
316
+ ];
317
+ }
318
+ // Default: simple container with text
319
+ return [{
320
+ id: `container-${Date.now()}`,
321
+ type: 'Container',
322
+ displayName: 'Container',
323
+ category: 'Layout',
324
+ props: { size: 'md' },
325
+ children: [{
326
+ id: `text-${Date.now()}`,
327
+ type: 'Text',
328
+ displayName: 'Text',
329
+ category: 'Typography',
330
+ props: {
331
+ children: 'Generated component',
332
+ size: 'md'
333
+ }
334
+ }]
335
+ }];
336
+ };
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Find a component and its parent in the component tree
3
+ */
4
+ export const findComponentWithParent = (components, targetId, parent = null) => {
5
+ for (let i = 0; i < components.length; i++) {
6
+ const component = components[i];
7
+ if (component.id === targetId) {
8
+ return {
9
+ component,
10
+ parent,
11
+ index: i
12
+ };
13
+ }
14
+ if (component.children && component.children.length > 0) {
15
+ const result = findComponentWithParent(component.children, targetId, component);
16
+ if (result) {
17
+ return result;
18
+ }
19
+ }
20
+ }
21
+ return null;
22
+ };
23
+ /**
24
+ * Remove a component from the tree and return the updated tree and removed component
25
+ */
26
+ export const removeComponentFromTree = (components, targetId) => {
27
+ for (let i = 0; i < components.length; i++) {
28
+ if (components[i].id === targetId) {
29
+ const removed = components[i];
30
+ return {
31
+ components: [...components.slice(0, i), ...components.slice(i + 1)],
32
+ removed
33
+ };
34
+ }
35
+ if (components[i].children && components[i].children.length > 0) {
36
+ const result = removeComponentFromTree(components[i].children, targetId);
37
+ if (result.removed) {
38
+ return {
39
+ components: components.map(comp => comp.id === components[i].id
40
+ ? { ...comp, children: result.components }
41
+ : comp),
42
+ removed: result.removed
43
+ };
44
+ }
45
+ }
46
+ }
47
+ return { components, removed: null };
48
+ };
49
+ /**
50
+ * Insert a component at a specific location in the tree
51
+ */
52
+ export const insertComponentInTree = (components, component, parentId, index) => {
53
+ if (!parentId) {
54
+ // Insert at root level
55
+ if (index !== undefined) {
56
+ return [...components.slice(0, index), component, ...components.slice(index)];
57
+ }
58
+ return [...components, component];
59
+ }
60
+ // Insert into specific parent
61
+ return components.map(comp => {
62
+ if (comp.id === parentId) {
63
+ const children = comp.children || [];
64
+ const newChildren = index !== undefined
65
+ ? [...children.slice(0, index), component, ...children.slice(index)]
66
+ : [...children, component];
67
+ return { ...comp, children: newChildren };
68
+ }
69
+ if (comp.children) {
70
+ return {
71
+ ...comp,
72
+ children: insertComponentInTree(comp.children, component, parentId, index)
73
+ };
74
+ }
75
+ return comp;
76
+ });
77
+ };
78
+ /**
79
+ * Check if a component is a container (can accept children)
80
+ */
81
+ export const isContainerComponent = (componentType) => {
82
+ const containerTypes = [
83
+ 'Container', 'Group', 'Stack', 'Card', 'Paper', 'Box',
84
+ 'Flex', 'Grid', 'GridCol', 'SimpleGrid', 'Tabs'
85
+ ];
86
+ return containerTypes.includes(componentType);
87
+ };
88
+ /**
89
+ * Get all parent IDs of a component (path from root to component)
90
+ */
91
+ export const getComponentPath = (components, targetId, path = []) => {
92
+ for (const component of components) {
93
+ if (component.id === targetId) {
94
+ return path;
95
+ }
96
+ if (component.children && component.children.length > 0) {
97
+ const result = getComponentPath(component.children, targetId, [...path, component.id]);
98
+ if (result) {
99
+ return result;
100
+ }
101
+ }
102
+ }
103
+ return null;
104
+ };
105
+ /**
106
+ * Check if one component is a descendant of another
107
+ */
108
+ export const isDescendant = (components, ancestorId, descendantId) => {
109
+ const path = getComponentPath(components, descendantId);
110
+ return path ? path.includes(ancestorId) : false;
111
+ };
@@ -0,0 +1,122 @@
1
+ // Validation utility to test the parser fix
2
+ import { parseStoryUIToBuilder } from './storyToBuilder';
3
+ /**
4
+ * Test the JSX parser with the recipe card story
5
+ */
6
+ export function validateParserFix() {
7
+ console.log('🧪 Validating JSX Parser Fix');
8
+ console.log('='.repeat(40));
9
+ // Sample JSX from the recipe card story (simplified for testing)
10
+ const testJSX = `
11
+ export const Default: Story = {
12
+ render: () => (
13
+ <Card shadow="sm" padding="lg" radius="md" withBorder>
14
+ <Card.Section>
15
+ <Image
16
+ src="https://picsum.photos/400/200?random=1"
17
+ height={200}
18
+ alt="Test image"
19
+ />
20
+ </Card.Section>
21
+ <Stack gap="md" mt="md">
22
+ <Group justify="space-between" align="flex-start">
23
+ <Text fw={500} size="lg">
24
+ Test Title
25
+ </Text>
26
+ <Badge color="green" variant="light">
27
+ 30 min
28
+ </Badge>
29
+ </Group>
30
+ <Text size="sm" c="dimmed">
31
+ Test description text
32
+ </Text>
33
+ </Stack>
34
+ </Card>
35
+ ),
36
+ };`;
37
+ try {
38
+ const result = parseStoryUIToBuilder(testJSX);
39
+ console.log('šŸ“Š Parse Results:');
40
+ console.log(` Components: ${result.components.length}`);
41
+ console.log(` Errors: ${result.errors.length}`);
42
+ console.log(` Warnings: ${result.warnings.length}`);
43
+ if (result.errors.length > 0) {
44
+ console.log('āŒ Errors:');
45
+ result.errors.forEach(error => console.log(` ${error}`));
46
+ return;
47
+ }
48
+ // Test the component structure
49
+ if (result.components.length > 0) {
50
+ const rootComponent = result.components[0];
51
+ console.log(`\nšŸ—ļø Root Component: ${rootComponent.type}`);
52
+ if (rootComponent.type === 'Card' && rootComponent.children) {
53
+ console.log(`āœ… Card has ${rootComponent.children.length} children`);
54
+ // Check for Card.Section -> CardSection mapping
55
+ const cardSection = rootComponent.children.find(c => c.type === 'CardSection');
56
+ if (cardSection) {
57
+ console.log('āœ… Found CardSection component');
58
+ console.log(` CardSection children: ${cardSection.children?.length || 0}`);
59
+ if (cardSection.children && cardSection.children.length > 0) {
60
+ const image = cardSection.children.find(c => c.type === 'Image');
61
+ if (image) {
62
+ console.log('āœ… Found Image inside CardSection');
63
+ }
64
+ else {
65
+ console.log('āŒ Image not found inside CardSection');
66
+ }
67
+ }
68
+ }
69
+ else {
70
+ console.log('āŒ CardSection not found');
71
+ }
72
+ // Check for Stack component
73
+ const stack = rootComponent.children.find(c => c.type === 'Stack');
74
+ if (stack) {
75
+ console.log('āœ… Found Stack component');
76
+ console.log(` Stack children: ${stack.children?.length || 0}`);
77
+ if (stack.children && stack.children.length >= 2) {
78
+ const group = stack.children.find(c => c.type === 'Group');
79
+ if (group) {
80
+ console.log('āœ… Found Group inside Stack');
81
+ console.log(` Group children: ${group.children?.length || 0}`);
82
+ }
83
+ }
84
+ }
85
+ else {
86
+ console.log('āŒ Stack not found');
87
+ }
88
+ // Display full tree structure
89
+ console.log('\n🌳 Full Component Tree:');
90
+ printComponentTree(result.components, 0);
91
+ // Success criteria
92
+ const hasCorrectNesting = rootComponent.type === 'Card' &&
93
+ rootComponent.children?.some(c => c.type === 'CardSection') &&
94
+ rootComponent.children?.some(c => c.type === 'Stack');
95
+ if (hasCorrectNesting) {
96
+ console.log('\nšŸŽ‰ SUCCESS: Parser correctly maintains nested structure!');
97
+ }
98
+ else {
99
+ console.log('\nāŒ FAILED: Parser still losing nested structure');
100
+ }
101
+ }
102
+ else {
103
+ console.log('āŒ Root component is not Card or has no children');
104
+ }
105
+ }
106
+ else {
107
+ console.log('āŒ No components parsed');
108
+ }
109
+ }
110
+ catch (error) {
111
+ console.error('āŒ Validation failed:', error);
112
+ }
113
+ }
114
+ function printComponentTree(components, depth) {
115
+ const indent = ' '.repeat(depth);
116
+ components.forEach(comp => {
117
+ console.log(`${indent}šŸ“¦ ${comp.type} (${comp.id})`);
118
+ if (comp.children && comp.children.length > 0) {
119
+ printComponentTree(comp.children, depth + 1);
120
+ }
121
+ });
122
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Unified Story File Management System
3
+ *
4
+ * This replaces the complex multi-path save logic with a simple, predictable system:
5
+ * 1. Always save to the main /generated/ directory
6
+ * 2. Overwrite existing files by default
7
+ * 3. Optional backup creation (only when explicitly requested)
8
+ * 4. No subdirectories, no versioning, no confusion
9
+ */
10
+ import { updateStoryFile } from './storyFileUpdater';
11
+ /**
12
+ * Save components to a story file using the new simplified architecture
13
+ * Always saves to the main /generated/ directory, never creates subdirectories
14
+ */
15
+ export async function saveStoryFile(filePath, components, options = {}) {
16
+ try {
17
+ const fileName = filePath.split('/').pop() || filePath;
18
+ const storyName = options.storyName ||
19
+ fileName.replace('.stories.tsx', '').replace(/[-_]/g, ' ');
20
+ // Use the existing updateStoryFile function with createBackup option
21
+ const result = await updateStoryFile(filePath, components, storyName);
22
+ if (result.success) {
23
+ return {
24
+ success: true,
25
+ filePath,
26
+ fileName,
27
+ action: 'updated', // We don't distinguish between create/update anymore
28
+ hasBackup: options.createBackup,
29
+ };
30
+ }
31
+ else {
32
+ return {
33
+ success: false,
34
+ action: 'updated',
35
+ error: result.error || 'Unknown error occurred'
36
+ };
37
+ }
38
+ }
39
+ catch (error) {
40
+ return {
41
+ success: false,
42
+ action: 'updated',
43
+ error: error instanceof Error ? error.message : 'Unknown error occurred'
44
+ };
45
+ }
46
+ }
47
+ /**
48
+ * Get a clean filename for saving
49
+ * Removes duplicate prefixes and ensures .stories.tsx extension
50
+ */
51
+ export function getCleanFileName(originalName) {
52
+ let cleanName = originalName;
53
+ // Remove duplicate "generated-" prefixes
54
+ while (cleanName.startsWith('generated-generated-')) {
55
+ cleanName = cleanName.replace(/^generated-/, '');
56
+ }
57
+ // Ensure .stories.tsx extension
58
+ if (!cleanName.endsWith('.stories.tsx')) {
59
+ cleanName = cleanName.replace(/\.tsx$/, '') + '.stories.tsx';
60
+ }
61
+ return cleanName;
62
+ }
63
+ /**
64
+ * Convert a file path to a story name
65
+ * Extracts a human-readable name from the file path
66
+ */
67
+ export function filePathToStoryName(filePath) {
68
+ const fileName = filePath.split('/').pop() || filePath;
69
+ return fileName
70
+ .replace('.stories.tsx', '')
71
+ .replace(/[-_]/g, ' ')
72
+ .replace(/\b\w/g, l => l.toUpperCase()); // Title case
73
+ }