Skip to content

Latest commit

 

History

History
177 lines (148 loc) · 6.02 KB

File metadata and controls

177 lines (148 loc) · 6.02 KB
# Project Context for Claude ## Project Overview Worktree Studio - A desktop application for managing Git worktrees built with Tauri, React, and TypeScript. ## Tech Stack - **Frontend**: React 19, TypeScript, Zustand - **Styling**: Tailwind CSS v4, shadcn/ui - **Desktop**: Tauri v2 - **Terminal**: xterm.js - **Icons**: Lucide React ## Tailwind CSS v4 Usage Guidelines ### Important: This project uses Tailwind CSS v4 Tailwind CSS v4 has significant changes from v3. Here are the key rules: #### 1. Configuration - **No `tailwind.config.js`**: Theme configuration is done in CSS using `@theme` directive - **Import syntax**: Use `@import "tailwindcss"` not `@tailwind` directives - **CSS-based config**: All theme values are defined in `src/styles.css` #### 2. Theme Variables - **Format**: Use space-separated RGB values (e.g., `229 229 229` not `#e5e5e5`) - **Usage in CSS**: `rgb(var(--color-name))` or `rgb(var(--color-name) / opacity)` - **Variable naming**: Use `--color-` prefix for colors Example: ```css @theme { --color-border: 229 229 229; --color-primary: 23 23 23; } ``` #### 3. Using Colors in Components - **Inline styles**: Use `style={{ color: 'rgb(var(--color-name))' }}` - **With opacity**: `style={{ backgroundColor: 'rgb(var(--color-name) / 0.5)' }}` - **Avoid**: Don't use Tailwind color classes like `bg-border` or `text-primary` directly #### 4. Dark Mode - Dark mode is enabled by default with `document.documentElement.classList.add('dark')` - Define dark mode colors within `.dark` selector in CSS - Variables automatically switch based on the `dark` class #### 5. Common Pitfalls to Avoid - L Don't use `tailwind.config.js` for theme configuration - L Don't use `@tailwind base/components/utilities` directives - L Don't use color classes without defining them in `@theme` - � Do use CSS variables for all theme values - � Do use inline styles with CSS variables for dynamic styling - � Do define all colors in the `@theme` block #### 6. Component Styling Pattern ```tsx // Preferred approach for dynamic styling
Content
// For hover effects { e.currentTarget.style.backgroundColor = 'rgb(var(--color-accent))'; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; }} > Button ``` ## Project Structure ``` src/ � components/ # React components � � ui/ # shadcn/ui components � � Sidebar.tsx # Main sidebar component � stores/ # Zustand stores � lib/ # Utilities (includes cn() helper) � styles.css # Global styles and Tailwind config � App.tsx # Main application component ``` ## Design System - **Dark mode by default** with support for light mode - **Color scheme**: Modern dark theme with accent colors - **Typography**: System fonts with -apple-system fallbacks - **Spacing**: Consistent padding and margins using Tailwind utilities - **Borders**: Subtle borders using border color variables - **Hover effects**: Smooth transitions with transform and color changes ## Component Guidelines 1. Use `cn()` utility from `@/lib/utils` for className merging 2. Prefer inline styles with CSS variables for dynamic theming 3. Add hover effects to all interactive elements 4. Maintain consistent spacing and alignment across components ## Development Commands ```bash npm run tauri dev # Run development server npm run build # Build for production npm run tauri build # Build desktop app ``` ## Tauri Command Parameter Naming Convention ### CRITICAL: Frontend ↔ Backend Parameter Naming When calling Tauri commands from React/TypeScript frontend to Rust backend: **✅ ALWAYS USE camelCase in frontend, snake_case in backend** ```typescript // ✅ CORRECT - Frontend (camelCase) await invoke('create_terminal', { request: { worktree_id: 'abc', // snake_case in nested objects name: 'Terminal 1', working_directory: '/path' } }); await invoke('write_to_terminal', { terminalId: 'abc123', // camelCase for direct parameters data: 'hello' }); ``` ```rust // ✅ CORRECT - Backend (snake_case) #[tauri::command] pub async fn write_to_terminal(terminal_id: String, data: String) -> Result<(), String> { // Tauri automatically converts terminalId → terminal_id } #[tauri::command] pub async fn create_terminal(request: CreateTerminalRequest) -> Result { // Nested struct fields use snake_case as defined } ``` **❌ COMMON MISTAKES:** ```typescript // ❌ WRONG - Don't use snake_case in frontend await invoke('write_to_terminal', { terminal_id: id, data }); // Will fail! // ❌ WRONG - Don't use camelCase in Rust backend pub async fn write_to_terminal(terminalId: String) // Will fail! ``` ### Parameter Patterns by Command Type: 1. **Simple Parameters**: Use camelCase in frontend, snake_case in backend - Frontend: `{ terminalId: 'abc', data: 'hello' }` - Backend: `fn command(terminal_id: String, data: String)` 2. **Nested Objects**: Use snake_case throughout (both frontend and backend) - Frontend: `{ request: { worktree_id: 'abc', working_directory: '/path' } }` - Backend: `struct Request { worktree_id: String, working_directory: String }` ### Why This Matters: - We've debugged this naming issue **multiple times** during terminal integration - Tauri automatically converts camelCase → snake_case but **only for direct parameters** - Wrong naming causes cryptic error messages like "missing required key terminalId" - This convention must be followed consistently across **all** Tauri commands ## Known Issues & Solutions 1. **CSS not loading**: Check that `@import "tailwindcss"` is at the top of styles.css 2. **Colors not working**: Ensure colors are defined in `@theme` block with RGB format 3. **Hover effects not smooth**: Add `transition-all` class to elements 4. **Tauri commands failing**: Check parameter naming follows camelCase (frontend) → snake_case (backend) convention