@yahoo/uds 3.46.2 → 3.48.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.
Files changed (39) hide show
  1. package/cli/commands/editor-rules.ts +159 -0
  2. package/cli/rules/config.ts +73 -0
  3. package/cli/rules/cursor/uds/components.mdc +25 -0
  4. package/cli/rules/cursor/uds/icons.mdc +8 -0
  5. package/cli/rules/cursor/uds/tailwind.mdc +9 -0
  6. package/cli/utils/types.ts +9 -0
  7. package/dist/metafile-cjs.json +1 -1
  8. package/dist/metafile-esm.json +1 -1
  9. package/package.json +1 -1
  10. package/dist/Box-CVbnF3KY.d.cts +0 -34
  11. package/dist/Box-KZ1-_3Y1.d.ts +0 -34
  12. package/dist/Pressable-BCKijzW4.d.ts +0 -44
  13. package/dist/Pressable-DM2L9PzA.d.cts +0 -44
  14. package/dist/Text-774Va3iq.d.ts +0 -88
  15. package/dist/Text-C58YvnSu.d.cts +0 -88
  16. package/dist/VStack-4KrkGBKP.d.ts +0 -83
  17. package/dist/VStack-AyF9g6Xi.d.cts +0 -83
  18. package/dist/chunk-3XMORCA6.cjs +0 -1
  19. package/dist/chunk-42TM364I.cjs +0 -1
  20. package/dist/chunk-4SWOQUGX.cjs +0 -1
  21. package/dist/chunk-53KBVJPZ.cjs +0 -2
  22. package/dist/chunk-6IIFFVGC.js +0 -1
  23. package/dist/chunk-6OLYHKI2.js +0 -2
  24. package/dist/chunk-7IYNK6VF.js +0 -3
  25. package/dist/chunk-D4G2CCD4.js +0 -2
  26. package/dist/chunk-D7XPTBPO.js +0 -2
  27. package/dist/chunk-HPXOQ4QK.js +0 -1
  28. package/dist/chunk-JD7PX7BB.cjs +0 -2
  29. package/dist/chunk-K7DHGT5F.cjs +0 -1
  30. package/dist/chunk-MEM4DBEJ.cjs +0 -1
  31. package/dist/chunk-ND5BLCNY.js +0 -2
  32. package/dist/chunk-O4TV6UVI.cjs +0 -1
  33. package/dist/chunk-QCLXCOEJ.js +0 -2
  34. package/dist/chunk-W7AQRGI5.cjs +0 -1
  35. package/dist/chunk-XWRSYGZJ.js +0 -2
  36. package/dist/index-BtKE9zn1.d.ts +0 -245
  37. package/dist/index-cZ0qEwcJ.d.cts +0 -245
  38. package/dist/types-D6kYghpa.d.cts +0 -10589
  39. package/dist/types-D6kYghpa.d.ts +0 -10589
