Commit Graph

548 Commits

  • refactor(database): migrate proxy_config to per-app three-row structure
    Replace singleton proxy_config table with app_type primary key structure,
    allowing independent proxy settings for Claude, Codex, and Gemini.
    Add GlobalProxyConfig queries and per-app config management in DAO layer.
  • refactor(ui): remove timeout settings from AutoFailoverConfigPanel
    Remove streaming/non-streaming timeout configuration from failover panel
    as these settings have been moved to a dedicated location.
  • feat(ui): add OpenRouter compatibility mode toggle
    Add UI toggle for OpenRouter providers to enable/disable compatibility
    mode which uses OpenAI Chat Completions format with SSE conversion.
  • feat(ui): add reasoning model field to Claude provider form
    Add ANTHROPIC_REASONING_MODEL configuration field for Claude providers,
    allowing users to specify a dedicated model for thinking/reasoning tasks.
  • feat(proxy): implement streaming timeout control with validation
    - Add first byte timeout (0 or 1-180s) for streaming requests
    - Add idle timeout (0 or 60-600s) for streaming data gaps
    - Add non-streaming timeout (0 or 60-1800s) for total request
    - Implement timeout logic in response processor
    - Add 1800s global timeout fallback when disabled
    - Add database schema migration for timeout fields
    - Add i18n translations for timeout settings
  • feat(proxy): extract model name from API response for accurate usage tracking
    - Add model field extraction in TokenUsage parsing for Claude, OpenAI, and Codex
    - Prioritize response model over request model in usage logging
    - Update model extractors to use parsed usage.model first
    - Add tests for model extraction in stream and non-stream responses
  • feat(ui): add exit animation to FullScreenPanel dialogs
    - Wrap FullScreenPanel content with AnimatePresence for exit animation
    - Add exit={{ opacity: 0 }} to enable fade-out on close
    - Use useRef + useEffect to preserve provider data during exit animation
    - Follow React best practices by updating refs in useEffect instead of render
    
    Affected components:
    - EditProviderDialog
    - UsageScriptModal
    - AddProviderDialog
    - McpFormModal
    - ProxySettingsDialog
  • fix(ui): reduce header spacing and fix layout shift on view switch
    - Change right-side button container from min-h-[40px] to h-[32px]
      for more compact header layout
    - Remove conditional padding (pt-6/pt-4) from main content area
      to eliminate layout jump during view transitions
  • Feat/auto failover switch (#440)
    * feat(failover): add auto-failover master switch with proxy integration
    
    - Add persistent auto_failover_enabled setting in database
    - Add get/set_auto_failover_enabled commands
    - Provider router respects master switch state
    - Proxy shutdown automatically disables failover
    - Enabling failover auto-starts proxy server
    - Optimistic updates for failover queue toggle
    
    * feat(proxy): persist proxy takeover state across app restarts
    
    - Add proxy_takeover_{app_type} settings for per-app state tracking
    - Restore proxy takeover state automatically on app startup
    - Preserve state on normal exit, clear on manual stop
    - Add stop_with_restore_keep_state method for graceful shutdown
    
    * fix(proxy): set takeover state for all apps in start_with_takeover
    
    * fix(windows): hide console window when checking CLI versions
    
    Add CREATE_NO_WINDOW flag to prevent command prompt from flashing
    when detecting claude/codex/gemini CLI versions on Windows.
    
    * refactor(failover): make auto-failover toggle per-app independent
    
    - Change setting key from 'auto_failover_enabled' to 'auto_failover_enabled_{app_type}'
    - Update provider_router to check per-app failover setting
    - When failover disabled, use current provider only; when enabled, use queue order
    - Add unit tests for failover enabled/disabled behavior
    
    * feat(failover): auto-switch to higher priority provider on recovery
    
    - After circuit breaker reset, check if recovered provider has higher priority
    - Automatically switch back if queue_order is lower (higher priority)
    - Stream health check now resets circuit breaker on success/degraded
    
    * chore: remove unused start_proxy_with_takeover command
    
    - Remove command registration from lib.rs
    - Add comment clarifying failover queue is preserved on proxy stop
    
    * feat(ui): integrate failover controls into provider cards
    
    - Add failover toggle button to provider card actions
    - Show priority badge (P1, P2, ...) for queued providers
    - Highlight active provider with green border in failover mode
    - Sync drag-drop order with failover queue
    - Move per-app failover toggle to FailoverQueueManager
    - Simplify SettingsPage failover section
    
    * test(providers): add mocks for failover hooks in ProviderList tests
    
    * refactor(failover): merge failover_queue table into providers
    
    - Add in_failover_queue field to providers table
    - Remove standalone failover_queue table and related indexes
    - Simplify queue ordering by reusing sort_index field
    - Remove reorder_failover_queue and set_failover_item_enabled commands
    - Update frontend to use simplified FailoverQueueItem type
    
    * fix(database): ensure in_failover_queue column exists for v2 databases
    
    Add column check in create_tables to handle existing v2 databases
    that were created before the failover queue refactor.
    
    * fix(ui): differentiate active provider border color by proxy mode
    
    - Use green border/gradient when proxy takeover is active
    - Use blue border/gradient in normal mode (no proxy)
    - Improves visual distinction between proxy and non-proxy states
    
    * fix(database): clear provider health record when removing from failover queue
    
    When a provider is removed from the failover queue, its health monitoring
    is no longer needed. This change ensures the health record is also deleted
    from the database to prevent stale data.
    
    * fix(failover): improve cache cleanup for provider health and circuit breaker
    
    - Use removeQueries instead of invalidateQueries when stopping proxy to
      completely clear health and circuit breaker caches
    - Clear provider health and circuit breaker caches when removing from
      failover queue
    - Refresh failover queue after drag-sort since queue order depends on
      sort_index
    - Only show health badge when provider is in failover queue
    
    * style: apply prettier formatting to App.tsx and ProviderList.tsx
    
    * fix(proxy): handle missing health records and clear health on proxy stop
    
    - Return default healthy state when provider health record not found
    - Add clear_provider_health_for_app to clear health for specific app
    - Clear app health records when stopping proxy takeover
    
    * fix(proxy): track actual provider used in forwarding for accurate logging
    
    Introduce ForwardResult and ForwardError structs to return the actual
    provider that handled the request. This ensures usage statistics and
    error logs reflect the correct provider after failover.
  • fix(ui): prevent header layout shift when switching views
    Add min-height to right-side button container and ml-auto to add buttons
    in MCP/Prompts views to maintain consistent header height and button
    position across all views.
  • feat(ui): add fade transition for view and panel switching
    Add smooth fade animations when navigating between views (Settings,
    MCP, Skills, Prompts) and opening full-screen panels (Add/Edit Provider).
  • feat: add provider search filter (#435)
    * feat: add provider search filter
    
    * feat: add provider search overlay
  • feat(failover): add auto-failover master switch with proxy integration (#427)
    * feat(failover): add auto-failover master switch with proxy integration
    
    - Add persistent auto_failover_enabled setting in database
    - Add get/set_auto_failover_enabled commands
    - Provider router respects master switch state
    - Proxy shutdown automatically disables failover
    - Enabling failover auto-starts proxy server
    - Optimistic updates for failover queue toggle
    
    * feat(proxy): persist proxy takeover state across app restarts
    
    - Add proxy_takeover_{app_type} settings for per-app state tracking
    - Restore proxy takeover state automatically on app startup
    - Preserve state on normal exit, clear on manual stop
    - Add stop_with_restore_keep_state method for graceful shutdown
    
    * fix(proxy): set takeover state for all apps in start_with_takeover
  • feat(ui): add fade transition for app switching
    - Add AnimatePresence + motion.div wrapper for provider list
    - Use key={activeApp} to trigger enter/exit animations on app switch
    - Remove redundant animate-slide-up from ProviderList to prevent
      animation conflicts and visual jitter
  • style(settings): unify tab transition animations
    Add framer-motion fade-in and slide-up animations to General and
    Advanced tabs, matching the existing Usage and About tab animations.
  • feat(settings): add option to skip Claude Code first-run confirmation
    Add a new setting to automatically skip Claude Code's onboarding screen
    by writing hasCompletedOnboarding=true to ~/.claude.json. The setting
    defaults to enabled for better user experience.
    
    - Add set/clear_has_completed_onboarding functions in claude_mcp.rs
    - Add Tauri commands and frontend API integration
    - Add toggle in WindowSettings with i18n support (en/zh/ja)
    - Fix hardcoded Chinese text in tests to use i18n keys
  • i18n: complete usage panel and settings internationalization
    - Add missing i18n keys for usage statistics panel (trends, cost, perMillion, etc.)
    - Add i18n keys for settings advanced section (configDir, proxy, modelTest, etc.)
    - Add streamCheck i18n keys for health check configuration
    - Remove hardcoded Chinese fallback values from t() calls
    - Add common keys (all, search, reset, actions, deleting)
  • i18n: complete internationalization for v3.8+ features
    - Add health status translations (operational, degraded, failed, circuitOpen)
    - Add proxy panel translations (serviceAddress, stats, stopped state)
    - Add usage filter translations (appType, statusCode, searchPlaceholder)
    - Add providerIcon click hints (clickToChange, clickToSelect)
    - Add config load error translations for main.tsx
    - Complete Japanese proxy section (failoverQueue, autoFailover)
    - Fix date/time locale in usage charts and tables
    - Use t() function in all hardcoded UI strings
  • style(switch): improve dark mode appearance
    - Track (unchecked): lighten in light mode (gray-300 → gray-200),
      darken in dark mode (gray-700 → gray-900) to blend with background
    - Thumb: soften in dark mode (white → gray-400) to reduce glare
  • fix(ui): improve text visibility in dark mode
    Replace hardcoded gray color classes with semantic color classes
    to fix poor text contrast in dark mode:
    
    - MCP panel: server names, descriptions, tags, app labels
    - Prompt panel: prompt names, descriptions, empty states
    - Usage footer: timestamps, refresh buttons
    - Update badge: close button icon
    - API key input: disabled state text
    - Env warning banner: source info text
    
    Changes:
    - `text-gray-400 dark:text-gray-500` → `text-muted-foreground`
      (fixes reversed dark mode logic)
    - `text-gray-500 dark:text-gray-400` → `text-muted-foreground`
    - `bg-gray-100 dark:bg-gray-800` → `bg-muted`
  • style(header): unify height and styling of header toolbar sections
    - Use consistent h-8 fixed height for all inner elements
    - Standardize border-radius to rounded-xl across all sections
    - Remove background from ProxyToggle for cleaner appearance
    - Simplify ProxyToggle structure with nested container
  • feat(providers): add DMXAPI as official partner
    Mark DMXAPI as partner in both Claude and Codex presets with promotion
    message for their Claude Code exclusive model 66% OFF offer.
  • feat(icons): add provider icons for OpenRouter, LongCat, ModelScope, AiHubMix
    - Add SVG icons for OpenRouter, LongCat, ModelScope, and AiHubMix
    - Register icons in index.ts and metadata.ts with search keywords
    - Link icons to corresponding provider presets in claudeProviderPresets.ts
  • fix(proxy): add fallback recovery for orphaned takeover state
    - Detect takeover residue in Live configs even when proxy is not running
    - Implement 3-tier fallback: backup → SSOT → cleanup placeholders
    - Only delete backup after successful restore to prevent data loss
    - Fix EditProviderDialog to check current app's takeover status only
  • refactor(proxy): remove global auto-start flag
    - Remove global proxy auto-start flag from config and UI.
    - Simplify per-app takeover start/stop and stop server when the last takeover is disabled.
    - Restore live takeover detection used for crash recovery.
    - Keep proxy_config.enabled column but always write 0 for compatibility.
    - Tests: not run (not requested).
  • fix(import): refresh all providers immediately after SQL import
    - Remove setTimeout delay that could be cancelled on component unmount
    - Invalidate all providers cache (not just current app) since import affects all apps
    - Call onImportSuccess before sync to ensure UI refresh even if sync fails
    - Update i18n: "Data refreshed" (past tense, reflecting immediate action)
  • fix(backup): restrict SQL import to CC Switch exported backups only
    - Add validation to reject SQL files without CC Switch export header
    - Remove redundant sanitize_import_sql (sqlite_* objects already excluded at export time)
    - Fix backup filename collision by appending counter suffix
    - Update i18n hints to clarify import restriction
  • Fix/about section UI (#419)
    * fix(ui): improve AboutSection styling and version detection
    
    - Add framer-motion animations for smooth page transitions
    - Unify button sizes and add icons for consistency
    - Add gradient backgrounds and hover effects to cards
    - Add notInstalled i18n translations (zh/en/ja)
    - Fix version detection when stdout/stderr is empty
    
    * fix(proxy): persist per-app takeover state across app restarts
    
    - Fix proxy toggle color to reflect current app's takeover state only
    - Restore proxy service on startup if Live config is still in takeover state
    - Preserve per-app backup records instead of clearing all on restart
    - Only recover Live config when proxy service fails to start
  • chore: bump version to 3.9.0-beta.1
    - Update version in package.json, Cargo.toml, tauri.conf.json
    - Add CHANGELOG entry for v3.9.0-beta.1 with:
      - Local Proxy Server feature
      - Auto Failover with circuit breaker
      - Skills multi-app support
      - Provider icon colors
      - 25+ bug fixes
    - Add proxy feature guide documentation (Chinese)
  • fix(ui): restore fade transition for Skills button
    The Skills button transition was accidentally removed in commit 1fb2d5e
    when adding multi-app support. This restores the smooth fade-in/out
    animation when switching between apps that support Skills (Claude/Codex)
    and those that don't (Gemini).
  • feat(proxy): implement per-app takeover mode
    Replace global live takeover with granular per-app control:
    - Add start_proxy_server command (start without takeover)
    - Add get_proxy_takeover_status to query each app's state
    - Add set_proxy_takeover_for_app for individual app control
    - Use live backup existence as SSOT for takeover state
    - Refactor sync_live_to_provider to eliminate code duplication
    - Update ProxyToggle to show status per active app
  • fix(proxy): stabilize live takeover and provider editing
    - Skip live writes when takeover is active and proxy is running
    - Refresh live backups from provider edits during takeover
    - Sync live tokens to DB without clobbering real keys with placeholders
    - Avoid injecting extra placeholder keys into Claude live env
    - Reapply takeover after proxy listen address/port changes
    - In takeover mode, edit dialog uses DB config and keeps API key state in sync
  • Feature/error request logging (#401)
    * feat(proxy): add error mapper for HTTP status code mapping
    
    - Add error_mapper.rs module to map ProxyError to HTTP status codes
    - Implement map_proxy_error_to_status() for error classification
    - Implement get_error_message() for user-friendly error messages
    - Support all error types: upstream, timeout, connection, provider failures
    - Include comprehensive unit tests for all mappings
    
    * feat(proxy): enhance error logging with context support
    
    - Add log_error_with_context() method for detailed error recording
    - Support streaming flag, session_id, and provider_type fields
    - Remove dead_code warning from log_error() method
    - Enable comprehensive error request tracking in database
    
    * feat(proxy): implement error capture and logging in all handlers
    
    - Capture and log all failed requests in handle_messages (Claude)
    - Capture and log all failed requests in handle_gemini (Gemini)
    - Capture and log all failed requests in handle_responses (Codex)
    - Capture and log all failed requests in handle_chat_completions (Codex)
    - Record error status codes, messages, and latency for all failures
    - Generate unique session_id for each request
    - Support both streaming and non-streaming error scenarios
    
    * style: fix clippy warnings and typescript errors
    
    - Add allow(dead_code) for CircuitBreaker::get_state (reserved for future)
    - Fix all uninlined format string warnings (27 instances)
    - Use inline format syntax for better readability
    - Fix unused import and parameter warnings in ProviderActions.tsx
    - Achieve zero warnings in both Rust and TypeScript
    
    * style: apply code formatting
    
    - Remove trailing whitespace in misc.rs
    - Add trailing comma in App.tsx
    - Format multi-line className in ProviderCard.tsx
    
    * feat(proxy): add settings button to proxy panel
    
    Add configuration buttons in both running and stopped states to
    provide easy access to proxy settings dialog.
    
    * fix(speedtest): skip client build for invalid inputs
    
    * chore(clippy): fix uninlined format args
    
    * Merge branch 'main' into feature/error-request-logging
  • refactor(proxy): remove is_proxy_target in favor of failover_queue
    - Remove `is_proxy_target` field from Provider struct (Rust & TypeScript)
    - Remove related DAO methods: get_proxy_target_provider, set_proxy_target
    - Remove deprecated Tauri commands: get_proxy_targets, set_proxy_target
    - Add `is_available()` method to CircuitBreaker for availability checks
      without consuming HalfOpen probe permits (used in select_providers)
    - Keep `allow_request()` for actual request gating with permit tracking
    - Update stream_check to use failover_queue instead of is_proxy_target
    - Clean up commented-out reset circuit breaker button in ProviderActions
    - Remove unused useProxyTargets and useSetProxyTarget hooks
  • chore(i18n): remove restart prompt from provider switch notification
    Claude Code now supports hot reload, so users no longer need to restart
    the terminal after switching providers. Also removes unused `restartClaude`
    i18n string.
  • fix(proxy): invalidate health cache when proxy stops
    The previous fix (e081c75) only cleared the database records but
    didn't invalidate the React Query cache. This caused stale health
    badges to appear when restarting the proxy.
    
    Now invalidates all providerHealth queries on stop, ensuring the
    frontend fetches fresh data from the database.
  • fix(ui): prevent card jitter when health badge appears
    Increase min-height of the name row from 20px to 28px (min-h-7)
    to accommodate the health badge height, preventing layout shift
    when the badge dynamically appears.
  • fix(usage): add fallback to provider config for usage credentials (#360)
    - Make usage script credential fields optional with provider config fallback
    - Optimize multi-plan card display: show plan count by default, expandable for details
    - Add hint text to explain credential fallback mechanism
  • feat(deeplink): 深链支持用量查询配置 (#400)
    ## 新增功能
    - 深链导入支持用量查询配置参数:
      - `usageEnabled`: 是否启用用量查询
      - `usageScript`: Base64 编码的用量查询脚本
      - `usageApiKey`: 用量查询专用 API Key
      - `usageBaseUrl`: 用量查询专用 Base URL
      - `usageAccessToken`: 访问令牌(NewAPI 模板)
      - `usageUserId`: 用户 ID(NewAPI 模板)
      - `usageAutoInterval`: 自动查询间隔(分钟)
    
    ## 修改文件
    - **mod.rs**: DeepLinkImportRequest 结构体添加用量查询字段
    - **parser.rs**: 解析 URL 中的用量查询参数
    - **provider.rs**: 构建 ProviderMeta 包含 UsageScript 配置
    - **deeplink.ts**: 添加 TypeScript 类型定义
    - **DeepLinkImportDialog.tsx**: 确认对话框显示用量查询配置
    
    ## Bug 修复
    - **formatters.ts**: 修复 formatJSON() 格式化时删除 "env" 键的问题
    
    ## 深链格式示例
    ```
    ccswitch://v1/import?resource=provider&app=claude&name=xxx&usageEnabled=true&usageScript={base64}&usageAutoInterval=30
    ```
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
  • feat(proxy): implement independent failover queue management
    Add a new failover queue system that operates independently from provider
    sortIndex, allowing users to configure failover order per app type.
    
    Backend changes:
    - Add failover_queue table to schema.rs for persistent storage
    - Create dao/failover.rs with CRUD operations for queue management
    - Add Tauri commands for queue operations (get, add, remove, reorder, toggle)
    - Refactor provider_router.rs select_providers() to use failover queue:
      - Current provider always takes first priority
      - Queue providers ordered by queue_order as fallback
      - Only providers with open circuit breakers are included
    
    Frontend changes:
    - Add FailoverQueueItem type to proxy.ts
    - Extend failover.ts API with queue management methods
    - Add React Query hooks for queue data fetching and mutations
    - Create FailoverQueueManager component with drag-and-drop reordering
    - Integrate queue management into SettingsPage under "Auto Failover"
    - Add i18n translations for zh and en locales
  • Feat/provider icon color (#385)
    * feat(ui): add color prop support to ProviderIcon component
    
    * feat(health): add stream check core functionality
    
    Add new stream-based health check module to replace model_test:
    - Add stream_check command layer with single and batch provider checks
    - Add stream_check DAO layer for config and log persistence
    - Add stream_check service layer with retry mechanism and health status evaluation
    - Add frontend HealthStatusIndicator component
    - Add frontend useStreamCheck hook
    
    This provides more comprehensive health checking capabilities.
    
    * refactor(health): replace model_test with stream_check
    
    Replace model_test module with stream_check across the codebase:
    - Remove model_test command and service modules
    - Update command registry in lib.rs to use stream_check commands
    - Update module exports in commands/mod.rs and services/mod.rs
    - Remove frontend useModelTest hook
    - Update stream_check command implementation
    
    This refactoring provides clearer naming and better separation of concerns.
    
    * refactor(db): clean up unused database tables and optimize schema
    
    Remove deprecated and unused database tables:
    - Remove proxy_usage table (replaced by proxy_request_logs)
    - Remove usage_daily_stats table (aggregation done on-the-fly)
    - Rename model_test_logs to stream_check_logs with updated schema
    - Remove related DAO methods for proxy_usage
    - Update usage_stats service to use proxy_request_logs only
    - Refactor usage_script to work with new schema
    
    This simplifies the database schema and removes redundant data storage.
    
    * refactor(ui): update frontend components for stream check
    
    Update frontend components to use stream check API:
    - Refactor ModelTestConfigPanel to use stream check config
    - Update API layer to use stream_check commands
    - Add HealthStatus type and StreamCheckResult interface
    - Update ProviderList to use new health check integration
    - Update AutoFailoverConfigPanel with stream check references
    - Improve UI layout and configuration options
    
    This completes the frontend migration from model_test to stream_check.
    
    * feat(health): add configurable test models and reasoning effort support
    
    Enhance stream check service with configurable test models:
    - Add claude_model, codex_model, gemini_model to StreamCheckConfig
    - Support reasoning effort syntax (model@level or model#level)
    - Parse and apply reasoning_effort for OpenAI-compatible models
    - Remove hardcoded model names from check functions
    - Add unit tests for model parsing logic
    - Remove obsolete model_test source files
    
    This allows users to customize which models are used for health checks.
  • Fix/misc updates (#387)
    * 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
    
    * 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
  • feat(proxy): cleanup proxy server on app exit and remove unused non-takeover mode
    - Add cleanup_before_exit() to gracefully stop proxy and restore live configs
    - Handle ExitRequested event to catch Cmd+Q, Alt+F4, and tray quit
    - Use std::process::exit(0) after cleanup to avoid infinite loop
    - Remove unused start_proxy_server and stop_proxy_server commands
    - Remove unused startMutation and stopMutation from useProxyStatus hook
    - Simplify API to only expose takeover mode (start_proxy_with_takeover/stop_proxy_with_restore)
  • style(ui): improve provider card hover animation and layout
    - Increase translate offset for usage footer to prevent overlap with action buttons
    - Add ease-out timing function and extend duration to 300ms for smoother animation
    - Temporarily disable circuit breaker reset button to reduce button clutter
  • style(ui): apply emerald theme when proxy takeover is active
    - Change provider card gradient background from hover to selected state
    - Use emerald color for card hover border, selected border, and gradient
      when proxy takeover mode is active
    - Update "CC Switch" title to emerald when proxy is running
    - Update "Enable" button to emerald in proxy takeover mode
  • refactor(proxy): simplify provider selection to use is_current directly
    Changes:
    - Modify provider_router to select provider based on is_current flag
      instead of is_proxy_target queue
    - Remove proxy target toggle UI from ProviderCard
    - Remove proxyPriority and allProviders props from ProviderList
    - Remove isProxyTarget prop from ProviderHealthBadge
    - Use start_with_takeover() for auto-start to ensure proper setup
    
    This simplifies the proxy architecture by directly using the current
    provider for proxying, eliminating the need for separate proxy target
    management. Switching providers now immediately takes effect in proxy
    mode.