@tpitre/story-ui 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/.env.sample +82 -11
  2. package/README.md +89 -0
  3. package/dist/cli/deploy.d.ts +17 -0
  4. package/dist/cli/deploy.d.ts.map +1 -0
  5. package/dist/cli/deploy.js +696 -0
  6. package/dist/cli/index.d.ts +3 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +26 -2
  9. package/dist/cli/setup.d.ts +11 -0
  10. package/dist/cli/setup.d.ts.map +1 -0
  11. package/dist/cli/setup.js +437 -110
  12. package/dist/mcp-server/index.d.ts +2 -0
  13. package/dist/mcp-server/index.d.ts.map +1 -0
  14. package/dist/mcp-server/index.js +120 -2
  15. package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
  16. package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
  17. package/dist/mcp-server/mcp-stdio-server.js +8 -1
  18. package/dist/mcp-server/routes/claude.d.ts +3 -0
  19. package/dist/mcp-server/routes/claude.d.ts.map +1 -0
  20. package/dist/mcp-server/routes/claude.js +60 -23
  21. package/dist/mcp-server/routes/components.d.ts +4 -0
  22. package/dist/mcp-server/routes/components.d.ts.map +1 -0
  23. package/dist/mcp-server/routes/frameworks.d.ts +38 -0
  24. package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
  25. package/dist/mcp-server/routes/frameworks.js +183 -0
  26. package/dist/mcp-server/routes/generateStory.d.ts +3 -0
  27. package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
  28. package/dist/mcp-server/routes/generateStory.js +160 -76
  29. package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
  30. package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
  31. package/dist/mcp-server/routes/generateStoryStream.js +947 -0
  32. package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
  33. package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
  34. package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
  35. package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
  36. package/dist/mcp-server/routes/mcpRemote.js +489 -0
  37. package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
  38. package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
  39. package/dist/mcp-server/routes/providers.d.ts +89 -0
  40. package/dist/mcp-server/routes/providers.d.ts.map +1 -0
  41. package/dist/mcp-server/routes/providers.js +369 -0
  42. package/dist/mcp-server/routes/storySync.d.ts +26 -0
  43. package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
  44. package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
  45. package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
  46. package/dist/mcp-server/routes/streamTypes.js +18 -0
  47. package/dist/mcp-server/sessionManager.d.ts +50 -0
  48. package/dist/mcp-server/sessionManager.d.ts.map +1 -0
  49. package/dist/story-generator/componentBlacklist.d.ts +21 -0
  50. package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
  51. package/dist/story-generator/componentDiscovery.d.ts +28 -0
  52. package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
  53. package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
  54. package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
  55. package/dist/story-generator/componentRegistryGenerator.js +205 -0
  56. package/dist/story-generator/configLoader.d.ts +33 -0
  57. package/dist/story-generator/configLoader.d.ts.map +1 -0
  58. package/dist/story-generator/considerationsLoader.d.ts +32 -0
  59. package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
  60. package/dist/story-generator/documentation-sources.d.ts +28 -0
  61. package/dist/story-generator/documentation-sources.d.ts.map +1 -0
  62. package/dist/story-generator/documentationLoader.d.ts +64 -0
  63. package/dist/story-generator/documentationLoader.d.ts.map +1 -0
  64. package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
  65. package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
  66. package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
  67. package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
  68. package/dist/story-generator/enhancedComponentDiscovery.js +111 -11
  69. package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
  70. package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
  71. package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
  72. package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
  73. package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
  74. package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
  75. package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
  76. package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
  77. package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
  78. package/dist/story-generator/framework-adapters/index.d.ts +97 -0
  79. package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
  80. package/dist/story-generator/framework-adapters/index.js +198 -0
  81. package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
  82. package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
  83. package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
  84. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
  85. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
  86. package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
  87. package/dist/story-generator/framework-adapters/types.d.ts +182 -0
  88. package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
  89. package/dist/story-generator/framework-adapters/types.js +8 -0
  90. package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
  91. package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
  92. package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
  93. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
  94. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
  95. package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
  96. package/dist/story-generator/generateStory.d.ts +7 -0
  97. package/dist/story-generator/generateStory.d.ts.map +1 -0
  98. package/dist/story-generator/gitignoreManager.d.ts +50 -0
  99. package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
  100. package/dist/story-generator/imageProcessor.d.ts +80 -0
  101. package/dist/story-generator/imageProcessor.d.ts.map +1 -0
  102. package/dist/story-generator/imageProcessor.js +391 -0
  103. package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
  104. package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
  105. package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
  106. package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
  107. package/dist/story-generator/llm-providers/base-provider.js +135 -0
  108. package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
  109. package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
  110. package/dist/story-generator/llm-providers/claude-provider.js +414 -0
  111. package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
  112. package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
  113. package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
  114. package/dist/story-generator/llm-providers/index.d.ts +63 -0
  115. package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
  116. package/dist/story-generator/llm-providers/index.js +169 -0
  117. package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
  118. package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
  119. package/dist/story-generator/llm-providers/openai-provider.js +458 -0
  120. package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
  121. package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
  122. package/dist/story-generator/llm-providers/settings-manager.js +173 -0
  123. package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
  124. package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
  125. package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
  126. package/dist/story-generator/llm-providers/types.d.ts +153 -0
  127. package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
  128. package/dist/story-generator/llm-providers/types.js +8 -0
  129. package/dist/story-generator/logger.d.ts +14 -0
  130. package/dist/story-generator/logger.d.ts.map +1 -0
  131. package/dist/story-generator/logger.js +96 -29
  132. package/dist/story-generator/postProcessStory.d.ts +6 -0
  133. package/dist/story-generator/postProcessStory.d.ts.map +1 -0
  134. package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
  135. package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
  136. package/dist/story-generator/promptGenerator.d.ts +48 -0
  137. package/dist/story-generator/promptGenerator.d.ts.map +1 -0
  138. package/dist/story-generator/promptGenerator.js +186 -1
  139. package/dist/story-generator/storyHistory.d.ts +44 -0
  140. package/dist/story-generator/storyHistory.d.ts.map +1 -0
  141. package/dist/story-generator/storySync.d.ts +68 -0
  142. package/dist/story-generator/storySync.d.ts.map +1 -0
  143. package/dist/story-generator/storyTracker.d.ts +48 -0
  144. package/dist/story-generator/storyTracker.d.ts.map +1 -0
  145. package/dist/story-generator/storyValidator.d.ts +6 -0
  146. package/dist/story-generator/storyValidator.d.ts.map +1 -0
  147. package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
  148. package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
  149. package/dist/story-generator/universalDesignSystemAdapter.js +138 -1
  150. package/dist/story-generator/urlRedirectService.d.ts +21 -0
  151. package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
  152. package/dist/story-generator/validateStory.d.ts +19 -0
  153. package/dist/story-generator/validateStory.d.ts.map +1 -0
  154. package/dist/story-generator/validateStory.js +6 -2
  155. package/dist/story-generator/visionPrompts.d.ts +88 -0
  156. package/dist/story-generator/visionPrompts.d.ts.map +1 -0
  157. package/dist/story-generator/visionPrompts.js +462 -0
  158. package/dist/story-ui.config.d.ts +78 -0
  159. package/dist/story-ui.config.d.ts.map +1 -0
  160. package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
  161. package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
  162. package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
  163. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
  164. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
  165. package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
  166. package/dist/templates/StoryUI/index.d.ts +3 -0
  167. package/dist/templates/StoryUI/index.d.ts.map +1 -0
  168. package/dist/templates/StoryUI/index.js +2 -0
  169. package/package.json +17 -3
  170. package/templates/StoryUI/StoryUIPanel.tsx +1960 -384
  171. package/templates/StoryUI/index.tsx +1 -1
  172. package/templates/StoryUI/manager.tsx +264 -0
  173. package/templates/production-app/.env.example +11 -0
  174. package/templates/production-app/index.html +66 -0
  175. package/templates/production-app/package.json +30 -0
  176. package/templates/production-app/public/favicon.svg +5 -0
  177. package/templates/production-app/src/App.tsx +1157 -0
  178. package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
  179. package/templates/production-app/src/componentRegistry.ts +315 -0
  180. package/templates/production-app/src/considerations.ts +16 -0
  181. package/templates/production-app/src/index.css +284 -0
  182. package/templates/production-app/src/main.tsx +25 -0
  183. package/templates/production-app/tsconfig.json +32 -0
  184. package/templates/production-app/tsconfig.node.json +11 -0
  185. package/templates/production-app/vite.config.ts +83 -0
  186. package/templates/react-import-rule.json +2 -2
  187. package/dist/index.js +0 -12
  188. package/dist/story-ui.config.loader.js +0 -205
