@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.
- package/README.md +36 -32
- package/dist/cli/index.js +0 -5
- package/dist/cli/setup.js +1 -1
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStory.js +178 -87
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStoryStream.js +149 -31
- package/dist/story-generator/dynamicPackageDiscovery.d.ts +35 -2
- package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -1
- package/dist/story-generator/dynamicPackageDiscovery.js +332 -6
- package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -1
- package/dist/story-generator/enhancedComponentDiscovery.js +149 -2
- package/dist/story-generator/framework-adapters/base-adapter.d.ts +1 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -1
- package/dist/story-generator/framework-adapters/base-adapter.js +12 -2
- package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -1
- package/dist/story-generator/framework-adapters/react-adapter.js +2 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -1
- package/dist/story-generator/framework-adapters/svelte-adapter.js +53 -7
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -1
- package/dist/story-generator/framework-adapters/vue-adapter.js +21 -1
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -1
- package/dist/story-generator/framework-adapters/web-components-adapter.js +4 -0
- package/dist/story-generator/llm-providers/openai-provider.js +2 -2
- package/dist/story-generator/promptGenerator.d.ts.map +1 -1
- package/dist/story-generator/promptGenerator.js +179 -26
- package/dist/story-generator/runtimeValidator.d.ts +64 -0
- package/dist/story-generator/runtimeValidator.d.ts.map +1 -0
- package/dist/story-generator/runtimeValidator.js +356 -0
- package/dist/story-generator/selfHealingLoop.d.ts +112 -0
- package/dist/story-generator/selfHealingLoop.d.ts.map +1 -0
- package/dist/story-generator/selfHealingLoop.js +202 -0
- package/dist/story-generator/validateStory.d.ts.map +1 -1
- package/dist/story-generator/validateStory.js +81 -12
- package/dist/story-ui.config.d.ts +2 -0
- package/dist/story-ui.config.d.ts.map +1 -1
- package/dist/templates/StoryUI/StoryUIPanel.d.ts +0 -5
- package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -1
- package/dist/templates/StoryUI/StoryUIPanel.js +411 -223
- package/package.json +4 -4
- package/templates/StoryUI/StoryUIPanel.mdx +84 -0
- package/templates/StoryUI/StoryUIPanel.tsx +493 -265
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +0 -18
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +0 -1
- package/dist/templates/StoryUI/StoryUIPanel.stories.js +0 -37
- package/templates/StoryUI/StoryUIPanel.stories.tsx +0 -44
- package/templates/StoryUI/manager.tsx +0 -859
|
@@ -9,12 +9,17 @@ export function validateStoryCode(code, fileName = 'story.tsx', config) {
|
|
|
9
9
|
errors: [],
|
|
10
10
|
warnings: []
|
|
11
11
|
};
|
|
12
|
+
// Determine framework from config
|
|
13
|
+
const framework = config?.componentFramework || config?.framework || 'react';
|
|
14
|
+
const isJsxFramework = framework === 'react' || framework === 'vue';
|
|
12
15
|
try {
|
|
13
16
|
// Create a TypeScript source file
|
|
14
|
-
|
|
17
|
+
// Use appropriate script kind based on framework
|
|
18
|
+
const scriptKind = isJsxFramework ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
19
|
+
const sourceFile = ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true, scriptKind);
|
|
15
20
|
// Check for syntax errors using the program API
|
|
16
21
|
const compilerOptions = {
|
|
17
|
-
jsx: ts.JsxEmit.ReactJSX,
|
|
22
|
+
jsx: isJsxFramework ? ts.JsxEmit.ReactJSX : ts.JsxEmit.None,
|
|
18
23
|
target: ts.ScriptTarget.Latest,
|
|
19
24
|
module: ts.ModuleKind.ESNext,
|
|
20
25
|
allowJs: true,
|
|
@@ -47,11 +52,13 @@ export function validateStoryCode(code, fileName = 'story.tsx', config) {
|
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
|
-
// Additional semantic checks
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
// Additional semantic checks - only for JSX frameworks (React, Vue with JSX)
|
|
56
|
+
// For non-JSX frameworks (Angular, Svelte, Web Components), skip JSX-specific validation
|
|
57
|
+
if (isJsxFramework) {
|
|
58
|
+
const semanticErrors = performSemanticChecks(sourceFile, config);
|
|
59
|
+
result.errors.push(...semanticErrors);
|
|
60
|
+
}
|
|
53
61
|
// Check for React import - but only for React-based frameworks
|
|
54
|
-
const framework = config?.framework || 'react';
|
|
55
62
|
const isReactFramework = framework === 'react' || framework.includes('react');
|
|
56
63
|
const hasJSX = code.includes('<') || code.includes('/>');
|
|
57
64
|
const hasReactImport = code.includes('import React from \'react\';');
|
|
@@ -61,6 +68,12 @@ export function validateStoryCode(code, fileName = 'story.tsx', config) {
|
|
|
61
68
|
result.errors.push('Missing React import - add "import React from \'react\';" at the top of the file');
|
|
62
69
|
result.isValid = false;
|
|
63
70
|
}
|
|
71
|
+
// CRITICAL: For non-React frameworks, REMOVE any React imports that the LLM incorrectly generated
|
|
72
|
+
if (!isReactFramework && hasReactImport) {
|
|
73
|
+
result.warnings.push(`Removed incorrect React import for ${framework} framework`);
|
|
74
|
+
code = removeReactImport(code);
|
|
75
|
+
result.fixedCode = code;
|
|
76
|
+
}
|
|
64
77
|
if (result.errors.length > 0) {
|
|
65
78
|
result.isValid = false;
|
|
66
79
|
// Attempt to fix common issues
|
|
@@ -89,6 +102,7 @@ function performSemanticChecks(sourceFile, config) {
|
|
|
89
102
|
const errors = [];
|
|
90
103
|
const availableComponents = new Set();
|
|
91
104
|
const importedComponents = new Set();
|
|
105
|
+
const usedJsxComponents = new Set();
|
|
92
106
|
// If config is provided, collect available components
|
|
93
107
|
if (config && config.componentsToImport) {
|
|
94
108
|
config.componentsToImport.forEach((comp) => availableComponents.add(comp));
|
|
@@ -127,19 +141,54 @@ function performSemanticChecks(sourceFile, config) {
|
|
|
127
141
|
});
|
|
128
142
|
}
|
|
129
143
|
}
|
|
144
|
+
// Track all named imports from any module (React, icons, etc.)
|
|
145
|
+
if (ts.isNamedImports(node.importClause.namedBindings)) {
|
|
146
|
+
node.importClause.namedBindings.elements.forEach(element => {
|
|
147
|
+
importedComponents.add(element.name.text);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
130
150
|
}
|
|
131
151
|
}
|
|
132
|
-
//
|
|
133
|
-
if (ts.
|
|
134
|
-
|
|
152
|
+
// Track default imports (e.g., import React from 'react')
|
|
153
|
+
if (ts.isImportDeclaration(node) && node.importClause && node.importClause.name) {
|
|
154
|
+
importedComponents.add(node.importClause.name.text);
|
|
135
155
|
}
|
|
136
|
-
//
|
|
137
|
-
if (ts.
|
|
138
|
-
|
|
156
|
+
// Track JSX element names - CRITICAL: Catch undefined components
|
|
157
|
+
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
|
|
158
|
+
const tagName = node.tagName;
|
|
159
|
+
// Handle different tag name types
|
|
160
|
+
if (ts.isIdentifier(tagName)) {
|
|
161
|
+
// Simple identifier like <Card> or <CardSection>
|
|
162
|
+
const name = tagName.text;
|
|
163
|
+
// Only track PascalCase names (components, not HTML elements like div, span)
|
|
164
|
+
if (/^[A-Z]/.test(name)) {
|
|
165
|
+
usedJsxComponents.add(name);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else if (ts.isPropertyAccessExpression(tagName)) {
|
|
169
|
+
// Compound component like <Card.Section>
|
|
170
|
+
// The parent (Card) needs to be imported, not Card.Section
|
|
171
|
+
if (ts.isIdentifier(tagName.expression)) {
|
|
172
|
+
const parentName = tagName.expression.text;
|
|
173
|
+
if (/^[A-Z]/.test(parentName)) {
|
|
174
|
+
usedJsxComponents.add(parentName);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
139
178
|
}
|
|
140
179
|
ts.forEachChild(node, visit);
|
|
141
180
|
}
|
|
142
181
|
visit(sourceFile);
|
|
182
|
+
// CRITICAL CHECK: Verify all used JSX components are imported
|
|
183
|
+
// This catches bugs where a component is used but never imported
|
|
184
|
+
// This is framework-agnostic - works for any JSX-based framework
|
|
185
|
+
for (const componentName of usedJsxComponents) {
|
|
186
|
+
if (!importedComponents.has(componentName)) {
|
|
187
|
+
errors.push(`JSX error: "${componentName}" is used but was never imported. ` +
|
|
188
|
+
`Either add it to your imports, or if you intended to use a sub-component, ` +
|
|
189
|
+
`use the correct syntax (e.g., Parent.Child instead of ParentChild).`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
143
192
|
return errors;
|
|
144
193
|
}
|
|
145
194
|
/**
|
|
@@ -307,6 +356,26 @@ function fixMissingReactImport(code) {
|
|
|
307
356
|
}
|
|
308
357
|
return code;
|
|
309
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Removes React import for non-React frameworks (Vue, Angular, Svelte, Web Components)
|
|
361
|
+
* The LLM sometimes incorrectly generates React imports for these frameworks
|
|
362
|
+
*/
|
|
363
|
+
function removeReactImport(code) {
|
|
364
|
+
// Remove various forms of React import
|
|
365
|
+
const reactImportPatterns = [
|
|
366
|
+
/import\s+React\s+from\s+['"]react['"]\s*;?\n?/g,
|
|
367
|
+
/import\s+\*\s+as\s+React\s+from\s+['"]react['"]\s*;?\n?/g,
|
|
368
|
+
/import\s+React,?\s*\{[^}]*\}\s+from\s+['"]react['"]\s*;?\n?/g,
|
|
369
|
+
/import\s+\{[^}]*\}\s+from\s+['"]react['"]\s*;?\n?/g,
|
|
370
|
+
];
|
|
371
|
+
let cleanedCode = code;
|
|
372
|
+
for (const pattern of reactImportPatterns) {
|
|
373
|
+
cleanedCode = cleanedCode.replace(pattern, '');
|
|
374
|
+
}
|
|
375
|
+
// Clean up any resulting double newlines
|
|
376
|
+
cleanedCode = cleanedCode.replace(/\n\n\n+/g, '\n\n');
|
|
377
|
+
return cleanedCode;
|
|
378
|
+
}
|
|
310
379
|
/**
|
|
311
380
|
* Fixes unclosed JSX elements
|
|
312
381
|
*/
|
|
@@ -59,6 +59,8 @@ export interface StoryUIConfig {
|
|
|
59
59
|
componentPrefix: string;
|
|
60
60
|
/** Framework type for story generation (e.g., 'react', 'web-components', 'angular', 'vue', 'svelte') */
|
|
61
61
|
framework?: string;
|
|
62
|
+
/** Component framework type for discovery routing (e.g., 'react', 'vue', 'angular', 'svelte', 'web-components') */
|
|
63
|
+
componentFramework?: string;
|
|
62
64
|
components: ComponentConfig[];
|
|
63
65
|
layoutComponents?: ComponentConfig[];
|
|
64
66
|
layoutRules: LayoutRules;
|
|
@@ -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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StoryUIPanel.d.ts","sourceRoot":"","sources":["../../../templates/StoryUI/StoryUIPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StoryUIPanel.d.ts","sourceRoot":"","sources":["../../../templates/StoryUI/StoryUIPanel.tsx"],"names":[],"mappings":"AAymDA,iBAAS,YAAY,4CAuyCpB;AAED,eAAe,YAAY,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,CAAC"}
|