@tpitre/story-ui 4.7.0 → 4.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.
package/dist/cli/index.js CHANGED
@@ -30,12 +30,16 @@ program
30
30
  .description('Start the Story UI server')
31
31
  .option('-p, --port <port>', 'Port to run the server on', '4001')
32
32
  .option('-c, --config <config>', 'Path to configuration file')
33
+ .option('--mcp', 'Also start MCP stdio server for Claude Desktop integration')
33
34
  .action(async (options) => {
34
- console.log('šŸš€ Starting Story UI server...');
35
+ // Use stderr for all logging to avoid breaking MCP JSON-RPC protocol
36
+ // when Claude Desktop spawns this process
37
+ console.error('šŸš€ Starting Story UI server...');
35
38
  // Use absolute path to avoid dist/dist issue when package is linked
36
39
  const pkgRoot = path.resolve(__dirname, '..');
37
40
  const serverPath = path.join(pkgRoot, 'mcp-server/index.js');
38
- console.log(`āœ… Using MCP server at: ${serverPath}`);
41
+ const mcpStdioPath = path.join(pkgRoot, 'mcp-server/mcp-stdio-server.js');
42
+ console.error(`āœ… Using HTTP server at: ${serverPath}`);
39
43
  // FIRST_EDIT: determine an available port
40
44
  const requestedPort = parseInt(options.port || '4001', 10);
41
45
  const isPortFree = (port) => {
@@ -55,7 +59,7 @@ program
55
59
  finalPort += 1;
56
60
  }
57
61
  if (finalPort !== requestedPort) {
58
- console.log(`āš ļø Port ${requestedPort} is in use. Using ${finalPort} instead.`);
62
+ console.error(`āš ļø Port ${requestedPort} is in use. Using ${finalPort} instead.`);
59
63
  }
60
64
  const env = { ...process.env, PORT: String(finalPort) };
61
65
  // Set memory limit to prevent heap exhaustion during vision/image processing
@@ -66,16 +70,53 @@ program
66
70
  if (options.config) {
67
71
  env.STORY_UI_CONFIG_PATH = options.config;
68
72
  }
73
+ // Log the working directory for debugging
74
+ console.error(`šŸ“ Working directory: ${process.cwd()}`);
75
+ // Redirect child stdout to stderr to avoid breaking MCP JSON-RPC protocol
76
+ // when Claude Desktop spawns this process. The HTTP server logs will still
77
+ // be visible but won't interfere with MCP communication.
69
78
  const server = spawn('node', [serverPath], {
70
- stdio: 'inherit',
71
- env
79
+ stdio: ['ignore', 'pipe', 'inherit'],
80
+ env,
81
+ cwd: process.cwd() // Explicitly pass cwd to ensure config is found
72
82
  });
83
+ // Pipe child's stdout to stderr so logs are visible without breaking MCP
84
+ if (server.stdout) {
85
+ server.stdout.pipe(process.stderr);
86
+ }
73
87
  server.on('close', (code) => {
74
- console.log(`Server exited with code ${code}`);
75
- });
76
- process.on('SIGINT', () => {
77
- server.kill('SIGINT');
88
+ console.error(`HTTP server exited with code ${code}`);
78
89
  });
90
+ // If --mcp flag is set, also start the MCP stdio server for Claude Desktop
91
+ // This allows a single command to run both HTTP server and MCP protocol handler
92
+ if (options.mcp) {
93
+ console.error('šŸ“” Starting MCP stdio server for Claude Desktop...');
94
+ // Wait a moment for HTTP server to start
95
+ await new Promise(resolve => setTimeout(resolve, 1000));
96
+ const mcpEnv = {
97
+ ...process.env,
98
+ STORY_UI_HTTP_PORT: String(finalPort)
99
+ };
100
+ // Spawn MCP stdio server with stdin/stdout inherited for JSON-RPC communication
101
+ const mcpServer = spawn('node', [mcpStdioPath], {
102
+ stdio: 'inherit',
103
+ env: mcpEnv,
104
+ cwd: process.cwd() // Explicitly pass cwd to ensure config is found
105
+ });
106
+ mcpServer.on('close', (code) => {
107
+ console.error(`MCP stdio server exited with code ${code}`);
108
+ server.kill('SIGTERM');
109
+ });
110
+ process.on('SIGINT', () => {
111
+ mcpServer.kill('SIGINT');
112
+ server.kill('SIGINT');
113
+ });
114
+ }
115
+ else {
116
+ process.on('SIGINT', () => {
117
+ server.kill('SIGINT');
118
+ });
119
+ }
79
120
  });
