@tpitre/story-ui 3.6.2 → 3.8.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 (47) hide show
  1. package/README.md +36 -32
  2. package/dist/cli/index.js +0 -5
  3. package/dist/cli/setup.js +1 -1
  4. package/dist/mcp-server/routes/generateStory.d.ts.map +1 -1
  5. package/dist/mcp-server/routes/generateStory.js +178 -87
  6. package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -1
  7. package/dist/mcp-server/routes/generateStoryStream.js +149 -31
  8. package/dist/story-generator/dynamicPackageDiscovery.d.ts +35 -2
  9. package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -1
  10. package/dist/story-generator/dynamicPackageDiscovery.js +332 -6
  11. package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -1
  12. package/dist/story-generator/enhancedComponentDiscovery.js +149 -2
  13. package/dist/story-generator/framework-adapters/base-adapter.d.ts +1 -0
  14. package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -1
  15. package/dist/story-generator/framework-adapters/base-adapter.js +12 -2
  16. package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -1
  17. package/dist/story-generator/framework-adapters/react-adapter.js +2 -0
  18. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -1
  19. package/dist/story-generator/framework-adapters/svelte-adapter.js +53 -7
  20. package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -1
  21. package/dist/story-generator/framework-adapters/vue-adapter.js +21 -1
  22. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -1
  23. package/dist/story-generator/framework-adapters/web-components-adapter.js +4 -0
  24. package/dist/story-generator/llm-providers/openai-provider.js +2 -2
  25. package/dist/story-generator/promptGenerator.d.ts.map +1 -1
  26. package/dist/story-generator/promptGenerator.js +179 -26
  27. package/dist/story-generator/runtimeValidator.d.ts +64 -0
  28. package/dist/story-generator/runtimeValidator.d.ts.map +1 -0
  29. package/dist/story-generator/runtimeValidator.js +356 -0
  30. package/dist/story-generator/selfHealingLoop.d.ts +112 -0
  31. package/dist/story-generator/selfHealingLoop.d.ts.map +1 -0
  32. package/dist/story-generator/selfHealingLoop.js +202 -0
  33. package/dist/story-generator/validateStory.d.ts.map +1 -1
  34. package/dist/story-generator/validateStory.js +81 -12
  35. package/dist/story-ui.config.d.ts +2 -0
  36. package/dist/story-ui.config.d.ts.map +1 -1
  37. package/dist/templates/StoryUI/StoryUIPanel.d.ts +0 -5
  38. package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -1
  39. package/dist/templates/StoryUI/StoryUIPanel.js +411 -223
  40. package/package.json +4 -4
  41. package/templates/StoryUI/StoryUIPanel.mdx +84 -0
  42. package/templates/StoryUI/StoryUIPanel.tsx +493 -265
  43. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +0 -18
  44. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +0 -1
  45. package/dist/templates/StoryUI/StoryUIPanel.stories.js +0 -37
  46. package/templates/StoryUI/StoryUIPanel.stories.tsx +0 -44
  47. package/templates/StoryUI/manager.tsx +0 -859
@@ -3,21 +3,42 @@ import path from 'path';
3
3
  import { createRequire } from 'module';
4
4
  import { logger } from './logger.js';
5
5
  /**
6
- * Dynamically discovers what components are actually available in an installed package
6
+ * Dynamically discovers what components are actually available in an installed package.
7
+ *
8
+ * IMPORTANT: This class is FRAMEWORK-aware, not DESIGN-SYSTEM-aware.
9
+ * It uses GENERIC patterns based on the framework type (React, Vue, Angular, Svelte, Web Components)
10
+ * without any knowledge of specific design systems (Mantine, Vuetify, Material, Skeleton, Shoelace, etc.)
7
11
  */
