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