@tpitre/story-ui 4.16.11 ā 4.16.12
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 +209 -460
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +7 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +69 -1
- package/dist/templates/StoryUI/StoryUIPanel.js +1 -1
- package/dist/templates/StoryUI/StoryUIPanel.tsx +1 -1
- package/package.json +1 -1
- package/templates/StoryUI/StoryUIPanel.tsx +1 -1
package/README.md
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
# Story UI
|
|
2
2
|
|
|
3
|
-
*AI-powered Storybook story generator for any JavaScript framework*
|
|
3
|
+
*AI-powered Storybook story generator for any JavaScript framework and design system*
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/%40tpitre%2Fstory-ui)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
Story UI
|
|
8
|
+
Story UI generates working Storybook stories from natural language. Describe what you want, and the AI writes production-ready story code using your design system's actual components. Works with **any framework** and **any component library**.
|
|
9
9
|
|
|
10
10
|
## Why Story UI?
|
|
11
11
|
|
|
12
|
-
- **
|
|
13
|
-
- **Multi-Provider AI**:
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
12
|
+
- **Design-System Agnostic**: React, Vue, Angular, Svelte, Web Components ā bring your own component library
|
|
13
|
+
- **Multi-Provider AI**: Claude, OpenAI, or Gemini with automatic model selection
|
|
14
|
+
- **Self-Healing Generation**: Validates generated code with TypeScript AST parsing and auto-corrects errors through an LLM retry loop
|
|
15
|
+
- **Voice Canvas**: Speak your component ideas and see them rendered live in Storybook
|
|
16
|
+
- **Storybook MCP Integration**: Fetches component docs and story patterns from Storybook's MCP addon for higher-quality output
|
|
17
|
+
- **Zero Lock-in**: Use Mantine, Vuetify, Angular Material, Shoelace, shadcn/ui, or your own components
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
@@ -40,24 +41,35 @@ Story UI will guide you through:
|
|
|
40
41
|
|
|
41
42
|
## Features
|
|
42
43
|
|
|
43
|
-
###
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
### AI-Powered Story Generation
|
|
45
|
+
Describe what you want in natural language. Story UI generates complete, working Storybook stories using your design system's components with proper imports, props, and TypeScript types.
|
|
46
|
+
|
|
47
|
+
### Self-Healing Code Generation
|
|
48
|
+
When generated code has syntax errors, invalid imports, or forbidden patterns, Story UI automatically:
|
|
49
|
+
1. Validates with TypeScript AST parsing and pattern checking
|
|
50
|
+
2. Sends errors back to the LLM with correction context
|
|
51
|
+
3. Retries up to 3 times, tracking error history to detect stuck loops
|
|
52
|
+
4. Selects the best attempt if all retries fail
|
|
53
|
+
|
|
54
|
+
### Voice Canvas
|
|
55
|
+
A live playground mode where you speak component ideas and see them rendered instantly in Storybook. Uses browser speech recognition with auto-submit, pauses during generation, and renders output through an iframe with `react-live`.
|
|
56
|
+
|
|
57
|
+
### Intelligent Iteration
|
|
58
|
+
Continue the conversation to refine generated stories. Story UI preserves context and modifies only what you request.
|
|
59
|
+
|
|
60
|
+
### Vision Support
|
|
61
|
+
Attach screenshots or mockups to your prompt. The AI uses them as reference when generating components.
|
|
49
62
|
|
|
50
63
|
### Story Management
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
- **Full MCP Integration**: Manage stories via Claude Desktop or any MCP-compatible client
|
|
64
|
+
- Edit, delete, and organize generated stories from the panel
|
|
65
|
+
- Orphan detection for stories without chat history
|
|
66
|
+
- File-based manifest system for tracking generated assets
|
|
55
67
|
|
|
56
68
|
### Multi-Framework Support
|
|
57
69
|
|
|
58
70
|
| Framework | Design Systems | Status |
|
|
59
71
|
|-----------|---------------|--------|
|
|
60
|
-
| React | Mantine, Chakra UI, Material UI, Custom | Fully Supported |
|
|
72
|
+
| React | Mantine, Chakra UI, Material UI, shadcn/ui, Custom | Fully Supported |
|
|
61
73
|
| Vue | Vuetify, Custom | Fully Supported |
|
|
62
74
|
| Angular | Angular Material, Custom | Fully Supported |
|
|
63
75
|
| Svelte | Flowbite-Svelte, Custom | Fully Supported |
|
|
@@ -65,342 +77,124 @@ Story UI will guide you through:
|
|
|
65
77
|
|
|
66
78
|
### Multi-Provider LLM Support
|
|
67
79
|
|
|
68
|
-
| Provider | Models |
|
|
69
|
-
|
|
70
|
-
| **Claude** (Anthropic) |
|
|
71
|
-
| **GPT** (OpenAI) |
|
|
72
|
-
| **Gemini** (Google) |
|
|
73
|
-
|
|
74
|
-
### Production Deployment
|
|
75
|
-
- **Railway**: Node.js backend with file-based story persistence
|
|
76
|
-
- **MCP Integration**: Connect AI clients directly to production
|
|
80
|
+
| Provider | Models | Default |
|
|
81
|
+
|----------|--------|---------|
|
|
82
|
+
| **Claude** (Anthropic) | Claude Opus 4.6, Claude Sonnet 4.6, Claude Haiku 4.5 | `claude-sonnet-4-6` |
|
|
83
|
+
| **GPT** (OpenAI) | GPT-5.4, GPT-5.4 Mini, o4 Mini | `gpt-5.4` |
|
|
84
|
+
| **Gemini** (Google) | Gemini 3.1 Pro Preview, Gemini 3 Flash Preview, Gemini 2.5 Flash | `gemini-3.1-pro-preview` |
|
|
77
85
|
|
|
78
86
|
---
|
|
79
87
|
|
|
80
|
-
## Installation
|
|
88
|
+
## Installation
|
|
81
89
|
|
|
82
|
-
###
|
|
90
|
+
### Interactive Setup (Recommended)
|
|
83
91
|
|
|
84
92
|
```bash
|
|
85
93
|
npx story-ui init
|
|
86
94
|
```
|
|
87
95
|
|
|
88
|
-
The
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
Angular
|
|
96
|
-
Svelte
|
|
97
|
-
Web Components
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
2. **Design System Selection** (varies by framework)
|
|
101
|
-
```
|
|
102
|
-
# For React:
|
|
103
|
-
? Choose a design system:
|
|
104
|
-
> Mantine - Most Popular
|
|
105
|
-
Chakra UI
|
|
106
|
-
Material UI
|
|
107
|
-
Custom
|
|
108
|
-
|
|
109
|
-
# For Vue:
|
|
110
|
-
? Choose a design system:
|
|
111
|
-
> Vuetify - Most Popular
|
|
112
|
-
Custom
|
|
113
|
-
|
|
114
|
-
# For Angular:
|
|
115
|
-
? Choose a design system:
|
|
116
|
-
> Angular Material - Most Popular
|
|
117
|
-
Custom
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
3. **AI Provider Selection**
|
|
121
|
-
```
|
|
122
|
-
? Which AI provider do you prefer?
|
|
123
|
-
> Claude (Anthropic) - Recommended
|
|
124
|
-
OpenAI
|
|
125
|
-
Google Gemini
|
|
126
|
-
|
|
127
|
-
? Enter your API key:
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Option 2: Manual Configuration
|
|
96
|
+
The installer prompts for:
|
|
97
|
+
1. **Framework** ā React, Vue, Angular, Svelte, or Web Components
|
|
98
|
+
2. **Design System** ā framework-specific options (Mantine, Vuetify, Angular Material, etc.)
|
|
99
|
+
3. **AI Provider** ā Claude (recommended), OpenAI, or Gemini
|
|
100
|
+
4. **Configuration** ā paths, ports, and API keys
|
|
101
|
+
|
|
102
|
+
### Manual Configuration
|
|
131
103
|
|
|
132
104
|
Create `story-ui.config.js` in your project root:
|
|
133
105
|
|
|
134
106
|
```javascript
|
|
135
|
-
|
|
107
|
+
module.exports = {
|
|
136
108
|
// Framework: 'react' | 'vue' | 'angular' | 'svelte' | 'web-components'
|
|
137
|
-
|
|
109
|
+
componentFramework: 'react',
|
|
138
110
|
|
|
139
111
|
// Component library import path
|
|
140
112
|
importPath: '@mantine/core',
|
|
141
113
|
|
|
142
|
-
// Path to custom components
|
|
143
|
-
componentsPath: './src/components',
|
|
144
|
-
|
|
145
114
|
// Generated stories location
|
|
146
115
|
generatedStoriesPath: './src/stories/generated/',
|
|
147
116
|
|
|
148
|
-
// LLM provider
|
|
149
|
-
llmProvider: 'claude',
|
|
117
|
+
// LLM provider: 'claude' | 'openai' | 'gemini'
|
|
118
|
+
llmProvider: 'claude',
|
|
119
|
+
|
|
120
|
+
// Import style: 'barrel' (default) or 'individual'
|
|
121
|
+
// Use 'individual' for libraries without barrel exports (shadcn/ui, Radix Vue, Angular Material)
|
|
122
|
+
// Use 'barrel' for libraries with index.ts barrel exports (Mantine, Chakra, Vuetify)
|
|
123
|
+
importStyle: 'barrel',
|
|
150
124
|
|
|
151
125
|
// Story configuration
|
|
152
126
|
storyPrefix: 'Generated/',
|
|
153
|
-
defaultAuthor: 'Story UI AI'
|
|
127
|
+
defaultAuthor: 'Story UI AI',
|
|
128
|
+
|
|
129
|
+
// Layout rules for multi-component compositions
|
|
130
|
+
layoutRules: {
|
|
131
|
+
multiColumnWrapper: 'SimpleGrid',
|
|
132
|
+
columnComponent: 'div',
|
|
133
|
+
containerComponent: 'Container',
|
|
134
|
+
},
|
|
154
135
|
};
|
|
155
136
|
```
|
|
156
137
|
|
|
157
|
-
###
|
|
138
|
+
### Import Examples (Web Components / Custom Libraries)
|
|
158
139
|
|
|
159
|
-
For component libraries with non-standard import paths
|
|
140
|
+
For component libraries with non-standard import paths, use `importExamples` to teach the AI your patterns:
|
|
160
141
|
|
|
161
142
|
```javascript
|
|
162
|
-
|
|
143
|
+
module.exports = {
|
|
163
144
|
framework: 'web-components',
|
|
164
145
|
importPath: '../../../components',
|
|
165
146
|
|
|
166
|
-
// Teach the AI your library's import structure
|
|
167
147
|
importExamples: [
|
|
168
148
|
"import '../../../components/button/button'; // For <my-button>",
|
|
169
149
|
"import '../../../components/card/card'; // For <my-card>",
|
|
170
|
-
"import '../../../components/icon/icons/check'; // For <my-icon-check>",
|
|
171
150
|
],
|
|
172
|
-
|
|
173
|
-
// ... other config
|
|
174
151
|
};
|
|
175
152
|
```
|
|
176
153
|
|
|
177
|
-
The AI uses these examples to understand your component library's folder structure and generate correct imports.
|
|
178
|
-
|
|
179
154
|
---
|
|
180
155
|
|
|
181
156
|
## Usage
|
|
182
157
|
|
|
183
|
-
###
|
|
158
|
+
### Generating Stories
|
|
184
159
|
|
|
185
160
|
Start the Story UI server:
|
|
186
161
|
```bash
|
|
187
162
|
npm run story-ui
|
|
188
163
|
```
|
|
189
164
|
|
|
190
|
-
|
|
191
|
-
```
|
|
192
|
-
You: "Create a product card with image, title, price, and add to cart button"
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
Story UI generates:
|
|
196
|
-
```tsx
|
|
197
|
-
export const ProductCard = {
|
|
198
|
-
render: () => (
|
|
199
|
-
<Card shadow="sm" padding="lg" radius="md" withBorder>
|
|
200
|
-
<Card.Section>
|
|
201
|
-
<Image src="https://example.com/product.jpg" height={160} alt="Product" />
|
|
202
|
-
</Card.Section>
|
|
203
|
-
<Group justify="space-between" mt="md" mb="xs">
|
|
204
|
-
<Text fw={500}>Product Name</Text>
|
|
205
|
-
<Badge color="pink">On Sale</Badge>
|
|
206
|
-
</Group>
|
|
207
|
-
<Text size="sm" c="dimmed">$29.99</Text>
|
|
208
|
-
<Button color="blue" fullWidth mt="md" radius="md">
|
|
209
|
-
Add to Cart
|
|
210
|
-
</Button>
|
|
211
|
-
</Card>
|
|
212
|
-
)
|
|
213
|
-
};
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Iterating on Stories
|
|
165
|
+
Open Storybook and navigate to the Story UI panel. Describe what you want:
|
|
217
166
|
|
|
218
|
-
Continue the conversation to refine:
|
|
219
|
-
```
|
|
220
|
-
You: "Make the button green and add a quantity selector"
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Story UI modifies only what you requested, preserving the rest.
|
|
224
|
-
|
|
225
|
-
### Using with Different Frameworks
|
|
226
|
-
|
|
227
|
-
**Vue Example:**
|
|
228
|
-
```
|
|
229
|
-
You: "Create a user profile card with avatar, name, and edit button"
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
Generates Vue template:
|
|
233
|
-
```vue
|
|
234
|
-
<template>
|
|
235
|
-
<v-card class="mx-auto" max-width="400">
|
|
236
|
-
<v-card-item>
|
|
237
|
-
<v-avatar size="80">
|
|
238
|
-
<v-img src="https://example.com/avatar.jpg" alt="User" />
|
|
239
|
-
</v-avatar>
|
|
240
|
-
<v-card-title>John Doe</v-card-title>
|
|
241
|
-
<v-card-subtitle>Software Engineer</v-card-subtitle>
|
|
242
|
-
</v-card-item>
|
|
243
|
-
<v-card-actions>
|
|
244
|
-
<v-btn color="primary" variant="outlined">Edit Profile</v-btn>
|
|
245
|
-
</v-card-actions>
|
|
246
|
-
</v-card>
|
|
247
|
-
</template>
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
**Angular Example:**
|
|
251
167
|
```
|
|
252
|
-
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Generates Angular component:
|
|
256
|
-
```typescript
|
|
257
|
-
@Component({
|
|
258
|
-
selector: 'app-data-table',
|
|
259
|
-
template: `
|
|
260
|
-
<mat-table [dataSource]="dataSource" matSort>
|
|
261
|
-
<ng-container matColumnDef="name">
|
|
262
|
-
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
|
|
263
|
-
<mat-cell *matCellDef="let element">{{element.name}}</mat-cell>
|
|
264
|
-
</ng-container>
|
|
265
|
-
<!-- Additional columns -->
|
|
266
|
-
</mat-table>
|
|
267
|
-
<mat-paginator [pageSizeOptions]="[5, 10, 25]" showFirstLastButtons />
|
|
268
|
-
`
|
|
269
|
-
})
|
|
270
|
-
export class DataTableComponent { }
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## MCP Server Integration
|
|
276
|
-
|
|
277
|
-
Story UI includes a Model Context Protocol (MCP) server, allowing direct integration with AI clients like Claude Desktop and Claude Code.
|
|
278
|
-
|
|
279
|
-
### Claude Desktop Integration (Recommended)
|
|
280
|
-
|
|
281
|
-
The easiest way to connect is via Claude Desktop's built-in connector UI:
|
|
282
|
-
|
|
283
|
-
1. Open **Claude Desktop**
|
|
284
|
-
2. Go to **Settings** ā **Connectors**
|
|
285
|
-
3. Click **"Add custom connector"**
|
|
286
|
-
4. Enter:
|
|
287
|
-
- **Name**: `Story UI React` (or any descriptive name)
|
|
288
|
-
- **URL**: Your deployed Railway URL + `/mcp-remote/mcp`
|
|
289
|
-
- Example: `https://your-app-name.up.railway.app/mcp-remote/mcp`
|
|
290
|
-
5. Click **Add**
|
|
291
|
-
6. **Restart Claude Desktop**
|
|
292
|
-
|
|
293
|
-
> **Note**: The URL will be your own Railway deployment URL. See [Production Deployment](#production-deployment) to set up your instance.
|
|
294
|
-
|
|
295
|
-
**Multiple Projects**: If you have multiple Storybook projects, add a separate connector for each:
|
|
296
|
-
- `Story UI React` ā `https://my-react-app.up.railway.app/mcp-remote/mcp`
|
|
297
|
-
- `Story UI Vue` ā `https://my-vue-app.up.railway.app/mcp-remote/mcp`
|
|
298
|
-
|
|
299
|
-
Once connected, you'll have access to all Story UI tools directly in your Claude conversations:
|
|
300
|
-
- `generate-story` - Generate Storybook stories from natural language
|
|
301
|
-
- `list-components` - Discover available components
|
|
302
|
-
- `list-stories` - View existing stories
|
|
303
|
-
- `get-story` / `update-story` / `delete-story` - Manage stories
|
|
304
|
-
- `get-component-props` - Get component property information
|
|
305
|
-
- `test-connection` - Verify MCP connection
|
|
306
|
-
|
|
307
|
-
### Claude Code Integration
|
|
308
|
-
|
|
309
|
-
Connect via Claude Code's built-in MCP support:
|
|
310
|
-
|
|
311
|
-
```bash
|
|
312
|
-
# Add your production Railway deployment
|
|
313
|
-
claude mcp add --transport http story-ui-react https://your-react-app.up.railway.app/mcp-remote/mcp
|
|
314
|
-
|
|
315
|
-
# Add another project (if needed)
|
|
316
|
-
claude mcp add --transport http story-ui-vue https://your-vue-app.up.railway.app/mcp-remote/mcp
|
|
317
|
-
|
|
318
|
-
# For local development (default port is 4001)
|
|
319
|
-
claude mcp add --transport http story-ui-local http://localhost:4001/mcp-remote/mcp
|
|
168
|
+
Create a product card with image, title, price, and add to cart button
|
|
320
169
|
```
|
|
321
170
|
|
|
322
|
-
|
|
171
|
+
Story UI generates a complete `.stories.tsx` file using your design system's components, writes it to your generated stories directory, and Storybook picks it up automatically via file watcher.
|
|
323
172
|
|
|
324
|
-
|
|
173
|
+
### Iterating
|
|
325
174
|
|
|
326
|
-
|
|
327
|
-
{
|
|
328
|
-
"mcpServers": {
|
|
329
|
-
"story-ui-react": {
|
|
330
|
-
"command": "npx",
|
|
331
|
-
"args": ["@tpitre/story-ui", "start", "--port", "4001"]
|
|
332
|
-
},
|
|
333
|
-
"story-ui-vue": {
|
|
334
|
-
"command": "npx",
|
|
335
|
-
"args": ["@tpitre/story-ui", "start", "--port", "4002"]
|
|
336
|
-
},
|
|
337
|
-
"story-ui-angular": {
|
|
338
|
-
"command": "npx",
|
|
339
|
-
"args": ["@tpitre/story-ui", "start", "--port", "4003"]
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
175
|
+
Continue the conversation to refine:
|
|
343
176
|
```
|
|
344
|
-
|
|
345
|
-
> **Note**: When using Claude Desktop, API keys are managed through your Anthropic account - no need to configure them in the MCP server.
|
|
346
|
-
|
|
347
|
-
### Starting the Local MCP Server
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
# Start with default port (4001)
|
|
351
|
-
npx story-ui start
|
|
352
|
-
|
|
353
|
-
# Or specify a custom port
|
|
354
|
-
npx story-ui start --port 4002
|
|
177
|
+
Make the button green and add a quantity selector
|
|
355
178
|
```
|
|
356
179
|
|
|
357
|
-
|
|
180
|
+
Story UI modifies only what you requested, preserving the rest of the story.
|
|
358
181
|
|
|
359
|
-
###
|
|
182
|
+
### Voice Canvas
|
|
360
183
|
|
|
361
|
-
|
|
362
|
-
- "Use Story UI to create a hero section with a CTA button"
|
|
363
|
-
- "List all available components in Story UI"
|
|
364
|
-
- "Generate a dashboard layout with sidebar navigation"
|
|
365
|
-
- "Show me the stories I've generated"
|
|
184
|
+
Switch to Voice Canvas mode in the panel header. Speak your component ideas and see them rendered live. The canvas uses `react-live` for instant rendering without page reloads.
|
|
366
185
|
|
|
367
186
|
---
|
|
368
187
|
|
|
369
188
|
## Storybook MCP Integration
|
|
370
189
|
|
|
371
|
-
Story UI can
|
|
190
|
+
Story UI can connect to [Storybook MCP](https://github.com/storybookjs/addon-mcp) (`@storybook/addon-mcp`) to fetch component documentation, UI building guidelines, and existing story patterns. This enhances generation quality by ensuring output matches your codebase.
|
|
372
191
|
|
|
373
|
-
###
|
|
192
|
+
### Setup
|
|
374
193
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
- **Component Documentation**: Props, descriptions, and usage examples for all components
|
|
378
|
-
- **UI Building Instructions**: Storybook-specific guidelines for writing stories
|
|
379
|
-
- **Story Patterns**: Existing story examples to match code style and conventions
|
|
380
|
-
|
|
381
|
-
### Configuration
|
|
382
|
-
|
|
383
|
-
Add the Storybook MCP URL to your `story-ui.config.js`:
|
|
194
|
+
1. Install `@storybook/addon-mcp` and enable `experimentalComponentsManifest` in `.storybook/main.js`:
|
|
384
195
|
|
|
385
196
|
```javascript
|
|
386
197
|
export default {
|
|
387
|
-
// ... other config options
|
|
388
|
-
|
|
389
|
-
// Storybook MCP integration
|
|
390
|
-
storybookMcpUrl: 'http://localhost:6006', // Your Storybook URL
|
|
391
|
-
storybookMcpTimeout: 5000, // Timeout in ms (default: 5000)
|
|
392
|
-
};
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### Requirements
|
|
396
|
-
|
|
397
|
-
1. **Storybook 8.4+** with `@storybook/addon-mcp` installed
|
|
398
|
-
2. **`experimentalComponentsManifest: true`** enabled in `.storybook/main.js`:
|
|
399
|
-
|
|
400
|
-
```javascript
|
|
401
|
-
// .storybook/main.js
|
|
402
|
-
export default {
|
|
403
|
-
// ... other config
|
|
404
198
|
features: {
|
|
405
199
|
experimentalComponentsManifest: true,
|
|
406
200
|
},
|
|
@@ -411,231 +205,203 @@ export default {
|
|
|
411
205
|
};
|
|
412
206
|
```
|
|
413
207
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
When both Story UI and Storybook are running, context is fetched automatically during story generation:
|
|
208
|
+
2. Add the Storybook URL to `story-ui.config.js`:
|
|
417
209
|
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
210
|
+
```javascript
|
|
211
|
+
module.exports = {
|
|
212
|
+
// ... other config
|
|
213
|
+
storybookMcpUrl: 'http://localhost:6006',
|
|
214
|
+
storybookMcpTimeout: 5000,
|
|
215
|
+
};
|
|
424
216
|
```
|
|
425
217
|
|
|
426
|
-
|
|
427
|
-
- More accurate component prop usage
|
|
428
|
-
- Consistent code style with existing stories
|
|
429
|
-
- Proper import statements matching your project
|
|
218
|
+
When both Story UI and Storybook are running, context is fetched automatically during generation, resulting in more accurate component usage and consistent code style.
|
|
430
219
|
|
|
431
220
|
---
|
|
432
221
|
|
|
433
|
-
##
|
|
222
|
+
## MCP Server Integration
|
|
434
223
|
|
|
435
|
-
Story UI
|
|
224
|
+
Story UI includes a Model Context Protocol (MCP) server for direct integration with AI clients like Claude Desktop and Claude Code.
|
|
436
225
|
|
|
437
|
-
###
|
|
226
|
+
### Claude Desktop
|
|
438
227
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
ā ā Express MCP Server (Node.js) āā
|
|
444
|
-
ā ā - Serves Storybook with Story UI addon āā
|
|
445
|
-
ā ā - API routes for story generation āā
|
|
446
|
-
ā ā - Multi-provider LLM support (Claude, OpenAI, Gemini) āā
|
|
447
|
-
ā ā - File-based story persistence āā
|
|
448
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
449
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
450
|
-
```
|
|
228
|
+
1. Open **Claude Desktop** > **Settings** > **Connectors**
|
|
229
|
+
2. Click **Add custom connector**
|
|
230
|
+
3. Enter your deployment URL + `/mcp-remote/mcp`
|
|
231
|
+
4. Restart Claude Desktop
|
|
451
232
|
|
|
452
|
-
###
|
|
453
|
-
|
|
454
|
-
Railway provides a straightforward deployment experience with automatic HTTPS and file-based story persistence.
|
|
455
|
-
|
|
456
|
-
**Quick Start:**
|
|
233
|
+
### Claude Code
|
|
457
234
|
|
|
458
235
|
```bash
|
|
459
|
-
#
|
|
460
|
-
|
|
461
|
-
railway login
|
|
236
|
+
# Production deployment
|
|
237
|
+
claude mcp add --transport http story-ui https://your-app.up.railway.app/mcp-remote/mcp
|
|
462
238
|
|
|
463
|
-
#
|
|
464
|
-
|
|
465
|
-
railway up
|
|
239
|
+
# Local development
|
|
240
|
+
claude mcp add --transport http story-ui-local http://localhost:4001/mcp-remote/mcp
|
|
466
241
|
```
|
|
467
242
|
|
|
468
|
-
|
|
469
|
-
- `ANTHROPIC_API_KEY` - Required for Claude models
|
|
470
|
-
- `OPENAI_API_KEY` - Optional, for OpenAI models
|
|
471
|
-
- `GEMINI_API_KEY` - Optional, for Gemini models
|
|
243
|
+
### Available MCP Tools
|
|
472
244
|
|
|
473
|
-
|
|
245
|
+
Once connected, these tools are available in Claude conversations:
|
|
246
|
+
- `generate-story` ā Generate Storybook stories from natural language
|
|
247
|
+
- `list-components` ā Discover available components
|
|
248
|
+
- `list-stories` ā View existing generated stories
|
|
249
|
+
- `get-story` / `update-story` / `delete-story` ā Manage stories
|
|
250
|
+
- `get-component-props` ā Get component property information
|
|
251
|
+
- `test-connection` ā Verify MCP connection
|
|
474
252
|
|
|
475
|
-
|
|
253
|
+
### Local STDIO Server
|
|
476
254
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
255
|
+
For Claude Desktop local integration without a deployed server:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"mcpServers": {
|
|
260
|
+
"story-ui": {
|
|
261
|
+
"command": "npx",
|
|
262
|
+
"args": ["@tpitre/story-ui", "mcp"]
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
480
266
|
```
|
|
481
267
|
|
|
482
|
-
|
|
268
|
+
This requires the HTTP server running on port 4001 (`npm run story-ui`).
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Production Deployment
|
|
483
273
|
|
|
484
|
-
|
|
274
|
+
Story UI can be deployed as a standalone web application. Railway is recommended for its simplicity.
|
|
485
275
|
|
|
486
|
-
|
|
276
|
+
### Deploy to Railway
|
|
487
277
|
|
|
488
278
|
```bash
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
git add src/stories/StoryUI/
|
|
494
|
-
git commit -m "Add StoryUI panel for production"
|
|
279
|
+
npm install -g @railway/cli
|
|
280
|
+
railway login
|
|
281
|
+
railway init
|
|
282
|
+
railway up
|
|
495
283
|
```
|
|
496
284
|
|
|
497
|
-
|
|
285
|
+
**Environment Variables:**
|
|
286
|
+
- `ANTHROPIC_API_KEY` ā Required for Claude models
|
|
287
|
+
- `OPENAI_API_KEY` ā Optional, for OpenAI models
|
|
288
|
+
- `GEMINI_API_KEY` ā Optional, for Gemini models
|
|
289
|
+
- `STORYBOOK_PROXY_ENABLED` ā Enable Storybook proxy mode for live demos
|
|
290
|
+
- `STORYBOOK_PROXY_PORT` ā Internal Storybook port (default: 6006)
|
|
498
291
|
|
|
499
|
-
See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed
|
|
292
|
+
See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed instructions and troubleshooting.
|
|
500
293
|
|
|
501
294
|
---
|
|
502
295
|
|
|
503
296
|
## Design System Documentation
|
|
504
297
|
|
|
505
|
-
Story UI
|
|
298
|
+
Story UI reads your design system guidelines before every generation to produce better output.
|
|
506
299
|
|
|
507
|
-
### Directory-Based
|
|
300
|
+
### Directory-Based (Recommended)
|
|
508
301
|
|
|
509
|
-
Create a `story-ui-docs/` directory:
|
|
302
|
+
Create a `story-ui-docs/` directory with guidelines, tokens, and component documentation:
|
|
510
303
|
|
|
511
304
|
```
|
|
512
305
|
story-ui-docs/
|
|
513
|
-
āāā README.md # Overview
|
|
514
306
|
āāā guidelines/
|
|
515
|
-
ā āāā accessibility.md
|
|
516
|
-
ā
|
|
517
|
-
ā āāā brand-guidelines.md # Brand usage
|
|
307
|
+
ā āāā accessibility.md
|
|
308
|
+
ā āāā responsive-design.md
|
|
518
309
|
āāā tokens/
|
|
519
|
-
ā āāā colors.json
|
|
520
|
-
ā
|
|
521
|
-
|
|
522
|
-
āāā
|
|
523
|
-
|
|
524
|
-
ā āāā forms.md # Form patterns
|
|
525
|
-
āāā patterns/
|
|
526
|
-
āāā layouts.md # Layout patterns
|
|
527
|
-
āāā data-tables.md # Table patterns
|
|
310
|
+
ā āāā colors.json
|
|
311
|
+
ā āāā spacing.md
|
|
312
|
+
āāā components/
|
|
313
|
+
āāā button.md
|
|
314
|
+
āāā forms.md
|
|
528
315
|
```
|
|
529
316
|
|
|
530
|
-
### Single-File
|
|
531
|
-
|
|
532
|
-
For simpler setups, use `story-ui-considerations.md`:
|
|
317
|
+
### Single-File
|
|
533
318
|
|
|
534
|
-
|
|
535
|
-
# Design System Considerations
|
|
536
|
-
|
|
537
|
-
## Color Usage
|
|
538
|
-
- Primary actions: blue.6
|
|
539
|
-
- Destructive actions: red.6
|
|
540
|
-
- Success states: green.6
|
|
541
|
-
|
|
542
|
-
## Component Preferences
|
|
543
|
-
- Use Button with variant="filled" for primary actions
|
|
544
|
-
- Use Card with shadow="sm" for content containers
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
### Component-Specific Behaviors (Critical for Web Components)
|
|
548
|
-
|
|
549
|
-
For libraries where components have specific requirements (like attributes needed for visibility), document these behaviors:
|
|
550
|
-
|
|
551
|
-
```markdown
|
|
552
|
-
# Component-Specific Behaviors
|
|
553
|
-
|
|
554
|
-
## Alert Component (`<my-alert>`)
|
|
555
|
-
**IMPORTANT**: The alert requires `is-active` attribute to be visible.
|
|
556
|
-
|
|
557
|
-
<!-- WRONG - will not render -->
|
|
558
|
-
<my-alert variant="success">Message</my-alert>
|
|
559
|
-
|
|
560
|
-
<!-- CORRECT -->
|
|
561
|
-
<my-alert variant="success" is-active>Message</my-alert>
|
|
562
|
-
|
|
563
|
-
## Import Patterns
|
|
564
|
-
Components are in individual folders:
|
|
565
|
-
- import '../../../components/alert/alert';
|
|
566
|
-
- import '../../../components/icon/icons/check';
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
The AI reads this file before every story generation, ensuring component-specific rules are followed.
|
|
319
|
+
For simpler setups, create `story-ui-considerations.md` in your project root with design system rules, color usage, and component preferences.
|
|
570
320
|
|
|
571
321
|
---
|
|
572
322
|
|
|
573
323
|
## CLI Reference
|
|
574
324
|
|
|
575
325
|
```bash
|
|
576
|
-
# Initialize Story UI in your project
|
|
577
|
-
npx story-ui
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
npx story-ui
|
|
581
|
-
npx story-ui start --port 4002 # Custom port
|
|
582
|
-
|
|
583
|
-
# Run MCP STDIO server (for Claude Desktop local integration)
|
|
584
|
-
npx story-ui mcp
|
|
585
|
-
|
|
586
|
-
# Check installation status and version
|
|
587
|
-
npx story-ui status
|
|
588
|
-
|
|
589
|
-
# Update Story UI files to latest version
|
|
590
|
-
npx story-ui update
|
|
326
|
+
npx story-ui init # Initialize Story UI in your project
|
|
327
|
+
npx story-ui start # Start the MCP server (default port: 4001)
|
|
328
|
+
npx story-ui mcp # Start STDIO MCP server for Claude Desktop
|
|
329
|
+
npx story-ui status # Check installation status and version
|
|
330
|
+
npx story-ui update # Update Story UI files to latest version
|
|
591
331
|
```
|
|
592
332
|
|
|
593
|
-
|
|
333
|
+
---
|
|
594
334
|
|
|
595
|
-
|
|
335
|
+
## Environment Variables
|
|
596
336
|
|
|
597
337
|
```bash
|
|
598
|
-
#
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
338
|
+
# .env
|
|
339
|
+
LLM_PROVIDER=claude
|
|
340
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
341
|
+
OPENAI_API_KEY=sk-... # optional
|
|
342
|
+
GEMINI_API_KEY=... # optional
|
|
343
|
+
VITE_STORY_UI_PORT=4001
|
|
344
|
+
```
|
|
604
345
|
|
|
605
|
-
|
|
606
|
-
# Delete "story-ui" and "storybook-with-ui" from scripts
|
|
346
|
+
---
|
|
607
347
|
|
|
608
|
-
|
|
609
|
-
npm uninstall @tpitre/story-ui
|
|
348
|
+
## API Reference
|
|
610
349
|
|
|
611
|
-
|
|
612
|
-
```
|
|
350
|
+
### Story Generation
|
|
613
351
|
|
|
614
|
-
|
|
352
|
+
| Method | Endpoint | Description |
|
|
353
|
+
|--------|----------|-------------|
|
|
354
|
+
| `POST` | `/mcp/generate-story` | Generate story from prompt |
|
|
355
|
+
| `POST` | `/mcp/generate-story-stream` | Streaming story generation |
|
|
356
|
+
| `POST` | `/mcp/canvas-generate` | Generate + write voice canvas story |
|
|
357
|
+
| `POST` | `/mcp/canvas-save` | Save canvas to named story file |
|
|
615
358
|
|
|
616
|
-
|
|
359
|
+
### Component Discovery
|
|
617
360
|
|
|
618
|
-
|
|
361
|
+
| Method | Endpoint | Description |
|
|
362
|
+
|--------|----------|-------------|
|
|
363
|
+
| `GET` | `/mcp/components` | List discovered components |
|
|
364
|
+
| `GET` | `/mcp/props` | Get component props |
|
|
365
|
+
| `GET` | `/mcp/frameworks` | List supported frameworks |
|
|
366
|
+
| `GET` | `/mcp/frameworks/detect` | Detect current project framework |
|
|
619
367
|
|
|
620
|
-
###
|
|
368
|
+
### Story Management
|
|
621
369
|
|
|
622
370
|
| Method | Endpoint | Description |
|
|
623
371
|
|--------|----------|-------------|
|
|
624
|
-
| `POST` | `/story-ui/generate` | Generate story (specify provider in body) |
|
|
625
|
-
| `POST` | `/story-ui/generate-stream` | Generate story with streaming |
|
|
626
|
-
| `GET` | `/story-ui/providers` | List available LLM providers and models |
|
|
627
|
-
| `GET` | `/story-ui/components` | List discovered components |
|
|
628
|
-
| `GET` | `/story-ui/considerations` | Get design system context |
|
|
629
372
|
| `GET` | `/mcp/stories` | List generated stories |
|
|
373
|
+
| `GET` | `/mcp/stories/:storyId` | Get a specific story |
|
|
374
|
+
| `GET` | `/mcp/stories/:storyId/content` | Get story file content |
|
|
630
375
|
| `DELETE` | `/mcp/stories/:storyId` | Delete a story |
|
|
631
376
|
|
|
377
|
+
### Provider Management
|
|
378
|
+
|
|
379
|
+
| Method | Endpoint | Description |
|
|
380
|
+
|--------|----------|-------------|
|
|
381
|
+
| `GET` | `/mcp/providers` | List available LLM providers |
|
|
382
|
+
| `GET` | `/mcp/providers/models` | List models per provider |
|
|
383
|
+
| `POST` | `/mcp/providers/configure` | Configure a provider |
|
|
384
|
+
| `POST` | `/mcp/providers/validate` | Validate an API key |
|
|
385
|
+
| `POST` | `/mcp/providers/model` | Set active model |
|
|
386
|
+
|
|
387
|
+
### Manifest
|
|
388
|
+
|
|
389
|
+
| Method | Endpoint | Description |
|
|
390
|
+
|--------|----------|-------------|
|
|
391
|
+
| `GET` | `/story-ui/manifest` | Get story manifest |
|
|
392
|
+
| `GET` | `/story-ui/manifest/poll` | Poll for manifest changes |
|
|
393
|
+
| `POST` | `/story-ui/manifest/reconcile` | Reconcile manifest with filesystem |
|
|
394
|
+
| `DELETE` | `/story-ui/manifest/:fileName` | Remove entry from manifest |
|
|
395
|
+
|
|
396
|
+
All endpoints are also available under the `/story-ui/` prefix.
|
|
397
|
+
|
|
632
398
|
### Request Format
|
|
633
399
|
|
|
634
400
|
```typescript
|
|
635
401
|
{
|
|
636
402
|
prompt: string; // User's request
|
|
637
|
-
provider?: string; //
|
|
638
|
-
model?: string; // Specific model
|
|
403
|
+
provider?: string; // 'claude' | 'openai' | 'gemini'
|
|
404
|
+
model?: string; // Specific model ID
|
|
639
405
|
previousCode?: string; // For iterations
|
|
640
406
|
history?: Message[]; // Conversation history
|
|
641
407
|
imageData?: string; // Base64 image for vision
|
|
@@ -644,18 +410,6 @@ After removal, run `npx story-ui init` to start fresh with a clean installation.
|
|
|
644
410
|
|
|
645
411
|
---
|
|
646
412
|
|
|
647
|
-
## Upgrading from v2
|
|
648
|
-
|
|
649
|
-
Story UI v4 is backwards compatible with previous configurations. However, to take advantage of new features:
|
|
650
|
-
|
|
651
|
-
1. **Multi-Provider Support**: Add `llmProvider` to your config
|
|
652
|
-
2. **Framework Detection**: Add `framework` to your config for non-React projects
|
|
653
|
-
3. **Production Deployment**: Use `npx story-ui deploy` for one-command deployment
|
|
654
|
-
|
|
655
|
-
No breaking changes - existing stories and configurations will continue to work.
|
|
656
|
-
|
|
657
|
-
---
|
|
658
|
-
|
|
659
413
|
## Contributing
|
|
660
414
|
|
|
661
415
|
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md).
|
|
@@ -667,18 +421,17 @@ git clone https://github.com/southleft/story-ui.git
|
|
|
667
421
|
cd story-ui
|
|
668
422
|
npm install
|
|
669
423
|
npm run build
|
|
670
|
-
npm link
|
|
671
424
|
|
|
672
|
-
# Test in a project
|
|
673
|
-
cd your-project
|
|
674
|
-
|
|
425
|
+
# Test in a consumer project (important: run from the consumer directory)
|
|
426
|
+
cd /path/to/your-storybook-project
|
|
427
|
+
PORT=4001 node /path/to/story-ui/dist/mcp-server/index.js
|
|
675
428
|
```
|
|
676
429
|
|
|
677
430
|
---
|
|
678
431
|
|
|
679
432
|
## License
|
|
680
433
|
|
|
681
|
-
MIT
|
|
434
|
+
MIT - [Story UI Contributors](LICENSE)
|
|
682
435
|
|
|
683
436
|
---
|
|
684
437
|
|
|
@@ -686,10 +439,6 @@ MIT Ā© [Story UI Contributors](LICENSE)
|
|
|
686
439
|
|
|
687
440
|
- [GitHub Repository](https://github.com/southleft/story-ui)
|
|
688
441
|
- [NPM Package](https://www.npmjs.com/package/@tpitre/story-ui)
|
|
689
|
-
- [Issues & Support](https://github.com/southleft/story-ui/issues)
|
|
690
|
-
- [MCP Integration Guide](docs/MCP_INTEGRATION.md)
|
|
691
442
|
- [Deployment Guide](DEPLOYMENT.md)
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
*Story UI - Making component documentation delightful, one conversation at a time.*
|
|
443
|
+
- [MCP Integration Guide](docs/MCP_INTEGRATION.md)
|
|
444
|
+
- [Issues & Support](https://github.com/southleft/story-ui/issues)
|
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;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,
|
|
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,iBAqgC5D"}
|
package/dist/cli/setup.js
CHANGED
|
@@ -1310,6 +1310,13 @@ VITE_STORY_UI_PORT=${answers.mcpPort || '4001'}
|
|
|
1310
1310
|
devDependencies['concurrently'] = '^8.2.0';
|
|
1311
1311
|
needsInstall = true;
|
|
1312
1312
|
}
|
|
1313
|
+
// Check for react-live (imported directly by voice canvas templates;
|
|
1314
|
+
// cannot be resolved transitively when @tpitre/story-ui is symlinked)
|
|
1315
|
+
if (!dependencies['react-live'] && !devDependencies['react-live']) {
|
|
1316
|
+
console.log(chalk.blue('š¦ Adding react-live dependency (required by voice canvas)...'));
|
|
1317
|
+
devDependencies['react-live'] = '^4.1.8';
|
|
1318
|
+
needsInstall = true;
|
|
1319
|
+
}
|
|
1313
1320
|
packageJson.dependencies = dependencies;
|
|
1314
1321
|
packageJson.devDependencies = devDependencies;
|
|
1315
1322
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
package/dist/cli/update.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../cli/update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../cli/update.ts"],"names":[],"mappings":"AAgBA;;;;;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;AAyYD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAyItF;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CA+BpC"}
|
package/dist/cli/update.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
5
|
import { fileURLToPath } from 'url';
|
|
5
6
|
import inquirer from 'inquirer';
|
|
6
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
8
|
const __dirname = path.dirname(__filename);
|
|
9
|
+
// Runtime dependencies that consumer projects must have installed for
|
|
10
|
+
// managed template files to resolve. The voice canvas templates import
|
|
11
|
+
// `react-live` directly, so it cannot be resolved transitively through
|
|
12
|
+
// a symlinked @tpitre/story-ui install.
|
|
13
|
+
const REQUIRED_CONSUMER_DEPS = ['react-live'];
|
|
8
14
|
// Files managed by Story UI that can be safely overwritten
|
|
9
15
|
const MANAGED_FILES = [
|
|
10
16
|
{
|
|
@@ -284,6 +290,62 @@ function updateConfigVersion(configPath, version) {
|
|
|
284
290
|
return false;
|
|
285
291
|
}
|
|
286
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Ensure the consumer project has the runtime deps required by managed
|
|
295
|
+
* template files (e.g. react-live for voice canvas). Installs any missing
|
|
296
|
+
* packages using the detected package manager.
|
|
297
|
+
*/
|
|
298
|
+
function ensureConsumerDependencies(options) {
|
|
299
|
+
const cwd = process.cwd();
|
|
300
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
301
|
+
const result = { installed: [], errors: [] };
|
|
302
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
let packageJson;
|
|
306
|
+
try {
|
|
307
|
+
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
result.errors.push(`Could not read package.json: ${error.message}`);
|
|
311
|
+
return result;
|
|
312
|
+
}
|
|
313
|
+
const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
314
|
+
const missing = REQUIRED_CONSUMER_DEPS.filter((pkg) => !allDeps[pkg]);
|
|
315
|
+
if (missing.length === 0) {
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
318
|
+
if (options.dryRun) {
|
|
319
|
+
console.log(chalk.cyan(` š Would install missing deps: ${missing.join(', ')}`));
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
// Detect package manager
|
|
323
|
+
const yarnLock = fs.existsSync(path.join(cwd, 'yarn.lock'));
|
|
324
|
+
const pnpmLock = fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'));
|
|
325
|
+
let installCommand = `npm install --save-dev ${missing.join(' ')}`;
|
|
326
|
+
if (yarnLock) {
|
|
327
|
+
installCommand = `yarn add --dev ${missing.join(' ')}`;
|
|
328
|
+
}
|
|
329
|
+
else if (pnpmLock) {
|
|
330
|
+
installCommand = `pnpm add -D ${missing.join(' ')}`;
|
|
331
|
+
}
|
|
332
|
+
console.log(chalk.bold('\nš¦ Installing required runtime dependencies:'));
|
|
333
|
+
for (const pkg of missing) {
|
|
334
|
+
console.log(chalk.cyan(` ⢠${pkg}`));
|
|
335
|
+
}
|
|
336
|
+
console.log(chalk.gray(` Running: ${installCommand}`));
|
|
337
|
+
try {
|
|
338
|
+
execSync(installCommand, { stdio: 'inherit', cwd });
|
|
339
|
+
result.installed.push(...missing);
|
|
340
|
+
console.log(chalk.green(` ā
Installed: ${missing.join(', ')}`));
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
const message = `Failed to install ${missing.join(', ')}. Run "${installCommand}" manually.`;
|
|
344
|
+
result.errors.push(message);
|
|
345
|
+
console.log(chalk.yellow(` ā ļø ${message}`));
|
|
346
|
+
}
|
|
347
|
+
return result;
|
|
348
|
+
}
|
|
287
349
|
/**
|
|
288
350
|
* Main update command
|
|
289
351
|
*/
|
|
@@ -372,7 +434,13 @@ export async function updateCommand(options = {}) {
|
|
|
372
434
|
result.errors.push(`${file.target}: ${updateResult.error}`);
|
|
373
435
|
}
|
|
374
436
|
}
|
|
375
|
-
// Step 5:
|
|
437
|
+
// Step 5: Ensure required consumer dependencies are installed
|
|
438
|
+
// (e.g. react-live, which voice canvas templates import directly)
|
|
439
|
+
const depsResult = ensureConsumerDependencies(options);
|
|
440
|
+
if (depsResult.errors.length > 0) {
|
|
441
|
+
result.errors.push(...depsResult.errors);
|
|
442
|
+
}
|
|
443
|
+
// Step 6: Update config version tracking
|
|
376
444
|
if (!options.dryRun && installation.configPath) {
|
|
377
445
|
if (updateConfigVersion(installation.configPath, result.newVersion)) {
|
|
378
446
|
console.log(chalk.gray(`\n Updated version tracking in ${path.basename(installation.configPath)}`));
|
|
@@ -171,7 +171,7 @@ const MIGRATION_FLAG = 'story-ui-manifest-migrated-v1';
|
|
|
171
171
|
const MIGRATION_FLAG_V2 = 'story-ui-manifest-migrated-v2';
|
|
172
172
|
// v3: seeds synthetic conversations for any manifest entry with metadata.prompt but no conversation
|
|
173
173
|
const MIGRATION_FLAG_V3 = 'story-ui-manifest-migrated-v3';
|
|
174
|
-
const CONSIDERATIONS_API = () => `${getApiBase()}/
|
|
174
|
+
const CONSIDERATIONS_API = () => `${getApiBase()}/story-ui/considerations`;
|
|
175
175
|
function isEdgeMode() {
|
|
176
176
|
if (typeof window !== 'undefined') {
|
|
177
177
|
const hostname = window.location.hostname;
|
|
@@ -361,7 +361,7 @@ const MIGRATION_FLAG = 'story-ui-manifest-migrated-v1';
|
|
|
361
361
|
const MIGRATION_FLAG_V2 = 'story-ui-manifest-migrated-v2';
|
|
362
362
|
// v3: seeds synthetic conversations for any manifest entry with metadata.prompt but no conversation
|
|
363
363
|
const MIGRATION_FLAG_V3 = 'story-ui-manifest-migrated-v3';
|
|
364
|
-
const CONSIDERATIONS_API = () => `${getApiBase()}/
|
|
364
|
+
const CONSIDERATIONS_API = () => `${getApiBase()}/story-ui/considerations`;
|
|
365
365
|
|
|
366
366
|
function isEdgeMode(): boolean {
|
|
367
367
|
if (typeof window !== 'undefined') {
|
package/package.json
CHANGED
|
@@ -361,7 +361,7 @@ const MIGRATION_FLAG = 'story-ui-manifest-migrated-v1';
|
|
|
361
361
|
const MIGRATION_FLAG_V2 = 'story-ui-manifest-migrated-v2';
|
|
362
362
|
// v3: seeds synthetic conversations for any manifest entry with metadata.prompt but no conversation
|
|
363
363
|
const MIGRATION_FLAG_V3 = 'story-ui-manifest-migrated-v3';
|
|
364
|
-
const CONSIDERATIONS_API = () => `${getApiBase()}/
|
|
364
|
+
const CONSIDERATIONS_API = () => `${getApiBase()}/story-ui/considerations`;
|
|
365
365
|
|
|
366
366
|
function isEdgeMode(): boolean {
|
|
367
367
|
if (typeof window !== 'undefined') {
|