@@ -260,17 +260,9 @@ export class EnhancedComponentDiscovery {
260
260
  // Determine the project root from the generated stories path
261
261
  const projectRoot = this.getProjectRoot();
262
262
  const packagePath = path.join(projectRoot, 'node_modules', source.path);
263
- if (!fs.existsSync(packagePath)) {
264
- console.warn(`Package ${source.path} not found in node_modules at ${packagePath}`);
265
- return;
266
- }
267
- logger.log(`🔍 Dynamically discovering components from ${source.path}...`);
268
- // Use dynamic discovery to get real exports
269
- const dynamicDiscovery = new DynamicPackageDiscovery(source.path, projectRoot);
270
- const packageExports = await dynamicDiscovery.getRealPackageExports();
271
- if (!packageExports) {
263
+ // Helper function to load known components as fallback
264
+ const loadFallbackComponents = () => {
272
265
  logger.log(`📋 ${source.path}: Using static component list (design system detected)`);
273
- // Fallback to predefined components if dynamic discovery fails
274
266
  const knownComponents = this.getKnownDesignSystemComponents(source.path);
275
267
  if (knownComponents.length > 0) {
276
268
  for (const comp of knownComponents) {
@@ -281,7 +273,22 @@ export class EnhancedComponentDiscovery {
281
273
  category: comp.category || this.categorizeComponent(comp.name || '', comp.description || '')
282
274
  });
283
275
  }
276
+ logger.log(`✅ Loaded ${knownComponents.length} known components for ${source.path}`);
284
277
  }
278
+ };
279
+ if (!fs.existsSync(packagePath)) {
280
+ console.warn(`Package ${source.path} not found in node_modules at ${packagePath}`);
281
+ // Use fallback component list when package is not installed (e.g., in production)
282
+ loadFallbackComponents();
283
+ return;
284
+ }
285
+ logger.log(`🔍 Dynamically discovering components from ${source.path}...`);
286
+ // Use dynamic discovery to get real exports
287
+ const dynamicDiscovery = new DynamicPackageDiscovery(source.path, projectRoot);
288
+ const packageExports = await dynamicDiscovery.getRealPackageExports();
289
+ if (!packageExports) {
290
+ // Fallback to predefined components if dynamic discovery fails
291
+ loadFallbackComponents();
285
292
  return;
286
293
  }
287
294
  // Process the real components found in the package
@@ -353,7 +360,100 @@ export class EnhancedComponentDiscovery {
353
360
  category: this.categorizeComponent(name, '')
354
361
  }));
