feat: migrate logging system to Winston with BigInt and rotation fixes#189
Closed
Saul-Gomez-J wants to merge 35 commits intolevante-hub:mainfrom
Closed
feat: migrate logging system to Winston with BigInt and rotation fixes#189Saul-Gomez-J wants to merge 35 commits intolevante-hub:mainfrom
Saul-Gomez-J wants to merge 35 commits intolevante-hub:mainfrom
Conversation
Problema:
- No se seleccionaba ningún modelo por defecto al crear chats nuevos
- El sistema permitía enviar peticiones sin modelo seleccionado
- Con muchos modelos configurados, el usuario debía seleccionar manualmente cada vez
Solución:
- Guardar el último modelo seleccionado en ui-preferences.json (lastUsedModel)
- Cargar automáticamente lastUsedModel al crear un nuevo chat
- Prevenir envío de mensajes sin modelo seleccionado:
* Botón de envío deshabilitado cuando no hay modelo
* Validación en handleSubmit antes de crear sesión
* Verificación de existencia del modelo en modelos disponibles
Beneficios:
- Mejor experiencia de usuario con modelo pre-seleccionado
- Previene errores al enviar sin modelo
- Reduce fricción en el flujo de trabajo
Archivos modificados:
- src/renderer/hooks/useModelSelection.ts
- src/renderer/pages/ChatPage.tsx
- src/renderer/components/chat/ChatPromptInput.tsx
…chat added auto-focus on new chat
## New Features ### Message Editing - Users can now edit their own messages in the chat - Edit button appears on hover below the message (outside the message container) - Inline editing with auto-resizing textarea (min 60px, max 300px height) - Cancel and Send buttons for edit actions - Editing a message triggers a new AI response with the updated content ### Copy to Clipboard - New copy button alongside the edit button - Allows users to quickly copy message content to clipboard ## UI/UX Improvements - Action buttons (copy, edit) appear on hover below user messages - Clean, minimal design matching the application style - Textarea auto-grows based on content length - Minimum width of 500px for better editing experience ## Technical Changes ### Frontend (Renderer) - `ChatMessageItem.tsx`: Added editing state, copy/edit buttons, inline textarea - `ChatPage.tsx`: Implemented `handleEditMessage` function - `chatStore.ts`: Added `editMessage` action with conversation branching logic - `prompt-input.tsx`: Minor adjustments for consistency ### Backend (Main Process) - `chatService.ts`: Added `editMessage` method with conversation history management - `databaseHandlers.ts`: New IPC handler for `levante/chat/edit-message` ### Preload & Types - `database.ts`: Added `editMessage` API method - `preload.ts`: Exposed `editMessage` in the bridge - `database.ts` (types): Added `EditMessageParams` interface 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show green check icon for 2 seconds after copying - Change tooltip to "Copied!" when copied - Smooth transition between icons 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
feat(chat): add message editing and copy functionality for user messages
Replace CSS field-sizing-content with JavaScript auto-resize since the CSS property is not supported in Electron's Chromium version. Changes: - Add useRef, useEffect, useCallback hooks for resize logic - Implement adjustHeight function that calculates height within bounds - Merge internal/external refs for proper ref forwarding - Update maxHeight default from 300px to 164px (~6 lines) - Add overflow-y-auto for internal scrolling at max height - Remove unsupported field-sizing-content CSS property The textarea now grows automatically as user types, stops at 164px showing internal scroll, and shrinks when text is deleted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…o-resize fix(chat): implement JavaScript-based auto-resize for textarea
Add the ability to enable/disable individual MCP tools from the chat UI, giving users fine-grained control over which tools are available to the AI. ## Features - **Tool Selection UI**: New dropdown in chat toolbar showing all MCP servers and their tools with checkboxes to enable/disable each one - **Server Toggle**: Enable/disable entire MCP servers with real connection management (not just config changes) - **Performance Warning**: Alert when >40 tools enabled, error when >80 - **Persistence**: Tool preferences saved to ui-preferences.json - **Real-time Updates**: Listen for MCP tools/list_changed notifications ## Architecture ### Data Model (Negative List Pattern) - Only disabled tools are stored in `disabledTools[serverId][]` - New tools are enabled by default - Compact storage, follows Claude Desktop pattern ### IPC Handlers (src/main/ipc/mcpHandlers/tools.ts) - `get-tools-cache`: Get cached tools without reconnecting - `get-disabled-tools`: Get disabled tools map - `toggle-tool`: Toggle individual tool - `toggle-all-tools`: Toggle all tools for a server - `clear-server-tools`: Cleanup on server removal ### AI Integration (src/main/services/ai/mcpToolsAdapter.ts) - `getMCPTools()` now accepts `disabledTools` parameter - Filters out disabled tools before passing to AI model - Logs show disabled tool count for debugging ### Store (src/renderer/stores/mcpStore.ts) - New state: `toolsCache`, `disabledTools`, `loadingTools` - Actions: `toggleTool`, `toggleAllTools`, `isToolEnabled`, etc. - `enableServer`/`disableServer` now properly connect/disconnect ## UI Components - **ToolsMenu**: Redesigned with two dropdowns (settings + tools) - **ToolsWarning**: Performance warning component - **ToolSelector**: Reusable tool selection component - **useMCPEvents**: Hook for MCP event handling ## Translations Added complete translations (EN/ES) for: - chat.json: tools_menu.* keys - settings.json: mcp_tools.* keys 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Convert denied tools to output-available state in sanitizeMessagesForModel to generate valid tool_result for Anthropic (fixes 500 error) - Replace lastAssistantMessageIsCompleteWithApprovalResponses with custom sendAutomaticallyWhen that only triggers for approvals, not denials (fixes infinite loop) - Update tool-approval-flow-explained.md with complete denial flow documentation The deny flow now: 1. User clicks Deny → sendAutomaticallyWhen returns false → no new call 2. If user continues conversation → denial converted to tool_result 3. Anthropic receives valid message structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove console.log statements added during debugging: - ElectronChatTransport.ts: FLOW-5, FLOW-6, FLOW-7, FLOW-8 logs - ChatMessageItem.tsx: FLOW-13, FLOW-14 logs The structured logger.aiSdk.debug calls are preserved as they are part of the logging system and can be toggled via DEBUG_AI_SDK env var. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…nable-disable feat(mcp): add individual tool enable/disable functionality
- Remove yellow card container and header from ToolApprovalInline - Add translations for tool approval (EN/ES) - Use useTranslation hook for all user-facing strings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove outdated documentation files and keep single comprehensive guide: - Remove tool-approval-deep-dive.md - Remove tool-approval-error-diagnostic.md - Remove tool-approval-implementation-plan.md - Remove tool-approval-status.md - Remove tool-execution-flow.md All information is now consolidated in tool-approval-flow-explained.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add useToolAutoApproval hook for per-session server auto-approval - Add "Approve for session" button to tool approval UI - Auto-approve tools from pre-approved servers automatically - Update tool-approval-flow-explained.md with accurate line references - Add i18n support for new approval button (en/es) - Clear auto-approvals when changing chat sessions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change from dynamic import() to static import for mcp-use - Remove module-level variables (MCPClient, MCPLogger) - Simplify initialize() to only configure Logger This fixes IPC handler registration errors that occurred when mcp-use was bundled with Vite (commit 74691fd). The dynamic import pattern was designed for external modules but fails with bundled code. Benefits: - Maintains optimized bundle size (~128MB vs ~489MB) - Fixes missing handlers: levante/mcp/get-tools-cache, get-disabled-tools - Only winston remains external (required for Logger.configure()) Bundle analysis: - mcp-use: bundled by Vite - winston: external (runtime dependency) - Total DMG: 128MB (-74% from original) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Update mcp-use dependency to latest version (1.13.4)
- Adapt Logger.configure() to new API (removed 'console' option)
- Use level: 'error' and format: 'minimal' for quiet logging
Breaking changes in mcp-use Logger API:
- Removed: { console: boolean }
- Added: { level?: LogLevel, format?: 'minimal' | 'detailed' | 'emoji' }
Version compatibility:
- mcp-use 1.13.4 uses @modelcontextprotocol/sdk 1.25.1 (matches our direct dependency)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Resolved all open security vulnerabilities: - Update @modelcontextprotocol/sdk 1.25.1 → 1.25.2 (ReDoS fix) - Force react-router ≥7.12.0 (XSS and CSRF fixes) - Force tar ≥7.5.3 (dev-only, path traversal fix) - Remove unnecessary jsondiffpatch override - Fix broken @modelcontextprotocol/sdk override (^1.24.3 → 1.25.2 exact) Fixes alerts: levante-hub#22, levante-hub#24, levante-hub#25, levante-hub#26, levante-hub#27, levante-hub#28, levante-hub#29, levante-hub#30, levante-hub#31 Changes: - Update @modelcontextprotocol/sdk to ^1.25.2 - Add react-router: >=7.12.0 override - Add tar: >=7.5.3 override - Fix @modelcontextprotocol/sdk override to exact version 1.25.2 - Remove jsondiffpatch override (package not installed) Verified: typecheck passes, all vulnerable packages at secure versions Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ol-execution2 feat(approval): Tool Approval System with Session-based Auto-approval
fix: seleccionar último modelo usado por defecto en chats nuevos
…c-import fix: resolve security vulnerabilities and optimize mcp-use integration
- Add .mcp.json and .claude/ to .gitignore - Remove files from git tracking while preserving local copies - Ensures user-specific Claude Code settings remain local Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…menu Improves UX by organizing MCP servers into 'Enabled' and 'Disabled' tabs, with enabled servers shown by default. Users can switch to the disabled tab to re-enable servers as needed. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Resolves levante-hub#158 The title generation for new chats was blocking the entire flow, causing a 3-5 second delay before redirecting to the chat page. Changes: - Title generation now runs in background (fire-and-forget) - Redirect happens immediately after message persistence - Title updates asynchronously when ready - Added error handling for background title generation Impact: - Chat creation feels instant - Better perceived performance - Title appears 1-2 seconds later without blocking UX Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- ai: 6.0.3 → 6.0.39 - @ai-sdk/anthropic: 3.0.1 → 3.0.15 - @ai-sdk/gateway: 3.0.2 → 3.0.16 - @ai-sdk/google: 3.0.1 → 3.0.10 - @ai-sdk/openai: 3.0.1 → 3.0.12 - @ai-sdk/openai-compatible: 2.0.1 → 2.0.13 - @ai-sdk/react: 3.0.3 → 3.0.41 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The ToolsMenu was displaying "No MCP servers configured" even when servers were connected and functioning. This happened because the MCP store state (activeServers, connectionStatus) was only loaded when visiting the Store page. Changes: - Load MCP state on app startup in useMCPEvents hook - Add periodic refresh of connection status (30s interval) - Remove duplicate connection refresh interval in store-layout This ensures the ToolsMenu shows accurate server status from app start. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Some MCP servers only implement structuredContent (MCP spec 2025-06-18) without providing the legacy content field. This caused responses to appear empty in the UI. Now both MCP service implementations prioritize structuredContent as the primary data source and fall back to content for backward compatibility. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds optional displayName field to MCP integrations to show user-friendly names in the UI while maintaining technical names for API compatibility. - Add displayName field to LevanteAPIServer and MCPRegistryEntry types - Map displayName from API responses in MCPProviderService - Update UI components to display displayName with fallback to name - Use technical name for server config to avoid special characters in APIs - Include displayName in search queries for better discoverability - Update AI tools to search and display using displayName This allows integrations like "Buscador_de_vuelos_navidenos" to be shown as "Buscador de vuelos navideños" while keeping API-safe names in configs. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…sion feat: add displayName support for user-friendly MCP integration names
## Summary Migrated Levante's custom logging system (420 lines) to Winston logger while maintaining 100% backward compatibility and zero overhead for disabled categories. ## Key Changes ### New Files - `src/main/services/logging/winstonConfig.ts` - Winston transport configuration - `src/main/services/logging/timezoneFormat.ts` - Timezone support (extracted from transports.ts) - `docs/testing/winston-migration-testing.md` - Comprehensive testing guide - `scripts/test-winston-logging.ts` - Automated testing script ### Modified Files - `src/main/services/logging/logger.ts` - Replaced custom transports with Winston logger - `src/main/services/logging/config.ts` - Added production/development defaults - `src/main/services/logging/index.ts` - Updated exports - `package.json` - Added winston-daily-rotate-file dependency ### Removed Files - `src/main/services/logging/transports.ts` - Replaced by Winston transports (420 lines removed) ## Features ### Production vs Development **Development** (NODE_ENV=development): - Console output with colors - Debug level logging - Verbose categories enabled (ai-sdk, mcp, database, oauth) - Single file: levante-YYYY-MM-DD-HHmmss.log - Rotation: 10MB, 3 files, 7 days **Production** (NODE_ENV=production): - No console output (file only) - Warn level logging - Verbose categories disabled - Two files: all logs + error-only log - Rotation: 50MB, 10 files, 30 days - Gzip compression enabled ### Preserved Features ✅ Zero overhead for disabled categories ✅ 9 categories (ai-sdk, mcp, database, ipc, preferences, models, core, analytics, oauth) ✅ Environment variable configuration ✅ Timezone support ✅ IPC bridge (renderer → main) ✅ Same public API (no breaking changes) ### New Capabilities ✨ Structured JSON logs (production) ✨ Separate error log file (production) ✨ Battle-tested Winston transports ✨ Automatic gzip compression ✨ Winston audit files for rotation tracking ✨ Foundation for future log viewer UI ## Code Impact - Lines added: ~350 - Lines removed: ~420 - Net reduction: ~70 lines - Breaking changes: 0 ## Documentation - Updated `docs/LOGGING.md` with "Arquitectura Winston" section - Updated `CLAUDE.md` logging section - Added comprehensive testing guide ## Testing - ✅ Typecheck passes - ✅ Zero overhead verified - ✅ Backward compatible API - Manual testing required per testing guide Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## Bloqueantes Corregidos 1. **Console colorization**: Moved `colorize()` before `printf()` to enable ANSI colors in development console logs 2. **Type safety**: Removed unnecessary `any` cast for `initializeFromEnvironment()` 3. **Error handling**: Added try-catch with rollback in `configure()` and `refresh()` to prevent broken logger state ## Mejora Opcional - **Development file format**: Use human-readable format (without ANSI colors) for log files in development mode ## Files Changed - `src/main/services/logging/winstonConfig.ts` - Fix colorize order + dev file format - `src/main/services/logging/logger.ts` - Fix type cast + error handling ## Testing - ✅ Console logs now show colors in development - ✅ Logger remains functional if reconfiguration fails - ✅ Typecheck passes Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## Fixes ### 1. BigInt Serialization Error **Problem**: SQLite returns `lastInsertRowid` as BigInt, which cannot be serialized to JSON by Winston, causing "Do not know how to serialize a BigInt" errors. **Root Cause**: Bug introduced in commit 98c443c when migrating from console.log (handles BigInt natively) to structured logging (uses JSON.stringify). **Solution**: - Convert BigInt to String in databaseService.ts before logging - Remove `fullResult` logging in chatStore.ts that contained BigInt **Files Changed**: - `src/main/services/databaseService.ts` - Convert lastInsertRowid to String - `src/renderer/stores/chatStore.ts` - Remove fullResult from error logs ### 2. Excessive Log Rotation **Problem**: Logs were rotating every second, creating hundreds of tiny files (levante-2026-01-28-205641.log, levante-2026-01-28-205647.log, etc.) **Root Cause**: datePattern 'YYYY-MM-DD-HHmmss' includes seconds, causing winston-daily-rotate-file to rotate whenever the second changes. **Solution**: - Changed datePattern from 'YYYY-MM-DD-HHmmss' to 'YYYY-MM-DD' - Now creates 1 file per day instead of per second **Files Changed**: - `src/main/services/logging/config.ts` - Update datePattern to daily rotation ## Testing - ✅ No BigInt serialization errors - ✅ Logs rotate daily (1 file per day) - ✅ All log categories working (AI-SDK, DATABASE, CORE, MCP) - ✅ JSON formatting correct with indentation - ✅ No ANSI colors in log files - ✅ Winston audit system tracking files correctly ## Impact - Eliminates BigInt serialization crashes - Reduces file system clutter (1 file/day vs hundreds) - Maintains all Winston logging benefits Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Contributor
Author
|
Closing to recreate against develop branch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎯 Resumen
Migración completa del sistema de logging custom a Winston con correcciones críticas de BigInt serialization y rotación excesiva de archivos.
🚀 Cambios Principales
✅ Migración a Winston (Commits anteriores)
🐛 Fix: BigInt Serialization Error (Este PR)
Problema:
Causa: SQLite devuelve
lastInsertRowidcomo BigInt. Winston usaJSON.stringifyque no puede serializar BigInt nativamente.Solución:
fullResultque contenía BigIntArchivos modificados:
src/main/services/databaseService.ts- Conversión de lastInsertRowidsrc/renderer/stores/chatStore.ts- Eliminación de fullResult🐛 Fix: Rotación Excesiva de Logs (Este PR)
Problema:
Causa:
datePattern: 'YYYY-MM-DD-HHmmss'incluye segundos, causando rotación cada segundo.Solución: Cambiar a
datePattern: 'YYYY-MM-DD'→ 1 archivo por díaArchivos modificados:
src/main/services/logging/config.ts- Actualización de datePattern📊 Impacto
🧪 Testing Realizado
✅ Verificaciones
📝 Ejemplo de Log
📁 Archivos Modificados
Este PR (3 archivos)
src/main/services/databaseService.ts- BigInt fixsrc/main/services/logging/config.ts- Rotation fixsrc/renderer/stores/chatStore.ts- Error logging cleanupPR Original Winston Migration
src/main/services/logging/winstonConfig.ts(nuevo)src/main/services/logging/logger.ts(refactor)src/main/services/logging/config.ts(actualizado)🔗 Enlaces Relacionados
docs/LOGGING.mddocs/testing/winston-migration-testing.md✅ Checklist de Revisión
📝 Notas Adicionales
Historia del Bug BigInt:
Decisión de diseño - Rotación diaria:
YYYY-MM-DD(1 archivo/día)YYYY-MM-DD(1 archivo/día)maxSize(10MB dev, 50MB prod)🤖 Generated with Claude Code