@tpitre/story-ui 1.7.1 → 2.0.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.
Files changed (35) hide show
  1. package/.env.sample +3 -1
  2. package/README.md +160 -606
  3. package/dist/cli/index.js +23 -24
  4. package/dist/cli/setup.js +295 -36
  5. package/dist/mcp-server/index.js +67 -0
  6. package/dist/mcp-server/routes/generateStory.js +323 -56
  7. package/dist/story-generator/componentBlacklist.js +181 -0
  8. package/dist/story-generator/componentDiscovery.js +9 -2
  9. package/dist/story-generator/configLoader.js +109 -39
  10. package/dist/story-generator/considerationsLoader.js +204 -0
  11. package/dist/story-generator/documentation-sources.js +36 -0
  12. package/dist/story-generator/documentationLoader.js +214 -0
  13. package/dist/story-generator/dynamicPackageDiscovery.js +527 -0
  14. package/dist/story-generator/enhancedComponentDiscovery.js +369 -118
  15. package/dist/story-generator/generateStory.js +7 -3
  16. package/dist/story-generator/postProcessStory.js +71 -0
  17. package/dist/story-generator/promptGenerator.js +286 -37
  18. package/dist/story-generator/storyHistory.js +118 -0
  19. package/dist/story-generator/storyTracker.js +33 -18
  20. package/dist/story-generator/storyValidator.js +39 -0
  21. package/dist/story-generator/universalDesignSystemAdapter.js +209 -0
  22. package/dist/story-generator/validateStory.js +82 -7
  23. package/dist/story-ui.config.js +12 -5
  24. package/package.json +11 -6
  25. package/templates/StoryUI/StoryUIPanel.stories.tsx +29 -13
  26. package/templates/StoryUI/StoryUIPanel.tsx +489 -359
  27. package/templates/react-import-rule.json +36 -0
  28. package/templates/story-generation-rules.json +29 -0
  29. package/templates/story-ui-considerations.json +156 -0
  30. package/templates/story-ui-considerations.md +109 -0
  31. package/templates/story-ui-docs-README.md +55 -0
  32. package/dist/scripts/test-validation.js +0 -81
  33. package/dist/test-storybooks/chakra-test/src/components/index.js +0 -3
  34. package/dist/test-storybooks/custom-design-test/src/components/index.js +0 -3
  35. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,214 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { glob } from 'glob';