355
362
  }
356
- // Add other design systems here as needed
363
+ // Mantine fallback components
364
+ if (packageName === '@mantine/core') {
365
+ const mantineComponents = [
366
+ // Layout
367
+ 'Container', 'SimpleGrid', 'Grid', 'Group', 'Stack', 'Flex', 'Center', 'Space', 'Divider',
368
+ 'AspectRatio', 'Box', 'AppShell', 'MediaQuery', 'Paper',
369
+ // Typography
370
+ 'Text', 'Title', 'Anchor', 'Blockquote', 'Code', 'Highlight', 'Mark', 'List',
371
+ // Buttons & Actions
372
+ 'Button', 'ActionIcon', 'CopyButton', 'FileButton', 'UnstyledButton', 'CloseButton',
373
+ // Inputs
374
+ 'TextInput', 'NumberInput', 'PasswordInput', 'Textarea', 'Select', 'MultiSelect',
375
+ 'Autocomplete', 'Checkbox', 'Switch', 'Radio', 'Slider', 'RangeSlider', 'Rating',
376
+ 'SegmentedControl', 'ColorInput', 'ColorPicker', 'FileInput', 'JsonInput', 'PinInput',
377
+ 'Chip', 'TransferList', 'NativeSelect',
378
+ // Navigation
379
+ 'Anchor', 'Breadcrumbs', 'Burger', 'NavLink', 'Pagination', 'Stepper', 'Tabs',
380
+ // Data Display
381
+ 'Accordion', 'Avatar', 'Badge', 'Card', 'Image', 'BackgroundImage', 'Indicator',
382
+ 'Kbd', 'Spoiler', 'Table', 'ThemeIcon', 'Timeline', 'ColorSwatch',
383
+ // Overlays
384
+ 'Dialog', 'Drawer', 'Modal', 'LoadingOverlay', 'Popover', 'Tooltip', 'Menu',
385
+ 'HoverCard', 'Affix', 'Overlay',
386
+ // Feedback
387
+ 'Alert', 'Loader', 'Notification', 'Progress', 'RingProgress', 'Skeleton',
388
+ // Misc
389
+ 'Portal', 'Transition', 'ScrollArea', 'FocusTrap', 'Input', 'InputWrapper',
390
+ // Dates (from @mantine/dates)
391
+ 'Calendar', 'DateInput', 'DatePicker', 'DateTimePicker', 'MonthPicker', 'YearPicker'
392
+ ];
393
+ return mantineComponents.map(name => ({
394
+ name,
395
+ description: `${name} component from Mantine`,
396
+ category: this.categorizeComponent(name, '')
397
+ }));
398
+ }
399
+ // Material UI fallback components
400
+ if (packageName === '@mui/material') {
401
+ const muiComponents = [
402
+ // Inputs
403
+ 'Autocomplete', 'Button', 'ButtonGroup', 'Checkbox', 'Fab', 'Radio', 'RadioGroup',
404
+ 'Rating', 'Select', 'Slider', 'Switch', 'TextField', 'ToggleButton', 'ToggleButtonGroup',
405
+ // Data Display
406
+ 'Avatar', 'AvatarGroup', 'Badge', 'Chip', 'Divider', 'Icon', 'List', 'ListItem',
407
+ 'ListItemText', 'ListItemIcon', 'ListItemButton', 'Table', 'TableBody', 'TableCell',
408
+ 'TableContainer', 'TableHead', 'TableRow', 'Tooltip', 'Typography',
409
+ // Feedback
410
+ 'Alert', 'AlertTitle', 'Backdrop', 'CircularProgress', 'Dialog', 'DialogActions',
411
+ 'DialogContent', 'DialogContentText', 'DialogTitle', 'LinearProgress', 'Skeleton', 'Snackbar',
412
+ // Surfaces
413
+ 'Accordion', 'AccordionActions', 'AccordionDetails', 'AccordionSummary', 'AppBar',
414
+ 'Card', 'CardActions', 'CardContent', 'CardHeader', 'CardMedia', 'Paper', 'Toolbar',
415
+ // Navigation
416
+ 'BottomNavigation', 'BottomNavigationAction', 'Breadcrumbs', 'Drawer', 'Link',
417
+ 'Menu', 'MenuItem', 'MenuList', 'Pagination', 'SpeedDial', 'SpeedDialAction',
418
+ 'SpeedDialIcon', 'Stepper', 'Step', 'StepLabel', 'Tabs', 'Tab',
419
+ // Layout
420
+ 'Box', 'Container', 'Grid', 'Stack', 'ImageList', 'ImageListItem',
421
+ // Utils
422
+ 'ClickAwayListener', 'Modal', 'NoSsr', 'Popover', 'Popper', 'Portal', 'Collapse', 'Fade', 'Grow', 'Slide', 'Zoom'
423
+ ];
424
+ return muiComponents.map(name => ({
425
+ name,
426
+ description: `${name} component from Material UI`,
427
+ category: this.categorizeComponent(name, '')
428
+ }));
429
+ }
430
+ // Ant Design fallback components
431
+ if (packageName === 'antd') {
432
+ const antdComponents = [
433
+ // General
434
+ 'Button', 'FloatButton', 'Icon', 'Typography', 'Text', 'Title', 'Paragraph', 'Link',
435
+ // Layout
436
+ 'Divider', 'Flex', 'Grid', 'Row', 'Col', 'Layout', 'Header', 'Footer', 'Sider', 'Content', 'Space',
437
+ // Navigation
438
+ 'Anchor', 'Breadcrumb', 'Dropdown', 'Menu', 'Pagination', 'Steps',
439
+ // Data Entry
440
+ 'AutoComplete', 'Cascader', 'Checkbox', 'ColorPicker', 'DatePicker', 'Form',
441
+ 'Input', 'InputNumber', 'Mentions', 'Radio', 'Rate', 'Select', 'Slider',
442
+ 'Switch', 'TimePicker', 'Transfer', 'TreeSelect', 'Upload',
443
+ // Data Display
444
+ 'Avatar', 'Badge', 'Calendar', 'Card', 'Carousel', 'Collapse', 'Descriptions',
445
+ 'Empty', 'Image', 'List', 'Popover', 'QRCode', 'Segmented', 'Statistic',
446
+ 'Table', 'Tabs', 'Tag', 'Timeline', 'Tooltip', 'Tour', 'Tree',
447
+ // Feedback
448
+ 'Alert', 'Drawer', 'Message', 'Modal', 'Notification', 'Popconfirm', 'Progress',
449
+ 'Result', 'Skeleton', 'Spin', 'Watermark'
450
+ ];
451
+ return antdComponents.map(name => ({
452
+ name,
453
+ description: `${name} component from Ant Design`,
454
+ category: this.categorizeComponent(name, '')
455
+ }));
456
+ }
357
457
  // Default: return empty array
