first
This commit is contained in:
246
client/CLAUDE.md
Normal file
246
client/CLAUDE.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# CLAUDE.md — Mesh Client
|
||||
|
||||
This file provides client-specific guidance for the Mesh web application.
|
||||
|
||||
## Client Role
|
||||
|
||||
The Mesh Client is a web application (React/TypeScript) that provides:
|
||||
- User interface for chat, audio/video calls, screen sharing
|
||||
- **WebRTC media plane**: Direct P2P audio/video/screen connections
|
||||
- WebSocket connection to server for control plane
|
||||
- Integration with desktop agent for advanced features
|
||||
|
||||
**Critical**: The client handles WebRTC media directly (P2P). File/folder/terminal sharing is delegated to the desktop agent via QUIC.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **React 18** with TypeScript
|
||||
- **Vite** for build tooling
|
||||
- **React Router** for navigation
|
||||
- **TanStack Query** for server state management
|
||||
- **Zustand** for client state management
|
||||
- **simple-peer** for WebRTC abstraction
|
||||
- **Monokai-inspired dark theme**
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
client/
|
||||
├── src/
|
||||
│ ├── main.tsx # App entry point
|
||||
│ ├── App.tsx # Main app component
|
||||
│ ├── pages/
|
||||
│ │ ├── Login.tsx # Login page
|
||||
│ │ └── Room.tsx # Main room interface
|
||||
│ ├── components/
|
||||
│ │ ├── Chat/ # Chat components
|
||||
│ │ ├── Video/ # Video call components
|
||||
│ │ ├── Participants/ # Participant list
|
||||
│ │ └── Controls/ # Call controls
|
||||
│ ├── lib/
|
||||
│ │ ├── websocket.ts # WebSocket client
|
||||
│ │ ├── webrtc.ts # WebRTC manager
|
||||
│ │ └── events.ts # Event handlers
|
||||
│ ├── stores/
|
||||
│ │ ├── authStore.ts # Auth state
|
||||
│ │ ├── roomStore.ts # Room state
|
||||
│ │ └── callStore.ts # Call state
|
||||
│ ├── hooks/
|
||||
│ │ ├── useWebSocket.ts # WebSocket hook
|
||||
│ │ └── useWebRTC.ts # WebRTC hook
|
||||
│ ├── types/
|
||||
│ │ └── events.ts # Event type definitions
|
||||
│ └── styles/
|
||||
│ ├── global.css # Global styles
|
||||
│ └── theme.css # Monokai theme
|
||||
├── public/
|
||||
├── index.html
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── vite.config.ts
|
||||
└── CLAUDE.md
|
||||
```
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Setup
|
||||
```bash
|
||||
cd client
|
||||
npm install
|
||||
# or
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Run Development Server
|
||||
```bash
|
||||
npm run dev
|
||||
# Opens at http://localhost:3000
|
||||
```
|
||||
|
||||
### Build for Production
|
||||
```bash
|
||||
npm run build
|
||||
# Output in dist/
|
||||
```
|
||||
|
||||
### Type Checking
|
||||
```bash
|
||||
npm run type-check
|
||||
```
|
||||
|
||||
### Linting
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
## Design System - Monokai Dark Theme
|
||||
|
||||
The UI uses a Monokai-inspired color palette defined in [src/styles/theme.css](src/styles/theme.css):
|
||||
|
||||
**Colors**:
|
||||
- Background Primary: `#272822`
|
||||
- Background Secondary: `#1e1f1c`
|
||||
- Text Primary: `#f8f8f2`
|
||||
- Accent Primary (cyan): `#66d9ef`
|
||||
- Accent Success (green): `#a6e22e`
|
||||
- Accent Warning (orange): `#fd971f`
|
||||
- Accent Error (pink): `#f92672`
|
||||
|
||||
**Typography**:
|
||||
- System font stack with fallbacks
|
||||
- `Fira Code` for code/monospace elements
|
||||
|
||||
## WebSocket Integration
|
||||
|
||||
The client maintains a persistent WebSocket connection to the server for control plane events.
|
||||
|
||||
**Connection flow**:
|
||||
1. Authenticate with JWT (obtained from login)
|
||||
2. Send `system.hello` with peer type and version
|
||||
3. Receive `system.welcome` with assigned `peer_id`
|
||||
4. Join room with `room.join`
|
||||
5. Listen for events and send messages
|
||||
|
||||
See [protocol_events_v_2.md](../protocol_events_v_2.md) for complete event protocol.
|
||||
|
||||
**Key events to handle**:
|
||||
- `system.welcome` - Store peer_id
|
||||
- `room.joined` - Update participant list
|
||||
- `chat.message.created` - Display message
|
||||
- `rtc.offer/answer/ice` - WebRTC signaling
|
||||
- `presence.update` - Update participant status
|
||||
|
||||
## WebRTC Implementation
|
||||
|
||||
**Call flow**:
|
||||
1. Request capability token from server (via REST API)
|
||||
2. Create local media stream (`getUserMedia`)
|
||||
3. Create peer connection with ICE servers
|
||||
4. Send `rtc.offer` with capability token
|
||||
5. Receive `rtc.answer`
|
||||
6. Exchange ICE candidates via `rtc.ice`
|
||||
7. Connection established, media flows P2P
|
||||
|
||||
**Screen sharing**:
|
||||
- Use `getDisplayMedia` instead of `getUserMedia`
|
||||
- Same signaling flow with screen capability token
|
||||
|
||||
**Important**:
|
||||
- Always include capability token in WebRTC signaling messages
|
||||
- Handle ICE connection failures gracefully
|
||||
- Implement reconnection logic
|
||||
- Clean up media streams on disconnect
|
||||
|
||||
## State Management
|
||||
|
||||
**Zustand stores**:
|
||||
|
||||
```typescript
|
||||
// authStore.ts
|
||||
{
|
||||
user: User | null,
|
||||
token: string | null,
|
||||
peerId: string | null,
|
||||
login: (username, password) => Promise<void>,
|
||||
logout: () => void
|
||||
}
|
||||
|
||||
// roomStore.ts
|
||||
{
|
||||
currentRoom: Room | null,
|
||||
participants: Participant[],
|
||||
messages: Message[],
|
||||
joinRoom: (roomId) => void,
|
||||
sendMessage: (content) => void
|
||||
}
|
||||
|
||||
// callStore.ts
|
||||
{
|
||||
activeCall: Call | null,
|
||||
localStream: MediaStream | null,
|
||||
remoteStreams: Map<peerId, MediaStream>,
|
||||
startCall: (peerId, type) => Promise<void>,
|
||||
endCall: () => void
|
||||
}
|
||||
```
|
||||
|
||||
## Component Guidelines
|
||||
|
||||
1. **Functional components with TypeScript**
|
||||
2. **Use hooks for side effects and state**
|
||||
3. **CSS Modules for component-scoped styles**
|
||||
4. **Semantic HTML**
|
||||
5. **Accessibility**: ARIA labels, keyboard navigation
|
||||
6. **Error boundaries** for graceful error handling
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- **Never store JWT in localStorage** (use httpOnly cookies or memory)
|
||||
- **Validate all incoming WebSocket messages**
|
||||
- **Sanitize user-generated content** (messages, usernames)
|
||||
- **Verify WebRTC fingerprints** (optional, V1+)
|
||||
- **No sensitive data in console logs**
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
- **Lazy load routes** with React.lazy
|
||||
- **Virtualize long lists** (messages, participants)
|
||||
- **Debounce input handlers**
|
||||
- **Memoize expensive computations** (useMemo)
|
||||
- **Avoid unnecessary re-renders** (React.memo)
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
1. **Unit tests**: Components, hooks, utilities
|
||||
2. **Integration tests**: WebSocket flows, WebRTC signaling
|
||||
3. **E2E tests**: Complete user journeys (login, join room, send message, call)
|
||||
|
||||
## Browser Support
|
||||
|
||||
- **Chrome/Edge**: 90+
|
||||
- **Firefox**: 88+
|
||||
- **Safari**: 15+
|
||||
|
||||
WebRTC requires modern browsers. Provide warning for unsupported browsers.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Create `.env.local` for development:
|
||||
|
||||
```
|
||||
VITE_API_URL=http://localhost:8000
|
||||
VITE_WS_URL=ws://localhost:8000/ws
|
||||
```
|
||||
|
||||
## Build & Deployment
|
||||
|
||||
The client builds to static files that can be served via:
|
||||
- Nginx/Caddy
|
||||
- CDN (CloudFront, Cloudflare)
|
||||
- Docker container with nginx
|
||||
|
||||
**Important**: Configure CORS on the server to allow client origin.
|
||||
|
||||
---
|
||||
|
||||
**Remember**: The client handles only WebRTC media (audio/video/screen) in P2P mode. File/folder/terminal sharing requires the desktop agent.
|
||||
Reference in New Issue
Block a user