# Design Document: Shell & Logs Feature Specification ## Overview Shell and Logs are real-time terminal and streaming views for Kubernetes resources. These features enable users to interact with running pods and monitor application behavior. ## Shell Terminal (kubectl exec) ### Requirements - **Implementation**: xterm.js on client - **Backend**: WebSocket → kubectl exec - **Protocol**: Bidirectional terminal protocol ### Terminal Configuration ```typescript { rows: 24, cols: 80, fontFamily: 'IBM Plex Mono', fontSize: 12, lineHeight: 1.5, cursorBlink: true, theme: { background: '#1a1e26', foreground: '#b9c6d8', } } ``` ### Connection Flow 1. User opens shell view 2. Extract pod name and namespace 3. Connect WebSocket to `/ws/shell?pod=X&ns=Y` 4. Backend: - Extract query params - Connect to k8s exec API - Create execstream - Proxy bidirectionally 5. Frontend: - Initialize xterm - Attach to WebSocket - Handle resize events - Route keypresses ### Key Routing - **Shell focused + type**: Route to terminal - **Canvas shortcuts disabled** when shell has focus - **Space key**: Goes to terminal (not spotlight) - **Ctrl/⌘+scroll**: Zoom canvas (not terminal zoom) ### Resize Handling - **Client**: term.resize(cols, rows) - **Server**: Send resize message via WebSocket - **Backend**: Update k8s exec term size - **Debounce**: 100ms for resize events ### State Management ```typescript interface ShellState { connected: boolean; connectedAt: number; lastActive: number; buffer: string[]; cols: number; rows: number; } ``` ### Error States - Connection failed: Show error message - Disconnected: Show "Disconnected" + reconnect button - Permission denied: Show clear error - Pod not found: Show error message ## Logs Viewer (kubectl logs) ### Requirements - **Implementation**: WebSocket streaming - **Auto-scroll**: To bottom by default - **Color coding**: ERROR/WARN/INFO ### Connection Flow 1. User opens logs view 2. Connect to `/ws/logs?pod=X&ns=Y` 3. Backend: - Start kubectl logs stream - Forward to WebSocket 4. Frontend: - Append lines to buffer - Auto-scroll if at bottom - Colorize based on level ### Log Parsing Each log line should include: - Timestamp - Log level (ERROR/WARN/INFO/DEBUG) - Message Format: ```typescript interface LogLine { timestamp: string; // ISO 8601 level: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'; message: string; } ``` ### Color Coding - **ERROR**: `#ef6f6f` - **WARN**: `#e8b54a` - **INFO**: `#b9c6d8` - **DEBUG**: `#6b7280` ### Auto-Scroll Logic - **Track scroll position**: Store `scrollTop` - **At bottom**: Auto-scroll on new log - **Scrolled up**: Don't auto-scroll - **Threshold**: Within 20px of bottom = "at bottom" ### User Controls - **Click auto-scroll toggle**: Switch between auto and manual scroll - **Clear logs**: Button to clear buffer - **Copy log line**: Right-click menu - **Filter**: Simple filtering (show/hide levels) ### State Management ```typescript interface LogsState { connected: boolean; autoScroll: boolean; logLines: LogLine[]; scrollPosition: number; filterLevels: Set; } ``` ### Streaming Considerations - **Backpressure**: Buffer if client slow - **Rate limiting**: Server can throttle logs - **Keep-alive**: Ping every 30s - **Reconnect**: Exponential backoff on disconnect ### Performance Optimization - **Virtualization**: Only render visible lines - **Batching**: Flush logs in batches if high volume - **Throttling**: 16ms throttle for updates - **Cleanup**: Remove old logs (keep last 1000 lines) ## Shared Features ### View State - Both views persist state in krate.window.state - reconnect: Auto reconnect on disconnect - timestamps: Show/hide timestamps - wrap: Word wrap toggle ### Tab Switching - Shell tab: Enabled for pods only - Logs tab: Enabled for pods/workloads - Empty state: Show helpful message for unsupported resources ### Close Behavior - Shell: Keep buffer, show "Disconnnected" - Logs: Stop streaming, keep buffer - Cleanup: Close WebSocket, cancel watchers ## WebSocket Protocol ### Shell ``` // Client → Server { type: 'shell:input', data: string // Key press data } { type: 'shell:resize', cols: number, rows: number } // Server → Client { type: 'shell:output', data: string // stdout/stderr } { type: 'shell:status', connected: boolean, message?: string } ``` ### Logs ``` // Client → Server { type: 'logs:subscribe', pod: string, namespace: string, follow: boolean, timestamps: boolean } { type: 'logs:filter', levels: string[] } // Server → Client { type: 'log', log: LogLine } { type: 'status', connected: boolean, message?: string } ``` ## Gotchas 1. **Space key**: Must distinguish between canvas pan and shell input 2. **Focus routing**: Route keys based on hovered window 3. **Scroll management**: Track scroll position for logs 4. **Terminal resize**: Debounce resize events 5. **Reconnection**: Handle WebSocket disconnects gracefully 6. **Memory**: Clean up old logs/shell buffers 7. **Authentication**: Validate user on WebSocket upgrade 8. **Permissions**: Enforce namespace RBAC on backend