Commit Graph

766 Commits

  • 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
  • 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
  • fix(ui): integrate usage dashboard and fix type errors
    Add usage dashboard tab to settings page.
    Fix UsageScriptModal TypeScript type annotations.
  • 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.
  • 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(commands): add usage statistics Tauri commands
    Register usage commands for summary, trends, logs, and pricing.
    Expose usage stats service through Tauri command layer.
  • 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(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(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.
  • 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
  • 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
  • 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.
  • 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
  • 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
  • Merge branch 'main' into feat/proxy-server
    # Conflicts:
    #	src/App.tsx
  • 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/*
  • 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
  • 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
  • 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(-)
  • 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
  • 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.