8
12
  export class DynamicPackageDiscovery {
9
- constructor(packageName, projectRoot = process.cwd()) {
13
+ constructor(packageName, projectRoot = process.cwd(), framework = 'react') {
10
14
  this.packageName = packageName;
11
15
  this.projectRoot = projectRoot;
16
+ this.framework = framework.toLowerCase();
12
17
  }
13
18
  /**
14
19
  * Get the real exports from the installed package
15
20
  */
16
21
  async getRealPackageExports() {
17
22
  try {
18
- const packagePath = path.join(this.projectRoot, 'node_modules', this.packageName);
23
+ // GENERIC: Normalize package names with subpath exports to their base package
24
+ // e.g., 'packagename/components' -> 'packagename', '@scope/pkg/sub' -> '@scope/pkg'
25
+ let normalizedPackageName = this.packageName;
26
+ if (!this.packageName.startsWith('@') && this.packageName.includes('/')) {
27
+ // Non-scoped package with subpath: extract base name
28
+ normalizedPackageName = this.packageName.split('/')[0];
29
+ logger.log(`🔧 Normalizing package path: ${this.packageName} → ${normalizedPackageName}`);
30
+ }
31
+ else if (this.packageName.startsWith('@')) {
32
+ // Scoped package: keep @scope/name, strip anything after
33
+ const parts = this.packageName.split('/');
34
+ if (parts.length > 2) {
35
+ normalizedPackageName = `${parts[0]}/${parts[1]}`;
36
+ logger.log(`🔧 Normalizing scoped package path: ${this.packageName} → ${normalizedPackageName}`);
37
+ }
38
+ }
39
+ const packagePath = path.join(this.projectRoot, 'node_modules', normalizedPackageName);
19
40
  if (!fs.existsSync(packagePath)) {
20
- console.warn(`Package ${this.packageName} not found in node_modules`);
41
+ console.warn(`Package ${normalizedPackageName} not found in node_modules`);
21
42
  return null;
22
43
  }
23
44
  // Get package version
@@ -338,17 +359,61 @@ export class DynamicPackageDiscovery {
338
359
  /**
339
360
  * Alternative discovery method when package imports fail due to CSS
340
361
  * Analyzes package.json exports and TypeScript definitions
362
+ *
363
+ * IMPORTANT: This uses GENERIC framework-based discovery patterns.
364
+ * It has NO knowledge of specific design systems - only framework types.
341
365
  */
342
366
  discoverFromPackageStructure() {
343
367
  try {
344
- const packagePath = path.join(this.projectRoot, 'node_modules', this.packageName);
368
+ // GENERIC: Normalize package name for subpath exports
369
+ let normalizedPackageName = this.packageName;
370
+ if (!this.packageName.startsWith('@') && this.packageName.includes('/')) {
371
+ normalizedPackageName = this.packageName.split('/')[0];
372
+ }
373
+ else if (this.packageName.startsWith('@')) {
374
+ const parts = this.packageName.split('/');
375
+ if (parts.length > 2) {
376
+ normalizedPackageName = `${parts[0]}/${parts[1]}`;
377
+ }
378
+ }
379
+ const packagePath = path.join(this.projectRoot, 'node_modules', normalizedPackageName);
345
380
  const packageJsonPath = path.join(packagePath, 'package.json');
346
381
  if (!fs.existsSync(packageJsonPath)) {
347
- logger.log(`📦 No package.json found for ${this.packageName}`);
382
+ logger.log(`📦 No package.json found for ${normalizedPackageName}`);
348
383
  return null;
349
384
  }
350
385
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
351
386
  const exports = {};
387
+ // GENERIC Framework-based discovery methods (prioritized by framework type)
388
+ logger.log(`🔧 Using GENERIC ${this.framework} framework discovery for ${this.packageName}...`);
389
+ // Vue framework: Parse ES module re-exports from lib/components/index.js
390
+ if (this.framework === 'vue') {
391
+ const vueComponents = this.discoverVueFrameworkComponents(packagePath);
392
+ if (vueComponents && Object.keys(vueComponents).length > 0) {
393
+ return vueComponents;
394
+ }
395
+ }
396
+ // Web Components framework: Parse custom-elements.json manifest
397
+ if (this.framework === 'web-components') {
398
+ const webComponents = this.discoverWebComponentsFromManifest(packagePath);
399
+ if (webComponents && Object.keys(webComponents).length > 0) {
400
+ return webComponents;
401
+ }
402
+ }
403
+ // Angular framework: Scan NgModule directories
404
+ if (this.framework === 'angular') {
405
+ const angularComponents = this.discoverAngularFrameworkComponents(packagePath);
406
+ if (angularComponents && Object.keys(angularComponents).length > 0) {
407
+ return angularComponents;
408
+ }
409
+ }
410
+ // Svelte framework: Check for CSS-only vs component packages
411
+ if (this.framework === 'svelte') {
412
+ const svelteComponents = this.discoverSvelteFrameworkComponents(packagePath, packageJson);
413
+ if (svelteComponents && Object.keys(svelteComponents).length > 0) {
414
+ return svelteComponents;
415
+ }
416
+ }
352
417
  // Method 1: Analyze package.json exports field
353
418
  if (packageJson.exports) {
354
419
  logger.log(`📋 Analyzing exports field in ${this.packageName}/package.json`);
@@ -373,6 +438,267 @@ export class DynamicPackageDiscovery {
373
438
  return null;
374
439
  }
375
440
  }
441
+ /**
442
+ * GENERIC Vue Framework Discovery: Parse ES module re-exports
443
+ * Works with Vue component libraries that use: export * from "./ComponentName/index.js" pattern
444
+ * Searches common locations: lib/components/, src/components/, components/
445
+ */
446
+ discoverVueFrameworkComponents(packagePath) {
447
+ try {
448
+ // GENERIC: Try multiple common component index locations
449
+ const possibleIndexPaths = [
450
+ path.join(packagePath, 'lib', 'components', 'index.js'),
451
+ path.join(packagePath, 'lib', 'components', 'index.mjs'),
452
+ path.join(packagePath, 'src', 'components', 'index.js'),
453
+ path.join(packagePath, 'src', 'components', 'index.ts'),
454
+ path.join(packagePath, 'components', 'index.js'),
455
+ path.join(packagePath, 'dist', 'components', 'index.js'),
456
+ ];
457
+ let componentsIndexPath = null;
458
+ for (const p of possibleIndexPaths) {
459
+ if (fs.existsSync(p)) {
460
+ componentsIndexPath = p;
461
+ logger.log(`📁 Found Vue components index at: ${p}`);
462
+ break;
463
+ }
464
+ }
465
+ if (!componentsIndexPath) {
466
+ logger.log(`📁 No Vue components index found in common locations`);
467
+ return null;
468
+ }
469
+ const content = fs.readFileSync(componentsIndexPath, 'utf-8');
470
+ const exports = {};
471
+ // GENERIC: Match ES module re-export patterns
472
+ // export * from "./ComponentName/index.js" or export * from "./ComponentName/index.mjs"
473
+ const reExportRegex = /export\s+\*\s+from\s+["']\.\/([^/]+)\/index(?:\.m?js)?["']/g;
474
+ let match;
475
+ while ((match = reExportRegex.exec(content)) !== null) {
476
+ const componentDir = match[1];
477
+ // Component name is the directory name
478
+ if (this.isComponentName(componentDir)) {
479
+ exports[componentDir] = () => { };
480
+ exports[componentDir].displayName = componentDir;
481
+ // GENERIC: Use relative path from package, not hardcoded design system name
482
+ const relativePath = path.relative(packagePath, componentsIndexPath);
483
+ const componentsDir = path.dirname(relativePath);
484
+ exports[componentDir].__componentPath = `${this.packageName}/${componentsDir}/${componentDir}`;
485
+ }
486
+ }
487
+ logger.log(`✅ Vue Framework: Found ${Object.keys(exports).length} components from ${path.basename(componentsIndexPath)}`);
488
+ return exports;
489
+ }
490
+ catch (error) {
491
+ logger.log(`❌ Vue framework discovery failed: ${error}`);
492
+ return null;
493
+ }
494
+ }
495
+ /**
496
+ * GENERIC Web Components Discovery: Parse custom-elements.json manifest
497
+ * Custom Elements Manifest is a standard spec for documenting Web Components
498
+ * Works with any Web Components library that provides a custom-elements.json manifest
499
+ */
500
+ discoverWebComponentsFromManifest(packagePath) {
501
+ try {
502
+ // GENERIC: Try multiple common locations for custom-elements.json manifest
503
+ const possiblePaths = [
504
+ path.join(packagePath, 'custom-elements.json'),
505
+ path.join(packagePath, 'dist', 'custom-elements.json'),
506
+ path.join(packagePath, 'cdn', 'custom-elements.json'),
507
+ path.join(packagePath, 'lib', 'custom-elements.json'),
508
+ path.join(packagePath, 'build', 'custom-elements.json'),
509
+ ];
510
+ let manifestPath = null;
511
+ for (const p of possiblePaths) {
512
+ if (fs.existsSync(p)) {
513
+ manifestPath = p;
514
+ logger.log(`📁 Found custom-elements.json manifest at: ${p}`);
515
+ break;
516
+ }
517
+ }
518
+ if (!manifestPath) {
519
+ logger.log(`📁 No custom-elements.json manifest found in common locations`);
520
+ return null;
521
+ }
522
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
523
+ const exports = {};
524
+ // custom-elements.json structure (standard spec):
525
+ // { modules: [{ declarations: [{ kind: "class", name: "SlAlert", tagName: "sl-alert" }] }] }
526
+ if (manifest.modules && Array.isArray(manifest.modules)) {
527
+ for (const module of manifest.modules) {
528
+ if (module.declarations && Array.isArray(module.declarations)) {
529
+ for (const declaration of module.declarations) {
530
+ // Look for class declarations that are Custom Elements
531
+ if (declaration.kind === 'class' && declaration.name && declaration.tagName) {
532
+ const componentName = declaration.name;
533
+ exports[componentName] = () => { };
534
+ exports[componentName].displayName = componentName;
535
+ // GENERIC: Use package name, not hardcoded design system name
536
+ exports[componentName].__componentPath = `${this.packageName}/${module.path || ''}`;
537
+ exports[componentName].__tagName = declaration.tagName;
538
+ }
539
+ }
540
+ }
541
+ }
542
+ }
543
+ logger.log(`✅ Web Components: Found ${Object.keys(exports).length} components from custom-elements.json`);
544
+ return exports;
545
+ }
546
+ catch (error) {
547
+ logger.log(`❌ Web Components manifest discovery failed: ${error}`);
548
+ return null;
549
+ }
550
+ }
551
+ /**
552
+ * GENERIC Angular Framework Discovery: Scan module directories
553
+ * Works with Angular component libraries that use NgModule patterns
554
+ * Discovers modules based on directory structure and file patterns
555
+ */
556
+ discoverAngularFrameworkComponents(packagePath) {
557
+ try {
558
+ const entries = fs.readdirSync(packagePath, { withFileTypes: true });
559
+ const exports = {};
560
+ // GENERIC: Common Angular-specific directories to exclude
561
+ const excludedDirs = new Set([
562
+ 'node_modules', 'schematics', 'prebuilt-themes', 'core',
563
+ 'esm2022', 'fesm2022', 'esm2020', 'fesm2020', 'esm2015', 'fesm2015',
564
+ 'testing', 'bundles', 'cdk', 'src', 'lib', 'dist'
565
+ ]);
566
+ // Filter to potential component module directories
567
+ const componentModules = entries.filter(entry => entry.isDirectory() &&
568
+ !entry.name.startsWith('.') &&
569
+ !entry.name.startsWith('_') &&
570
+ !excludedDirs.has(entry.name));
571
+ for (const moduleDir of componentModules) {
572
+ const moduleName = moduleDir.name;
573
+ const modulePath = path.join(packagePath, moduleName);
574
+ // GENERIC: Check if this directory contains Angular-relevant content
575
+ let hasContent = false;
576
+ try {
577
+ const moduleContents = fs.readdirSync(modulePath);
578
+ hasContent = moduleContents.some(f => f.endsWith('.scss') ||
579
+ f.endsWith('.css') ||
580
+ f.includes('index') ||
581
+ f.endsWith('.html') ||
582
+ f.endsWith('.module.ts') ||
583
+ f.endsWith('.component.ts'));
584
+ }
585
+ catch {
586
+ continue;
587
+ }
588
+ if (hasContent) {
589
+ // GENERIC: Convert directory name to Angular component name pattern
590
+ // "button" -> "MatButton" or "MyButton" depending on package naming
591
+ // Try to detect prefix from package name
592
+ let prefix = 'Mat';
593
+ const packageNameParts = this.packageName.split('/');
594
+ const baseName = packageNameParts[packageNameParts.length - 1];
595
+ if (baseName && baseName !== 'material') {
596
+ // Use first 3 chars capitalized as prefix (e.g., @mylib/ui -> "Myl")
597
+ prefix = baseName.charAt(0).toUpperCase() + baseName.slice(1, 3);
598
+ }
599
+ const componentName = prefix + moduleName
600
+ .split('-')
601
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
602
+ .join('');
603
+ exports[componentName] = () => { };
604
+ exports[componentName].displayName = componentName;
605
+ // GENERIC: Use actual package name, not hardcoded
606
+ exports[componentName].__componentPath = `${this.packageName}/${moduleName}`;
607
+ exports[componentName].__moduleName = moduleName;
608
+ }
609
+ }
610
+ logger.log(`✅ Angular Framework: Found ${Object.keys(exports).length} component modules`);
611
+ return exports;
612
+ }
613
+ catch (error) {
614
+ logger.log(`❌ Angular framework discovery failed: ${error}`);
615
+ return null;
616
+ }
617
+ }
618
+ /**
619
+ * GENERIC Svelte Framework Discovery: Scan for .svelte component files
620
+ * Works with any Svelte component library that includes .svelte files
621
+ * Searches common locations: dist/, src/, lib/, components/
622
+ * Also detects CSS-only packages that provide no Svelte components
623
+ */
624
+ discoverSvelteFrameworkComponents(packagePath, packageJson) {
625
+ try {
626
+ const exports = {};
627
+ // GENERIC: Try multiple common locations for Svelte components
628
+ const possibleDirs = [
629
+ path.join(packagePath, 'dist'),
630
+ path.join(packagePath, 'src'),
631
+ path.join(packagePath, 'lib'),
632
+ path.join(packagePath, 'components'),
633
+ path.join(packagePath, 'build'),
634
+ ];
635
+ for (const searchDir of possibleDirs) {
636
+ if (!fs.existsSync(searchDir))
637
+ continue;
638
+ const entries = fs.readdirSync(searchDir, { withFileTypes: true });
639
+ for (const entry of entries) {
640
+ if (entry.isDirectory()) {
641
+ // Check for .svelte files in subdirectory
642
+ const subPath = path.join(searchDir, entry.name);
643
+ try {
644
+ const files = fs.readdirSync(subPath);
645
+ for (const file of files) {
646
+ if (file.endsWith('.svelte')) {
647
+ const componentName = file.replace('.svelte', '');
648
+ if (this.isComponentName(componentName)) {
649
+ exports[componentName] = () => { };
650
+ exports[componentName].displayName = componentName;
651
+ // GENERIC: Use package name, not hardcoded design system name
652
+ const relativePath = path.relative(packagePath, subPath);
653
+ exports[componentName].__componentPath = `${this.packageName}/${relativePath}`;
654
+ }
655
+ }
656
+ }
657
+ }
658
+ catch {
659
+ continue;
660
+ }
661
+ }
662
+ else if (entry.name.endsWith('.svelte')) {
663
+ // Direct .svelte files in the directory
664
+ const componentName = entry.name.replace('.svelte', '');
665
+ if (this.isComponentName(componentName)) {
666
+ exports[componentName] = () => { };
667
+ exports[componentName].displayName = componentName;
668
+ const relativePath = path.relative(packagePath, searchDir);
669
+ exports[componentName].__componentPath = `${this.packageName}/${relativePath}`;
670
+ }
671
+ }
672
+ }
673
+ if (Object.keys(exports).length > 0) {
674
+ logger.log(`📁 Found Svelte components in: ${searchDir}`);
675
+ break;
676
+ }
677
+ }
678
+ // GENERIC: Check if package.json exports only CSS (no components)
679
+ if (packageJson.exports && Object.keys(exports).length === 0) {
680
+ const mainExport = packageJson.exports['.'];
681
+ const isCSSOnly = (typeof mainExport === 'object')
682
+ ? (mainExport.import?.endsWith('.css') || mainExport.style?.endsWith('.css'))
683
+ : (typeof mainExport === 'string' && mainExport.endsWith('.css'));
684
+ if (isCSSOnly) {
685
+ logger.log(`⚠️ ${this.packageName} is CSS-only (Tailwind/CSS utilities). No Svelte components available.`);
686
+ logger.log(`💡 This package provides CSS utilities only. Use standard HTML elements with its CSS classes.`);
687
+ // Return a special marker indicating CSS-only
688
+ exports['__CSS_ONLY__'] = true;
689
+ exports['__MESSAGE__'] = `${this.packageName} provides CSS utilities only. Use standard HTML elements with CSS classes.`;
690
+ }
691
+ }
692
+ if (Object.keys(exports).length > 0 && !exports['__CSS_ONLY__']) {
693
+ logger.log(`✅ Svelte Framework: Found ${Object.keys(exports).length} components`);
694
+ }
695
+ return Object.keys(exports).length > 0 ? exports : null;
696
+ }
697
+ catch (error) {
698
+ logger.log(`❌ Svelte framework discovery failed: ${error}`);
699
+ return null;
700
+ }
701
+ }
376
702
  /**
377
703
  * Scan package subdirectories for components (e.g., antd/button, chakra-ui/input)
378
704
  */
@@ -1 +1 @@
1
- {"version":3,"file":"enhancedComponentDiscovery.d.ts","sourceRoot":"","sources":["../../story-generator/enhancedComponentDiscovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,iBAAiB,GAAG,YAAY,CAAC;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,oBAAoB,CAA6C;IACzE,OAAO,CAAC,2BAA2B,CAA0B;gBAEjD,MAAM,EAAE,aAAa;IAIjC;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA2CjD;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAyCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAWvB;;GAED;IACH,OAAO,CAAC,cAAc;IAmBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IA6GvB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA6B9B;;KAEC;YACW,sBAAsB;IAsEpC;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAiJtC;;OAEG;YACW,sBAAsB;IAsCpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA0B5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAiBpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkC3B;;OAEG;YACW,0BAA0B;IAmCxC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAcnC;;OAEG;YACW,sBAAsB;IAMpC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA4CjC;;OAEG;IACG,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC9D,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,CAAC;IAwCF;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAwC5B;;OAEG;IACH,0BAA0B,IAAI,MAAM,EAAE;CAMvC"}
1
+ {"version":3,"file":"enhancedComponentDiscovery.d.ts","sourceRoot":"","sources":["../../story-generator/enhancedComponentDiscovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,iBAAiB,GAAG,YAAY,CAAC;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,oBAAoB,CAA6C;IACzE,OAAO,CAAC,2BAA2B,CAA0B;gBAEjD,MAAM,EAAE,aAAa;IAIjC;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA2CjD;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAyCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAWvB;;GAED;IACH,OAAO,CAAC,cAAc;IAmBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IA6GvB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA6B9B;;KAEC;YACW,sBAAsB;IAgGpC;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAoRtC;;OAEG;YACW,sBAAsB;IAsCpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA0B5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAiBpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkC3B;;OAEG;YACW,0BAA0B;IAmCxC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAcnC;;OAEG;YACW,sBAAsB;IAMpC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA4CjC;;OAEG;IACG,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC9D,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,CAAC;IAwCF;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAwC5B;;OAEG;IACH,0BAA0B,IAAI,MAAM,EAAE;CAMvC"}
@@ -259,7 +259,23 @@ export class EnhancedComponentDiscovery {
259
259
  async discoverFromNpmPackage(source) {
260
260
  // Determine the project root from the generated stories path
261
261
  const projectRoot = this.getProjectRoot();
262
- const packagePath = path.join(projectRoot, 'node_modules', source.path);
262
+ // Normalize package paths with subpath exports to their base package
263
+ // e.g., 'vuetify/components' -> 'vuetify', '@scope/pkg/sub' -> '@scope/pkg'
264
+ let normalizedPackageName = source.path;
265
+ if (!source.path.startsWith('@') && source.path.includes('/')) {
266
+ // Non-scoped package with subpath: extract base name
267
+ normalizedPackageName = source.path.split('/')[0];
268
+ logger.log(`🔧 Normalizing package path: ${source.path} → ${normalizedPackageName}`);
269
+ }
270
+ else if (source.path.startsWith('@')) {
271
+ // Scoped package: keep @scope/name, strip anything after
272
+ const parts = source.path.split('/');
273
+ if (parts.length > 2) {
274
+ normalizedPackageName = `${parts[0]}/${parts[1]}`;
275
+ logger.log(`🔧 Normalizing scoped package path: ${source.path} → ${normalizedPackageName}`);
276
+ }
277
+ }
278
+ const packagePath = path.join(projectRoot, 'node_modules', normalizedPackageName);
263
279
  // Helper function to load known components as fallback
264
280
  const loadFallbackComponents = () => {
265
281
  logger.log(`📋 ${source.path}: Using static component list (design system detected)`);
@@ -284,7 +300,7 @@ export class EnhancedComponentDiscovery {
284
300
  }
285
301
  logger.log(`🔍 Dynamically discovering components from ${source.path}...`);
286
302
  // Use dynamic discovery to get real exports
287
- const dynamicDiscovery = new DynamicPackageDiscovery(source.path, projectRoot);
303
+ const dynamicDiscovery = new DynamicPackageDiscovery(source.path, projectRoot, this.config.componentFramework);
288
304
  const packageExports = await dynamicDiscovery.getRealPackageExports();
289
305
  if (!packageExports) {
290
306
  // Fallback to predefined components if dynamic discovery fails
@@ -295,6 +311,14 @@ export class EnhancedComponentDiscovery {
295
311
  const realComponents = packageExports.components.filter(comp => comp.isComponent);
296
312
  console.log(`✅ Found ${realComponents.length} real components in ${source.path} v${packageExports.packageVersion}`);
297
313
  logger.log(`📦 Available components: ${realComponents.map(c => c.name).join(', ')}`);
314
+ // If dynamic discovery found 0 components, use fallback list
315
+ if (realComponents.length === 0) {
316
+ logger.log(`🔄 No components found dynamically, checking for known design system fallback...`);
317
+ loadFallbackComponents();
318
+ if (this.discoveredComponents.size > 0) {
319
+ return; // Fallback loaded successfully
320
+ }
321
+ }
298
322
  for (const realComp of realComponents) {
299
323
  // Get enhanced metadata from predefined list if available
300
324
  const knownComponents = this.getKnownDesignSystemComponents(source.path);
@@ -452,6 +476,129 @@ export class EnhancedComponentDiscovery {
452
476
  category: this.categorizeComponent(name, '')
453
477
  }));
454
478
  }
479
+ // Vuetify fallback components (Vue 3)
480
+ if (packageName === 'vuetify' || packageName === 'vuetify/components') {
481
+ const vuetifyComponents = [
482
+ // Layout
483
+ 'VApp', 'VMain', 'VContainer', 'VRow', 'VCol', 'VSpacer', 'VDivider', 'VFooter', 'VToolbar',
484
+ 'VAppBar', 'VNavigationDrawer', 'VSheet', 'VCard', 'VCardTitle', 'VCardSubtitle', 'VCardText', 'VCardActions',
485
+ // Buttons & Actions
486
+ 'VBtn', 'VBtnToggle', 'VFab', 'VSpeedDial',
487
+ // Inputs & Forms
488
+ 'VTextField', 'VTextarea', 'VSelect', 'VAutocomplete', 'VCombobox', 'VCheckbox', 'VRadio', 'VRadioGroup',
489
+ 'VSwitch', 'VSlider', 'VRangeSlider', 'VFileInput', 'VForm', 'VColorPicker', 'VDatePicker', 'VTimePicker',
490
+ 'VOtpInput', 'VNumberInput',
491
+ // Data Display
492
+ 'VAvatar', 'VBadge', 'VChip', 'VChipGroup', 'VImg', 'VIcon', 'VList', 'VListItem', 'VListItemTitle',
493
+ 'VListItemSubtitle', 'VListItemAction', 'VTable', 'VDataTable', 'VDataTableServer', 'VDataTableVirtual',
494
+ 'VTimeline', 'VTimelineItem', 'VTooltip', 'VExpansionPanels', 'VExpansionPanel', 'VExpansionPanelTitle',
495
+ 'VExpansionPanelText', 'VTreeview', 'VVirtualScroll',
496
+ // Navigation
497
+ 'VTabs', 'VTab', 'VTabsWindow', 'VTabsWindowItem', 'VMenu', 'VBreadcrumbs', 'VBreadcrumbsItem',
498
+ 'VPagination', 'VBottomNavigation', 'VStepper', 'VStepperHeader', 'VStepperItem', 'VStepperContent',
499
+ // Feedback
500
+ 'VAlert', 'VSnackbar', 'VProgressLinear', 'VProgressCircular', 'VSkeleton', 'VSkeletonLoader',
501
+ 'VDialog', 'VBottomSheet', 'VOverlay', 'VBanner',
502
+ // Typography
503
+ 'VSystemBar', 'VLabel',
504
+ // Misc
505
+ 'VCarousel', 'VCarouselItem', 'VParallax', 'VRating', 'VHover', 'VLazy', 'VThemeProvider',
506
+ 'VDefaultsProvider', 'VLocaleProvider', 'VResponsive', 'VNoSsr', 'VInfiniteScroll'
507
+ ];
508
+ return vuetifyComponents.map(name => ({
509
+ name,
510
+ description: `${name} component from Vuetify`,
511
+ category: this.categorizeComponent(name, '')
512
+ }));
513
+ }
514
+ // Angular Material fallback components
515
+ if (packageName === '@angular/material' || packageName.startsWith('@angular/material/')) {
516
+ const angularMaterialComponents = [
517
+ // Form Controls
518
+ 'MatAutocomplete', 'MatCheckbox', 'MatDatepicker', 'MatFormField', 'MatInput', 'MatRadioButton',
519
+ 'MatRadioGroup', 'MatSelect', 'MatSlider', 'MatSlideToggle',
520
+ // Navigation
521
+ 'MatMenu', 'MatSidenav', 'MatToolbar', 'MatList', 'MatListItem', 'MatNavList', 'MatTabs',
522
+ 'MatTabGroup', 'MatStepper',
523
+ // Layout
524
+ 'MatCard', 'MatCardHeader', 'MatCardTitle', 'MatCardContent', 'MatCardActions', 'MatDivider',
525
+ 'MatExpansionPanel', 'MatAccordion', 'MatGridList', 'MatGridTile',
526
+ // Buttons & Indicators
527
+ 'MatButton', 'MatButtonToggle', 'MatButtonToggleGroup', 'MatBadge', 'MatChip', 'MatChipList',
528
+ 'MatChipListbox', 'MatIcon', 'MatProgressSpinner', 'MatProgressBar', 'MatRipple',
529
+ // Popups & Modals
530
+ 'MatDialog', 'MatDialogTitle', 'MatDialogContent', 'MatDialogActions', 'MatSnackBar',
531
+ 'MatTooltip', 'MatBottomSheet',
532
+ // Data Table
533
+ 'MatTable', 'MatSort', 'MatSortHeader', 'MatPaginator',
534
+ // Tree
535
+ 'MatTree', 'MatTreeNode', 'MatNestedTreeNode'
536
+ ];
537
+ return angularMaterialComponents.map(name => ({
538
+ name,
539
+ description: `${name} component from Angular Material`,
540
+ category: this.categorizeComponent(name, '')
541
+ }));
542
+ }
543
+ // Skeleton UI fallback components (Svelte)
544
+ if (packageName === '@skeletonlabs/skeleton' || packageName === '@skeletonlabs/skeleton-svelte') {
545
+ const skeletonComponents = [
546
+ // Layout
547
+ 'AppShell', 'AppBar', 'AppRail', 'AppRailTile', 'AppRailAnchor',
548
+ // Navigation
549
+ 'TabGroup', 'Tab', 'TabAnchor', 'Stepper', 'Step', 'Pagination',
550
+ // Surfaces
551
+ 'Card', 'Accordion', 'AccordionItem',
552
+ // Input
553
+ 'FileButton', 'FileDropzone', 'SlideToggle', 'RadioGroup', 'RangeSlider',
554
+ 'InputChip', 'Autocomplete', 'ListBox', 'ListBoxItem', 'Ratings',
555
+ // Feedback
556
+ 'Alert', 'Toast', 'ProgressBar', 'ProgressRadial', 'Drawer', 'Modal',
557
+ // Visualization
558
+ 'Avatar', 'CodeBlock', 'Table', 'TableBody', 'TableHead',
559
+ // Utility
560
+ 'Popup', 'ConicGradient', 'GradientHeading', 'LightSwitch',
561
+ // Typography
562
+ 'Typography'
563
+ ];
564
+ return skeletonComponents.map(name => ({
565
+ name,
566
+ description: `${name} component from Skeleton UI`,
567
+ category: this.categorizeComponent(name, '')
568
+ }));
569
+ }
570
+ // Shoelace fallback components (Web Components)
571
+ if (packageName === '@shoelace-style/shoelace') {
572
+ const shoelaceComponents = [
573
+ // Layout
574
+ 'SlCard', 'SlDivider', 'SlDrawer', 'SlDialog', 'SlDetails', 'SlPopup', 'SlCarousel',
575
+ 'SlCarouselItem', 'SlSplitPanel', 'SlResizeObserver',
576
+ // Buttons & Actions
577
+ 'SlButton', 'SlButtonGroup', 'SlCopyButton', 'SlIconButton',
578
+ // Form Controls
579
+ 'SlInput', 'SlSelect', 'SlOption', 'SlOptgroup', 'SlTextarea', 'SlCheckbox',
580
+ 'SlRadio', 'SlRadioButton', 'SlRadioGroup', 'SlSwitch', 'SlRange',
581
+ 'SlColorPicker', 'SlRating',
582
+ // Data Display
583
+ 'SlAvatar', 'SlBadge', 'SlTag', 'SlIcon', 'SlImage', 'SlImageComparer',
584
+ 'SlFormatBytes', 'SlFormatDate', 'SlFormatNumber', 'SlRelativeTime', 'SlQrCode',
585
+ 'SlTree', 'SlTreeItem',
586
+ // Navigation
587
+ 'SlBreadcrumb', 'SlBreadcrumbItem', 'SlMenu', 'SlMenuItem', 'SlMenuLabel',
588
+ 'SlTab', 'SlTabGroup', 'SlTabPanel',
589
+ // Feedback
590
+ 'SlAlert', 'SlProgressBar', 'SlProgressRing', 'SlSpinner', 'SlSkeleton',
591
+ 'SlTooltip',
592
+ // Typography & Misc
593
+ 'SlAnimatedImage', 'SlAnimation', 'SlInclude', 'SlMutationObserver',
594
+ 'SlVisuallyHidden'
595
+ ];
596
+ return shoelaceComponents.map(name => ({
597
+ name,
598
+ description: `${name} component from Shoelace`,
599
+ category: this.categorizeComponent(name, '')
600
+ }));
601
+ }
455
602
  // Default: return empty array
456
603
  return [];
457
604
  }
@@ -50,6 +50,7 @@ export declare abstract class BaseFrameworkAdapter implements FrameworkAdapter {
50
50
  generateImports(components: DiscoveredComponent[], config: StoryUIConfig): string;
51
51
  /**
52
52
  * Post-process generated story content
53
+ * Removes React imports for non-React frameworks as a safety net
53
54
  */
54
55
  postProcess(storyContent: string): string;
55
56
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"base-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/base-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D;;GAEG;AACH,8BAAsB,oBAAqB,YAAW,gBAAgB;IACpE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,wBAAwB,EAAE,cAAc,EAAE,CAAC;IAC7D,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,oBAAoB,CAC3B,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM;IAET;;OAEG;IACH,0BAA0B,CACxB,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,MAAM;IAmBT;;OAEG;IACH,SAAS,CAAC,oBAAoB,CAC5B,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,aAAa,GACpB,MAAM;IAkBT;;OAEG;IACH,SAAS,CAAC,aAAa,CACrB,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,aAAa,GACpB,MAAM;IAUT;;OAEG;IACH,SAAS,CAAC,wBAAwB,CAChC,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAcxC;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAExD;;OAEG;IACH,QAAQ,CAAC,mBAAmB,CAC1B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IAET;;OAEG;IACH,eAAe,CACb,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,MAAM;IAoBT;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAQzC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAkBpE;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IAEnE;;OAEG;IACH,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIpE;;OAEG;IACH,SAAS,CAAC,cAAc,IAAI,MAAM;CAoBnC"}
1
+ {"version":3,"file":"base-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/base-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D;;GAEG;AACH,8BAAsB,oBAAqB,YAAW,gBAAgB;IACpE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,wBAAwB,EAAE,cAAc,EAAE,CAAC;IAC7D,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,oBAAoB,CAC3B,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM;IAET;;OAEG;IACH,0BAA0B,CACxB,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,MAAM;IAmBT;;OAEG;IACH,SAAS,CAAC,oBAAoB,CAC5B,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,aAAa,GACpB,MAAM;IAkBT;;OAEG;IACH,SAAS,CAAC,aAAa,CACrB,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,aAAa,GACpB,MAAM;IAUT;;OAEG;IACH,SAAS,CAAC,wBAAwB,CAChC,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAcxC;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAExD;;OAEG;IACH,QAAQ,CAAC,mBAAmB,CAC1B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IAET;;OAEG;IACH,eAAe,CACb,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,MAAM;IAoBT;;;OAGG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAmBzC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAkBpE;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IAEnE;;OAEG;IACH,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIpE;;OAEG;IACH,SAAS,CAAC,cAAc,IAAI,MAAM;CAoBnC"}
@@ -90,13 +90,23 @@ export class BaseFrameworkAdapter {
90
90
  }
91
91
  /**
92
92
  * Post-process generated story content
93
+ * Removes React imports for non-React frameworks as a safety net
93
94
  */
94
95
  postProcess(storyContent) {
95
- // Default implementation - can be overridden by subclasses
96
- return storyContent
96
+ let processed = storyContent
97
97
  .trim()
98
98
  .replace(/\r\n/g, '\n')
99
99
  .replace(/\n{3,}/g, '\n\n');
100
+ // For non-React frameworks, remove any React imports that may have been generated
101
+ // This is a safety net in case the LLM generates React imports for non-React frameworks
102
+ if (this.type !== 'react') {
103
+ processed = processed.replace(/import React from ['"]react['"];?\n?/g, '');
104
+ processed = processed.replace(/import \* as React from ['"]react['"];?\n?/g, '');
105
+ processed = processed.replace(/import { React } from ['"]react['"];?\n?/g, '');
106
+ // Clean up any resulting empty lines at the start of the file
107
+ processed = processed.replace(/^\n+/, '');
108
+ }
109
+ return processed;
100
110
  }
101
111
  /**
102
112
  * Validate generated story syntax
@@ -1 +1 @@
1
- {"version":3,"file":"react-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/react-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,YAAa,SAAQ,oBAAoB;IACpD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAW;IACvC,QAAQ,CAAC,IAAI,WAAW;IACxB,QAAQ,CAAC,wBAAwB,EAAE,cAAc,EAAE,CAIjD;IACF,QAAQ,CAAC,gBAAgB,kBAAkB;IAE3C,oBAAoB,CAClB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM;IA+GT;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAgE/C,mBAAmB,CACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IA4CT,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IA0B1D;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IA4BzC;;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,kBAAkB,IAAI,YAAY,CAEjD"}
1
+ {"version":3,"file":"react-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/react-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,YAAa,SAAQ,oBAAoB;IACpD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAW;IACvC,QAAQ,CAAC,IAAI,WAAW;IACxB,QAAQ,CAAC,wBAAwB,EAAE,cAAc,EAAE,CAIjD;IACF,QAAQ,CAAC,gBAAgB,kBAAkB;IAE3C,oBAAoB,CAClB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM;IA+GT;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAkE/C,mBAAmB,CACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IA4CT,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IA0B1D;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IA4BzC;;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,kBAAkB,IAAI,YAAY,CAEjD"}
@@ -146,6 +146,7 @@ const meta: Meta<typeof Button> = {
146
146
  title: 'Components/Button',
147
147
  component: Button,
148
148
  parameters: { layout: 'centered' },
149
+ tags: ['autodocs'],
149
150
  argTypes: {
150
151
  variant: {
151
152
  control: 'select',
@@ -175,6 +176,7 @@ import { Card, Button, Text } from '${lib}';
175
176
  const meta: Meta = {
176
177
  title: 'Examples/Card Layout',
177
178
  parameters: { layout: 'padded' },
179
+ tags: ['autodocs'],
178
180
  };
179
181
 
180
182
  export default meta;
@@ -1 +1 @@
1
- {"version":3,"file":"svelte-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/svelte-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,aAAc,SAAQ,oBAAoB;IACrD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAY;IACxC,QAAQ,CAAC,IAAI,YAAY;IACzB,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;IAqGT,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IA0I/C,mBAAmB,CACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IA4CT,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IAsB1D;;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;IAwBpE;;OAEG;IACH,eAAe,CACb,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,MAAM;CAWV;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD"}
1
+ {"version":3,"file":"svelte-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/svelte-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,aAAc,SAAQ,oBAAoB;IACrD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAY;IACxC,QAAQ,CAAC,IAAI,YAAY;IACzB,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;IA8GT,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAuJ/C,mBAAmB,CACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IA4CT,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IAsB1D;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAiDzC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAwBpE;;OAEG;IACH,eAAe,CACb,UAAU,EAAE,mBAAmB,EAAE,EACjC,MAAM,EAAE,aAAa,GACpB,MAAM;CAWV;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD"}