@tpitre/story-ui 2.2.0 → 2.3.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/.env.sample +82 -11
- package/README.md +89 -0
- package/dist/cli/deploy.d.ts +17 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +696 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +26 -2
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +437 -110
- package/dist/mcp-server/index.d.ts +2 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +120 -2
- package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
- package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
- package/dist/mcp-server/mcp-stdio-server.js +8 -1
- package/dist/mcp-server/routes/claude.d.ts +3 -0
- package/dist/mcp-server/routes/claude.d.ts.map +1 -0
- package/dist/mcp-server/routes/claude.js +60 -23
- package/dist/mcp-server/routes/components.d.ts +4 -0
- package/dist/mcp-server/routes/components.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.d.ts +38 -0
- package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.js +183 -0
- package/dist/mcp-server/routes/generateStory.d.ts +3 -0
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStory.js +160 -76
- package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStoryStream.js +947 -0
- package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
- package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.js +489 -0
- package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
- package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.d.ts +89 -0
- package/dist/mcp-server/routes/providers.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.js +369 -0
- package/dist/mcp-server/routes/storySync.d.ts +26 -0
- package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
- package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.js +18 -0
- package/dist/mcp-server/sessionManager.d.ts +50 -0
- package/dist/mcp-server/sessionManager.d.ts.map +1 -0
- package/dist/story-generator/componentBlacklist.d.ts +21 -0
- package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
- package/dist/story-generator/componentDiscovery.d.ts +28 -0
- package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.js +205 -0
- package/dist/story-generator/configLoader.d.ts +33 -0
- package/dist/story-generator/configLoader.d.ts.map +1 -0
- package/dist/story-generator/considerationsLoader.d.ts +32 -0
- package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
- package/dist/story-generator/documentation-sources.d.ts +28 -0
- package/dist/story-generator/documentation-sources.d.ts.map +1 -0
- package/dist/story-generator/documentationLoader.d.ts +64 -0
- package/dist/story-generator/documentationLoader.d.ts.map +1 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.js +111 -11
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
- package/dist/story-generator/framework-adapters/index.d.ts +97 -0
- package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/index.js +198 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
- package/dist/story-generator/framework-adapters/types.d.ts +182 -0
- package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/types.js +8 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
- package/dist/story-generator/generateStory.d.ts +7 -0
- package/dist/story-generator/generateStory.d.ts.map +1 -0
- package/dist/story-generator/gitignoreManager.d.ts +50 -0
- package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.d.ts +80 -0
- package/dist/story-generator/imageProcessor.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.js +391 -0
- package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
- package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.js +135 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/claude-provider.js +414 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
- package/dist/story-generator/llm-providers/index.d.ts +63 -0
- package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/index.js +169 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/openai-provider.js +458 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/settings-manager.js +173 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
- package/dist/story-generator/llm-providers/types.d.ts +153 -0
- package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/types.js +8 -0
- package/dist/story-generator/logger.d.ts +14 -0
- package/dist/story-generator/logger.d.ts.map +1 -0
- package/dist/story-generator/logger.js +96 -29
- package/dist/story-generator/postProcessStory.d.ts +6 -0
- package/dist/story-generator/postProcessStory.d.ts.map +1 -0
- package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
- package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.d.ts +48 -0
- package/dist/story-generator/promptGenerator.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.js +186 -1
- package/dist/story-generator/storyHistory.d.ts +44 -0
- package/dist/story-generator/storyHistory.d.ts.map +1 -0
- package/dist/story-generator/storySync.d.ts +68 -0
- package/dist/story-generator/storySync.d.ts.map +1 -0
- package/dist/story-generator/storyTracker.d.ts +48 -0
- package/dist/story-generator/storyTracker.d.ts.map +1 -0
- package/dist/story-generator/storyValidator.d.ts +6 -0
- package/dist/story-generator/storyValidator.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.js +138 -1
- package/dist/story-generator/urlRedirectService.d.ts +21 -0
- package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
- package/dist/story-generator/validateStory.d.ts +19 -0
- package/dist/story-generator/validateStory.d.ts.map +1 -0
- package/dist/story-generator/validateStory.js +6 -2
- package/dist/story-generator/visionPrompts.d.ts +88 -0
- package/dist/story-generator/visionPrompts.d.ts.map +1 -0
- package/dist/story-generator/visionPrompts.js +462 -0
- package/dist/story-ui.config.d.ts +78 -0
- package/dist/story-ui.config.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
- package/dist/templates/StoryUI/index.d.ts +3 -0
- package/dist/templates/StoryUI/index.d.ts.map +1 -0
- package/dist/templates/StoryUI/index.js +2 -0
- package/package.json +17 -3
- package/templates/StoryUI/StoryUIPanel.tsx +1960 -384
- package/templates/StoryUI/index.tsx +1 -1
- package/templates/StoryUI/manager.tsx +264 -0
- package/templates/production-app/.env.example +11 -0
- package/templates/production-app/index.html +66 -0
- package/templates/production-app/package.json +30 -0
- package/templates/production-app/public/favicon.svg +5 -0
- package/templates/production-app/src/App.tsx +1560 -0
- package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
- package/templates/production-app/src/componentRegistry.ts +315 -0
- package/templates/production-app/src/considerations.ts +16 -0
- package/templates/production-app/src/index.css +284 -0
- package/templates/production-app/src/main.tsx +25 -0
- package/templates/production-app/tsconfig.json +32 -0
- package/templates/production-app/tsconfig.node.json +11 -0
- package/templates/production-app/vite.config.ts +83 -0
- package/templates/react-import-rule.json +2 -2
- package/dist/index.js +0 -12
- package/dist/story-ui.config.loader.js +0 -205
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Components Framework Adapter
|
|
3
|
+
*
|
|
4
|
+
* Generates Storybook stories for Web Components (Lit, vanilla, etc.).
|
|
5
|
+
* Supports standard Web Components and Lit framework.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseFrameworkAdapter } from './base-adapter.js';
|
|
8
|
+
export class WebComponentsAdapter extends BaseFrameworkAdapter {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.type = 'web-components';
|
|
12
|
+
this.name = 'Web Components';
|
|
13
|
+
this.supportedStoryFrameworks = [
|
|
14
|
+
'storybook-web-components',
|
|
15
|
+
'chromatic',
|
|
16
|
+
];
|
|
17
|
+
this.defaultExtension = '.stories.ts';
|
|
18
|
+
}
|
|
19
|
+
generateSystemPrompt(config, options) {
|
|
20
|
+
if (config.systemPrompt) {
|
|
21
|
+
return config.systemPrompt;
|
|
22
|
+
}
|
|
23
|
+
const componentSystemName = config.componentPrefix
|
|
24
|
+
? `${config.componentPrefix.replace(/^[A-Z]+/, '')} design system`
|
|
25
|
+
: 'component library';
|
|
26
|
+
return `You are an expert Web Components developer creating Storybook stories using CSF 3.0 format.
|
|
27
|
+
Use ONLY the Web Components from the ${componentSystemName} listed below.
|
|
28
|
+
|
|
29
|
+
MANDATORY IMPORTS - First lines of every story file:
|
|
30
|
+
1. import { html } from 'lit';
|
|
31
|
+
2. import type { Meta, StoryObj } from '@storybook/web-components';
|
|
32
|
+
3. import '${config.importPath || 'your-library'}'; // Register custom elements
|
|
33
|
+
|
|
34
|
+
WEB COMPONENTS STORY FORMAT:
|
|
35
|
+
- Use the html template literal from Lit for rendering
|
|
36
|
+
- Custom elements use kebab-case tag names (e.g., <my-button>)
|
|
37
|
+
- Properties are set as attributes or with . prefix for property binding
|
|
38
|
+
- Events use @ prefix (e.g., @click)
|
|
39
|
+
|
|
40
|
+
COMPONENT REGISTRATION:
|
|
41
|
+
- Web Components must be registered before use
|
|
42
|
+
- Import the component file to auto-register: import 'my-library/my-button';
|
|
43
|
+
- Or import the class and define: customElements.define('my-button', MyButton);
|
|
44
|
+
|
|
45
|
+
STORY STRUCTURE (CSF 3.0):
|
|
46
|
+
- Meta object with title and optional component reference
|
|
47
|
+
- Use render function with html\`\` template literal
|
|
48
|
+
- Export named stories as StoryObj
|
|
49
|
+
|
|
50
|
+
CRITICAL RULES:
|
|
51
|
+
- Use html template literal, NOT JSX
|
|
52
|
+
- Use kebab-case for tag names
|
|
53
|
+
- Use .property for property binding, attribute for attributes
|
|
54
|
+
- Use @event for event handlers
|
|
55
|
+
|
|
56
|
+
Example structure:
|
|
57
|
+
\`\`\`typescript
|
|
58
|
+
import { html } from 'lit';
|
|
59
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
60
|
+
import 'your-library/button';
|
|
61
|
+
|
|
62
|
+
const meta: Meta = {
|
|
63
|
+
title: 'Components/Button',
|
|
64
|
+
tags: ['autodocs'],
|
|
65
|
+
argTypes: {
|
|
66
|
+
variant: {
|
|
67
|
+
control: 'select',
|
|
68
|
+
options: ['primary', 'secondary', 'ghost'],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default meta;
|
|
74
|
+
type Story = StoryObj;
|
|
75
|
+
|
|
76
|
+
export const Primary: Story = {
|
|
77
|
+
args: { variant: 'primary' },
|
|
78
|
+
render: (args) => html\`
|
|
79
|
+
<my-button variant=\${args.variant}>
|
|
80
|
+
Click me
|
|
81
|
+
</my-button>
|
|
82
|
+
\`,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const WithIcon: Story = {
|
|
86
|
+
render: () => html\`
|
|
87
|
+
<my-button variant="primary">
|
|
88
|
+
<my-icon slot="icon" name="star"></my-icon>
|
|
89
|
+
Starred
|
|
90
|
+
</my-button>
|
|
91
|
+
\`,
|
|
92
|
+
};
|
|
93
|
+
\`\`\`
|
|
94
|
+
|
|
95
|
+
ATTRIBUTE VS PROPERTY BINDING:
|
|
96
|
+
- Attributes (string values): variant="primary"
|
|
97
|
+
- Properties (any value): .disabled=\${true}
|
|
98
|
+
- Boolean attributes: ?disabled=\${true}
|
|
99
|
+
- Events: @click=\${handleClick}
|
|
100
|
+
|
|
101
|
+
SLOTS:
|
|
102
|
+
- Default slot: Content between tags
|
|
103
|
+
- Named slots: Use slot="name" attribute
|
|
104
|
+
- Example: <my-card><span slot="header">Title</span>Content</my-card>
|
|
105
|
+
|
|
106
|
+
${this.getCommonRules()}`;
|
|
107
|
+
}
|
|
108
|
+
generateExamples(config) {
|
|
109
|
+
const lib = config.importPath || 'your-library';
|
|
110
|
+
return `
|
|
111
|
+
## Example Stories for Web Components
|
|
112
|
+
|
|
113
|
+
### Single Component Story
|
|
114
|
+
\`\`\`typescript
|
|
115
|
+
import { html } from 'lit';
|
|
116
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
117
|
+
import 'your-library/button';
|
|
118
|
+
|
|
119
|
+
const meta: Meta = {
|
|
120
|
+
title: 'Components/Button',
|
|
121
|
+
tags: ['autodocs'],
|
|
122
|
+
argTypes: {
|
|
123
|
+
variant: {
|
|
124
|
+
control: 'select',
|
|
125
|
+
options: ['primary', 'secondary', 'ghost'],
|
|
126
|
+
},
|
|
127
|
+
size: {
|
|
128
|
+
control: 'select',
|
|
129
|
+
options: ['small', 'medium', 'large'],
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export default meta;
|
|
135
|
+
type Story = StoryObj;
|
|
136
|
+
|
|
137
|
+
export const Default: Story = {
|
|
138
|
+
args: { variant: 'primary', size: 'medium' },
|
|
139
|
+
render: (args) => html\`
|
|
140
|
+
<my-button
|
|
141
|
+
variant=\${args.variant}
|
|
142
|
+
size=\${args.size}
|
|
143
|
+
>
|
|
144
|
+
Button
|
|
145
|
+
</my-button>
|
|
146
|
+
\`,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const Disabled: Story = {
|
|
150
|
+
render: () => html\`
|
|
151
|
+
<my-button variant="primary" ?disabled=\${true}>
|
|
152
|
+
Disabled Button
|
|
153
|
+
</my-button>
|
|
154
|
+
\`,
|
|
155
|
+
};
|
|
156
|
+
\`\`\`
|
|
157
|
+
|
|
158
|
+
### Layout Story (Multiple Components)
|
|
159
|
+
\`\`\`typescript
|
|
160
|
+
import { html } from 'lit';
|
|
161
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
162
|
+
import '${lib}/card';
|
|
163
|
+
import 'your-library/button';
|
|
164
|
+
import '${lib}/text';
|
|
165
|
+
|
|
166
|
+
const meta: Meta = {
|
|
167
|
+
title: 'Examples/Card Layout',
|
|
168
|
+
parameters: { layout: 'padded' },
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export default meta;
|
|
172
|
+
type Story = StoryObj;
|
|
173
|
+
|
|
174
|
+
export const ProductCard: Story = {
|
|
175
|
+
render: () => html\`
|
|
176
|
+
<my-card style="width: 300px">
|
|
177
|
+
<img slot="media" src="https://picsum.photos/300/200" alt="Product">
|
|
178
|
+
<span slot="header">Product Name</span>
|
|
179
|
+
<my-text>$99.00</my-text>
|
|
180
|
+
<my-button slot="footer" variant="primary">Add to Cart</my-button>
|
|
181
|
+
</my-card>
|
|
182
|
+
\`,
|
|
183
|
+
};
|
|
184
|
+
\`\`\`
|
|
185
|
+
|
|
186
|
+
### With Event Handling
|
|
187
|
+
\`\`\`typescript
|
|
188
|
+
import { html } from 'lit';
|
|
189
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
190
|
+
import 'your-library/button';
|
|
191
|
+
|
|
192
|
+
const meta: Meta = {
|
|
193
|
+
title: 'Components/Button',
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export default meta;
|
|
197
|
+
type Story = StoryObj;
|
|
198
|
+
|
|
199
|
+
export const WithClickHandler: Story = {
|
|
200
|
+
render: () => html\`
|
|
201
|
+
<my-button
|
|
202
|
+
variant="primary"
|
|
203
|
+
@click=\${(e: Event) => console.log('Clicked!', e)}
|
|
204
|
+
>
|
|
205
|
+
Click me
|
|
206
|
+
</my-button>
|
|
207
|
+
\`,
|
|
208
|
+
};
|
|
209
|
+
\`\`\`
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
generateSampleStory(config, components) {
|
|
213
|
+
const lib = config.importPath || 'your-library';
|
|
214
|
+
const firstComponent = components[0];
|
|
215
|
+
if (!firstComponent) {
|
|
216
|
+
return `
|
|
217
|
+
import { html } from 'lit';
|
|
218
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
219
|
+
|
|
220
|
+
const meta: Meta = {
|
|
221
|
+
title: 'Examples/Sample',
|
|
222
|
+
parameters: { layout: 'centered' },
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export default meta;
|
|
226
|
+
type Story = StoryObj;
|
|
227
|
+
|
|
228
|
+
export const Default: Story = {
|
|
229
|
+
render: () => html\`<div>Sample story content</div>\`,
|
|
230
|
+
};
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
233
|
+
// Convert PascalCase to kebab-case for tag name
|
|
234
|
+
const tagName = this.toKebabCase(firstComponent.name);
|
|
235
|
+
return `
|
|
236
|
+
import { html } from 'lit';
|
|
237
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
238
|
+
import '${lib}/${tagName}';
|
|
239
|
+
|
|
240
|
+
const meta: Meta = {
|
|
241
|
+
title: 'Components/${firstComponent.name}',
|
|
242
|
+
tags: ['autodocs'],
|
|
243
|
+
parameters: { layout: 'centered' },
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export default meta;
|
|
247
|
+
type Story = StoryObj;
|
|
248
|
+
|
|
249
|
+
export const Default: Story = {
|
|
250
|
+
render: () => html\`<${tagName}></${tagName}>\`,
|
|
251
|
+
};
|
|
252
|
+
`;
|
|
253
|
+
}
|
|
254
|
+
getStoryTemplate(options) {
|
|
255
|
+
return `
|
|
256
|
+
// {{componentName}}.stories.ts
|
|
257
|
+
import { html } from 'lit';
|
|
258
|
+
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
259
|
+
import '{{importPath}}';
|
|
260
|
+
|
|
261
|
+
const meta: Meta = {
|
|
262
|
+
title: '{{category}}/{{componentName}}',
|
|
263
|
+
tags: ['autodocs'],
|
|
264
|
+
parameters: { layout: 'centered' },
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export default meta;
|
|
268
|
+
type Story = StoryObj;
|
|
269
|
+
|
|
270
|
+
export const Default: Story = {
|
|
271
|
+
render: () => html\`<{{tagName}}></{{tagName}}>\`,
|
|
272
|
+
};
|
|
273
|
+
`;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Convert PascalCase to kebab-case
|
|
277
|
+
*/
|
|
278
|
+
toKebabCase(str) {
|
|
279
|
+
return str
|
|
280
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
281
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
282
|
+
.toLowerCase();
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Post-process Web Components stories
|
|
286
|
+
*/
|
|
287
|
+
postProcess(storyContent) {
|
|
288
|
+
let processed = super.postProcess(storyContent);
|
|
289
|
+
// Ensure lit import is present
|
|
290
|
+
if (!processed.includes("import { html } from 'lit'")) {
|
|
291
|
+
processed = "import { html } from 'lit';\n" + processed;
|
|
292
|
+
}
|
|
293
|
+
// FIX #3: Remove React imports from Web Components stories
|
|
294
|
+
// LLMs sometimes incorrectly include React imports in non-React frameworks
|
|
295
|
+
processed = processed.replace(/import React from ['"]react['"];?\n?/g, '');
|
|
296
|
+
processed = processed.replace(/import \* as React from ['"]react['"];?\n?/g, '');
|
|
297
|
+
// Fix common issues
|
|
298
|
+
processed = processed
|
|
299
|
+
// Remove React-style className
|
|
300
|
+
.replace(/className=/g, 'class=')
|
|
301
|
+
// Fix JSX-style event handlers
|
|
302
|
+
.replace(/onClick=/g, '@click=')
|
|
303
|
+
.replace(/onChange=/g, '@change=')
|
|
304
|
+
.replace(/onInput=/g, '@input=');
|
|
305
|
+
// FIX #1: Handle escaped backticks in nested template literals
|
|
306
|
+
// When LLMs generate complex Lit templates with inline JavaScript that uses
|
|
307
|
+
// template literals, they sometimes escape backticks incorrectly causing
|
|
308
|
+
// Babel parsing errors like "Expecting Unicode escape sequence \uXXXX"
|
|
309
|
+
processed = this.fixNestedTemplateLiterals(processed);
|
|
310
|
+
return processed;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Fix nested template literal escaping issues
|
|
314
|
+
*
|
|
315
|
+
* Problem: LLMs generate code like:
|
|
316
|
+
* innerHTML: \`<sl-icon></sl-icon>\`
|
|
317
|
+
*
|
|
318
|
+
* This causes Babel syntax errors. The fix converts problematic patterns
|
|
319
|
+
* to use string concatenation instead of nested template literals.
|
|
320
|
+
*/
|
|
321
|
+
fixNestedTemplateLiterals(code) {
|
|
322
|
+
// Pattern 1: innerHTML with escaped template literals
|
|
323
|
+
// Convert: innerHTML: \`...\` to innerHTML: '...'
|
|
324
|
+
code = code.replace(/innerHTML:\s*\\`([^`]*?)\\`/g, (match, content) => {
|
|
325
|
+
// Convert to single quotes, escaping any existing single quotes
|
|
326
|
+
const escaped = content.replace(/'/g, "\\'");
|
|
327
|
+
return `innerHTML: '${escaped}'`;
|
|
328
|
+
});
|
|
329
|
+
// Pattern 2: Template literals with escaped backticks inside html``
|
|
330
|
+
// These patterns indicate the LLM tried to nest template literals incorrectly
|
|
331
|
+
// Look for patterns like \`...\` that appear inside render functions
|
|
332
|
+
code = code.replace(/\\`/g, (match, offset, fullString) => {
|
|
333
|
+
// Check if we're inside a JavaScript context (not in a comment or string)
|
|
334
|
+
const before = fullString.slice(Math.max(0, offset - 50), offset);
|
|
335
|
+
// If this looks like it's in an innerHTML or template context, convert to quote
|
|
336
|
+
if (/innerHTML\s*[:=]\s*$/.test(before) ||
|
|
337
|
+
/Object\.assign\([^)]*\{\s*$/.test(before) ||
|
|
338
|
+
/:\s*$/.test(before)) {
|
|
339
|
+
return "'";
|
|
340
|
+
}
|
|
341
|
+
// Otherwise keep the escaped backtick (might be intentional)
|
|
342
|
+
return match;
|
|
343
|
+
});
|
|
344
|
+
return code;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Validate Web Components story
|
|
348
|
+
*/
|
|
349
|
+
validate(storyContent) {
|
|
350
|
+
const baseValidation = super.validate(storyContent);
|
|
351
|
+
const errors = [...baseValidation.errors];
|
|
352
|
+
// Web Components specific validations
|
|
353
|
+
if (!storyContent.includes("import { html } from 'lit'")) {
|
|
354
|
+
errors.push("Missing 'import { html } from 'lit'' statement");
|
|
355
|
+
}
|
|
356
|
+
if (storyContent.includes('import React')) {
|
|
357
|
+
errors.push('React import found in Web Components story');
|
|
358
|
+
}
|
|
359
|
+
// Check for JSX syntax (should use lit html)
|
|
360
|
+
if (/<[A-Z][a-zA-Z]*\s/.test(storyContent) && !storyContent.includes('html`')) {
|
|
361
|
+
errors.push('Using JSX syntax instead of Lit html template');
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
valid: errors.length === 0,
|
|
365
|
+
errors,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Generate import statements for Web Components
|
|
370
|
+
*/
|
|
371
|
+
generateImports(components, config) {
|
|
372
|
+
const lib = config.importPath || 'your-library';
|
|
373
|
+
const imports = ["import { html } from 'lit';"];
|
|
374
|
+
// Import each component (side-effect import to register custom element)
|
|
375
|
+
for (const component of components) {
|
|
376
|
+
const tagName = this.toKebabCase(component.name);
|
|
377
|
+
imports.push(`import '${lib}/${tagName}';`);
|
|
378
|
+
}
|
|
379
|
+
return imports.join('\n');
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Factory function
|
|
384
|
+
*/
|
|
385
|
+
export function createWebComponentsAdapter() {
|
|
386
|
+
return new WebComponentsAdapter();
|
|
387
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateStory.d.ts","sourceRoot":"","sources":["../../story-generator/generateStory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAStD,wBAAgB,aAAa,CAAC,EAC5B,YAAY,EACZ,QAAQ,EACR,MAAM,EACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB,UAWA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages .gitignore entries for Story UI generated content
|
|
4
|
+
*/
|
|
5
|
+
export declare class GitignoreManager {
|
|
6
|
+
private config;
|
|
7
|
+
private projectRoot;
|
|
8
|
+
constructor(config: StoryUIConfig, projectRoot?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Ensures the generated stories directory is added to .gitignore
|
|
11
|
+
*/
|
|
12
|
+
ensureGeneratedDirectoryIgnored(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Gets the relative path from project root to generated stories directory
|
|
15
|
+
*/
|
|
16
|
+
private getRelativeGeneratedPath;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new .gitignore file with Story UI section
|
|
19
|
+
*/
|
|
20
|
+
private createGitignore;
|
|
21
|
+
/**
|
|
22
|
+
* Checks if the generated path is already ignored
|
|
23
|
+
*/
|
|
24
|
+
private isPathIgnored;
|
|
25
|
+
/**
|
|
26
|
+
* Adds ignore rule to existing .gitignore
|
|
27
|
+
*/
|
|
28
|
+
private addIgnoreRule;
|
|
29
|
+
/**
|
|
30
|
+
* Generates the gitignore section for Story UI
|
|
31
|
+
*/
|
|
32
|
+
private generateGitignoreSection;
|
|
33
|
+
/**
|
|
34
|
+
* Creates the generated directory if it doesn't exist
|
|
35
|
+
*/
|
|
36
|
+
ensureGeneratedDirectoryExists(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a README in the generated directory explaining its purpose
|
|
39
|
+
*/
|
|
40
|
+
private createGeneratedDirectoryReadme;
|
|
41
|
+
/**
|
|
42
|
+
* Cleans up old generated stories (optional utility)
|
|
43
|
+
*/
|
|
44
|
+
cleanupOldStories(maxAge?: number): void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convenience function to set up gitignore for Story UI
|
|
48
|
+
*/
|
|
49
|
+
export declare function setupGitignoreForStoryUI(config: StoryUIConfig, projectRoot?: string): void;
|
|
50
|
+
//# sourceMappingURL=gitignoreManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignoreManager.d.ts","sourceRoot":"","sources":["../../story-generator/gitignoreManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,aAAa,EAAE,WAAW,GAAE,MAAsB;IAKtE;;OAEG;IACH,+BAA+B,IAAI,IAAI;IA0BvC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAmBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAOhC;;OAEG;IACH,8BAA8B,IAAI,IAAI;IAYtC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IA+BtC;;OAEG;IACH,iBAAiB,CAAC,MAAM,GAAE,MAAgC,GAAG,IAAI;CA8BlE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAI1F"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Processing Module for StoryUI Vision Feature
|
|
3
|
+
*
|
|
4
|
+
* This module handles all image processing operations including:
|
|
5
|
+
* - Validation of image inputs (size, format, data integrity)
|
|
6
|
+
* - Conversion between different image formats (URL, base64, buffer)
|
|
7
|
+
* - Media type detection from magic bytes and file extensions
|
|
8
|
+
* - Preparation of images for LLM provider consumption
|
|
9
|
+
*
|
|
10
|
+
* Supports: PNG, JPEG, GIF, WebP formats
|
|
11
|
+
* Max size: 20MB for base64 encoded images
|
|
12
|
+
*/
|
|
13
|
+
import { ImageContent } from './llm-providers/types.js';
|
|
14
|
+
declare const SUPPORTED_MEDIA_TYPES: readonly ["image/png", "image/jpeg", "image/jpg", "image/gif", "image/webp"];
|
|
15
|
+
type SupportedMediaType = typeof SUPPORTED_MEDIA_TYPES[number];
|
|
16
|
+
/**
|
|
17
|
+
* Image Input Interface
|
|
18
|
+
* Accepts images from API requests in various formats
|
|
19
|
+
*/
|
|
20
|
+
export interface ImageInput {
|
|
21
|
+
data?: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
mediaType?: string;
|
|
24
|
+
name?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Image Validation Result
|
|
28
|
+
*/
|
|
29
|
+
export interface ImageValidationResult {
|
|
30
|
+
valid: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
warning?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get media type from buffer by checking magic bytes
|
|
36
|
+
*
|
|
37
|
+
* @param buffer - Image buffer to analyze
|
|
38
|
+
* @returns Detected MIME type or undefined if not recognized
|
|
39
|
+
*/
|
|
40
|
+
export declare function getMediaTypeFromBuffer(buffer: Buffer): SupportedMediaType | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Validate an image input
|
|
43
|
+
*
|
|
44
|
+
* Checks:
|
|
45
|
+
* - Has either data or url
|
|
46
|
+
* - File size is within limits
|
|
47
|
+
* - Media type is supported
|
|
48
|
+
* - Base64 data is valid
|
|
49
|
+
*
|
|
50
|
+
* @param image - Image input to validate
|
|
51
|
+
* @returns Validation result with error/warning messages
|
|
52
|
+
*/
|
|
53
|
+
export declare function validateImage(image: ImageInput): ImageValidationResult;
|
|
54
|
+
/**
|
|
55
|
+
* Fetch an image from a URL and convert to base64
|
|
56
|
+
*
|
|
57
|
+
* @param url - URL to fetch image from
|
|
58
|
+
* @returns Object containing base64 data and detected media type
|
|
59
|
+
* @throws Error if fetch fails or image is invalid
|
|
60
|
+
*/
|
|
61
|
+
export declare function fetchImageAsBase64(url: string): Promise<{
|
|
62
|
+
data: string;
|
|
63
|
+
mediaType: SupportedMediaType;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Process multiple image inputs and convert to ImageContent format
|
|
67
|
+
*
|
|
68
|
+
* This is the main entry point for image processing. It:
|
|
69
|
+
* 1. Validates each image input
|
|
70
|
+
* 2. Fetches URL images and converts to base64
|
|
71
|
+
* 3. Detects media types from magic bytes, headers, or extensions
|
|
72
|
+
* 4. Returns array of ImageContent objects ready for LLM providers
|
|
73
|
+
*
|
|
74
|
+
* @param images - Array of image inputs to process
|
|
75
|
+
* @returns Promise resolving to array of ImageContent objects
|
|
76
|
+
* @throws Error if any image fails to process
|
|
77
|
+
*/
|
|
78
|
+
export declare function processImageInputs(images: ImageInput[]): Promise<ImageContent[]>;
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=imageProcessor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageProcessor.d.ts","sourceRoot":"","sources":["../../story-generator/imageProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AASxD,QAAA,MAAM,qBAAqB,8EAMjB,CAAC;AAEX,KAAK,kBAAkB,GAAG,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAoB/D;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAYD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CA2BrF;AAkED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,qBAAqB,CAqFtE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAqD9G;AAmGD;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgCtF"}
|