@tpitre/story-ui 4.12.0 ā 4.13.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/dist/cli/generateRegistry.d.ts +23 -0
- package/dist/cli/generateRegistry.d.ts.map +1 -0
- package/dist/cli/generateRegistry.js +155 -0
- package/dist/cli/index.js +19 -111
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +115 -4
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +26 -0
- package/dist/mcp-server/index.js +155 -22
- package/dist/mcp-server/routes/canvasGenerate.d.ts +25 -0
- package/dist/mcp-server/routes/canvasGenerate.d.ts.map +1 -0
- package/dist/mcp-server/routes/canvasGenerate.js +268 -0
- package/dist/mcp-server/routes/canvasIntent.d.ts +15 -0
- package/dist/mcp-server/routes/canvasIntent.d.ts.map +1 -0
- package/dist/mcp-server/routes/canvasIntent.js +553 -0
- package/dist/mcp-server/routes/canvasPreview.d.ts +14 -0
- package/dist/mcp-server/routes/canvasPreview.d.ts.map +1 -0
- package/dist/mcp-server/routes/canvasPreview.js +25 -0
- package/dist/mcp-server/routes/canvasSave.d.ts +13 -0
- package/dist/mcp-server/routes/canvasSave.d.ts.map +1 -0
- package/dist/mcp-server/routes/canvasSave.js +273 -0
- package/dist/mcp-server/routes/convertToStory.d.ts +17 -0
- package/dist/mcp-server/routes/convertToStory.d.ts.map +1 -0
- package/dist/mcp-server/routes/convertToStory.js +730 -0
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStory.js +18 -1
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStoryStream.js +38 -2
- package/dist/mcp-server/routes/manifest.d.ts +19 -0
- package/dist/mcp-server/routes/manifest.d.ts.map +1 -0
- package/dist/mcp-server/routes/manifest.js +100 -0
- package/dist/mcp-server/routes/voiceRender.d.ts +19 -0
- package/dist/mcp-server/routes/voiceRender.d.ts.map +1 -0
- package/dist/mcp-server/routes/voiceRender.js +329 -0
- package/dist/story-generator/configLoader.d.ts.map +1 -1
- package/dist/story-generator/configLoader.js +3 -3
- package/dist/story-generator/llm-providers/gemini-provider.js +1 -1
- package/dist/story-generator/llm-providers/openai-provider.js +1 -1
- package/dist/story-generator/manifestManager.d.ts +105 -0
- package/dist/story-generator/manifestManager.d.ts.map +1 -0
- package/dist/story-generator/manifestManager.js +265 -0
- package/dist/templates/StoryUI/StoryUIPanel.css +732 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -1
- package/dist/templates/StoryUI/StoryUIPanel.js +432 -110
- package/dist/templates/StoryUI/StoryUIPanel.tsx +2509 -0
- package/dist/templates/StoryUI/index.tsx +2 -0
- package/dist/templates/StoryUI/voice/VoiceCanvas.d.ts +15 -0
- package/dist/templates/StoryUI/voice/VoiceCanvas.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/VoiceCanvas.js +477 -0
- package/dist/templates/StoryUI/voice/VoiceCanvas.tsx +702 -0
- package/dist/templates/StoryUI/voice/VoiceControls.d.ts +12 -0
- package/dist/templates/StoryUI/voice/VoiceControls.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/VoiceControls.js +73 -0
- package/dist/templates/StoryUI/voice/VoiceControls.tsx +167 -0
- package/dist/templates/StoryUI/voice/canvas/ComponentRenderer.d.ts +14 -0
- package/dist/templates/StoryUI/voice/canvas/ComponentRenderer.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/canvas/ComponentRenderer.js +90 -0
- package/dist/templates/StoryUI/voice/canvas/ComponentRenderer.tsx +168 -0
- package/dist/templates/StoryUI/voice/canvas/componentRegistry.d.ts +21 -0
- package/dist/templates/StoryUI/voice/canvas/componentRegistry.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/canvas/componentRegistry.js +24 -0
- package/dist/templates/StoryUI/voice/canvas/componentRegistry.ts +30 -0
- package/dist/templates/StoryUI/voice/canvas/operations.d.ts +8 -0
- package/dist/templates/StoryUI/voice/canvas/operations.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/canvas/operations.js +189 -0
- package/dist/templates/StoryUI/voice/canvas/operations.ts +233 -0
- package/dist/templates/StoryUI/voice/canvas/types.d.ts +89 -0
- package/dist/templates/StoryUI/voice/canvas/types.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/canvas/types.js +2 -0
- package/dist/templates/StoryUI/voice/canvas/types.ts +106 -0
- package/dist/templates/StoryUI/voice/types.d.ts +83 -0
- package/dist/templates/StoryUI/voice/types.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/types.js +2 -0
- package/dist/templates/StoryUI/voice/types.ts +114 -0
- package/dist/templates/StoryUI/voice/useVoiceInput.d.ts +3 -0
- package/dist/templates/StoryUI/voice/useVoiceInput.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/useVoiceInput.js +182 -0
- package/dist/templates/StoryUI/voice/useVoiceInput.ts +224 -0
- package/dist/templates/StoryUI/voice/voiceCommands.d.ts +8 -0
- package/dist/templates/StoryUI/voice/voiceCommands.d.ts.map +1 -0
- package/dist/templates/StoryUI/voice/voiceCommands.js +46 -0
- package/dist/templates/StoryUI/voice/voiceCommands.ts +54 -0
- package/package.json +4 -4
- package/templates/StoryUI/StoryUIPanel.css +732 -0
- package/templates/StoryUI/StoryUIPanel.tsx +456 -105
- package/templates/StoryUI/voice/VoiceCanvas.tsx +702 -0
- package/templates/StoryUI/voice/VoiceControls.tsx +167 -0
- package/templates/StoryUI/voice/canvas/ComponentRenderer.tsx +168 -0
- package/templates/StoryUI/voice/canvas/componentRegistry.ts +30 -0
- package/templates/StoryUI/voice/canvas/operations.ts +233 -0
- package/templates/StoryUI/voice/canvas/types.ts +106 -0
- package/templates/StoryUI/voice/types.ts +114 -0
- package/templates/StoryUI/voice/useVoiceInput.ts +224 -0
- package/templates/StoryUI/voice/voiceCommands.ts +54 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Registry Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates a `componentRegistry.ts` file that maps component names to
|
|
5
|
+
* actual React/Vue/etc imports for use by the Voice Canvas ComponentRenderer.
|
|
6
|
+
*
|
|
7
|
+
* Design-system agnostic ā uses existing component discovery to find
|
|
8
|
+
* components from npm packages, local directories, and custom elements.
|
|
9
|
+
*
|
|
10
|
+
* Called during `npx story-ui init` and can be re-run with `npx story-ui registry`.
|
|
11
|
+
*/
|
|
12
|
+
export interface RegistryGeneratorOptions {
|
|
13
|
+
/** Working directory (defaults to cwd) */
|
|
14
|
+
cwd?: string;
|
|
15
|
+
/** Output path relative to cwd (defaults to src/stories/StoryUI/voice/canvas/) */
|
|
16
|
+
outputDir?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Generate the component registry file using project's discovered components.
|
|
20
|
+
* Returns the path to the generated file.
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateComponentRegistry(options?: RegistryGeneratorOptions): Promise<string>;
|
|
23
|
+
//# sourceMappingURL=generateRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateRegistry.d.ts","sourceRoot":"","sources":["../../cli/generateRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,wBAAwB;IACvC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAgDvG"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Registry Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates a `componentRegistry.ts` file that maps component names to
|
|
5
|
+
* actual React/Vue/etc imports for use by the Voice Canvas ComponentRenderer.
|
|
6
|
+
*
|
|
7
|
+
* Design-system agnostic ā uses existing component discovery to find
|
|
8
|
+
* components from npm packages, local directories, and custom elements.
|
|
9
|
+
*
|
|
10
|
+
* Called during `npx story-ui init` and can be re-run with `npx story-ui registry`.
|
|
11
|
+
*/
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import fs from 'fs';
|
|
14
|
+
import { loadUserConfig } from '../story-generator/configLoader.js';
|
|
15
|
+
import { EnhancedComponentDiscovery } from '../story-generator/enhancedComponentDiscovery.js';
|
|
16
|
+
/**
|
|
17
|
+
* Generate the component registry file using project's discovered components.
|
|
18
|
+
* Returns the path to the generated file.
|
|
19
|
+
*/
|
|
20
|
+
export async function generateComponentRegistry(options = {}) {
|
|
21
|
+
const cwd = options.cwd || process.cwd();
|
|
22
|
+
// loadUserConfig reads from cwd ā ensure we're in the right directory
|
|
23
|
+
const originalCwd = process.cwd();
|
|
24
|
+
if (cwd !== originalCwd)
|
|
25
|
+
process.chdir(cwd);
|
|
26
|
+
const config = loadUserConfig();
|
|
27
|
+
if (cwd !== originalCwd)
|
|
28
|
+
process.chdir(originalCwd);
|
|
29
|
+
// Discover components using the existing discovery system
|
|
30
|
+
const discovery = new EnhancedComponentDiscovery(config);
|
|
31
|
+
const components = await discovery.discoverAll();
|
|
32
|
+
const componentNames = components.map(c => c.name).sort();
|
|
33
|
+
if (componentNames.length === 0) {
|
|
34
|
+
console.warn('ā ļø No components discovered ā registry will be empty');
|
|
35
|
+
}
|
|
36
|
+
const importPath = config.importPath || '@mantine/core';
|
|
37
|
+
const framework = config.componentFramework || 'react';
|
|
38
|
+
const importStyle = config.importStyle || 'barrel';
|
|
39
|
+
// Determine output directory
|
|
40
|
+
const outputDir = options.outputDir
|
|
41
|
+
? path.resolve(cwd, options.outputDir)
|
|
42
|
+
: path.resolve(cwd, 'src/stories/StoryUI/voice/canvas');
|
|
43
|
+
if (!fs.existsSync(outputDir)) {
|
|
44
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
const outputPath = path.join(outputDir, 'componentRegistry.ts');
|
|
47
|
+
// Generate the file content
|
|
48
|
+
let code;
|
|
49
|
+
if (framework === 'react') {
|
|
50
|
+
code = generateReactRegistry(componentNames, importPath, importStyle);
|
|
51
|
+
}
|
|
52
|
+
else if (framework === 'vue') {
|
|
53
|
+
code = generateVueRegistry(componentNames, importPath, importStyle);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Fallback: generic registry with dynamic imports note
|
|
57
|
+
code = generateGenericRegistry(componentNames, importPath, framework);
|
|
58
|
+
}
|
|
59
|
+
fs.writeFileSync(outputPath, code, 'utf-8');
|
|
60
|
+
console.log(`ā
Component registry generated: ${path.relative(cwd, outputPath)} (${componentNames.length} components)`);
|
|
61
|
+
return outputPath;
|
|
62
|
+
}
|
|
63
|
+
// āā React registry generator āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
64
|
+
function generateReactRegistry(names, importPath, importStyle) {
|
|
65
|
+
// Separate parent components from sub-components (e.g., "Card.Section")
|
|
66
|
+
const topLevel = names.filter(n => !n.includes('.'));
|
|
67
|
+
const subComponents = names.filter(n => n.includes('.'));
|
|
68
|
+
// For barrel imports, import all top-level from one path
|
|
69
|
+
// For individual imports, import each from its own path
|
|
70
|
+
let imports;
|
|
71
|
+
if (importStyle === 'individual') {
|
|
72
|
+
imports = topLevel.map(name => `import { ${name} } from '${importPath}/${name}';`).join('\n');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Barrel import ā single line
|
|
76
|
+
imports = `import {\n${topLevel.map(n => ` ${n},`).join('\n')}\n} from '${importPath}';`;
|
|
77
|
+
}
|
|
78
|
+
// Build registry entries
|
|
79
|
+
const entries = topLevel.map(name => ` '${name}': ${name},`);
|
|
80
|
+
// Sub-components map automatically via dot-notation in ComponentRenderer
|
|
81
|
+
// e.g., "Card.Section" resolves to Card.Section at runtime
|
|
82
|
+
// But we still add them for explicit lookup
|
|
83
|
+
for (const sub of subComponents) {
|
|
84
|
+
const [parent, child] = sub.split('.');
|
|
85
|
+
entries.push(` '${sub}': (${parent} as any).${child},`);
|
|
86
|
+
}
|
|
87
|
+
return `/**
|
|
88
|
+
* Auto-generated component registry for Voice Canvas
|
|
89
|
+
* Source: ${importPath}
|
|
90
|
+
* Components: ${names.length}
|
|
91
|
+
*
|
|
92
|
+
* DO NOT EDIT ā regenerate with: npx story-ui registry
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
${imports}
|
|
96
|
+
import type { ComponentRegistry } from './ComponentRenderer';
|
|
97
|
+
|
|
98
|
+
export const registry: ComponentRegistry = {
|
|
99
|
+
${entries.join('\n')}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export default registry;
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
// āā Vue registry generator āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
106
|
+
function generateVueRegistry(names, importPath, importStyle) {
|
|
107
|
+
const topLevel = names.filter(n => !n.includes('.'));
|
|
108
|
+
let imports;
|
|
109
|
+
if (importStyle === 'individual') {
|
|
110
|
+
imports = topLevel.map(name => `import { ${name} } from '${importPath}/${name}';`).join('\n');
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
imports = `import {\n${topLevel.map(n => ` ${n},`).join('\n')}\n} from '${importPath}';`;
|
|
114
|
+
}
|
|
115
|
+
const entries = topLevel.map(name => ` '${name}': ${name},`);
|
|
116
|
+
return `/**
|
|
117
|
+
* Auto-generated component registry for Voice Canvas (Vue)
|
|
118
|
+
* Source: ${importPath}
|
|
119
|
+
* Components: ${names.length}
|
|
120
|
+
*
|
|
121
|
+
* DO NOT EDIT ā regenerate with: npx story-ui registry
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
${imports}
|
|
125
|
+
|
|
126
|
+
export const registry: Record<string, any> = {
|
|
127
|
+
${entries.join('\n')}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export default registry;
|
|
131
|
+
`;
|
|
132
|
+
}
|
|
133
|
+
// āā Generic fallback āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
134
|
+
function generateGenericRegistry(names, importPath, framework) {
|
|
135
|
+
return `/**
|
|
136
|
+
* Auto-generated component registry for Voice Canvas (${framework})
|
|
137
|
+
* Source: ${importPath}
|
|
138
|
+
* Components: ${names.length}
|
|
139
|
+
*
|
|
140
|
+
* NOTE: This is a placeholder registry for ${framework}.
|
|
141
|
+
* You may need to customize imports for your framework.
|
|
142
|
+
*
|
|
143
|
+
* DO NOT EDIT ā regenerate with: npx story-ui registry
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
// TODO: Add imports for ${framework} components from '${importPath}'
|
|
147
|
+
// ${names.map(n => `// import { ${n} } from '${importPath}';`).join('\n')}
|
|
148
|
+
|
|
149
|
+
export const registry: Record<string, any> = {
|
|
150
|
+
${names.map(n => ` // '${n}': ${n},`).join('\n')}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export default registry;
|
|
154
|
+
`;
|
|
155
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -10,11 +10,29 @@ import { updateCommand, statusCommand } from './update.js';
|
|
|
10
10
|
import net from 'net';
|
|
11
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
12
|
const __dirname = path.dirname(__filename);
|
|
13
|
+
// Read version from package.json (try both src/cli and dist/cli paths)
|
|
14
|
+
const packageJsonPaths = [
|
|
15
|
+
path.resolve(__dirname, '..', 'package.json'), // From src/cli
|
|
16
|
+
path.resolve(__dirname, '..', '..', 'package.json'), // From dist/cli
|
|
17
|
+
];
|
|
18
|
+
let packageVersion = 'unknown';
|
|
19
|
+
for (const p of packageJsonPaths) {
|
|
20
|
+
if (fs.existsSync(p)) {
|
|
21
|
+
try {
|
|
22
|
+
const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
23
|
+
if (pkg.version) {
|
|
24
|
+
packageVersion = pkg.version;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch { /* skip */ }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
13
31
|
const program = new Command();
|
|
14
32
|
program
|
|
15
33
|
.name('story-ui')
|
|
16
34
|
.description('AI-powered Storybook story generator for React component libraries')
|
|
17
|
-
.version(
|
|
35
|
+
.version(packageVersion);
|
|
18
36
|
program
|
|
19
37
|
.command('init')
|
|
20
38
|
.description('Initialize Story UI configuration with interactive setup')
|
|
@@ -130,116 +148,6 @@ program
|
|
|
130
148
|
console.log(`ā
Sample configuration generated: ${filename}`);
|
|
131
149
|
}
|
|
132
150
|
});
|
|
133
|
-
async function autoDetectAndCreateConfig() {
|
|
134
|
-
const cwd = process.cwd();
|
|
135
|
-
const config = {
|
|
136
|
-
generatedStoriesPath: './src/stories/generated',
|
|
137
|
-
storyPrefix: 'Generated/',
|
|
138
|
-
defaultAuthor: 'Story UI AI',
|
|
139
|
-
componentPrefix: '',
|
|
140
|
-
layoutRules: {
|
|
141
|
-
multiColumnWrapper: 'div',
|
|
142
|
-
columnComponent: 'div',
|
|
143
|
-
layoutExamples: {
|
|
144
|
-
twoColumn: `<div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem'}}>
|
|
145
|
-
<div>Column 1 content</div>
|
|
146
|
-
<div>Column 2 content</div>
|
|
147
|
-
</div>`
|
|
148
|
-
},
|
|
149
|
-
prohibitedElements: []
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
// Try to detect package.json
|
|
153
|
-
const packageJsonPath = path.join(cwd, 'package.json');
|
|
154
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
155
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
156
|
-
config.importPath = packageJson.name || 'your-component-library';
|
|
157
|
-
}
|
|
158
|
-
// Try to detect components directory
|
|
159
|
-
const possibleComponentPaths = [
|
|
160
|
-
'./src/components',
|
|
161
|
-
'./lib/components',
|
|
162
|
-
'./components',
|
|
163
|
-
'./src'
|
|
164
|
-
];
|
|
165
|
-
for (const possiblePath of possibleComponentPaths) {
|
|
166
|
-
if (fs.existsSync(path.join(cwd, possiblePath))) {
|
|
167
|
-
config.componentsPath = possiblePath;
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
writeConfig(config, 'js');
|
|
172
|
-
}
|
|
173
|
-
async function createTemplateConfig(template) {
|
|
174
|
-
let config;
|
|
175
|
-
switch (template) {
|
|
176
|
-
case 'chakra-ui':
|
|
177
|
-
config = {
|
|
178
|
-
importPath: '@chakra-ui/react',
|
|
179
|
-
componentPrefix: '',
|
|
180
|
-
layoutRules: {
|
|
181
|
-
multiColumnWrapper: 'SimpleGrid',
|
|
182
|
-
columnComponent: 'Box',
|
|
183
|
-
layoutExamples: {
|
|
184
|
-
twoColumn: `<SimpleGrid columns={2} spacing={4}>
|
|
185
|
-
<Box><Card>Left content</Card></Box>
|
|
186
|
-
<Box><Card>Right content</Card></Box>
|
|
187
|
-
</SimpleGrid>`
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
break;
|
|
192
|
-
case 'ant-design':
|
|
193
|
-
config = {
|
|
194
|
-
importPath: 'antd',
|
|
195
|
-
componentPrefix: '',
|
|
196
|
-
layoutRules: {
|
|
197
|
-
multiColumnWrapper: 'Row',
|
|
198
|
-
columnComponent: 'Col',
|
|
199
|
-
layoutExamples: {
|
|
200
|
-
twoColumn: `<Row gutter={16}>
|
|
201
|
-
<Col span={12}><Card>Left content</Card></Col>
|
|
202
|
-
<Col span={12}><Card>Right content</Card></Col>
|
|
203
|
-
</Row>`
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
break;
|
|
208
|
-
default:
|
|
209
|
-
throw new Error(`Unknown template: ${template}`);
|
|
210
|
-
}
|
|
211
|
-
// Add common defaults
|
|
212
|
-
config = {
|
|
213
|
-
generatedStoriesPath: './src/stories/generated',
|
|
214
|
-
componentsPath: './src/components',
|
|
215
|
-
storyPrefix: 'Generated/',
|
|
216
|
-
defaultAuthor: 'Story UI AI',
|
|
217
|
-
...config
|
|
218
|
-
};
|
|
219
|
-
writeConfig(config, 'js');
|
|
220
|
-
}
|
|
221
|
-
async function createBasicConfig() {
|
|
222
|
-
const config = {
|
|
223
|
-
generatedStoriesPath: './src/stories/generated',
|
|
224
|
-
componentsPath: './src/components',
|
|
225
|
-
storyPrefix: 'Generated/',
|
|
226
|
-
defaultAuthor: 'Story UI AI',
|
|
227
|
-
importPath: 'your-component-library',
|
|
228
|
-
componentPrefix: '',
|
|
229
|
-
layoutRules: {
|
|
230
|
-
multiColumnWrapper: 'div',
|
|
231
|
-
columnComponent: 'div',
|
|
232
|
-
layoutExamples: {
|
|
233
|
-
twoColumn: `<div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem'}}>
|
|
234
|
-
<div>Column 1 content</div>
|
|
235
|
-
<div>Column 2 content</div>
|
|
236
|
-
</div>`
|
|
237
|
-
},
|
|
238
|
-
prohibitedElements: []
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
writeConfig(config, 'js');
|
|
242
|
-
}
|
|
243
151
|
function generateSampleConfig(filename, type) {
|
|
244
152
|
const config = {
|
|
245
153
|
generatedStoriesPath: './src/stories/generated',
|
package/dist/cli/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../cli/setup.ts"],"names":[],"mappings":"AAmDA;;GAEG;AACH,wBAAgB,iCAAiC,SA8ChD;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../cli/setup.ts"],"names":[],"mappings":"AAmDA;;GAEG;AACH,wBAAgB,iCAAiC,SA8ChD;AAoXD,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC7C,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,iBA6/B5D"}
|
package/dist/cli/setup.js
CHANGED
|
@@ -128,10 +128,19 @@ function setupStorybookPreview(designSystem) {
|
|
|
128
128
|
const designSystemConfigs = {
|
|
129
129
|
chakra: {
|
|
130
130
|
imports: [
|
|
131
|
+
"import React from 'react'",
|
|
131
132
|
"import type { Preview } from '@storybook/react-vite'",
|
|
132
|
-
"import
|
|
133
|
-
"import React from 'react'"
|
|
133
|
+
"import * as ChakraUI from '@chakra-ui/react'",
|
|
134
134
|
],
|
|
135
|
+
globals: `
|
|
136
|
+
const { ChakraProvider, defaultSystem } = ChakraUI;
|
|
137
|
+
|
|
138
|
+
// Expose all Chakra components for Voice Canvas live preview.
|
|
139
|
+
// Voice Canvas uses these globals to render components without import statements.
|
|
140
|
+
(window as any).__STORY_UI_DESIGN_SYSTEM__ = ChakraUI;
|
|
141
|
+
(window as any).__STORY_UI_CANVAS_PROVIDER__ = ({ children }: { children: React.ReactNode }) => (
|
|
142
|
+
<ChakraProvider value={defaultSystem}>{children}</ChakraProvider>
|
|
143
|
+
);`,
|
|
135
144
|
decorator: `(Story) => (
|
|
136
145
|
<ChakraProvider value={defaultSystem}>
|
|
137
146
|
<Story />
|
|
@@ -140,11 +149,20 @@ function setupStorybookPreview(designSystem) {
|
|
|
140
149
|
},
|
|
141
150
|
mantine: {
|
|
142
151
|
imports: [
|
|
152
|
+
"import React from 'react'",
|
|
143
153
|
"import type { Preview } from '@storybook/react-vite'",
|
|
144
|
-
"import
|
|
154
|
+
"import * as MantineCore from '@mantine/core'",
|
|
145
155
|
"import '@mantine/core/styles.css'",
|
|
146
|
-
"import React from 'react'"
|
|
147
156
|
],
|
|
157
|
+
globals: `
|
|
158
|
+
const { MantineProvider } = MantineCore;
|
|
159
|
+
|
|
160
|
+
// Expose all Mantine components for Voice Canvas live preview.
|
|
161
|
+
// Voice Canvas uses these globals to render components without import statements.
|
|
162
|
+
(window as any).__STORY_UI_DESIGN_SYSTEM__ = MantineCore;
|
|
163
|
+
(window as any).__STORY_UI_CANVAS_PROVIDER__ = ({ children }: { children: React.ReactNode }) => (
|
|
164
|
+
<MantineProvider>{children}</MantineProvider>
|
|
165
|
+
);`,
|
|
148
166
|
decorator: `(Story) => (
|
|
149
167
|
<MantineProvider>
|
|
150
168
|
<Story />
|
|
@@ -157,6 +175,7 @@ function setupStorybookPreview(designSystem) {
|
|
|
157
175
|
return;
|
|
158
176
|
// Create the preview content
|
|
159
177
|
const previewContent = `${config.imports.join('\n')}
|
|
178
|
+
${config.globals || ''}
|
|
160
179
|
|
|
161
180
|
const preview: Preview = {
|
|
162
181
|
parameters: {
|
|
@@ -917,6 +936,8 @@ Material UI (MUI) is a React component library implementing Material Design.
|
|
|
917
936
|
// Copy component files
|
|
918
937
|
const templatesDir = path.resolve(__dirname, '../../templates/StoryUI');
|
|
919
938
|
const componentFiles = ['StoryUIPanel.tsx', 'StoryUIPanel.mdx', 'StoryUIPanel.css'];
|
|
939
|
+
// Voice Canvas files (subdirectory)
|
|
940
|
+
const voiceFiles = ['VoiceCanvas.tsx', 'VoiceControls.tsx', 'useVoiceInput.ts', 'voiceCommands.ts', 'types.ts'];
|
|
920
941
|
console.log(chalk.blue('\nš¦ Installing Story UI component...'));
|
|
921
942
|
for (const file of componentFiles) {
|
|
922
943
|
const sourcePath = path.join(templatesDir, file);
|
|
@@ -934,6 +955,96 @@ Material UI (MUI) is a React component library implementing Material Design.
|
|
|
934
955
|
console.warn(chalk.yellow(`ā ļø Template file not found: ${file}`));
|
|
935
956
|
}
|
|
936
957
|
}
|
|
958
|
+
// Copy Voice Canvas files
|
|
959
|
+
const voiceSourceDir = path.join(templatesDir, 'voice');
|
|
960
|
+
const voiceTargetDir = path.join(storyUITargetDir, 'voice');
|
|
961
|
+
if (fs.existsSync(voiceSourceDir)) {
|
|
962
|
+
if (!fs.existsSync(voiceTargetDir)) {
|
|
963
|
+
fs.mkdirSync(voiceTargetDir, { recursive: true });
|
|
964
|
+
}
|
|
965
|
+
for (const file of voiceFiles) {
|
|
966
|
+
const sourcePath = path.join(voiceSourceDir, file);
|
|
967
|
+
const targetPath = path.join(voiceTargetDir, file);
|
|
968
|
+
if (fs.existsSync(sourcePath)) {
|
|
969
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
970
|
+
console.log(chalk.green(`ā
Copied voice/${file}`));
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
// Generate component registry for Voice Canvas with static design system import
|
|
975
|
+
// Vite requires static imports ā bare specifiers can't be resolved at runtime
|
|
976
|
+
const canvasTargetDir = path.join(voiceTargetDir, 'canvas');
|
|
977
|
+
if (!fs.existsSync(canvasTargetDir)) {
|
|
978
|
+
fs.mkdirSync(canvasTargetDir, { recursive: true });
|
|
979
|
+
}
|
|
980
|
+
// Copy canvas template files (types.ts, operations.ts, ComponentRenderer.tsx)
|
|
981
|
+
const canvasSourceDir = path.join(voiceSourceDir, 'canvas');
|
|
982
|
+
if (fs.existsSync(canvasSourceDir)) {
|
|
983
|
+
for (const file of fs.readdirSync(canvasSourceDir)) {
|
|
984
|
+
if (file === 'componentRegistry.ts')
|
|
985
|
+
continue; // generated below
|
|
986
|
+
const src = path.join(canvasSourceDir, file);
|
|
987
|
+
const dst = path.join(canvasTargetDir, file);
|
|
988
|
+
if (fs.statSync(src).isFile()) {
|
|
989
|
+
fs.copyFileSync(src, dst);
|
|
990
|
+
console.log(chalk.green(`ā
Copied voice/canvas/${file}`));
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
// Generate the registry with a lazy async import of the design system.
|
|
995
|
+
// Uses a literal string in import() so Vite resolves it at build time,
|
|
996
|
+
// but execution is deferred until loadRegistry() is called ā avoiding
|
|
997
|
+
// module-level side effects that can crash the docs page.
|
|
998
|
+
if (config.importPath && config.importStyle !== 'individual') {
|
|
999
|
+
const registryContent = `/**
|
|
1000
|
+
* Component registry for Voice Canvas ā lazy-loaded from design system.
|
|
1001
|
+
*
|
|
1002
|
+
* Uses dynamic import('${config.importPath}') with a literal string so Vite
|
|
1003
|
+
* resolves it at build time, but the import only executes when loadRegistry()
|
|
1004
|
+
* is called (not at module evaluation time). This prevents crashes from
|
|
1005
|
+
* module-level side effects.
|
|
1006
|
+
*
|
|
1007
|
+
* Generated by story-ui init. Regenerate with: npx story-ui registry
|
|
1008
|
+
*/
|
|
1009
|
+
|
|
1010
|
+
export const registry: Record<string, any> = {};
|
|
1011
|
+
|
|
1012
|
+
let _loaded = false;
|
|
1013
|
+
|
|
1014
|
+
export async function loadRegistry(): Promise<Record<string, any>> {
|
|
1015
|
+
if (_loaded) return registry;
|
|
1016
|
+
|
|
1017
|
+
try {
|
|
1018
|
+
const mod = await import('${config.importPath}');
|
|
1019
|
+
|
|
1020
|
+
for (const [key, value] of Object.entries(mod)) {
|
|
1021
|
+
if (/^[A-Z]/.test(key) && (typeof value === 'function' || typeof value === 'object')) {
|
|
1022
|
+
registry[key] = value;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
_loaded = true;
|
|
1027
|
+
console.log(\\\`[componentRegistry] Loaded \\\${Object.keys(registry).length} components from ${config.importPath}\\\`);
|
|
1028
|
+
} catch (err) {
|
|
1029
|
+
console.error('[componentRegistry] Failed to load design system:', err);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
return registry;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
export default registry;
|
|
1036
|
+
`;
|
|
1037
|
+
fs.writeFileSync(path.join(canvasTargetDir, 'componentRegistry.ts'), registryContent);
|
|
1038
|
+
console.log(chalk.green(`ā
Generated voice/canvas/componentRegistry.ts with ${config.importPath} imports`));
|
|
1039
|
+
}
|
|
1040
|
+
else {
|
|
1041
|
+
// For individual import style or unknown, copy the placeholder
|
|
1042
|
+
const placeholderSrc = path.join(canvasSourceDir, 'componentRegistry.ts');
|
|
1043
|
+
if (fs.existsSync(placeholderSrc)) {
|
|
1044
|
+
fs.copyFileSync(placeholderSrc, path.join(canvasTargetDir, 'componentRegistry.ts'));
|
|
1045
|
+
}
|
|
1046
|
+
console.log(chalk.yellow(`ā ļø Voice Canvas registry is empty ā populate voice/canvas/componentRegistry.ts manually`));
|
|
1047
|
+
}
|
|
937
1048
|
// Configure Storybook bundler for StoryUIPanel requirements
|
|
938
1049
|
console.log(chalk.blue('\nš§ Configuring Storybook for Story UI...'));
|
|
939
1050
|
const mainConfigPath = path.join(process.cwd(), '.storybook', 'main.ts');
|
package/dist/cli/update.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../cli/update.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../cli/update.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AA0UD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkItF;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CA+BpC"}
|
package/dist/cli/update.js
CHANGED
|
@@ -26,6 +26,32 @@ const MANAGED_FILES = [
|
|
|
26
26
|
source: 'templates/StoryUI/index.tsx',
|
|
27
27
|
target: 'src/stories/StoryUI/index.tsx',
|
|
28
28
|
description: 'Panel registration'
|
|
29
|
+
},
|
|
30
|
+
// Voice Canvas files
|
|
31
|
+
{
|
|
32
|
+
source: 'templates/StoryUI/voice/VoiceCanvas.tsx',
|
|
33
|
+
target: 'src/stories/StoryUI/voice/VoiceCanvas.tsx',
|
|
34
|
+
description: 'Voice Canvas component'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
source: 'templates/StoryUI/voice/VoiceControls.tsx',
|
|
38
|
+
target: 'src/stories/StoryUI/voice/VoiceControls.tsx',
|
|
39
|
+
description: 'Voice control UI components'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
source: 'templates/StoryUI/voice/useVoiceInput.ts',
|
|
43
|
+
target: 'src/stories/StoryUI/voice/useVoiceInput.ts',
|
|
44
|
+
description: 'Voice input hook'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
source: 'templates/StoryUI/voice/voiceCommands.ts',
|
|
48
|
+
target: 'src/stories/StoryUI/voice/voiceCommands.ts',
|
|
49
|
+
description: 'Voice command definitions'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
source: 'templates/StoryUI/voice/types.ts',
|
|
53
|
+
target: 'src/stories/StoryUI/voice/types.ts',
|
|
54
|
+
description: 'Voice module type definitions'
|
|
29
55
|
}
|
|
30
56
|
];
|
|
31
57
|
// Files that should NEVER be modified by update
|