358
458
  return [];
359
459
  }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Angular Framework Adapter
3
+ *
4
+ * Generates Storybook stories for Angular components.
5
+ * Supports standalone components and module-based components.
6
+ */
7
+ import { FrameworkType, StoryFramework, StoryGenerationOptions } from './types.js';
8
+ import { BaseFrameworkAdapter } from './base-adapter.js';
9
+ import { StoryUIConfig } from '../../story-ui.config.js';
10
+ import { DiscoveredComponent } from '../componentDiscovery.js';
11
+ export declare class AngularAdapter extends BaseFrameworkAdapter {
12
+ readonly type: FrameworkType;
13
+ readonly name = "Angular";
14
+ readonly supportedStoryFrameworks: StoryFramework[];
15
+ readonly defaultExtension = ".stories.ts";
16
+ generateSystemPrompt(config: StoryUIConfig, options?: StoryGenerationOptions): string;
17
+ generateExamples(config: StoryUIConfig): string;
18
+ generateSampleStory(config: StoryUIConfig, components: DiscoveredComponent[]): string;
19
+ getStoryTemplate(options?: StoryGenerationOptions): string;
20
+ /**
21
+ * Convert PascalCase to kebab-case for selectors
22
+ */
23
+ private toKebabCase;
24
+ /**
25
+ * Post-process Angular stories
26
+ */
27
+ postProcess(storyContent: string): string;
28
+ /**
29
+ * Validate Angular story
30
+ */
31
+ validate(storyContent: string): {
32
+ valid: boolean;
33
+ errors: string[];
34
+ };
35
+ }
36
+ /**
37
+ * Factory function
38
+ */
39
+ export declare function createAngularAdapter(): AngularAdapter;
40
+ //# sourceMappingURL=angular-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/angular-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,cAAc,EACd,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,qBAAa,cAAe,SAAQ,oBAAoB;IACtD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAa;IACzC,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,cAAc,EAAE,CAGjD;IACF,QAAQ,CAAC,gBAAgB,iBAAiB;IAE1C,oBAAoB,CAClB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM;IA0HT,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IA+J/C,mBAAmB,CACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IAqDT,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IA4B1D;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAkBzC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;CA2BrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
@@ -0,0 +1,427 @@
1
+ /**
2
+ * Angular Framework Adapter
3
+ *
4
+ * Generates Storybook stories for Angular components.
5
+ * Supports standalone components and module-based components.
6
+ */
7
+ import { BaseFrameworkAdapter } from './base-adapter.js';
8
+ export class AngularAdapter extends BaseFrameworkAdapter {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.type = 'angular';
12
+ this.name = 'Angular';
13
+ this.supportedStoryFrameworks = [
14
+ 'storybook-angular',
15
+ 'chromatic',
16
+ ];
17
+ this.defaultExtension = '.stories.ts';
18
+ }
19
+ generateSystemPrompt(config, options) {
20
+ if (config.systemPrompt) {
21
+ return config.systemPrompt;
22
+ }
23
+ const componentSystemName = config.componentPrefix
24
+ ? `${config.componentPrefix.replace(/^[A-Z]+/, '')} design system`
25
+ : 'component library';
26
+ return `You are an expert Angular developer creating Storybook stories using CSF 3.0 format.
27
+ Use ONLY the Angular components from the ${componentSystemName} listed below.
28
+
29
+ MANDATORY IMPORTS - First lines of every story file:
30
+ 1. import type { Meta, StoryObj } from '@storybook/angular';
31
+ 2. import { ComponentName } from '${config.importPath || 'your-library'}';
32
+
33
+ ANGULAR STORY FORMAT:
34
+ - Use moduleMetadata for imports and providers
35
+ - Components can be standalone or module-based
36
+ - Use applicationConfig for standalone components
37
+
38
+ STORY STRUCTURE (CSF 3.0):
39
+ - Meta object with component, title, and decorators
40
+ - Use render function for template customization
41
+ - Export named stories as StoryObj
42
+
43
+ CRITICAL RULES:
44
+ - Import modules/components in moduleMetadata or applicationConfig
45
+ - Use Angular template syntax in render functions
46
+ - Event bindings use (event) syntax
47
+
48
+ Example structure (Standalone Components):
49
+ \`\`\`typescript
50
+ import type { Meta, StoryObj } from '@storybook/angular';
51
+ import { applicationConfig, argsToTemplate } from '@storybook/angular';
52
+ import { ButtonComponent } from 'your-library';
53
+
54
+ const meta: Meta<ButtonComponent> = {
55
+ title: 'Components/Button',
56
+ component: ButtonComponent,
57
+ tags: ['autodocs'],
58
+ decorators: [
59
+ applicationConfig({
60
+ providers: [],
61
+ }),
62
+ ],
63
+ argTypes: {
64
+ variant: {
65
+ control: 'select',
66
+ options: ['primary', 'secondary', 'ghost'],
67
+ },
68
+ },
69
+ };
70
+
71
+ export default meta;
72
+ type Story = StoryObj<ButtonComponent>;
73
+
74
+ export const Primary: Story = {
75
+ args: {
76
+ variant: 'primary',
77
+ label: 'Click me',
78
+ },
79
+ };
80
+
81
+ export const WithContent: Story = {
82
+ render: (args) => ({
83
+ props: args,
84
+ template: \`
85
+ <app-button [variant]="variant">
86
+ <span class="icon">★</span>
87
+ Click me
88
+ </app-button>
89
+ \`,
90
+ }),
91
+ };
92
+ \`\`\`
93
+
94
+ Example structure (Module-based Components):
95
+ \`\`\`typescript
96
+ import type { Meta, StoryObj } from '@storybook/angular';
97
+ import { moduleMetadata } from '@storybook/angular';
98
+ import { ButtonModule } from 'your-library';
99
+
100
+ const meta: Meta = {
101
+ title: 'Components/Button',
102
+ decorators: [
103
+ moduleMetadata({
104
+ imports: [ButtonModule],
105
+ }),
106
+ ],
107
+ argTypes: {
108
+ variant: {
109
+ control: 'select',
110
+ options: ['primary', 'secondary', 'ghost'],
111
+ },
112
+ },
113
+ };
114
+
115
+ export default meta;
116
+ type Story = StoryObj;
117
+
118
+ export const Primary: Story = {
119
+ render: (args) => ({
120
+ props: args,
121
+ template: \`<app-button [variant]="variant">Click me</app-button>\`,
122
+ }),
123
+ };
124
+ \`\`\`
125
+
126
+ ANGULAR TEMPLATE SYNTAX:
127
+ - Property binding: [property]="value"
128
+ - Event binding: (event)="handler($event)"
129
+ - Two-way binding: [(ngModel)]="value"
130
+ - Structural directives: *ngIf, *ngFor, *ngSwitch
131
+
132
+ CONTENT PROJECTION (ng-content):
133
+ - Default slot: Content between tags
134
+ - Named slots: Use ngProjectAs or select attribute
135
+
136
+ ${this.getCommonRules()}`;
137
+ }
138
+ generateExamples(config) {
139
+ const lib = config.importPath || 'your-library';
140
+ return `
141
+ ## Example Stories for Angular
142
+
143
+ ### Standalone Component
144
+ \`\`\`typescript
145
+ import type { Meta, StoryObj } from '@storybook/angular';
146
+ import { applicationConfig } from '@storybook/angular';
147
+ import { ButtonComponent } from 'your-library';
148
+
149
+ const meta: Meta<ButtonComponent> = {
150
+ title: 'Components/Button',
151
+ component: ButtonComponent,
152
+ tags: ['autodocs'],
153
+ decorators: [
154
+ applicationConfig({
155
+ providers: [],
156
+ }),
157
+ ],
158
+ argTypes: {
159
+ variant: {
160
+ control: 'select',
161
+ options: ['primary', 'secondary', 'ghost'],
162
+ },
163
+ size: {
164
+ control: 'select',
165
+ options: ['small', 'medium', 'large'],
166
+ },
167
+ },
168
+ };
169
+
170
+ export default meta;
171
+ type Story = StoryObj<ButtonComponent>;
172
+
173
+ export const Default: Story = {
174
+ args: {
175
+ variant: 'primary',
176
+ size: 'medium',
177
+ label: 'Button',
178
+ },
179
+ };
180
+
181
+ export const AllVariants: Story = {
182
+ render: () => ({
183
+ template: \`
184
+ <div style="display: flex; gap: 8px;">
185
+ <app-button variant="primary">Primary</app-button>
186
+ <app-button variant="secondary">Secondary</app-button>
187
+ <app-button variant="ghost">Ghost</app-button>
188
+ </div>
189
+ \`,
190
+ }),
191
+ };
192
+ \`\`\`
193
+
194
+ ### Module-based Component
195
+ \`\`\`typescript
196
+ import type { Meta, StoryObj } from '@storybook/angular';
197
+ import { moduleMetadata } from '@storybook/angular';
198
+ import { CardModule, ButtonModule } from '${lib}';
199
+
200
+ const meta: Meta = {
201
+ title: 'Components/Card',
202
+ decorators: [
203
+ moduleMetadata({
204
+ imports: [CardModule, ButtonModule],
205
+ }),
206
+ ],
207
+ };
208
+
209
+ export default meta;
210
+ type Story = StoryObj;
211
+
212
+ export const ProductCard: Story = {
213
+ render: () => ({
214
+ template: \`
215
+ <app-card style="width: 300px">
216
+ <img appCardImage src="https://picsum.photos/300/200" alt="Product">
217
+ <h3 appCardTitle>Product Name</h3>
218
+ <p appCardContent>$99.00</p>
219
+ <app-button appCardAction variant="primary">Add to Cart</app-button>
220
+ </app-card>
221
+ \`,
222
+ }),
223
+ };
224
+ \`\`\`
225
+
226
+ ### With Event Handling
227
+ \`\`\`typescript
228
+ import type { Meta, StoryObj } from '@storybook/angular';
229
+ import { applicationConfig } from '@storybook/angular';
230
+ import { action } from '@storybook/addon-actions';
231
+ import { ButtonComponent } from 'your-library';
232
+
233
+ const meta: Meta<ButtonComponent> = {
234
+ title: 'Components/Button',
235
+ component: ButtonComponent,
236
+ decorators: [
237
+ applicationConfig({
238
+ providers: [],
239
+ }),
240
+ ],
241
+ };
242
+
243
+ export default meta;
244
+ type Story = StoryObj<ButtonComponent>;
245
+
246
+ export const WithClick: Story = {
247
+ render: () => ({
248
+ props: {
249
+ onClick: action('button-click'),
250
+ },
251
+ template: \`
252
+ <app-button (click)="onClick($event)" variant="primary">
253
+ Click me
254
+ </app-button>
255
+ \`,
256
+ }),
257
+ };
258
+ \`\`\`
259
+
260
+ ### With Forms
261
+ \`\`\`typescript
262
+ import type { Meta, StoryObj } from '@storybook/angular';
263
+ import { moduleMetadata } from '@storybook/angular';
264
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
265
+ import { InputModule } from '${lib}';
266
+
267
+ const meta: Meta = {
268
+ title: 'Components/Input',
269
+ decorators: [
270
+ moduleMetadata({
271
+ imports: [FormsModule, ReactiveFormsModule, InputModule],
272
+ }),
273
+ ],
274
+ };
275
+
276
+ export default meta;
277
+ type Story = StoryObj;
278
+
279
+ export const WithNgModel: Story = {
280
+ render: () => ({
281
+ props: {
282
+ value: '',
283
+ },
284
+ template: \`
285
+ <div>
286
+ <app-input [(ngModel)]="value" placeholder="Type here..."></app-input>
287
+ <p>Value: {{ value }}</p>
288
+ </div>
289
+ \`,
290
+ }),
291
+ };
292
+ \`\`\`
293
+ `;
294
+ }
295
+ generateSampleStory(config, components) {
296
+ const lib = config.importPath || 'your-library';
297
+ const firstComponent = components[0];
298
+ if (!firstComponent) {
299
+ return `
300
+ import type { Meta, StoryObj } from '@storybook/angular';
301
+
302
+ const meta: Meta = {
303
+ title: 'Examples/Sample',
304
+ parameters: { layout: 'centered' },
305
+ };
306
+
307
+ export default meta;
308
+ type Story = StoryObj;
309
+
310
+ export const Default: Story = {
311
+ render: () => ({
312
+ template: '<div>Sample story content</div>',
313
+ }),
314
+ };
315
+ `;
316
+ }
317
+ // Convert PascalCase to kebab-case for selector
318
+ const selector = this.toKebabCase(firstComponent.name);
319
+ return `
320
+ import type { Meta, StoryObj } from '@storybook/angular';
321
+ import { applicationConfig } from '@storybook/angular';
322
+ import { ${firstComponent.name}Component } from '${lib}';
323
+
324
+ const meta: Meta<${firstComponent.name}Component> = {
325
+ title: 'Components/${firstComponent.name}',
326
+ component: ${firstComponent.name}Component,
327
+ tags: ['autodocs'],
328
+ decorators: [
329
+ applicationConfig({
330
+ providers: [],
331
+ }),
332
+ ],
333
+ parameters: { layout: 'centered' },
334
+ };
335
+
336
+ export default meta;
337
+ type Story = StoryObj<${firstComponent.name}Component>;
338
+
339
+ export const Default: Story = {
340
+ args: {},
341
+ };
342
+ `;
343
+ }
344
+ getStoryTemplate(options) {
345
+ return `
346
+ // {{componentName}}.stories.ts
347
+ import type { Meta, StoryObj } from '@storybook/angular';
348
+ import { applicationConfig } from '@storybook/angular';
349
+ import { {{componentName}}Component } from '{{importPath}}';
350
+
351
+ const meta: Meta<{{componentName}}Component> = {
352
+ title: '{{category}}/{{componentName}}',
353
+ component: {{componentName}}Component,
354
+ tags: ['autodocs'],
355
+ decorators: [
356
+ applicationConfig({
357
+ providers: [],
358
+ }),
359
+ ],
360
+ parameters: { layout: 'centered' },
361
+ };
362
+
363
+ export default meta;
364
+ type Story = StoryObj<{{componentName}}Component>;
365
+
366
+ export const Default: Story = {
367
+ args: {},
368
+ };
369
+ `;
370
+ }
371
+ /**
372
+ * Convert PascalCase to kebab-case for selectors
373
+ */
374
+ toKebabCase(str) {
375
+ return str
376
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
377
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
378
+ .toLowerCase();
379
+ }
380
+ /**
381
+ * Post-process Angular stories
382
+ */
383
+ postProcess(storyContent) {
384
+ let processed = super.postProcess(storyContent);
385
+ // Remove React imports if present
386
+ processed = processed.replace(/import React from ['"]react['"];?\n?/g, '');
387
+ // Fix JSX to Angular template syntax
388
+ processed = processed
389
+ // Fix className to class
390
+ .replace(/className=/g, 'class=')
391
+ // Fix onClick to (click)
392
+ .replace(/onClick=/g, '(click)=')
393
+ .replace(/onChange=/g, '(change)=')
394
+ .replace(/onInput=/g, '(input)=');
395
+ return processed;
396
+ }
397
+ /**
398
+ * Validate Angular story
399
+ */
400
+ validate(storyContent) {
401
+ const baseValidation = super.validate(storyContent);
402
+ const errors = [...baseValidation.errors];
403
+ // Angular-specific validations
404
+ if (!storyContent.includes('@storybook/angular')) {
405
+ errors.push("Missing '@storybook/angular' import");
406
+ }
407
+ if (storyContent.includes("import React from 'react'")) {
408
+ errors.push('React import found in Angular story');
409
+ }
410
+ // Check for neither moduleMetadata nor applicationConfig
411
+ if (!storyContent.includes('moduleMetadata') &&
412
+ !storyContent.includes('applicationConfig') &&
413
+ !storyContent.includes('component:')) {
414
+ errors.push('Missing moduleMetadata or applicationConfig decorator');
415
+ }
416
+ return {
417
+ valid: errors.length === 0,
418
+ errors,
419
+ };
420
+ }
421
+ }
422
+ /**
423
+ * Factory function
424
+ */
425
+ export function createAngularAdapter() {
426
+ return new AngularAdapter();
427
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Base Framework Adapter
3
+ *
4
+ * Abstract base class that provides common functionality for all
5
+ * framework-specific adapters. Subclasses implement framework-specific
6
+ * prompt generation and story templates.
7
+ */
8
+ import { FrameworkType, StoryFramework, FrameworkAdapter, StoryGenerationOptions } from './types.js';
9
+ import { StoryUIConfig } from '../../story-ui.config.js';
10
+ import { DiscoveredComponent } from '../componentDiscovery.js';
11
+ /**
12
+ * Abstract Base Framework Adapter
13
+ */
14
+ export declare abstract class BaseFrameworkAdapter implements FrameworkAdapter {
15
+ abstract readonly type: FrameworkType;
16
+ abstract readonly name: string;
17
+ abstract readonly supportedStoryFrameworks: StoryFramework[];
18
+ abstract readonly defaultExtension: string;
19
+ /**
20
+ * Generate the system prompt for this framework
21
+ */
22
+ abstract generateSystemPrompt(config: StoryUIConfig, options?: StoryGenerationOptions): string;
23
+ /**
24
+ * Generate component reference documentation
25
+ */
26
+ generateComponentReference(components: DiscoveredComponent[], config: StoryUIConfig): string;
27
+ /**
28
+ * Format a single component entry
29
+ */
30
+ protected formatComponentEntry(component: DiscoveredComponent, config: StoryUIConfig): string;
31
+ /**
32
+ * Get the import path for a component
33
+ */
34
+ protected getImportPath(component: DiscoveredComponent, config: StoryUIConfig): string;
35
+ /**
36
+ * Group components by their category
37
+ */
38
+ protected groupComponentsByPackage(components: DiscoveredComponent[]): Record<string, DiscoveredComponent[]>;
39
+ /**
40
+ * Generate example stories - framework specific
41
+ */
42
+ abstract generateExamples(config: StoryUIConfig): string;
43
+ /**
44
+ * Generate a sample story template - framework specific
45
+ */
46
+ abstract generateSampleStory(config: StoryUIConfig, components: DiscoveredComponent[]): string;
47
+ /**
48
+ * Generate import statements for components
49
+ */
50
+ generateImports(components: DiscoveredComponent[], config: StoryUIConfig): string;
51
+ /**
52
+ * Post-process generated story content
53
+ */
54
+ postProcess(storyContent: string): string;
55
+ /**
56
+ * Validate generated story syntax
57
+ */
58
+ validate(storyContent: string): {
59
+ valid: boolean;
60
+ errors: string[];
61
+ };
62
+ /**
63
+ * Get the story file template - framework specific
64
+ */
65
+ abstract getStoryTemplate(options?: StoryGenerationOptions): string;
66
+ /**
67
+ * Log adapter activity
68
+ */
69
+ protected log(message: string, data?: Record<string, unknown>): void;
70
+ /**
71
+ * Get common story structure rules
72
+ */
73
+ protected getCommonRules(): string;
74
+ }
75
+ //# sourceMappingURL=base-adapter.d.ts.map