4
+ export class DocumentationLoader {
5
+ constructor(projectRoot) {
6
+ this.cache = null;
7
+ this.lastModified = 0;
8
+ // Look for story-ui-docs directory in project root
9
+ this.docsDir = path.join(projectRoot, 'story-ui-docs');
10
+ }
11
+ /**
12
+ * Check if documentation directory exists
13
+ */
14
+ hasDocumentation() {
15
+ return fs.existsSync(this.docsDir);
16
+ }
17
+ /**
18
+ * Load all documentation from the directory
19
+ */
20
+ async loadDocumentation() {
21
+ if (!this.hasDocumentation()) {
22
+ return {
23
+ sources: [],
24
+ guidelines: [],
25
+ tokens: {},
26
+ patterns: {},
27
+ components: {}
28
+ };
29
+ }
30
+ // Check if cache is still valid
31
+ const stats = fs.statSync(this.docsDir);
32
+ if (this.cache && stats.mtimeMs <= this.lastModified) {
33
+ return this.cache;
34
+ }
35
+ console.log(`šŸ“š Loading documentation from ${this.docsDir}`);
36
+ const documentation = {
37
+ sources: [],
38
+ guidelines: [],
39
+ tokens: {},
40
+ patterns: {},
41
+ components: {}
42
+ };
43
+ // Find all documentation files
44
+ const patterns = [
45
+ '**/*.md',
46
+ '**/*.json',
47
+ '**/*.html',
48
+ '**/*.txt'
49
+ ];
50
+ // Use async glob for ESM compatibility
51
+ const allFiles = [];
52
+ for (const pattern of patterns) {
53
+ const matches = await glob(pattern, {
54
+ cwd: this.docsDir,
55
+ absolute: false,
56
+ ignore: ['**/node_modules/**', '**/.git/**']
57
+ });
58
+ allFiles.push(...matches);
59
+ }
60
+ const files = [...new Set(allFiles)]; // Remove duplicates
61
+ console.log(`šŸ“„ Found ${files.length} documentation files`);
62
+ // Process each file
63
+ for (const file of files) {
64
+ // Skip README files as they are instructional, not design system documentation
65
+ if (path.basename(file).toLowerCase().startsWith('readme')) {
66
+ continue;
67
+ }
68
+ const filePath = path.join(this.docsDir, file);
69
+ const content = fs.readFileSync(filePath, 'utf-8');
70
+ const ext = path.extname(file).toLowerCase();
71
+ const category = this.categorizeFile(file);
72
+ const source = {
73
+ type: ext.slice(1),
74
+ path: file,
75
+ content,
76
+ category
77
+ };
78
+ documentation.sources.push(source);
79
+ // Process based on category and type
80
+ this.processSource(source, documentation);
81
+ }
82
+ // Cache the results
83
+ this.cache = documentation;
84
+ this.lastModified = stats.mtimeMs;
85
+ console.log(`āœ… Loaded documentation with ${documentation.guidelines.length} guidelines, ${Object.keys(documentation.tokens).length} token categories, ${Object.keys(documentation.patterns).length} patterns`);
86
+ return documentation;
87
+ }
88
+ /**
89
+ * Categorize file based on path and name
90
+ */
91
+ categorizeFile(filePath) {
92
+ const lower = filePath.toLowerCase();
93
+ if (lower.includes('token'))
94
+ return 'tokens';
95
+ if (lower.includes('pattern'))
96
+ return 'patterns';
97
+ if (lower.includes('component'))
98
+ return 'components';
99
+ if (lower.includes('guideline') || lower.includes('guide'))
100
+ return 'guidelines';
101
+ if (lower.includes('spacing'))
102
+ return 'tokens';
103
+ if (lower.includes('color') || lower.includes('colour'))
104
+ return 'tokens';
105
+ if (lower.includes('typography') || lower.includes('font'))
106
+ return 'tokens';
107
+ // Check directory structure
108
+ const parts = filePath.split(path.sep);
109
+ if (parts.includes('tokens'))
110
+ return 'tokens';
111
+ if (parts.includes('patterns'))
112
+ return 'patterns';
113
+ if (parts.includes('components'))
114
+ return 'components';
115
+ if (parts.includes('guidelines'))
116
+ return 'guidelines';
117
+ return 'guidelines'; // default
118
+ }
119
+ /**
120
+ * Process a documentation source based on its type and category
121
+ */
122
+ processSource(source, docs) {
123
+ switch (source.category) {
124
+ case 'tokens':
125
+ if (source.type === 'json') {
126
+ try {
127
+ const tokens = JSON.parse(source.content);
128
+ Object.assign(docs.tokens, tokens);
129
+ }
130
+ catch (e) {
131
+ console.warn(`Failed to parse JSON tokens from ${source.path}`);
132
+ }
133
+ }
134
+ else {
135
+ // Extract token information from markdown/text
136
+ docs.guidelines.push(`\n## Tokens from ${source.path}\n${source.content}`);
137
+ }
138
+ break;
139
+ case 'patterns':
140
+ // Extract pattern name from filename
141
+ const patternName = path.basename(source.path, path.extname(source.path));
142
+ docs.patterns[patternName] = source.content;
143
+ break;
144
+ case 'components':
145
+ if (source.type === 'json') {
146
+ try {
147
+ const components = JSON.parse(source.content);
148
+ Object.assign(docs.components, components);
149
+ }
150
+ catch (e) {
151
+ console.warn(`Failed to parse JSON components from ${source.path}`);
152
+ }
153
+ }
154
+ else {
155
+ // Add to guidelines for AI to understand
156
+ docs.guidelines.push(`\n## Component Documentation from ${source.path}\n${source.content}`);
157
+ }
158
+ break;
159
+ case 'guidelines':
160
+ default:
161
+ docs.guidelines.push(`\n## ${path.basename(source.path, path.extname(source.path))}\n${source.content}`);
162
+ break;
163
+ }
164
+ }
165
+ /**
166
+ * Format documentation for AI prompt
167
+ */
168
+ formatForPrompt(docs) {
169
+ let prompt = '';
170
+ // Add guidelines
171
+ if (docs.guidelines.length > 0) {
172
+ prompt += '\n\nšŸ“š DESIGN SYSTEM DOCUMENTATION:\n';
173
+ prompt += docs.guidelines.join('\n\n');
174
+ }
175
+ // Add tokens
176
+ if (Object.keys(docs.tokens).length > 0) {
177
+ prompt += '\n\nšŸŽØ DESIGN TOKENS:\n```json\n';
178
+ prompt += JSON.stringify(docs.tokens, null, 2);
179
+ prompt += '\n```\n';
180
+ }
181
+ // Add patterns
182
+ if (Object.keys(docs.patterns).length > 0) {
183
+ prompt += '\n\nšŸ“‹ DESIGN PATTERNS:\n';
184
+ for (const [name, pattern] of Object.entries(docs.patterns)) {
185
+ prompt += `\n### ${name}\n${pattern}\n`;
186
+ }
187
+ }
188
+ return prompt;
189
+ }
190
+ }
191
+ /**
192
+ * Example directory structure:
193
+ *
194
+ * story-ui-docs/
195
+ * ā”œā”€ā”€ README.md # Overview and getting started
196
+ * ā”œā”€ā”€ guidelines/
197
+ * │ ā”œā”€ā”€ accessibility.md # Accessibility guidelines
198
+ * │ ā”œā”€ā”€ responsive-design.md # Responsive design rules
199
+ * │ └── brand-guidelines.md # Brand usage
200
+ * ā”œā”€ā”€ tokens/
201
+ * │ ā”œā”€ā”€ colors.json # Color tokens
202
+ * │ ā”œā”€ā”€ spacing.md # Spacing system
203
+ * │ ā”œā”€ā”€ typography.json # Typography tokens
204
+ * │ └── shadows.json # Shadow tokens
205
+ * ā”œā”€ā”€ components/
206
+ * │ ā”œā”€ā”€ button.md # Button documentation
207
+ * │ ā”œā”€ā”€ form-fields.md # Form component docs
208
+ * │ └── navigation.md # Navigation patterns
209
+ * └── patterns/
210
+ * ā”œā”€ā”€ forms.md # Form patterns
211
+ * ā”œā”€ā”€ cards.md # Card layouts
212
+ * ā”œā”€ā”€ data-tables.md # Table patterns
213
+ * └── authentication.md # Auth flow patterns
214
+ */