Commit Graph

760 Commits

  • fix(ui): use semantic color tokens for text foreground
    - Replace hardcoded gray-900/gray-100 with text-foreground in EndpointSpeedTest
    - Add text-foreground class to Input component for consistent theming
    - Ensures proper text color in both light and dark modes
  • fix(misc): improve CLI version detection with path scanning
    - Extract version helper to parse semver from raw output
    - Add fallback path scanning when direct execution fails
    - Scan common npm global paths: .npm-global, .local/bin, homebrew
    - Support nvm by scanning all node versions under ~/.nvm/versions/node
    - Add platform-specific paths for macOS, Linux, and Windows
    - Ensure node is in PATH when executing CLI tools from scanned paths
  • Security fixes javascript executor and usage script (#151)
    * dependencies: url
    
    * fix: comprehensive security improvements for usage script execution
    
    🛡️ Security Fixes:
    - Implement robust SSRF protection with same-origin URL validation
    - Add precise IP address validation for IPv4/IPv6 private networks
    - Fix port comparison to handle default ports correctly (443/80)
    - Remove hardcoded domain whitelist, support custom domains flexibly
    - Add comprehensive input validation and hostname security checks
    
    🔧 Technical Improvements:
    - Replace string-based IP checks with proper IpAddr parsing
    - Use port_or_known_default() for accurate port validation
    - Add comprehensive unit tests covering edge cases
    - Implement CIDR-compliant private IP detection (RFC1918)
    - Fix IPv6 address validation to prevent false positives
    
    📊 Fixed Issues:
    - Prevent access to private IP addresses while allowing public services
    - Support Cloudflare (172.67.x.x) and other public 172.x.x.x ranges
    - Fix port matching between explicit (e.g., :443) and implicit (default) ports
    - Resolve IPv6 false positives for addresses containing ::1 substrings
    - Maintain backward compatibility with existing script usage patterns
    
     Testing:
    - Add comprehensive test suite for IP validation (IPv4/IPv6)
    - Add port comparison tests for various scenarios
    - Add edge case tests for CIDR boundaries
    - All tests passing, ensuring no regressions
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * fix: add is_loopback_host for proper localhost validation
    
    * fix: use Database::memory() in tests
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
  • Feat/skill multi app migration (#378)
    * feat(skill): add database migration and Gemini support for multi-app skills
    
    - Refactor skills table from single key to (directory, app_type) composite primary key
    - Add migration logic to convert existing skill records
    - Support skill installation/uninstallation for Claude/Codex/Gemini independently
    - Add new Tauri commands: get_skills_for_app, install_skill_for_app, uninstall_skill_for_app
    - Update frontend API and components to support app-specific skill operations
    
    * fix(usage): correct cache token column order in request log table
    
    - Swap cache read and cache creation columns to match data binding
    - Add whitespace-nowrap to all table headers for better display
  • fix(misc): use correct npm package for Codex CLI version check
    - Change Codex version source from GitHub `openai/openai-python` to npm `@openai/codex`
    - Remove unused `fetch_github_latest_release` helper function
    - All three tools (Claude, Codex, Gemini) now consistently use npm registry
  • Feat/auto failover (#367)
    * feat(db): add circuit breaker config table and provider proxy target APIs
    
    Add database support for auto-failover feature:
    
    - Add circuit_breaker_config table for storing failover thresholds
    - Add get/update_circuit_breaker_config methods in proxy DAO
    - Add reset_provider_health method for manual recovery
    - Add set_proxy_target and get_proxy_targets methods in providers DAO
      for managing multi-provider failover configuration
    
    * feat(proxy): implement circuit breaker and provider router for auto-failover
    
    Add core failover logic:
    
    - CircuitBreaker: Tracks provider health with three states:
      - Closed: Normal operation, requests pass through
      - Open: Circuit broken after consecutive failures, skip provider
      - HalfOpen: Testing recovery with limited requests
    - ProviderRouter: Routes requests across multiple providers with:
      - Health tracking and automatic failover
      - Configurable failure/success thresholds
      - Auto-disable proxy target after reaching failure threshold
      - Support for manual circuit breaker reset
    - Export new types in proxy module
    
    * feat(proxy): add failover Tauri commands and integrate with forwarder
    
    Expose failover functionality to frontend:
    
    - Add Tauri commands: get_proxy_targets, set_proxy_target,
      get_provider_health, reset_circuit_breaker,
      get/update_circuit_breaker_config, get_circuit_breaker_stats
    - Register all new commands in lib.rs invoke handler
    - Update forwarder with improved error handling and logging
    - Integrate ProviderRouter with proxy server startup
    - Add provider health tracking in request handlers
    
    * feat(frontend): add failover API layer and TanStack Query hooks
    
    Add frontend data layer for failover management:
    
    - Add failover.ts API: Tauri invoke wrappers for all failover commands
    - Add failover.ts query hooks: TanStack Query mutations and queries
      - useProxyTargets, useProviderHealth queries
      - useSetProxyTarget, useResetCircuitBreaker mutations
      - useCircuitBreakerConfig query and mutation
    - Update queries.ts with provider health query key
    - Update mutations.ts to invalidate health on provider changes
    - Add CircuitBreakerConfig and ProviderHealth types
    
    * feat(ui): add auto-failover configuration UI and provider health display
    
    Add comprehensive UI for failover management:
    
    Components:
    - ProviderHealthBadge: Display provider health status with color coding
    - CircuitBreakerConfigPanel: Configure failure/success thresholds,
      timeout duration, and error rate limits
    - AutoFailoverConfigPanel: Manage proxy targets with drag-and-drop
      priority ordering and individual enable/disable controls
    - ProxyPanel: Integrate failover tabs for unified proxy management
    
    Provider enhancements:
    - ProviderCard: Show health badge and proxy target indicator
    - ProviderActions: Add "Set as Proxy Target" action
    - EditProviderDialog: Add is_proxy_target toggle
    - ProviderList: Support proxy target filtering mode
    
    Other:
    - Update App.tsx routing for settings integration
    - Update useProviderActions hook with proxy target mutation
    - Fix ProviderList tests for updated component API
    
    * fix(usage): stabilize date range to prevent infinite re-renders
    
    * feat(backend): add tool version check command
    
    Add get_tool_versions command to check local and latest versions of
    Claude, Codex, and Gemini CLI tools:
    
    - Detect local installed versions via command line execution
    - Fetch latest versions from npm registry (Claude, Gemini)
      and GitHub releases API (Codex)
    - Return comprehensive version info including error details
      for uninstalled tools
    - Register command in Tauri invoke handler
    
    * style(ui): format accordion component code style
    
    Apply consistent code formatting to accordion component:
    - Convert double quotes to semicolons at line endings
    - Adjust indentation to 2-space standard
    - Align with project code style conventions
    
    * refactor(providers): update provider card styling to use theme tokens
    
    Replace hardcoded color classes with semantic design tokens:
    - Use bg-card, border-border, text-card-foreground instead of glass-card
    - Replace gray/white color literals with muted/foreground tokens
    - Change proxy target indicator color from purple to green
    - Improve hover states with border-border-active
    - Ensure consistent dark mode support via CSS variables
    
    * refactor(proxy): simplify auto-failover config panel structure
    
    Restructure AutoFailoverConfigPanel for better integration:
    - Remove internal Card wrapper and expansion toggle (now handled by parent)
    - Extract enabled state to props for external control
    - Simplify loading state display
    - Clean up redundant CardHeader/CardContent wrappers
    - ProxyPanel: reduce complexity by delegating to parent components
    
    * feat(settings): enhance settings page with accordion layout and tool versions
    
    Major settings page improvements:
    
    AboutSection:
    - Add local tool version detection (Claude, Codex, Gemini)
    - Display installed vs latest version comparison with visual indicators
    - Show update availability badges and environment check cards
    
    SettingsPage:
    - Reorganize advanced settings into collapsible accordion sections
    - Add proxy control panel with inline status toggle
    - Integrate auto-failover configuration with accordion UI
    - Add database and cost calculation config sections
    
    DirectorySettings & WindowSettings:
    - Minor styling adjustments for consistency
    
    settings.ts API:
    - Add getToolVersions() wrapper for new backend command
    
    * refactor(usage): restructure usage dashboard components
    
    Comprehensive usage statistics panel refactoring:
    
    UsageDashboard:
    - Reorganize layout with improved section headers
    - Add better loading states and empty state handling
    
    ModelStatsTable & ProviderStatsTable:
    - Minor styling updates for consistency
    
    ModelTestConfigPanel & PricingConfigPanel:
    - Simplify component structure
    - Remove redundant Card wrappers
    - Improve form field organization
    
    RequestLogTable:
    - Enhance table layout with better column sizing
    - Improve pagination controls
    
    UsageSummaryCards:
    - Update card styling with semantic tokens
    - Better responsive grid layout
    
    UsageTrendChart:
    - Refine chart container styling
    - Improve legend and tooltip display
    
    * chore(deps): add accordion and animation dependencies
    
    Package updates:
    - Add @radix-ui/react-accordion for collapsible sections
    - Add cmdk for command palette support
    - Add framer-motion for enhanced animations
    
    Tailwind config:
    - Add accordion-up/accordion-down animations
    - Update darkMode config to support both selector and class
    - Reorganize color and keyframe definitions for clarity
    
    * style(app): update header and app switcher styling
    
    App.tsx:
    - Replace glass-header with explicit bg-background/80 backdrop-blur
    - Update navigation button container to use bg-muted
    
    AppSwitcher:
    - Replace hardcoded gray colors with semantic muted/foreground tokens
    - Ensure consistent dark mode support via CSS variables
    - Add group class for better hover state transitions
  • feat(skill): add multi-app skill support for Claude/Codex (#365)
    * feat(skill): add multi-app skill support for Claude/Codex/Gemini
    
    - Add app-specific skill management with AppType prefix in skill keys
    - Implement per-app skill tracking in database schema
    - Add get_skills_for_app command to retrieve skills by application
    - Update SkillsPage to support app-specific skill loading with initialApp prop
    - Parse app parameter and validate against supported app types
    - Maintain backward compatibility with default claude app
    
    * fix(usage): reorder cache columns and prevent header text wrapping
    
    - Swap cache read and cache write columns order
    - Add whitespace-nowrap to all table headers to prevent text wrapping
    - Improves table readability and layout consistency
  • fix(skill): use directory basename for skill installation path (#358)
    Extract last segment from skill directory path to prevent nested directory
    issues during install/uninstall operations. For example, "skills/codex" now
    correctly installs to "codex" instead of creating nested "skills/codex" path.
  • fix(windows): use system titlebar to prevent black screen on startup
    The `titleBarStyle: "Overlay"` setting in tauri.conf.json causes black
    screen and crash on Windows due to WebView2 compatibility issues.
    
    Add platform-specific config `tauri.windows.conf.json` to override
    titleBarStyle to "Visible" on Windows while keeping the overlay style
    on macOS for the immersive UI experience.
    
    Fixes black screen issue on Windows for v3.8.x releases.
  • Feat/proxy server (#355)
    * feat(proxy): implement local HTTP proxy server with multi-provider failover
    
    Add a complete HTTP proxy server implementation built on Axum framework,
    enabling local API request forwarding with automatic provider failover
    and load balancing capabilities.
    
    Backend Implementation (Rust):
    - Add proxy server module with 7 core components:
      * server.rs: Axum HTTP server lifecycle management (start/stop/status)
      * router.rs: API routing configuration for Claude/OpenAI/Gemini endpoints
      * handlers.rs: Request/response handling and transformation
      * forwarder.rs: Upstream forwarding logic with retry mechanism (652 lines)
      * error.rs: Comprehensive error handling and HTTP status mapping
      * types.rs: Shared types (ProxyConfig, ProxyStatus, ProxyServerInfo)
      * health.rs: Provider health check infrastructure
    
    Service Layer:
    - Add ProxyService (services/proxy.rs, 157 lines):
      * Manage proxy server lifecycle
      * Handle configuration updates
      * Track runtime status and metrics
    
    Database Layer:
    - Add proxy configuration DAO (dao/proxy.rs, 242 lines):
      * Persist proxy settings (listen address, port, timeout)
      * Store provider priority and availability flags
    - Update schema with proxy_config table (schema.rs):
      * Support runtime configuration persistence
    
    Tauri Commands:
    - Add 6 command endpoints (commands/proxy.rs):
      * start_proxy_server: Launch proxy server
      * stop_proxy_server: Gracefully shutdown server
      * get_proxy_status: Query runtime status
      * get_proxy_config: Retrieve current configuration
      * update_proxy_config: Modify settings without restart
      * is_proxy_running: Check server state
    
    Frontend Implementation (React + TypeScript):
    - Add ProxyPanel component (222 lines):
      * Real-time server status display
      * Start/stop controls
      * Provider availability monitoring
    - Add ProxySettingsDialog component (420 lines):
      * Configuration editor (address, port, timeout)
      * Provider priority management
      * Settings validation
    - Add React hooks:
      * useProxyConfig: Manage proxy configuration state
      * useProxyStatus: Poll and display server status
    - Add TypeScript types (types/proxy.ts):
      * Define ProxyConfig, ProxyStatus interfaces
    
    Provider Integration:
    - Extend Provider model with availability field (providers.rs):
      * Track provider health for failover logic
    - Update ProviderCard UI to display proxy status
    - Integrate proxy controls in Settings page
    
    Dependencies:
    - Add Axum 0.7 (async web framework)
    - Add Tower 0.4 (middleware and service abstractions)
    - Add Tower-HTTP (CORS layer)
    - Add Tokio sync primitives (oneshot, RwLock)
    
    Technical Details:
    - Graceful shutdown via oneshot channel
    - Shared state with Arc<RwLock<T>> for thread-safe config updates
    - CORS enabled for cross-origin frontend access
    - Request/response streaming support
    - Automatic retry with exponential backoff (forwarder)
    - API key extraction from multiple config formats (Claude/Codex/Gemini)
    
    File Statistics:
    - 41 files changed
    - 3491 insertions(+), 41 deletions(-)
    - Core modules: 1393 lines (server + forwarder + handlers)
    - Frontend UI: 642 lines (ProxyPanel + ProxySettingsDialog)
    - Database/DAO: 326 lines
    
    This implementation provides the foundation for advanced features like:
    - Multi-provider load balancing
    - Automatic failover on provider errors
    - Request logging and analytics
    - Usage tracking and cost monitoring
    
    * fix(proxy): resolve UI/UX issues and database constraint error
    
    Simplify proxy control interface and fix database persistence issues:
    
    Backend Fixes:
    - Fix NOT NULL constraint error in proxy_config.created_at field
      * Use COALESCE to preserve created_at on updates
      * Ensure proper INSERT OR REPLACE behavior
    - Remove redundant enabled field validation on startup
      * Auto-enable when user clicks start button
      * Persist enabled state after successful start
    - Preserve enabled state during config updates
      * Prevent accidental service shutdown on config save
    
    Frontend Improvements:
    - Remove duplicate proxy enable switch from settings dialog
      * Keep only runtime toggle in ProxyPanel
      * Simplify user experience with single control point
    - Hide proxy target button when proxy service is stopped
      * Add isProxyRunning prop to ProviderCard
      * Conditionally render proxy controls based on service status
    - Update form schema to omit enabled field
      * Managed automatically by backend
    
    Files: 5 changed, 81 insertions(+), 94 deletions(-)
    
    * fix(proxy): improve URL building and Gemini request handling
    
    - Refactor URL construction with version path deduplication (/v1, /v1beta)
    - Preserve query parameters for Gemini API requests
    - Support GOOGLE_GEMINI_API_KEY field name (with fallback)
    - Change default proxy port from 5000 to 15721
    - Fix test: use Option type for is_proxy_target field
    
    * refactor(proxy): remove unused request handlers and routes
    
    - Remove unused GET/DELETE request forwarding methods
    - Remove count_tokens, get/delete response handlers
    - Simplify router by removing unused endpoints
    - Keep only essential routes: /v1/messages, /v1/responses, /v1beta/*
    
    * Merge branch 'main' into feat/proxy-server
    
    * fix(proxy): resolve clippy warnings for dead code and uninlined format args
    
    - Add #[allow(dead_code)] to unused ProviderUnhealthy variant
    - Inline format string arguments in handlers.rs and codex.rs log macros
    - Refactor error response handling to properly pass through upstream errors
    - Add URL deduplication logic for /v1/v1 paths in CodexAdapter
    
    * feat(proxy): implement provider adapter pattern with OpenRouter support
    
    This major refactoring introduces a modular provider adapter architecture
    to support format transformation between different AI API formats.
    
    New features:
    - Add ProviderAdapter trait for unified provider abstraction
    - Implement Claude, Codex, and Gemini adapters with specific logic
    - Add Anthropic ↔ OpenAI format transformation for OpenRouter compatibility
    - Support model mapping from provider configuration (ANTHROPIC_MODEL, etc.)
    - Add OpenRouter preset to Claude provider presets
    
    Refactoring:
    - Extract authentication logic into auth.rs with AuthInfo and AuthStrategy
    - Move URL building and request transformation to individual adapters
    - Simplify ProviderRouter to only use proxy target providers
    - Refactor RequestForwarder to use adapter-based request/response handling
    - Use whitelist mode for header forwarding (only pass necessary headers)
    
    Architecture:
    - providers/adapter.rs: ProviderAdapter trait definition
    - providers/auth.rs: AuthInfo, AuthStrategy types
    - providers/claude.rs: Claude adapter with OpenRouter detection
    - providers/codex.rs: Codex (OpenAI) adapter
    - providers/gemini.rs: Gemini (Google) adapter
    - providers/models/: Anthropic and OpenAI API data models
    - providers/transform.rs: Bidirectional format transformation
    
    * feat(proxy): add streaming SSE transform and thinking parameter support
    
    New features:
    - Add OpenAI → Anthropic SSE streaming response transformation
    - Support thinking parameter detection for reasoning model selection
    - Add ANTHROPIC_REASONING_MODEL config option for extended thinking
    
    Changes:
    - streaming.rs: Implement SSE event parsing and Anthropic format conversion
    - transform.rs: Add thinking detection logic and reasoning model mapping
    - handlers.rs: Integrate streaming transform for OpenRouter compatibility
    - Cargo.toml: Add async-stream and bytes dependencies
    
    * feat(db): add usage tracking schema and types
    
    Add database tables for proxy request logs and model pricing.
    Extend Provider and error types to support usage statistics.
    
    * feat(proxy): implement usage tracking subsystem
    
    Add request logger with automatic cost calculation.
    Implement token parser for Claude/OpenAI/Gemini responses.
    Add cost calculator based on model pricing configuration.
    
    * feat(proxy): integrate usage logging into request handlers
    
    Add usage logging to forwarder and streaming handlers.
    Track token usage and costs for each proxy request.
    
    * feat(commands): add usage statistics Tauri commands
    
    Register usage commands for summary, trends, logs, and pricing.
    Expose usage stats service through Tauri command layer.
    
    * feat(api): add frontend usage API and query hooks
    
    Add TypeScript types for usage statistics.
    Implement usage API with Tauri invoke calls.
    Add TanStack Query hooks for usage data fetching.
    
    * feat(ui): add usage dashboard components
    
    Add UsageDashboard with summary cards, trend chart, and data tables.
    Implement model pricing configuration panel.
    Add request log viewer with filtering and detail panel.
    
    * fix(ui): integrate usage dashboard and fix type errors
    
    Add usage dashboard tab to settings page.
    Fix UsageScriptModal TypeScript type annotations.
    
    * deps: add recharts for charts and rust_decimal/uuid for usage tracking
    
    - recharts: Chart visualization for usage trends
    - rust_decimal: Precise cost calculations
    - uuid: Request ID generation
    
    * feat(proxy): add ProviderType enum for fine-grained provider detection
    
    Introduce ProviderType enum to distinguish between different provider
    implementations (Claude, ClaudeAuth, Codex, Gemini, GeminiCli, OpenRouter).
    This enables proper authentication handling and request transformation
    based on the actual provider type rather than just AppType.
    
    - Add ProviderType enum with detection logic from config
    - Enhance Claude adapter with OpenRouter detection
    - Enhance Gemini adapter with CLI mode detection
    - Add helper methods for provider type inference
    
    * feat(database): extend schema with streaming and timing fields
    
    Add new columns to proxy_request_logs table for enhanced usage tracking:
    - first_token_ms and duration_ms for performance metrics
    - provider_type and is_streaming for request classification
    - cost_multiplier for flexible pricing
    
    Update model pricing with accurate rates for Claude/GPT/Gemini models.
    Add ensure_model_pricing_seeded() call on database initialization.
    Add test for model pricing auto-seeding verification.
    
    * feat(proxy/usage): enhance token parser and logger for multi-format support
    
    Parser enhancements:
    - Add OpenAI Chat Completions format parsing (prompt_tokens/completion_tokens)
    - Add model field to TokenUsage for actual model name extraction
    - Add from_codex_response_adjusted() for proper cache token handling
    - Add debug logging for better stream event tracing
    
    Logger enhancements:
    - Add first_token_ms, provider_type, is_streaming, cost_multiplier fields
    - Extend RequestLog struct with full metadata tracking
    - Update log_with_calculation() signature for new fields
    
    Calculator: Update tests with model field in TokenUsage.
    
    * feat(proxy): enhance proxy server with session tracking and OpenAI route
    
    Error handling:
    - Add StreamIdleTimeout and AuthError variants for better error classification
    
    Module exports:
    - Export ResponseType, StreamHandler, NonStreamHandler from response_handler
    - Export ProxySession, ClientFormat from session module
    
    Server routing:
    - Add /v1/chat/completions route for OpenAI Chat Completions API
    
    Handlers:
    - Add log_usage_with_session() for enhanced usage tracking with session context
    - Add first_token_ms timing measurement for streaming responses
    - Use SseUsageCollector with start_time for accurate latency calculation
    - Track is_streaming flag in usage logs
    
    * feat(services): add pagination and enhanced filtering for request logs
    
    Usage stats service:
    - Change get_request_logs() from limit/offset to page/page_size pagination
    - Return PaginatedLogs with total count, page, and page_size
    - Add appType and providerName filters with LIKE search
    - Add is_streaming, first_token_ms, duration_ms to RequestLogDetail
    - Join with providers table for provider name lookup
    
    Commands:
    - Update get_request_logs command signature for pagination params
    
    Module exports:
    - Export PaginatedLogs struct
    
    * feat(frontend): update usage types and API for pagination support
    
    Types (usage.ts):
    - Add isStreaming, firstTokenMs, durationMs to RequestLog
    - Add PaginatedLogs interface with data, total, page, pageSize
    - Change LogFilters: providerId -> appType + providerName
    
    API (usage.ts):
    - Change getRequestLogs params from limit/offset to page/pageSize
    - Return PaginatedLogs instead of RequestLog[]
    - Pass filters object directly to backend
    
    Query (usage.ts):
    - Update usageKeys.logs key generation for pagination
    - Update useRequestLogs hook signature
    
    * refactor(ui): enhance RequestLogTable with filtering and pagination
    
    UI improvements:
    - Add filter bar with app type, provider name, model, status selectors
    - Add date range picker (startDate/endDate)
    - Add search/reset/refresh buttons
    
    Pagination:
    - Implement proper page-based pagination with page info display
    - Show total count and current page range
    - Add prev/next navigation buttons
    
    Features:
    - Default to last 24 hours filter
    - Streamlined table columns layout
    - Query invalidation on refresh
    
    * style(config): format mcpPresets code style
    
    Apply consistent formatting to createNpxCommand function and
    sequential-thinking server configuration.
    
    * fix(ui): update SettingsPage tab styles for improved appearance (#342)
    
    * feat(model-test): add provider model availability testing
    
    Implement standalone model testing feature to verify provider API connectivity:
    - Add ModelTestService for Claude/Codex/Gemini endpoint testing
    - Create model_test_logs table for test result persistence
    - Add test button to ProviderCard with loading state
    - Include ModelTestConfigPanel for customizing test parameters
    
    * fix(proxy): resolve token parsing for OpenRouter streaming responses
    
    Problem:
    - OpenRouter and similar third-party services return streaming responses
      where input_tokens appear in message_delta instead of message_start
    - The previous implementation only extracted input_tokens from message_start,
      causing input_tokens to be recorded as 0 for these providers
    
    Changes:
    - streaming.rs: Add prompt_tokens field to Usage struct and include
      input_tokens in the transformed message_delta event when converting
      OpenAI format to Anthropic format
    - parser.rs: Update from_claude_stream_events() to handle input_tokens
      from both message_start (native Claude API) and message_delta (OpenRouter)
      - Use if-let pattern instead of direct unwrap for safer parsing
      - Only update input_tokens from message_delta if not already set
    - logger.rs: Adjust test parameters to match updated function signature
    
    Tests:
    - Add test_openrouter_stream_parsing() for OpenRouter format validation
    - Add test_native_claude_stream_parsing() for native Claude API validation
    
    * fix(pricing): standardize model ID format for pricing lookup
    
    Normalize model IDs by removing vendor prefixes and converting dots to hyphens to ensure consistent pricing lookups across different API response formats.
    
    Changes:
    - Update seed data to use hyphen format (e.g., gpt-5-1, gemini-2-5-pro)
    - Add normalize_model_id() function to strip vendor prefixes (anthropic/, openai/)
    - Convert dots to hyphens in model IDs (claude-haiku-4.5 → claude-haiku-4-5)
    - Try both original and normalized IDs for exact matching
    - Use normalized ID for suffix-based fallback matching
    - Add comprehensive test cases for prefix and dot handling
    - Add warning log when no pricing found
    
    This ensures pricing lookups work correctly for:
    - Models with vendor prefixes: anthropic/claude-haiku-4.5
    - Models with dots in version: claude-sonnet-4.5
    - Models with date suffixes: claude-haiku-4-5-20240229
    
    * style(rust): apply clippy formatting suggestions
    
    Apply automatic clippy fixes for uninlined_format_args warnings across Rust codebase. Replace format string placeholders with inline variable syntax for improved readability.
    
    Changes:
    - Convert format!("{}", var) to format!("{var}")
    - Apply to model_test.rs, parser.rs, and usage_stats.rs
    - Fix line length issues by breaking long function calls
    - Improve code formatting consistency
    
    All changes are automatic formatting with no functional impact.
    
    * fix(ui): restore card borders in usage statistics panels
    
    Restore proper card styling for ModelTestConfigPanel and PricingConfigPanel by adding back border and rounded-lg classes. The transparent background styling was causing visual inconsistency.
    
    Changes:
    - Replace border-none bg-transparent shadow-none with border rounded-lg
    - Apply to both loading and error states for consistency
    - Format TypeScript code for better readability
    - Break long function signatures across multiple lines
    
    This ensures the usage statistics panels have consistent visual appearance with proper borders and rounded corners.
    
    * feat(pricing): add GPT-5 Codex model pricing presets
    
    Add pricing configuration for GPT-5 Codex variants to support cost tracking for Codex-specific models.
    
    Changes:
    - Add gpt-5-codex model with standard GPT-5 pricing
    - Add gpt-5-1-codex model with standard GPT-5.1 pricing
    - Input: $1.25/M tokens, Output: $10/M tokens
    - Cache read: $0.125/M tokens, Cache creation: $0
    
    This ensures accurate cost calculation for Codex API requests using GPT-5 Codex models.
  • fix: add fallback for crypto.randomUUID() on older WebViews
    crypto.randomUUID() is not available on older systems (macOS < 12.3,
    Safari < 15.4). This caused "crypto.randomUUID is not a function"
    error when adding providers.
    
    - Add generateUUID() utility with getRandomValues() fallback
    - Provide user-friendly error message if crypto API unavailable
  • fix(mcp): use browser-compatible platform detection for MCP presets
    Replace Node.js process.platform check with navigator.userAgent-based
    detection from @/lib/platform. The previous implementation using
    process.platform failed in Tauri's browser environment, causing
    Windows platform to always return false and not apply the required
    'cmd /c' wrapper for npx commands.
    
    This fix ensures that on Windows, MCP presets like sequential-thinking
    correctly use 'cmd /c npx' format instead of direct 'npx', eliminating
    the warning: "Windows requires 'cmd /c' wrapper to execute npx"
    
    Changes:
    - Import isWindows() from @/lib/platform instead of defining locally
    - Remove incorrect process.platform-based detection
    - Now properly detects Windows in browser/WebView environment
  • fix(ui): prevent provider card hover scale from being clipped
    Move 1px of horizontal padding from outer container to inner scroll
    container, providing buffer space for the hover scale-[1.01] effect
    without being cut off by overflow-hidden.
  • fix(ui): add independent scroll containers to fix scroll wheel on Linux
    Providers page was using DndContext which may interfere with scroll wheel
    events on Linux/Ubuntu WebKitGTK. Added independent scroll containers
    with `overflow-y-auto` to all main pages, matching the pattern already
    used by the MCP panel which works correctly.
    
    Changes:
    - App.tsx: Wrap ProviderList in independent scroll container
    - SkillsPage: Use consistent h-[calc(100vh-8rem)] layout
    - SettingsPage: Add overflow-hidden and overflow-x-hidden for consistency
  • fix(config): update Codex default model and correct MiniMax URL
    - Update Codex preset model from gpt-5-codex to gpt-5.1-codex
    - Fix MiniMax English preset URL from minimaxi.io to minimax.io
  • style: apply code formatting fixes
    - Fix Prettier formatting in claudeProviderPresets.ts
    - Fix cargo fmt trailing blank line in provider/mod.rs
  • fix(config): correct MiniMax apiKeyUrl to minimaxi.com
    Update apiKeyUrl domain to match official website URL.
    Also update screenshots for all locales (en, ja, zh).
  • docs: update screenshots and add Japanese locale images
    - Update README_JA.md to reference Japanese screenshots
    - Add Japanese screenshots (main-ja.png, add-ja.png)
    - Update English and Chinese screenshots with latest UI
    - Remove outdated README_i18n.md documentation
  • fix(skills): use theme-aware glass-card class for light mode compatibility
    Replace hardcoded dark mode styles (bg-gray-900/40, border-white/10) with
    the unified glass-card class that adapts to both light and dark themes.
  • refactor(url): remove automatic trailing slash stripping from base URL inputs
    - Remove `.replace(/\/+$/, "")` from all base URL handlers in useBaseUrlState.ts
    - Remove trailing slash stripping in useCodexConfigState.ts
    - Remove trailing slash normalization in providerConfigUtils.ts setCodexBaseUrl()
    - Update i18n hints (en/ja/zh) to instruct users to avoid trailing slashes
    
    This gives users explicit control over URL format rather than silently modifying input.
  • fix(ui): persist active provider card highlight when not hovered
    The selected provider's visual highlight (background, border, glow)
    was being overridden by .glass-card base styles due to CSS specificity.
    Add dedicated .glass-card-active class to ensure active state persists.
  • style(css): consolidate global selector rules and remove duplicates
    - Merge three separate `*` selector blocks into one for better maintainability
    - Remove duplicate "Glassmorphism Utilities" comment
  • fix(tailwind): add missing shadcn/ui color mappings for opaque dialog backgrounds
    The dialog backgrounds were transparent because Tailwind 3 requires explicit
    color mappings in the config to use CSS variables. Added standard shadcn/ui
    color mappings (background, foreground, card, primary, etc.) and removed
    unnecessary overlayClassName overrides from dialog components.
  • style(mcp): align wizard modal with confirm dialog styling
    - Use zIndex="alert" and semi-transparent overlay for consistency
    - Apply border-b-0/border-t-0 bg-transparent to header/footer
    - Replace emerald accent with blue to match app theme
    - Use Input component instead of raw input elements
    - Simplify button variants (outline for cancel)
  • chore: remove dead code from MCP and provider modules
    - Remove unused `read_mcp_json` from gemini_mcp.rs
    - Remove unused `normalize_server_keys` from mcp/claude.rs
    - Remove unused `validate_mcp_entry` from mcp/validation.rs
    - Remove unused `write_codex_live`, `write_claude_live`, `app_not_found` from services/provider/mod.rs
    - Clean up unused imports
  • refactor(mcp): modularize MCP and tray menu logic
    Split mcp.rs (1135 lines) into focused modules:
    - validation.rs: server config validation
    - claude.rs: Claude MCP sync/import
    - codex.rs: Codex MCP sync (TOML handling)
    - gemini.rs: Gemini MCP sync/import
    
    Extract tray menu logic from lib.rs to tray.rs for better separation of concerns.
  • fix(auto-launch): use AutoLaunchBuilder for cross-platform compatibility
    The auto-launch crate has different API signatures on each platform:
    - Windows/Linux: AutoLaunch::new() takes 3 arguments
    - macOS: AutoLaunch::new() takes 4 arguments (includes hidden param)
    
    The previous code used #[cfg(not(target_os = "windows"))] which incorrectly
    applied macOS's 4-argument signature to Linux, causing build failures.
    
    Switch to AutoLaunchBuilder which handles platform differences internally.
  • feat(preset): add MiniMax international version and split promotions
    - Add MiniMax en preset with international API endpoint (minimaxi.io)
    - Split MiniMax partner promotion into CN and EN versions
    - Remove unnecessary icon config from Aliyun and Alibaba Lingma presets
  • docs: add v3.8.0 release documentation and Japanese README
    - Add CHANGELOG entry for v3.8.0
    - Update README.md and README_ZH.md with v3.8.0 features
    - Add Japanese README (README_JA.md)
    - Add release notes in English, Chinese, and Japanese
  • refactor(skill): remove skillsPath configuration (#310)
    Remove the skillsPath field from SkillRepo and Skill structs since
    recursive scanning now automatically discovers skills in all directories.
    Simplify the UI by removing the path input field.
  • fix(test): update component tests to match current implementation
    - Add JsonEditor mock to McpFormModal tests (component uses CodeMirror
      instead of Textarea)
    - Fix assertion for missing command error message
    - Update ImportExportSection tests for new button behavior and file
      display format
  • fix: pre-release fixes for code formatting, i18n, and test suite
    - Run cargo fmt to fix Rust code formatting (lib.rs)
    - Add missing i18n keys: migration.success, agents.title (zh/en/ja)
    - Replace hardcoded strings "Agents" and "MCP" with t() calls in App.tsx
    - Fix test mocks and assertions:
      - Add providersApi.updateTrayMenu to useSettings.test.tsx mock
      - Update SettingsPage mock path in App.test.tsx
      - Fix toast message assertion in integration/SettingsDialog.test.tsx
      - Add autoSaveSettings to SettingsDialog component test mock
      - Fix loading state test to check spinner instead of title
      - Update import button name matching for selected file state
      - Fix save button test to switch to advanced tab first
      - Remove obsolete cancel button test (button no longer exists)
    
    Test results improved from 99 passed / 17 failed to 104 passed / 11 failed
  • feat(i18n): add Japanese language support
    - Add complete Japanese translation file (ja.json)
    - Update frontend types and hooks to support "ja" language option
    - Add Japanese tray menu texts in Rust backend
    - Add Japanese option to language settings component
    - Update Zod schema to include Japanese language validation
    - Add test case for Japanese language preference
    - Update i18n documentation to reflect three-language support
  • refactor(startup): improve first-launch import logic with per-table detection
    - Replace global `is_empty_for_first_import()` with independent checks:
      - `is_mcp_table_empty()` for MCP server imports
      - `is_prompts_table_empty()` for prompt imports
      - Skills and providers already have built-in idempotency checks
    
    - Fix misleading logs in provider import:
      - Change `import_default_config` return type from `Result<()>` to `Result<bool>`
      - Return `true` when actually imported, `false` when skipped
      - Only log success message when import actually occurred
    
    - Add idempotency protection to `import_from_file_on_first_launch`
    
    This allows each data type to be independently recovered if deleted,
    rather than requiring all tables to be empty for any import to trigger.
  • feat(skill): implement recursive scanning for skill repositories (#309)
    Add recursive directory scanning to discover SKILL.md files in nested
    directories. When a SKILL.md is found, treat sibling directories as
    functional folders rather than separate skills.
  • fix(usage): correct selectedTemplate initialization logic
    Previously, selectedTemplate was initialized to null when no NEW_API
    credentials were detected, which caused the credentials config section
    to be hidden even for new configurations or GENERAL template users.
    
    Now properly detects:
    - NEW_API template (has accessToken or userId)
    - GENERAL template (has apiKey or baseUrl)
    - Default to GENERAL for new configurations (matches default code template)
  • refactor(usage): simplify usage script modal UI
    - Remove redundant "Request Configuration" section (URL, method, headers, body editors)
    - Move timeout and auto query interval fields to preset template section
    - Simplify "Enable usage query" toggle styling
    - Remove redundant hints and variables description
    - Add i18n support for Base URL label
    - Include "0 to disable" hint directly in auto interval label
  • fix(auto-launch): use platform-specific API for AutoLaunch::new
    Windows version of auto-launch crate takes 3 arguments while
    Linux/macOS takes 4 (includes hidden parameter). Use conditional
    compilation to handle the difference.
  • feat(preset): add icon configuration to provider presets
    - Add icon/iconColor fields to CodexProviderPreset and GeminiProviderPreset interfaces
    - Configure icons for Claude presets (DeepSeek, Zhipu, Qwen, Kimi, MiniMax, DouBao, etc.)
    - Configure icons for Codex presets (OpenAI, Azure, PackyCode)
    - Configure icons for Gemini presets (Google, PackyCode)
    - Fix handlePresetChange to pass icon fields when resetting form
    
    This ensures preset icons are displayed in the icon picker when selecting a provider preset.
  • fix(css): downgrade Tailwind CSS from v4 to v3.4 for better browser compatibility
    Tailwind CSS v4 requires modern CSS features (@layer, @property, color-mix)
    that are not supported in older WebView2 versions, causing styles to fail
    on some Windows 11 systems.
    
    Changes:
    - Replace @tailwindcss/vite with postcss + autoprefixer
    - Downgrade tailwindcss from 4.1.13 to 3.4.17
    - Convert CSS imports from v4 syntax to v3 @tailwind directives
    - Add darkMode: "selector" to tailwind.config.js
    - Create postcss.config.js for PostCSS pipeline
    
    This improves compatibility with older browsers and WebView2 runtimes
    while maintaining the same visual appearance.