80
121
  program
81
122
  .command('config')
@@ -769,8 +769,8 @@ if (storybookProxyEnabled) {
769
769
  }
770
770
  // Start server
771
771
  app.listen(PORT, () => {
772
- console.log(`MCP server running on port ${PORT}`);
773
- console.log(`Stories will be generated to: ${config.generatedStoriesPath}`);
772
+ console.error(`MCP server running on port ${PORT}`);
773
+ console.error(`Stories will be generated to: ${config.generatedStoriesPath}`);
774
774
  }).on('error', (err) => {
775
775
  if (err.code === 'EADDRINUSE') {
776
776
  console.error(`\nāŒ Port ${PORT} is already in use!`);
@@ -12,7 +12,8 @@ import { fileURLToPath } from 'url';
12
12
  // Get package version dynamically
13
13
  const __filename_mcp = fileURLToPath(import.meta.url);
14
14
  const __dirname_mcp = path.dirname(__filename_mcp);
15
- const packageJsonPath = path.resolve(__dirname_mcp, '../package.json');
15
+ // Go up two levels from dist/mcp-server/ to reach the project root
16
+ const packageJsonPath = path.resolve(__dirname_mcp, '../../package.json');
16
17
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
17
18
  const PACKAGE_VERSION = packageJson.version;
18
19
  // Check for working directory override from environment or command line
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAW5C,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAkC9D;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DA8CzD"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../mcp-server/routes/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAW5C,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAkC9D;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,2DAgDzD"}
@@ -58,19 +58,21 @@ export async function getProps(req, res) {
58
58
  // Find the requested component
59
59
  const comp = cachedComponents.find(c => c.name === component);
60
60
  if (!comp) {
61
- return res.json([]);
61
+ return res.json({});
62
62
  }
63
- // Return props in a format compatible with existing UI
64
- const props = comp.props.map((prop) => ({
65
- name: prop,
66
- type: 'string', // We'd need more sophisticated type detection
67
- description: `${prop} property`,
68
- required: false
69
- }));
70
- res.json(props);
63
+ // Return props as an object keyed by prop name (for MCP handler compatibility)
64
+ const propsObject = {};
65
+ for (const prop of comp.props) {
66
+ propsObject[prop] = {
67
+ type: 'string', // We'd need more sophisticated type detection
68
+ description: `${prop} property`,
69
+ required: false
70
+ };
71
+ }
72
+ res.json(propsObject);
71
73
  }
72
74
  catch (error) {
73
75
  console.error('Error getting component props:', error);
74
- res.json([]);
76
+ res.json({});
75
77
  }
76
78
  }
@@ -84,8 +84,23 @@ export declare class EnhancedComponentDiscovery {
84
84
  private extractComponentNames;
85
85
  /**
86
86
  * Extract props from file content
87
+ * Supports multiple patterns:
88
+ * - TypeScript interfaces (interface ButtonProps { variant: ... })
89
+ * - PropTypes (Component.propTypes = { variant: ... })
90
+ * - Function parameter destructuring ({ className, variant, ...props }: Props)
91
+ * - VariantProps from class-variance-authority
87
92
  */
88
93
  private extractPropsFromFile;
94
+ /**
95
+ * Extract props from function parameter destructuring patterns
96
+ * Works with React, Vue <script setup>, and other frameworks
97
+ */
98
+ private extractDestructuredProps;
99
+ /**
100
+ * Extract props from co-located story file (e.g., Button.stories.tsx)
101
+ * This is a fallback for components like shadcn/ui that don't use interface Props patterns
102
+ */
103
+ private extractPropsFromStoryFile;
89
104
  /**
90
105
  * Extract slots from content
91
106
  */
@@ -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;AAWtD,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;IAC7D,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,MAAM,EAAE,aAAa;IAKjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;;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;IA+CpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAmC7B;;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;AAWtD,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;IAC7D,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,MAAM,EAAE,aAAa;IAKjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;;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;IAwDpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAmC7B;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAyD5B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAkChC;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IA2EjC;;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"}
@@ -654,7 +654,15 @@ export class EnhancedComponentDiscovery {
654
654
  if (this.shouldSkipComponent(componentName, content)) {
655
655
  continue;
656
656
  }
657
- const props = this.extractPropsFromFile(content);
657
+ let props = this.extractPropsFromFile(content);
658
+ // Always check co-located story file for additional props (argTypes, args)
659
+ // Story files often define props that aren't in the component source (e.g., disabled, children)
660
+ const storyProps = this.extractPropsFromStoryFile(file);
661
+ for (const prop of storyProps) {
662
+ if (!props.includes(prop)) {
663
+ props.push(prop);
664
+ }
665
+ }
658
666
  this.discoveredComponents.set(componentName, {
659
667
  name: componentName,
660
668
  filePath: file,
@@ -765,6 +773,11 @@ export class EnhancedComponentDiscovery {
765
773
  }
766
774
  /**
767
775
  * Extract props from file content
776
+ * Supports multiple patterns:
777
+ * - TypeScript interfaces (interface ButtonProps { variant: ... })
778
+ * - PropTypes (Component.propTypes = { variant: ... })
779
+ * - Function parameter destructuring ({ className, variant, ...props }: Props)
780
+ * - VariantProps from class-variance-authority
768
781
  */
769
782
  extractPropsFromFile(content) {
770
783
  const props = [];
@@ -786,6 +799,140 @@ export class EnhancedComponentDiscovery {
786
799
  props.push(match[1]);
787
800
  }
788
801
  }
802
+ // Extract from function parameter destructuring
803
+ // Matches patterns like:
804
+ // function Component({ prop1, prop2, ...rest }: Props)
805
+ // const Component = ({ prop1, prop2 }: Props) =>
806
+ // export function Component({ prop1, prop2 }: React.ComponentProps<"div">)
807
+ const destructuringProps = this.extractDestructuredProps(content);
808
+ for (const prop of destructuringProps) {
809
+ if (!props.includes(prop)) {
810
+ props.push(prop);
811
+ }
812
+ }
813
+ // Extract from VariantProps (class-variance-authority pattern)
814
+ // Matches: VariantProps<typeof buttonVariants>
815
+ const variantPropsMatch = content.match(/VariantProps<typeof\s+(\w+)>/);
816
+ if (variantPropsMatch) {
817
+ const variantsName = variantPropsMatch[1];
818
+ // Look for the cva definition to extract variant names
819
+ const cvaMatch = content.match(new RegExp(`${variantsName}\\s*=\\s*cva\\([^,]+,\\s*{\\s*variants:\\s*{([^}]+(?:{[^}]*}[^}]*)*)}`));
820
+ if (cvaMatch) {
821
+ const variantsContent = cvaMatch[1];
822
+ // Extract variant property names (e.g., variant, size)
823
+ const variantMatches = variantsContent.matchAll(/^\s*(\w+)\s*:\s*{/gm);
824
+ for (const match of variantMatches) {
825
+ if (!props.includes(match[1])) {
826
+ props.push(match[1]);
827
+ }
828
+ }
829
+ }
830
+ }
831
+ return props;
832
+ }
833
+ /**
834
+ * Extract props from function parameter destructuring patterns
835
+ * Works with React, Vue <script setup>, and other frameworks
836
+ */
837
+ extractDestructuredProps(content) {
838
+ const props = [];
839
+ // Pattern 1: function Component({ prop1, prop2, ...rest }: Type)
840
+ // Pattern 2: const Component = ({ prop1, prop2 }: Type) =>
841
+ // Pattern 3: export function Component({ prop1, prop2 }: Type)
842
+ const functionPatterns = [
843
+ // function Name({ destructured }: Type)
844
+ /(?:export\s+)?(?:default\s+)?function\s+[A-Z]\w*\s*\(\s*\{\s*([^}]+)\s*\}\s*:/g,
845
+ // const Name = ({ destructured }: Type) =>
846
+ /(?:export\s+)?const\s+[A-Z]\w*\s*=\s*\(\s*\{\s*([^}]+)\s*\}\s*:/g,
847
+ // const Name: FC<Props> = ({ destructured }) =>
848
+ /(?:export\s+)?const\s+[A-Z]\w*\s*:\s*\w+(?:<[^>]+>)?\s*=\s*\(\s*\{\s*([^}]+)\s*\}\s*\)/g,
849
+ ];
850
+ for (const pattern of functionPatterns) {
851
+ let match;
852
+ while ((match = pattern.exec(content)) !== null) {
853
+ const destructuredContent = match[1];
854
+ // Extract individual prop names, ignoring spread operator (...rest)
855
+ const propMatches = destructuredContent.matchAll(/(?:^|,)\s*(?!\.\.\.)([\w]+)(?:\s*=\s*[^,}]+)?(?=\s*[,}]|$)/g);
856
+ for (const propMatch of propMatches) {
857
+ const propName = propMatch[1].trim();
858
+ // Skip common internal props and rest patterns
859
+ if (propName && !['ref', 'props', 'rest'].includes(propName) && !props.includes(propName)) {
860
+ props.push(propName);
861
+ }
862
+ }
863
+ }
864
+ }
865
+ return props;
866
+ }
867
+ /**
868
+ * Extract props from co-located story file (e.g., Button.stories.tsx)
869
+ * This is a fallback for components like shadcn/ui that don't use interface Props patterns
870
+ */
871
+ extractPropsFromStoryFile(componentPath) {
872
+ const props = [];
873
+ // Construct story file path: button.tsx -> button.stories.tsx
874
+ const dir = path.dirname(componentPath);
875
+ const ext = path.extname(componentPath);
876
+ const name = path.basename(componentPath, ext);
877
+ // Try different story file naming conventions
878
+ const storyPaths = [
879
+ path.join(dir, `${name}.stories.tsx`),
880
+ path.join(dir, `${name}.stories.ts`),
881
+ path.join(dir, `${name}.story.tsx`),
882
+ path.join(dir, `${name}.story.ts`),
883
+ ];
884
+ let storyContent = '';
885
+ for (const storyPath of storyPaths) {
886
+ if (fs.existsSync(storyPath)) {
887
+ try {
888
+ storyContent = fs.readFileSync(storyPath, 'utf-8');
889
+ break;
890
+ }
891
+ catch {
892
+ continue;
893
+ }
894
+ }
895
+ }
896
+ if (!storyContent) {
897
+ return props;
898
+ }
899
+ // Extract from argTypes: { propName: { control: ..., options: ... } }
900
+ // Only match prop names followed by `: {` to avoid picking up nested properties like control, options
901
+ const argTypesMatch = storyContent.match(/argTypes\s*:\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/);
902
+ if (argTypesMatch) {
903
+ // Match prop names followed by `: {` which indicates argType config object
904
+ const propMatches = argTypesMatch[1].matchAll(/(\w+)\s*:\s*\{/g);
905
+ for (const match of propMatches) {
906
+ // Skip common argTypes meta-properties that shouldn't be props
907
+ const metaProps = ['control', 'options', 'description', 'table', 'type', 'defaultValue', 'if', 'mapping'];
908
+ if (!metaProps.includes(match[1]) && !props.includes(match[1])) {
909
+ props.push(match[1]);
910
+ }
911
+ }
912
+ }
913
+ // Extract from args: { propName: value }
914
+ const argsMatches = storyContent.matchAll(/args\s*:\s*\{([^}]+)\}/g);
915
+ for (const argsMatch of argsMatches) {
916
+ const argContent = argsMatch[1];
917
+ const propMatches = argContent.matchAll(/^\s*(\w+)\s*:/gm);
918
+ for (const match of propMatches) {
919
+ if (!props.includes(match[1])) {
920
+ props.push(match[1]);
921
+ }
922
+ }
923
+ }
924
+ // Extract from render function parameters if they use destructuring
925
+ // e.g., render: ({ variant, size }) => ...
926
+ const renderMatches = storyContent.matchAll(/render\s*:\s*\(\s*\{\s*([^}]+)\s*\}\s*\)/g);
927
+ for (const renderMatch of renderMatches) {
928
+ const paramContent = renderMatch[1];
929
+ const propMatches = paramContent.matchAll(/(\w+)(?:\s*,|\s*$)/g);
930
+ for (const match of propMatches) {
931
+ if (!props.includes(match[1])) {
932
+ props.push(match[1]);
933
+ }
934
+ }
935
+ }
789
936
  return props;
790
937
  }
791
938
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"promptGenerator.d.ts","sourceRoot":"","sources":["../../story-generator/promptGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAI9D,OAAO,EAEL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AAyOvC;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,eAAe,EAAE,oBAAoB,CAAC;IACvF,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,eAAe,CAcxG;AAqTD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CA6D1E;AA0MD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,OAAO,CAAC,MAAM,CAAC,CA8JjB;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,EACjC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAqB/B;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,EACjC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAiHjB;AA4ED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAIzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,aAAa,GAAG,gBAAgB,CAG9E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,aAAa,EAAE,CAGxD"}
1
+ {"version":3,"file":"promptGenerator.d.ts","sourceRoot":"","sources":["../../story-generator/promptGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAI9D,OAAO,EAEL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AAyOvC;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,eAAe,EAAE,oBAAoB,CAAC;IACvF,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,eAAe,CAcxG;AAqTD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CA6D1E;AAsRD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,OAAO,CAAC,MAAM,CAAC,CA8JjB;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,EACjC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAqB/B;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,EACjC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAiHjB;AA4ED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAIzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,aAAa,GAAG,gBAAgB,CAG9E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,aAAa,EAAE,CAGxD"}
@@ -603,11 +603,71 @@ function generateExamples(config) {
603
603
  }
604
604
  return examples;
605
605
  }
606
+ /**
607
+ * Extracts the base component name from a compound component name.
608
+ * Used when generating individual file imports to group related components.
609
+ *
610
+ * Examples:
611
+ * - CardHeader -> Card (imports from card.tsx)
612
+ * - AlertDialogTrigger -> AlertDialog (imports from alert-dialog.tsx)
613
+ * - Button -> Button (imports from button.tsx)
614
+ *
615
+ * This pattern is common across multiple frameworks:
616
+ * - React: shadcn/ui, Radix UI compound components
617
+ * - Vue: Radix Vue, shadcn-vue compound components
618
+ * - Angular: Angular Material (mat-card-header -> mat-card)
619
+ * - Web Components: Shoelace (sl-card-header -> sl-card)
620
+ *
621
+ * Note: For frameworks that use slots instead of compound components
622
+ * (many Web Components, some Svelte), this function returns the name unchanged.
623
+ */
624
+ function getBaseComponentName(componentName) {
625
+ // Known suffixes that indicate sub-components (order matters - check longer ones first)
626
+ const suffixes = [
627
+ 'Fallback', 'Image', 'Trigger', 'Content', 'Header', 'Footer', 'Title',
628
+ 'Description', 'Action', 'Cancel', 'Close', 'Overlay', 'Portal',
629
+ 'Item', 'Group', 'Label', 'Separator', 'Root', 'List', 'Link',
630
+ 'Previous', 'Next', 'Ellipsis', 'Viewport', 'ScrollBar', 'Corner',
631
+ 'Thumb', 'Track', 'Range', 'Indicator', 'Icon', 'Slot', 'Input',
632
+ 'Handle', 'Panel', 'Primitive'
633
+ ];
634
+ for (const suffix of suffixes) {
635
+ if (componentName.endsWith(suffix) && componentName !== suffix) {
636
+ const base = componentName.slice(0, -suffix.length);
637
+ if (base.length > 0) {
638
+ return base;
639
+ }
640
+ }
641
+ }
642
+ return componentName;
643
+ }
644
+ /**
645
+ * Converts PascalCase to kebab-case for file names.
646
+ * Used when generating individual file imports.
647
+ *
648
+ * Examples:
649
+ * - AlertDialog -> alert-dialog
650
+ * - Button -> button
651
+ * - InputOTP -> input-otp
652
+ *
653
+ * This conversion works across frameworks since kebab-case file names are:
654
+ * - Required: Angular, Web Components
655
+ * - Common: Vue, React (for some libraries)
656
+ * - Accepted: Svelte (though PascalCase is more common)
657
+ */
658
+ function toKebabCase(name) {
659
+ return name
660
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
661
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
662
+ .toLowerCase();
663
+ }
606
664
  /**
607
665
  * Generates import statements, using individual import paths if available
608
666
  */
609
667
  function generateImportStatements(config, components, componentNames) {
610
668
  const importMap = new Map();
669
+ // Check if individual file imports are configured (for libraries without barrel exports)
670
+ const useIndividualImports = config.importStyle === 'individual';
611
671
  for (const componentName of componentNames) {
612
672
  // Find the component in our discovered components to get its specific import path
613
673
  const component = components.find(c => c.name === componentName);
@@ -619,8 +679,20 @@ function generateImportStatements(config, components, componentNames) {
619
679
  }
620
680
  importMap.get(importPath).push(componentName);
621
681
  }
682
+ else if (useIndividualImports) {
683
+ // Generate individual file imports for libraries without barrel exports
684
+ // Group by base component: CardHeader, CardContent -> card.tsx
685
+ // This pattern works for React (shadcn/ui), Vue (PrimeVue), Angular (Material), Web Components (Shoelace)
686
+ const baseComponent = getBaseComponentName(componentName);
687
+ const fileName = toKebabCase(baseComponent);
688
+ const importPath = `${config.importPath}/${fileName}`;
689
+ if (!importMap.has(importPath)) {
690
+ importMap.set(importPath, []);
691
+ }
692
+ importMap.get(importPath).push(componentName);
693
+ }
622
694
  else {
623
- // Fallback to the main package import path
695
+ // Use barrel import (default) - import all from single entry point
624
696
  if (!importMap.has(config.importPath)) {
625
697
  importMap.set(config.importPath, []);
626
698
  }
@@ -629,8 +701,8 @@ function generateImportStatements(config, components, componentNames) {
629
701
  }
630
702
  // Generate import statements
631
703
  const importLines = [];
632
- for (const [importPath, components] of importMap) {
633
- importLines.push(`import { ${components.join(', ')} } from '${importPath}';`);
704
+ for (const [importPath, comps] of importMap) {
705
+ importLines.push(`import { ${comps.join(', ')} } from '${importPath}';`);
634
706
  }
635
707
  return importLines.join('\n');
636
708
  }
@@ -81,6 +81,22 @@ export interface StoryUIConfig {
81
81
  additionalImports?: AdditionalImport[];
82
82
  considerationsPath?: string;
83
83
  storybookFramework?: string;
84
+ /**
85
+ * Import style for generated stories:
86
+ * - 'barrel': Use barrel imports from a single entry point (e.g., `import { Button } from 'library'`)
87
+ * - 'individual': Use individual file imports (e.g., `import { Button } from 'library/button'`)
88
+ *
89
+ * Use 'individual' for libraries without barrel exports (index.ts), such as:
90
+ * - shadcn/ui, Radix Vue, PrimeVue (Vue)
91
+ * - Angular Material, PrimeNG (Angular)
92
+ * - Shoelace, Lion (Web Components)
93
+ *
94
+ * Use 'barrel' (default) for libraries with barrel exports, such as:
95
+ * - Chakra UI, Mantine, Ant Design (React)
96
+ * - Vuetify, Quasar (Vue)
97
+ * - Skeleton UI (Svelte)
98
+ */
99
+ importStyle?: 'barrel' | 'individual';
84
100
  designSystemGuidelines?: DesignSystemGuidelines;
85
101
  /** Icon imports configuration (auto-detected from package.json or manually configured) */
86
102
  iconImports?: IconImportsConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"story-ui.config.d.ts","sourceRoot":"","sources":["../story-ui.config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"story-ui.config.d.ts","sourceRoot":"","sources":["../story-ui.config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpitre/story-ui",
3
- "version": "4.7.0",
3
+ "version": "4.7.1",
4
4
  "description": "AI-powered Storybook story generator with dynamic component discovery",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",