trae-starter 0.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 (83) hide show
  1. package/README.md +45 -0
  2. package/bin/cli.js +33 -0
  3. package/package.json +25 -0
  4. package/public/app.js +263 -0
  5. package/public/index.html +123 -0
  6. package/server/api.js +181 -0
  7. package/server/index.js +38 -0
  8. package/templates/proto/.agents/skills/ui-ux-pro-max/SKILL.md +659 -0
  9. package/templates/proto/.agents/skills/ui-ux-pro-max/data/_sync_all.py +414 -0
  10. package/templates/proto/.agents/skills/ui-ux-pro-max/data/app-interface.csv +31 -0
  11. package/templates/proto/.agents/skills/ui-ux-pro-max/data/charts.csv +26 -0
  12. package/templates/proto/.agents/skills/ui-ux-pro-max/data/colors.csv +162 -0
  13. package/templates/proto/.agents/skills/ui-ux-pro-max/data/design.csv +1776 -0
  14. package/templates/proto/.agents/skills/ui-ux-pro-max/data/draft.csv +1779 -0
  15. package/templates/proto/.agents/skills/ui-ux-pro-max/data/google-fonts.csv +1924 -0
  16. package/templates/proto/.agents/skills/ui-ux-pro-max/data/icons.csv +106 -0
  17. package/templates/proto/.agents/skills/ui-ux-pro-max/data/landing.csv +35 -0
  18. package/templates/proto/.agents/skills/ui-ux-pro-max/data/products.csv +162 -0
  19. package/templates/proto/.agents/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  20. package/templates/proto/.agents/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  21. package/templates/proto/.agents/skills/ui-ux-pro-max/data/styles.csv +85 -0
  22. package/templates/proto/.agents/skills/ui-ux-pro-max/data/typography.csv +74 -0
  23. package/templates/proto/.agents/skills/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
  24. package/templates/proto/.agents/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  25. package/templates/proto/.agents/skills/ui-ux-pro-max/scripts/core.py +247 -0
  26. package/templates/proto/.agents/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  27. package/templates/proto/.agents/skills/ui-ux-pro-max/scripts/search.py +114 -0
  28. package/templates/proto/.trae/skills/preview-manager/SKILL.md +37 -0
  29. package/templates/proto/.trae/skills/ui-ux-pro-max/SKILL.md +659 -0
  30. package/templates/proto/.trae/skills/ui-ux-pro-max/data/_sync_all.py +414 -0
  31. package/templates/proto/.trae/skills/ui-ux-pro-max/data/app-interface.csv +31 -0
  32. package/templates/proto/.trae/skills/ui-ux-pro-max/data/charts.csv +26 -0
  33. package/templates/proto/.trae/skills/ui-ux-pro-max/data/colors.csv +162 -0
  34. package/templates/proto/.trae/skills/ui-ux-pro-max/data/design.csv +1776 -0
  35. package/templates/proto/.trae/skills/ui-ux-pro-max/data/draft.csv +1779 -0
  36. package/templates/proto/.trae/skills/ui-ux-pro-max/data/google-fonts.csv +1924 -0
  37. package/templates/proto/.trae/skills/ui-ux-pro-max/data/icons.csv +106 -0
  38. package/templates/proto/.trae/skills/ui-ux-pro-max/data/landing.csv +35 -0
  39. package/templates/proto/.trae/skills/ui-ux-pro-max/data/products.csv +162 -0
  40. package/templates/proto/.trae/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  41. package/templates/proto/.trae/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  42. package/templates/proto/.trae/skills/ui-ux-pro-max/data/styles.csv +85 -0
  43. package/templates/proto/.trae/skills/ui-ux-pro-max/data/typography.csv +74 -0
  44. package/templates/proto/.trae/skills/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
  45. package/templates/proto/.trae/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  46. package/templates/proto/.trae/skills/ui-ux-pro-max/scripts/core.py +247 -0
  47. package/templates/proto/.trae/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  48. package/templates/proto/.trae/skills/ui-ux-pro-max/scripts/search.py +114 -0
  49. package/templates/proto/README.md +77 -0
  50. package/templates/proto/agent.md +361 -0
  51. package/templates/proto/eslint.config.js +23 -0
  52. package/templates/proto/index.html +13 -0
  53. package/templates/proto/package.json +39 -0
  54. package/templates/proto/pnpm-lock.yaml +2401 -0
  55. package/templates/proto/postcss.config.js +6 -0
  56. package/templates/proto/public/favicon.svg +1 -0
  57. package/templates/proto/public/icons.svg +24 -0
  58. package/templates/proto/skills-lock.json +10 -0
  59. package/templates/proto/src/App.css +184 -0
  60. package/templates/proto/src/App.tsx +15 -0
  61. package/templates/proto/src/assets/hero.png +0 -0
  62. package/templates/proto/src/assets/react.svg +1 -0
  63. package/templates/proto/src/assets/vite.svg +1 -0
  64. package/templates/proto/src/components/ui/SampleButton/sampleButton.css +4 -0
  65. package/templates/proto/src/components/ui/SampleButton/sampleButton.tsx +14 -0
  66. package/templates/proto/src/data/mock/products.csv +4 -0
  67. package/templates/proto/src/data/mock/users.json +16 -0
  68. package/templates/proto/src/data/types.ts +17 -0
  69. package/templates/proto/src/index.css +64 -0
  70. package/templates/proto/src/main.tsx +13 -0
  71. package/templates/proto/src/pages/Demo/components/DemoHeader/demoHeader.tsx +20 -0
  72. package/templates/proto/src/pages/Demo/components/FeatureGrid/featureGrid.tsx +18 -0
  73. package/templates/proto/src/pages/Demo/index.tsx +29 -0
  74. package/templates/proto/src/pages/Home/components/FeatureCard/featureCard.tsx +15 -0
  75. package/templates/proto/src/pages/Home/components/HeroSection/heroSection.tsx +28 -0
  76. package/templates/proto/src/pages/Home/components/InteractiveControls/interactiveControls.tsx +27 -0
  77. package/templates/proto/src/pages/Home/index.tsx +39 -0
  78. package/templates/proto/src/utils/format.ts +7 -0
  79. package/templates/proto/tailwind.config.js +11 -0
  80. package/templates/proto/tsconfig.app.json +28 -0
  81. package/templates/proto/tsconfig.json +7 -0
  82. package/templates/proto/tsconfig.node.json +26 -0
  83. package/templates/proto/vite.config.ts +10 -0
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ UI/UX Pro Max Search - BM25 search engine for UI/UX style guides
5
+ Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-results 3]
6
+ python search.py "<query>" --design-system [-p "Project Name"]
7
+ python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
8
+
9
+ Domains: style, prompt, color, chart, landing, product, ux, typography, google-fonts
10
+ Stacks: html-tailwind, react, nextjs
11
+
12
+ Persistence (Master + Overrides pattern):
13
+ --persist Save design system to design-system/MASTER.md
14
+ --page Also create a page-specific override file in design-system/pages/
15
+ """
16
+
17
+ import argparse
18
+ import sys
19
+ import io
20
+ from core import CSV_CONFIG, AVAILABLE_STACKS, MAX_RESULTS, search, search_stack
21
+ from design_system import generate_design_system, persist_design_system
22
+
23
+ # Force UTF-8 for stdout/stderr to handle emojis on Windows (cp1252 default)
24
+ if sys.stdout.encoding and sys.stdout.encoding.lower() != 'utf-8':
25
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
26
+ if sys.stderr.encoding and sys.stderr.encoding.lower() != 'utf-8':
27
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
28
+
29
+
30
+ def format_output(result):
31
+ """Format results for Claude consumption (token-optimized)"""
32
+ if "error" in result:
33
+ return f"Error: {result['error']}"
34
+
35
+ output = []
36
+ if result.get("stack"):
37
+ output.append(f"## UI Pro Max Stack Guidelines")
38
+ output.append(f"**Stack:** {result['stack']} | **Query:** {result['query']}")
39
+ else:
40
+ output.append(f"## UI Pro Max Search Results")
41
+ output.append(f"**Domain:** {result['domain']} | **Query:** {result['query']}")
42
+ output.append(f"**Source:** {result['file']} | **Found:** {result['count']} results\n")
43
+
44
+ for i, row in enumerate(result['results'], 1):
45
+ output.append(f"### Result {i}")
46
+ for key, value in row.items():
47
+ value_str = str(value)
48
+ if len(value_str) > 300:
49
+ value_str = value_str[:300] + "..."
50
+ output.append(f"- **{key}:** {value_str}")
51
+ output.append("")
52
+
53
+ return "\n".join(output)
54
+
55
+
56
+ if __name__ == "__main__":
57
+ parser = argparse.ArgumentParser(description="UI Pro Max Search")
58
+ parser.add_argument("query", help="Search query")
59
+ parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
60
+ parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs)")
61
+ parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
62
+ parser.add_argument("--json", action="store_true", help="Output as JSON")
63
+ # Design system generation
64
+ parser.add_argument("--design-system", "-ds", action="store_true", help="Generate complete design system recommendation")
65
+ parser.add_argument("--project-name", "-p", type=str, default=None, help="Project name for design system output")
66
+ parser.add_argument("--format", "-f", choices=["ascii", "markdown"], default="ascii", help="Output format for design system")
67
+ # Persistence (Master + Overrides pattern)
68
+ parser.add_argument("--persist", action="store_true", help="Save design system to design-system/MASTER.md (creates hierarchical structure)")
69
+ parser.add_argument("--page", type=str, default=None, help="Create page-specific override file in design-system/pages/")
70
+ parser.add_argument("--output-dir", "-o", type=str, default=None, help="Output directory for persisted files (default: current directory)")
71
+
72
+ args = parser.parse_args()
73
+
74
+ # Design system takes priority
75
+ if args.design_system:
76
+ result = generate_design_system(
77
+ args.query,
78
+ args.project_name,
79
+ args.format,
80
+ persist=args.persist,
81
+ page=args.page,
82
+ output_dir=args.output_dir
83
+ )
84
+ print(result)
85
+
86
+ # Print persistence confirmation
87
+ if args.persist:
88
+ project_slug = args.project_name.lower().replace(' ', '-') if args.project_name else "default"
89
+ print("\n" + "=" * 60)
90
+ print(f"✅ Design system persisted to design-system/{project_slug}/")
91
+ print(f" 📄 design-system/{project_slug}/MASTER.md (Global Source of Truth)")
92
+ if args.page:
93
+ page_filename = args.page.lower().replace(' ', '-')
94
+ print(f" 📄 design-system/{project_slug}/pages/{page_filename}.md (Page Overrides)")
95
+ print("")
96
+ print(f"📖 Usage: When building a page, check design-system/{project_slug}/pages/[page].md first.")
97
+ print(f" If exists, its rules override MASTER.md. Otherwise, use MASTER.md.")
98
+ print("=" * 60)
99
+ # Stack search
100
+ elif args.stack:
101
+ result = search_stack(args.query, args.stack, args.max_results)
102
+ if args.json:
103
+ import json
104
+ print(json.dumps(result, indent=2, ensure_ascii=False))
105
+ else:
106
+ print(format_output(result))
107
+ # Domain search
108
+ else:
109
+ result = search(args.query, args.domain, args.max_results)
110
+ if args.json:
111
+ import json
112
+ print(json.dumps(result, indent=2, ensure_ascii=False))
113
+ else:
114
+ print(format_output(result))
@@ -0,0 +1,77 @@
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ ## Project Conventions
6
+
7
+ - **Demo Directory**: The `Demo` page (`src/pages/Demo`) is an example directory for the project. **Do not delete or modify it** unless the intent explicitly states to add or modify a demo.
8
+
9
+ Currently, two official plugins are available:
10
+
11
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
12
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
13
+
14
+ ## React Compiler
15
+
16
+ The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
17
+
18
+ ## Expanding the ESLint configuration
19
+
20
+ If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
21
+
22
+ ```js
23
+ export default defineConfig([
24
+ globalIgnores(['dist']),
25
+ {
26
+ files: ['**/*.{ts,tsx}'],
27
+ extends: [
28
+ // Other configs...
29
+
30
+ // Remove tseslint.configs.recommended and replace with this
31
+ tseslint.configs.recommendedTypeChecked,
32
+ // Alternatively, use this for stricter rules
33
+ tseslint.configs.strictTypeChecked,
34
+ // Optionally, add this for stylistic rules
35
+ tseslint.configs.stylisticTypeChecked,
36
+
37
+ // Other configs...
38
+ ],
39
+ languageOptions: {
40
+ parserOptions: {
41
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
42
+ tsconfigRootDir: import.meta.dirname,
43
+ },
44
+ // other options...
45
+ },
46
+ },
47
+ ])
48
+ ```
49
+
50
+ You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
51
+
52
+ ```js
53
+ // eslint.config.js
54
+ import reactX from 'eslint-plugin-react-x'
55
+ import reactDom from 'eslint-plugin-react-dom'
56
+
57
+ export default defineConfig([
58
+ globalIgnores(['dist']),
59
+ {
60
+ files: ['**/*.{ts,tsx}'],
61
+ extends: [
62
+ // Other configs...
63
+ // Enable lint rules for React
64
+ reactX.configs['recommended-typescript'],
65
+ // Enable lint rules for React DOM
66
+ reactDom.configs.recommended,
67
+ ],
68
+ languageOptions: {
69
+ parserOptions: {
70
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
71
+ tsconfigRootDir: import.meta.dirname,
72
+ },
73
+ // other options...
74
+ },
75
+ },
76
+ ])
77
+ ```
@@ -0,0 +1,361 @@
1
+ # Project Overview
2
+
3
+ This is a modern React web application built with Vite and TypeScript.
4
+
5
+ ## Technology Stack
6
+
7
+ - **Framework**: React 19
8
+ - **Routing**: React Router v7
9
+ - **Language**: TypeScript (v5.9)
10
+ - **Build Tool**: Vite (v8)
11
+ - **Styling**: Tailwind CSS (v4) with PostCSS and Autoprefixer
12
+ - **Linting**: ESLint (v9) with Flat Config (`eslint.config.js`)
13
+ - **Package Manager**: pnpm
14
+
15
+ ## Project Structure
16
+
17
+ - `/src` - Source code directory
18
+ - `/assets` - Static assets like images and SVGs
19
+ - `/components` - Global reusable UI components
20
+ - `/ui` - Atomic UI components (purely for rendering)
21
+ - `ComponentName/` - Component directory (PascalCase, e.g., `SampleButton/`)
22
+ - `componentName.tsx` - Component file (camelCase)
23
+ - `componentName.css` - Component specific styles
24
+ - `/features` - Functional UI components
25
+ - `/data` - Mock data and type definitions for demo purposes
26
+ - `types.ts` - TypeScript interfaces/types for the mock data
27
+ - `/mock` - JSON and CSV files containing the mock data
28
+ - `/pages` - Page components for routing
29
+ - `PageName/` - Directory for a specific page (e.g., `Home/`, `Demo/`)
30
+ - `index.tsx` - Main entry file for the page
31
+ - `components/` - Logical components specific to this page template
32
+ - `/utils` - Utility functions and helpers
33
+ - `App.tsx` - Main application component with routing setup
34
+ - `main.tsx` - Application entry point
35
+ - `index.css` - Global styles and Tailwind directives
36
+ - `/public` - Static assets served directly (e.g., favicons)
37
+
38
+ ## Development Guidelines
39
+
40
+ 1. **Architecture & Layering**:
41
+ - The project strictly separates UI and logic.
42
+ - **UI Components**: Responsible only for rendering. Placed in `src/components/ui` (atomic) or `src/components/features` (functional).
43
+ - **Logical Components**: Specific to a page template, placed in `src/pages/[PageName]/components/`.
44
+ - **Pages**: A page is composed of multiple logical components. Layout components that combine them can be written directly within the page's `index.tsx`.
45
+ 2. **Naming Conventions**: Component directories must be PascalCase (e.g., `SampleButton`), and files inside them must be camelCase (e.g., `sampleButton.tsx`, `sampleButton.css`). Pages use `index.tsx` as their entry.
46
+ 3. **Data Management (Demo First)**:
47
+ - The project is primarily used for demo presentations.
48
+ - All mock data should be placed in the `src/data/mock/` directory (supports `.json` and `.csv` formats).
49
+ - Strict TypeScript types must be defined for all mock data in `src/data/types.ts` to ensure type safety across the application.
50
+ 4. **Styling**: Use Tailwind CSS utility classes for styling. For component-specific custom CSS, place it in the component's directory.
51
+ 5. **TypeScript**: Use strict typing. Avoid using `any` type; define interfaces or types for props and state.
52
+ 6. **Routing**: Use React Router v7 for any navigation or new pages. Place new page components in `src/pages/`.
53
+ 7. **State Management**: Use React built-in hooks (`useState`, `useReducer`, `useContext`) for state management.
54
+ 8. **Linting**: Ensure code passes ESLint rules defined in the project.
55
+ 9. **Demo Directory Convention**: The `Demo` page (`src/pages/Demo`) serves as an example directory for the project. **Do not delete or modify it** unless the intent explicitly states to add or modify a demo.
56
+
57
+ <br />
58
+
59
+ **React and TypeScript guidance**
60
+
61
+ Your task is to generate a React single-page application (SPA) using TypeScript. Adhere strictly to the following guidelines:
62
+
63
+ **TypeScript & Type Safety**
64
+
65
+ - **Type Imports:**
66
+ - All `import` statements **MUST** be placed at the top level of the module (alongside other imports).
67
+ - **MUST NOT** use `import` inline within other type annotations or code structures.
68
+ - **MUST** use named import; do *not* use object destructuring.
69
+ - Correct Example: `import { BarChart } from 'recharts';`
70
+ - Incorrect Example: `const { BarChart } = Recharts;`
71
+ - **MUST NOT** use `import type` to import enum type and use its value; use `import {...}` instead.
72
+ - Correct Example
73
+ ```
74
+ // types.ts
75
+ export enum CarType {
76
+ SUV = 'SUV',
77
+ SEDAN = 'SEDAN',
78
+ TRUCK = 'TRUCK'
79
+ }
80
+ // car.ts
81
+ import {CarType} from './types'
82
+ const carType = CarType.SUV; // Can use the enum value because it is using `import` directly.
83
+ ```
84
+ - Incorrect Example
85
+ ```
86
+ // types.ts
87
+ export enum CarType {
88
+ SUV = 'SUV',
89
+ SEDAN = 'SEDAN',
90
+ TRUCK = 'TRUCK'
91
+ }
92
+ // car.ts
93
+ import type {CarType} from './types'
94
+ const carType = CarType.SUV; // Cannot use the enum value during runtime because it is using `import type`.
95
+ ```
96
+ - **CRITICAL:** When using any constants or types defined in the modules (e.g., `constants`, `types`), you **MUST** explicitly import them from their respective source module at the top of the file before using them. Do not assume they are globally available.
97
+ - **Enums:**
98
+ - **MUST** use standard `enum` declarations (e.g., `enum MyEnum { Value1, Value2 }`).
99
+ - **MUST NOT** use `const enum`. Use standard `enum` instead to ensure the enum definition is preserved in the compiled output.
100
+
101
+ **Styling**
102
+
103
+ - **Method:** Use **Tailwind CSS ONLY**.
104
+ - **Restrictions:** **DO NOT** use separate CSS files (`.css`, `.module.css`), CSS-in-JS libraries (styled-components, emotion, etc.), or inline `style` attributes.
105
+ - **Guidance:** Implement layout, color palette, and specific styles based on the web app's features.
106
+
107
+ **Responsive Design**
108
+
109
+ - **Cross-Device Support:** Ensure the application provides an optimal and consistent user experience across a wide range of devices, including desktops, tablets, and mobile phones.
110
+ - **Mobile-First Approach:** Adhere to Tailwind's mobile-first principle. Design and style for the smallest screen size by default, then use breakpoint prefixes (e.g., sm:, md:, lg:) to progressively enhance the layout for larger screens. This ensures a functional baseline experience on all devices and leads to cleaner, more maintainable code.
111
+ \*. **Persistent Call-to-Action:** Make primary controls sticky to ensure they are always readily accessible, regardless of scroll position.
112
+
113
+ **React & TSX Syntax Rules**
114
+
115
+ - **Rendering:** Use the `createRoot` API for rendering the application. **MUST NOT** use the legacy `ReactDOM.render`.
116
+ - **Correct** **`index.tsx`** **Example (React 18+):**
117
+ ```tsx
118
+ import React from 'react';
119
+ import ReactDOM from 'react-dom/client'; // <--- Use 'react-dom/client'
120
+ import App from './App'; // Assuming App is in App.tsx
121
+
122
+ const rootElement = document.getElementById('root');
123
+ if (!rootElement) {
124
+ throw new Error("Could not find root element to mount to");
125
+ }
126
+
127
+ const root = ReactDOM.createRoot(rootElement);
128
+ root.render(
129
+ <React.StrictMode>
130
+ <App />
131
+ </React.StrictMode>
132
+ );
133
+ ```
134
+ - **TSX Expressions:** Use standard JavaScript expressions inside curly braces `{}`.
135
+ - **Template Literals (Backticks)**: Must *not* escape the outer delimiting backticks; you must escape the inner literal backticks.
136
+ - Outer delimiting backticks: The backticks that start and end the template literal string must *not* be escaped. These define the template literal.
137
+ **Correct usage:**
138
+ ```
139
+ const simpleGreeting = `Hello, ${name}!`; // Outer backticks are NOT escaped
140
+
141
+ const multiLinePrompt = `
142
+ This is a multi-line prompt
143
+ for ${name}.
144
+ ---
145
+ Keep it simple.
146
+ ---
147
+ `; // Outer backticks are NOT escaped
148
+
149
+ alert(`got error ${error}`); // The outer backticks in a function argument are not escaped
150
+ ```
151
+ **Incorrect usage:**
152
+ ```
153
+ // INCORRECT - Escaping the outer backticks
154
+ const simpleGreeting = \`Hello, ${name}!\`;
155
+
156
+ // INCORRECT - Escaping the outer backticks in a function argument
157
+ alert(\`got error ${error}\`);
158
+
159
+ // INCORRECT - Escaping the outer backticks
160
+ const multiLinePrompt = \`
161
+ This is a multi-line prompt
162
+ ...
163
+ \`;
164
+ ```
165
+ - Inner literal backticks: When including a backtick character inside the string, you must escape the inner literal backtick.
166
+ **Correct usage**
167
+ ```
168
+ const commandInstruction = `To run the script, type \`npm start\` in your terminal.`; // Inner backticks are escaped
169
+ const markdownCodeBlock = `
170
+ Here's an example in JSON:
171
+ \`\`\`json
172
+ {
173
+ "key": "value"
174
+ }
175
+ \`\`\`
176
+ This is how you include a literal code block.
177
+ `; // Inner backticks are escaped
178
+ ```
179
+ **Incorrect usage:**
180
+ ```
181
+ // INCORRECT - If you want `npm start` to have literal backticks
182
+ const commandInstruction = `To run the script, type `npm start` in your terminal.`;
183
+ // This would likely cause a syntax error because the second ` would end the template literal prematurely.
184
+ ```
185
+ - **Generics in Arrow Functions:** For generic arrow functions in TSX, a trailing comma **MUST** be added after the type parameter(s) to avoid parsing ambiguity. Only use Generics when the code is truly reusable.
186
+ - **Correct:** `const processData = <T,>(data: T): T => { ... };` (Note the comma after `T`)
187
+ - **Incorrect:** `const processData = <T>(data: T): T => { ... };`
188
+ - **MUST NOT** use `<style jsx>` which doesn't work in standard React.
189
+ - **React Router:** The app will run in an environment where it cannot update the URL path, except for the hash string. As such, do not generate any code that depends on manipulating the URL path, such as using React's `BrowserRouter`. But you may use React's `HashRouter`, as it only manipulates the hash string.
190
+ - **MUST NOT** use `react-dropzone` for file upload; use a file input element instead, for example, `<input type="file">`.
191
+
192
+ **Code Quality & Patterns**
193
+
194
+ - **Components:** Use **Functional Components** and **React Hooks** (e.g., `useState`, `useEffect`, `useCallback`).
195
+ - **Readability:** Prioritize clean, readable, and well-organized code.
196
+ - **Performance:** Write performant code where applicable.
197
+ - **Accessibility:** Ensure sufficient color contrast between text and its background for readability.
198
+
199
+ **Libraries**
200
+
201
+ - Use popular and existing libraries for improving functionality and visual appeal. Do not use mock or made-up libraries.
202
+ - Use `d3` for data visualization.
203
+ - Use `recharts` for charts.
204
+
205
+ **React common pitfalls**
206
+
207
+ You must avoid the common pitfalls below when generating the code.
208
+
209
+ - **React Hook Infinite Loop:** When using `useEffect` and `useCallback` together, be cautious to avoid infinite re-render loops.
210
+ - **The Pitfall:** A common loop occurs when:
211
+ 1. A `useEffect` hook includes a memoized function (from `useCallback`) in its dependency array.
212
+ 2. The `useCallback` hook includes a state variable (e.g., `count`) in *its* dependency array.
213
+ 3. The function *inside* `useCallback` updates that same state variable (`setCount`) based on its current value (`count + 1`).
214
+ - *Resulting Cycle:* `setCount` updates `count` -> Component re-renders -> `useCallback` sees new `count`, creates a *new* function instance -> `useEffect` sees the function changed, runs again -> Calls `setCount`... loop!
215
+ - When using `useEffect`, if you want to run only once when the component mounts (and clean up when it unmounts), an empty dependency array \[] is the correct pattern.
216
+ - **Incorrect Code Example:**
217
+ ```
218
+ const [count, setCount] = useState(0);
219
+ const [message, setMessage] = useState('Loading...');
220
+
221
+ // This function's identity changes whenever 'count' changes
222
+ const incrementAndLog = useCallback(() => {
223
+ console.log('incrementAndLog called, current count:', count);
224
+ const newCount = count + 1;
225
+ setMessage(`Loading count ${newCount}...`); // Simulate work
226
+ // Simulate async operation like fetching
227
+ setTimeout(() => {
228
+ console.log('Setting count to:', newCount);
229
+ setCount(newCount); // <-- This state update triggers the useCallback dependency change
230
+ setMessage(`Count is ${newCount}`);
231
+ }, 500);
232
+ }, [count]); // <-- Depends on 'count'
233
+
234
+ // This effect runs whenever 'incrementAndLog' changes identity
235
+ useEffect(() => {
236
+ console.log("Effect running because incrementAndLog changed");
237
+ incrementAndLog(); // Call the function
238
+ }, [incrementAndLog]); // <-- Depends on the function that depends on 'count'
239
+ ```
240
+ - **Correct Code Example:**
241
+ ```
242
+ const [count, setCount] = useState(0);
243
+ const [message, setMessage] = useState('Loading...');
244
+
245
+ const incrementAndLog = useCallback(() => {
246
+ // Use functional update to avoid direct dependency on 'count' in useCallback
247
+ // OR keep the dependency but fix the useEffect call
248
+ setCount(prevCount => {
249
+ console.log('incrementAndLog called, previous count:', prevCount);
250
+ const newCount = prevCount + 1;
251
+ setMessage(`Loading count ${newCount}...`);
252
+ // Simulate async operation
253
+ setTimeout(() => {
254
+ console.log('Setting count (functional update) to:', newCount);
255
+ setMessage(`Count is ${newCount}`);
256
+ }, 500);
257
+ return newCount; // Return the new count for the functional update
258
+ });
259
+ }, [count]);
260
+
261
+ // This effect runs ONLY ONCE on mount
262
+ useEffect(() => {
263
+ console.log("Effect running ONCE on mount to set initial state");
264
+ setMessage('Setting initial count...');
265
+ // Simulate initial load
266
+ setTimeout(() => {
267
+ setCount(1); // Set initial count
268
+ setMessage('Count is 1');
269
+ }, 500);
270
+ // eslint-disable-next-line react-hooks/exhaustive-deps
271
+ }, []); // <-- Empty array fixes the loop. Runs only once.
272
+ ```
273
+ - **Incorrect Code Example:**
274
+ ```
275
+ useEffect(() => {
276
+ fetchScenario();
277
+ }, [fetchScenario]); // Infinite initialize data.
278
+ ```
279
+ - **Correct Code Example:**
280
+ ```
281
+ useEffect(() => {
282
+ fetchScenario();
283
+ // eslint-disable-next-line react-hooks/exhaustive-deps
284
+ }, []); // Only initialize data once
285
+ ```
286
+ The correct code will very likely cause the `eslint-plugin-react-hooks` to raise a warning. Add `eslint-disable-next-line react-hooks/exhaustive-deps` to suppress the warning.
287
+ - **Be Explicit About Component Scope:**
288
+ - Ensure helper components are defined outside the main component function body to prevent re-rendering issues.
289
+ - Define components outside parent components to avoid unnecessary unmounting and remounting, which can lead to loss of input state and focus.
290
+ - **Incorrect Code Example:**
291
+ ```
292
+ function ParentComponent() {
293
+ const [text, setText] = useState('');
294
+ // !! BAD: ChildInput is defined INSIDE ParentComponent !!
295
+ const ChildInput: React.FC = () => {
296
+ return (
297
+ <input
298
+ type="text"
299
+ value={text} // Gets value from parent state
300
+ onChange={(e) => setText(e.target.value)} // Updates parent state
301
+ placeholder="Type here..."
302
+ className="border p-2"
303
+ />
304
+ );
305
+ };
306
+
307
+ return (
308
+ <div className="p-4 border border-red-500">
309
+ <h2 className="text-lg font-bold mb-2">Bad Example</h2>
310
+ <p className="mb-2">Parent State: {text}</p>
311
+ <ChildInput /> {/* Rendering the locally defined component */}
312
+ </div>
313
+ );
314
+ }
315
+ export default ParentComponent;
316
+ ```
317
+ - **Correct Code Example:**
318
+ ```
319
+ interface ChildInputProps {
320
+ value: string;
321
+ onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
322
+ }
323
+
324
+ const ChildInput: React.FC<ChildInputProps> = ({ value, onChange }) => {
325
+ return (
326
+ <input
327
+ type="text"
328
+ value={value} // Gets value from props
329
+ onChange={onChange} // Uses handler from props
330
+ placeholder="Type here..."
331
+ className="border p-2"
332
+ />
333
+ );
334
+ };
335
+
336
+ function ParentComponent() {
337
+ const [text, setText] = useState('');
338
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
339
+ setText(e.target.value);
340
+ };
341
+
342
+ return (
343
+ <div className="p-4 border border-green-500">
344
+ <h2 className="text-lg font-bold mb-2">Good Example</h2>
345
+ <p className="mb-2">Parent State: {text}</p>
346
+ {/* Pass state and handler down as props */}
347
+ <ChildInput value={text} onChange={handleInputChange} />
348
+ </div>
349
+ );
350
+ }
351
+
352
+ export default ParentComponent;
353
+ ```
354
+
355
+ ## Scripts
356
+
357
+ - `pnpm dev` - Start the development server
358
+ - `pnpm build` - Type check and build the application for production
359
+ - `pnpm lint` - Run ESLint on the codebase
360
+ - `pnpm preview` - Preview the production build locally
361
+
@@ -0,0 +1,23 @@
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+ import { defineConfig, globalIgnores } from 'eslint/config'
7
+
8
+ export default defineConfig([
9
+ globalIgnores(['dist']),
10
+ {
11
+ files: ['**/*.{ts,tsx}'],
12
+ extends: [
13
+ js.configs.recommended,
14
+ tseslint.configs.recommended,
15
+ reactHooks.configs.flat.recommended,
16
+ reactRefresh.configs.vite,
17
+ ],
18
+ languageOptions: {
19
+ ecmaVersion: 2020,
20
+ globals: globals.browser,
21
+ },
22
+ },
23
+ ])
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>my-vue-app</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "proto",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "tsc -b && vite build",
8
+ "lint": "eslint .",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "clsx": "^2.1.1",
13
+ "framer-motion": "^12.38.0",
14
+ "lucide-react": "^0.577.0",
15
+ "react": "^19.2.4",
16
+ "react-dom": "^19.2.4",
17
+ "react-router-dom": "^7.13.1",
18
+ "recharts": "^3.8.0",
19
+ "tailwind-merge": "^3.5.0"
20
+ },
21
+ "devDependencies": {
22
+ "@eslint/js": "^9.39.4",
23
+ "@tailwindcss/postcss": "^4.2.1",
24
+ "@types/node": "^24.12.0",
25
+ "@types/react": "^19.2.14",
26
+ "@types/react-dom": "^19.2.3",
27
+ "@vitejs/plugin-react": "^6.0.0",
28
+ "autoprefixer": "^10.4.27",
29
+ "eslint": "^9.39.4",
30
+ "eslint-plugin-react-hooks": "^7.0.1",
31
+ "eslint-plugin-react-refresh": "^0.5.2",
32
+ "globals": "^17.4.0",
33
+ "postcss": "^8.5.8",
34
+ "tailwindcss": "^4.2.1",
35
+ "typescript": "~5.9.3",
36
+ "typescript-eslint": "^8.56.1",
37
+ "vite": "^8.0.0"
38
+ }
39
+ }