@@ -0,0 +1,159 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ import type { Props } from 'bluebun';
5
+ import { blue, green, print, red, yellow } from 'bluebun';
6
+
7
+ import type { EditorConfig } from '../rules/config';
8
+ import { getAvailableEditors, getEditorConfig, getRuleContent } from '../rules/config';
9
+ import { trackEvent } from '../utils/analytics';
10
+ import type { EditorRulesOptions } from '../utils/types';
11
+
12
+ interface EditorRulesProps extends Props {
13
+ options: EditorRulesOptions;
14
+ }
15
+
16
+ export default {
17
+ name: 'editor-rules',
18
+ description: '🎯 Generate editor rules for various code editors and AI tools',
19
+ alias: ['rules', 'editor'],
20
+ options: {
21
+ force: {
22
+ type: 'boolean',
23
+ description: 'Force overwrite existing rules directory',
24
+ alias: 'f',
25
+ },
26
+ output: {
27
+ type: 'string',
28
+ description: 'Output directory (defaults to workspace root)',
29
+ alias: 'o',
30
+ },
31
+ editor: {
32
+ type: 'string',
33
+ description: 'Specific editor or AI tool to generate rules for',
34
+ alias: 'e',
35
+ },
36
+ },
37
+ run: async ({ options }: EditorRulesProps) => {
38
+ // Check for help flag manually since bluebun help handling seems to have issues
39
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
40
+ print(blue('🎯 UDS Editor Rules Command'));
41
+ print('');
42
+ print(green('Description: Generate editor rules for various code editors and AI tools'));
43
+ print('');
44
+ print(yellow('Options:'));
45
+ print(' --force, -f Force overwrite existing rules directory');
46
+ print(' --output, -o Output directory (defaults to workspace root)');
47
+ print(' --editor, -e Specific editor/tool (defaults to all)');
48
+ print('');
49
+ print(blue('Available editors/tools:'));
50
+ const editors = getAvailableEditors();
51
+ for (const editor of editors) {
52
+ const config = getEditorConfig(editor);
53
+ if (config) {
54
+ print(` • ${editor}: ${config.description}`);
55
+ }
56
+ }
57
+ print('');
58
+ print(blue('Examples:'));
59
+ print(' uds editor-rules # Generate all rules in current directory');
60
+ print(' uds editor-rules --editor cursor # Generate only Cursor rules');
61
+ print(' uds editor-rules --output /path # Generate rules in specific directory');
62
+ print(' uds editor-rules --force # Force overwrite existing rules');
63
+ print('');
64
+ print(green('What it generates:'));
65
+ print(' • Cursor Rules (.cursor/uds/)');
66
+ return;
67
+ }
68
+
69
+ try {
70
+ const outputDir = options.output || process.cwd();
71
+ const selectedEditor = options.editor?.toLowerCase();
72
+
73
+ print(blue(`📁 Generating editor rules in: ${outputDir}`));
74
+
75
+ if (selectedEditor) {
76
+ // Generate rules for specific editor
77
+ const editorConfig = getEditorConfig(selectedEditor);
78
+ if (!editorConfig) {
79
+ print(red(`❌ Unknown editor: ${selectedEditor}`));
80
+ print(yellow('Available editors:'));
81
+ const editors = getAvailableEditors();
82
+ for (const editor of editors) {
83
+ const config = getEditorConfig(editor);
84
+ if (config) {
85
+ print(` • ${editor}: ${config.description}`);
86
+ }
87
+ }
88
+ return;
89
+ }
90
+
91
+ await generateEditorRules(outputDir, selectedEditor, editorConfig, options.force);
92
+ } else {
93
+ // Generate rules for all editors
94
+ const editors = getAvailableEditors();
95
+ for (const editor of editors) {
96
+ const editorConfig = getEditorConfig(editor);
97
+ if (editorConfig) {
98
+ await generateEditorRules(outputDir, editor, editorConfig, options.force);
99
+ }
100
+ }
101
+ }
102
+
103
+ print(green('🎉 Editor rules generated successfully!'));
104
+ print(blue('📝 Rules are now available for your development environment'));
105
+
106
+ await trackEvent('editor_rules_generated', {
107
+ output_dir: outputDir,
108
+ force: options.force || false,
109
+ editor: selectedEditor || 'all',
110
+ });
111
+ } catch (error) {
112
+ print(red(`❌ Error generating editor rules: ${error}`));
113
+ process.exitCode = 1;
114
+ }
115
+ },
116
+ };
117
+
118
+ async function generateEditorRules(
119
+ outputDir: string,
120
+ editorName: string,
121
+ editorConfig: EditorConfig,
122
+ force: boolean = false,
123
+ ) {
124
+ print(blue(`\n🔧 Generating ${editorConfig.name} rules...`));
125
+
126
+ for (const rule of editorConfig.rules) {
127
+ print(yellow(` 📝 ${rule.name}: ${rule.description}`));
128
+
129
+ for (const file of rule.files) {
130
+ const targetPath = join(outputDir, file.target);
131
+ const targetDir = join(targetPath, '..');
132
+
133
+ // Create target directory if it doesn't exist
134
+ if (!existsSync(targetDir)) {
135
+ mkdirSync(targetDir, { recursive: true });
136
+ }
137
+
138
+ // Check if file exists and handle force flag
139
+ if (existsSync(targetPath)) {
140
+ if (force) {
141
+ print(yellow(` 🗑️ Overwriting: ${file.target}`));
142
+ } else {
143
+ print(red(` ❌ File already exists: ${file.target}`));
144
+ print(yellow(' Use --force to overwrite existing files'));
145
+ continue;
146
+ }
147
+ }
148
+
149
+ try {
150
+ // Read and write the rule file
151
+ const content = getRuleContent(file.source);
152
+ writeFileSync(targetPath, content);
153
+ print(green(` ✅ Created: ${file.target}`));
154
+ } catch (error) {
155
+ print(red(` ❌ Error creating ${file.target}: ${error}`));
156
+ }
157
+ }
158
+ }
159
+ }
@@ -0,0 +1,73 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ export interface RuleConfig {
5
+ name: string;
6
+ description: string;
7
+ files: Array<{
8
+ source: string;
9
+ target: string;
10
+ type: 'file' | 'directory';
11
+ }>;
12
+ }
13
+
14
+ export interface EditorConfig {
15
+ name: string;
16
+ description: string;
17
+ rules: RuleConfig[];
18
+ }
19
+
20
+ export const EDITOR_CONFIGS: Record<string, EditorConfig> = {
21
+ cursor: {
22
+ name: 'Cursor',
23
+ description: 'AI-powered coding assistant rules for UDS development',
24
+ rules: [
25
+ {
26
+ name: 'UDS Components',
27
+ description: 'Component development guidelines and patterns',
28
+ files: [
29
+ {
30
+ source: 'cursor/uds/components.mdc',
31
+ target: '.cursor/rules/uds/components.mdc',
32
+ type: 'file',
33
+ },
34
+ ],
35
+ },
36
+ {
37
+ name: 'UDS Tailwind',
38
+ description: 'Tailwind CSS configuration and setup guidelines',
39
+ files: [
40
+ {
41
+ source: 'cursor/uds/tailwind.mdc',
42
+ target: '.cursor/rules/uds/tailwind.mdc',
43
+ type: 'file',
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ name: 'UDS Icons',
49
+ description: 'Icon usage and documentation guidelines',
50
+ files: [
51
+ {
52
+ source: 'cursor/uds/icons.mdc',
53
+ target: '.cursor/rules/uds/icons.mdc',
54
+ type: 'file',
55
+ },
56
+ ],
57
+ },
58
+ ],
59
+ },
60
+ };
61
+
62
+ export function getAvailableEditors(): string[] {
63
+ return Object.keys(EDITOR_CONFIGS);
64
+ }
65
+
66
+ export function getEditorConfig(editor: string): EditorConfig | undefined {
67
+ return EDITOR_CONFIGS[editor];
68
+ }
69
+
70
+ export function getRuleContent(rulePath: string): string {
71
+ const fullPath = join(__dirname, rulePath);
72
+ return readFileSync(fullPath, 'utf-8');
73
+ }
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: UDS components
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ - Always fetch components type definition using the UDS mcp server
8
+ - Always fetch the possible components from uds using the UDS mcp server
9
+ - Anytime you are about to use a component, fetch the type definition
10
+ - Anytime you are about to use a component, fetch the component documentation examples
11
+ - Anytime you have to create a component, make sure you are using UDS components
12
+ - Never create already existing UDS components from scratch
13
+ - Make sure there are no type errors when you create new components
14
+ - Always use UDS UI library components instead of raw HTML tags.
15
+ - Only create custom components when UDS doesn't provide the needed functionality
16
+ - `<Box>` has `display = 'flex'` by default - use `<VStack>` for vertical stacking, `<HStack>` for horizontal, or `<div>` for simple containers
17
+ - Use `<Text>` instead of `<p>`, `<span>`, `<h1>`-`<h6>`
18
+ - Use `<Button>` instead of `<button>`
19
+ - Use `<Input>` instead of `<input>`
20
+ - Use `<Checkbox>` instead of `<input type="checkbox">`
21
+ - Use `<Radio>` instead of `<input type="radio">`
22
+ - Use `<Switch>` instead of custom toggle components
23
+ - Use `<Link>` instead of `<a>`
24
+ - Use `<Icon>` instead of SVG elements
25
+ - Fix all lint errors before completing the task
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: UDS Icons
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ - Anytime you have to use an icon in a UDS component or use UDS icons outside UDS components, fetch Icon documentation for more context from the MCP server
8
+ - Always check what icons are available in UDS through the MCP server
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: UDS config
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ - Never create a UDS config manually
8
+ - If `uds.config.ts` or `uds.config.js` is not present at the root of the project, ask the user to create it using UDS CLI sync command
9
+ - Make sure that tailwind configuration has the UDS tailwind plugin
@@ -19,3 +19,12 @@ export type SyncOptions = {
19
19
  /** The version of the CLI */
20
20
  version: string;
21
21
  };
22
+
23
+ export type EditorRulesOptions = {
24
+ /** Force overwrite existing rules directory */
25
+ force?: boolean;
26
+ /** Output directory (defaults to workspace root) */
27
+ output?: string;
28
+ /** Specific editor or AI tool to generate rules for */
29
+ editor?: string;
30
+ };