Commit Graph

1058 Commits

  • refactor(ui): extract shared components and deduplicate MCP/Skills panels (#897)
    * refactor(ui): add tooltips and icons to MCP and Skills panels
    
    * refactor: deduplicate UnifiedSkillsPanel and UnifiedMcpPanel shared code
  • feat: session manger (#867)
    * feat: init session manger
    
    * feat: persist selected app to localStorage
    
    - Save app selection when switching providers
    - Restore last selected app on page load
    
    * feat: persist current view to localStorage
    
    - Save view selection when switching tabs
    - Restore last selected view on page load
    
    * styles: update ui
    
    * feat: Improve macOS Terminal activation and refactor Kitty launch to use  command with user's default shell.
    
    * fix: session view
    
    * feat: toc
    
    * feat: Implement FlexSearch for improved session search functionality.
    
    * feat: Redesign session manager search and filter UI for a more compact and dynamic experience.
    
    * refactor: modularize session manager by extracting components and utility functions into dedicated files.
    
    * feat: Enhance session terminal launching with support for iTerm2, Ghostty, WezTerm, and Alacritty, including UI and custom configuration options.
    
    * feat: Conditionally render terminal selection and resume session buttons only on macOS.
  • fix(stream_check): respect auth_mode for Claude health checks (#824)
    Previously, check_claude_stream always added the x-api-key header,
    ignoring the provider's auth_mode setting. This caused health check
    failures for proxy services that only support Bearer authentication.
    
    Now the function respects the auth.strategy field:
    - AuthStrategy::Anthropic: Authorization Bearer + x-api-key
    - AuthStrategy::ClaudeAuth: Authorization Bearer only
    - AuthStrategy::Bearer: Authorization Bearer only
    
    This aligns with the behavior of ClaudeAdapter::add_auth_headers
    and fixes health checks for proxy providers with auth_mode="bearer_only".
    
    Changes:
    - Modified check_claude_stream to conditionally add x-api-key header
    - Added AuthStrategy import
    - Added test_auth_strategy_imports unit test
    
    Tests: All passing (7/7 for stream_check module)
    
    Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
  • fix(skills): handle Windows path separator in installed status matching (#868)
    * fix(skills): handle Windows path separator in installed status matching
    
    Use regex to split directory path by both / and \ to correctly extract
    the install name on Windows, fixing the issue where installed skills
    were not showing as installed in the discovery page filter.
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * feat(skills): add repository filter to skills discovery page
    
    - Add dropdown to filter skills by repository (owner/name)
    - Extract unique repos from discoverable skills list
    - Add truncate style for long repo names with hover title
    - Add i18n translations for zh/en/ja
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
  • feat(ui): dynamic endpoint hint based on API format selection (#860)
    - Add apiHintOAI i18n key for OpenAI Chat Completions format hint
    - Update ClaudeFormFields to show format-specific endpoint hints
    - When API format is "openai_chat", show OAI-specific hint
    - Maintains consistency between hint and selected API format
    
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
  • fix(ci): add xdg-utils for ARM64 AppImage and suppress dead_code warnings
    - Add xdg-utils dependency for xdg-mime binary required by AppImage bundler
    - Remove unused McpStatus struct from gemini_mcp.rs (duplicate of claude_mcp.rs)
    - Add #![allow(dead_code)] to proxy models reserved for future type-safe API
  • feat(ci): add Linux ARM64 build support
    - Add ubuntu-22.04-arm runner to build matrix
    - Rename Linux artifacts with architecture suffix (x86_64/arm64)
    - Update pnpm cache key with runner.arch to avoid cross-arch pollution
    - Add linux-aarch64 platform to latest.json for Tauri updater
  • fix(mutations): use extractErrorMessage for complete error display
    Provider add/update/delete mutations were using error.message directly,
    which doesn't extract Tauri invoke errors properly. Now using the same
    extractErrorMessage pattern as the rest of the codebase.
  • chore: bump version to 3.10.3
    - Update version in package.json, Cargo.toml, and tauri.conf.json
    - Add missing changelog entries for OpenCode API key link and AICodeMirror preset
    - Fix Prettier formatting for new hook files
  • feat(opencode): add API key link support for OpenCode provider form
    Enable API key link feature for OpenCode app, allowing users to access
    provider websites for key registration directly from the form.
  • feat(providers): add AICodeMirror partner preset for all apps
    Register AICodeMirror icon, add i18n partner promotion texts (zh/en/ja),
    and fix trailing whitespace in codexProviderPresets.
  • docs(changelog): release v3.10.3
    Add changelog entry for v3.10.3 feature release including:
    - API format selector and presets
    - Pricing config enhancement
    - Skills ZIP install
    - Preferred terminal selection
    - Silent startup option
    - OpenCode environment check and directory sync
    - NVIDIA NIM and n1n.ai presets
    - Multiple bug fixes for Codex, proxy URL, tray menu, etc.
  • feat(settings): add OpenCode support to environment check and one-click install
    - Add OpenCode version detection with Go path scanning
    - Add GitHub Releases API for fetching latest OpenCode version
    - Add OpenCode install command to one-click install section
    - Update i18n hints to include OpenCode across all locales
    - Fix SettingsPage indentation formatting
  • feat(claude): show proxy hint when switching to OpenAI Chat format provider
    Display an info toast when switching to a provider that uses OpenAI Chat
    format (apiFormat === "openai_chat"), reminding users to enable the proxy
    service. Move toast logic from mutation to useProviderActions for better
    control over notification content based on provider properties.
  • refactor(proxy): remove DeepSeek max_tokens clamp from transform layer
    The max_tokens restriction was too aggressive and should be handled
    upstream or by the provider itself. Simplify anthropic_to_openai by
    removing provider parameter since model mapping is already done by
    proxy::model_mapper.
  • feat(providers): add NVIDIA NIM preset for Claude and OpenCode
    - Add NVIDIA NIM provider preset with API configuration
    - Add nvidia.svg icon and register in icon system
    - Add nvidia metadata with keywords and default color (#74B71B)
  • feat(claude): add apiFormat support for provider presets
    Allow preset providers to specify API format (anthropic or openai_chat),
    enabling third-party proxy services that use OpenAI Chat Completions format.
  • fix(proxy): improve URL building and remove redundant model mapping
    - Add model parameter to request logs for better debugging
    - Fix duplicate /v1/v1 in URL when both base_url and endpoint have version
    - Extend ?beta=true parameter to /v1/chat/completions endpoint
    - Remove model mapping from transform layer (now handled by model_mapper)
    - Add DeepSeek max_tokens clamping (1-8192 range)
  • refactor(claude): migrate api_format from settings_config to meta
    Move api_format storage from settings_config to ProviderMeta to prevent
    polluting ~/.claude/settings.json when switching providers.
    
    - Add api_format field to ProviderMeta (Rust + TypeScript)
    - Update ProviderForm to read/write apiFormat from meta
    - Maintain backward compatibility for legacy settings_config.api_format
      and openrouter_compat_mode fields (read-only fallback)
    - Strip api_format from settings_config before writing to live config
  • fix(i18n): update apiFormatOpenAIChat label to mention proxy requirement
    Change label from "Requires conversion" to "Requires proxy" for clarity:
    - zh: "需转换" → "需开启代理"
    - en: "Requires conversion" → "Requires proxy"
    - ja: "変換が必要" → "プロキシが必要"
  • fix(claude): improve backward compatibility for openrouter_compat_mode
    Extend backward compatibility support for legacy openrouter_compat_mode field:
    - Support number type (1 = enabled, 0 = disabled)
    - Support string type ("true"/"1" = enabled)
    - Add corresponding test cases for number and string types
  • feat(claude): add API format selector for third-party providers
    Replace the OpenRouter-specific compatibility toggle with a generic
    API format selector that allows all Claude providers to choose between:
    
    - Anthropic Messages (native): Direct passthrough, no conversion
    - OpenAI Chat Completions: Enables Anthropic ↔ OpenAI format conversion
    
    Changes:
    - Add ClaudeApiFormat type ("anthropic" | "openai_chat") to types.ts
    - Replace openRouterCompatToggle with apiFormat dropdown in ClaudeFormFields
    - Update ProviderForm to manage apiFormat state via settingsConfig.api_format
    - Refactor claude.rs: add get_api_format() method, update needs_transform()
    - Maintain backward compatibility with legacy openrouter_compat_mode field
    - Update i18n translations (zh, en, ja)
  • feat(skills): add install from ZIP file feature
    - Add open_zip_file_dialog command for selecting ZIP files
    - Add install_from_zip service method with recursive skill scanning
    - Add install_skills_from_zip Tauri command
    - Add frontend API methods and useInstallSkillsFromZip hook
    - Add "Install from ZIP" button in Skills management page
    - Support local skill ID format: local:{directory}
    - Add i18n translations for new feature and error messages
  • feat(settings): prioritize native install path for Claude Code detection
    - Move ~/.local/bin to first position in version scan search paths
    - Update one-click install commands to use official native installation
      (curl script) instead of npm for Claude Code
  • fix(codex): fix 404 errors and connection timeout with custom base_url (#760)
    * fix(proxy): fix Codex 404 errors with custom base_url prefixes
    
    - handlers.rs:268: Remove hardcoded /v1 prefix in Codex forwarding
    - codex.rs:140: Only add /v1 for origin-only base_urls, dedupe /v1/v1
    - stream_check.rs:364: Try /responses first, fallback to /v1/responses
    - provider.rs:427: Don't force /v1 for custom prefix base_urls
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * fix(codex): always add /v1 for custom prefix base_urls
    
    Changed logic to always add /v1 prefix unless base_url already ends with /v1.
    This fixes 504 timeout errors with relay services that expect /v1 in the path.
    
    - Most relay services follow OpenAI standard format: /v1/responses
    - Users can opt-out by adding /v1 to their base_url configuration
    - Updated test case to reflect new behavior
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * fix(proxy): allow system proxy on localhost with different ports
    
    - Only bypass system proxy if it points to CC Switch's own port (15721)
    - Allow other localhost proxies (e.g., Clash on 7890) to be used
    - Add INFO level logging for request URLs to aid debugging
    
    This fixes connection timeout issues when using local proxy tools.
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * fix(codex): don't add /v1 for custom prefix base_urls
    
    Reverted logic to not add /v1 for base_urls with custom prefixes.
    Many relay services use custom paths without /v1.
    
    - Pure origin (e.g., https://api.openai.com) → adds /v1
    - With /v1 (e.g., https://api.openai.com/v1) → no change
    - Custom prefix (e.g., https://example.com/openai) → no /v1
    
    This fixes 404 errors with relay services that don't use /v1 in their paths.
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * fix(proxy): use dynamic port for system proxy detection
    
    Instead of hardcoding port 15721, now uses the actual configured
    listen_port from proxy settings.
    
    - Added set_proxy_port() to update the port when proxy server starts
    - Added get_proxy_port() to retrieve current port for detection
    - Updated server.rs to call set_proxy_port() on startup
    - Updated tests to reflect new behavior
    
    This allows users to change the proxy port in settings without
    breaking the system proxy detection logic.
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * fix(proxy): change default proxy port from 15721 to 5000
    
    Update the default fallback port in get_proxy_port() from 15721 to 5000
    to match the project's standard default port configuration.
    
    Also updated test cases to use port 5000 consistently.
    
    Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
    
    * fix(proxy): revert default port back to 15721
    
    Revert the default fallback port in get_proxy_port() from 5000 back to 15721
    to align with the project's updated default port configuration.
    
    Also updated test cases to use port 15721 consistently.
    
    Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: ozbombor <ozbombor@users.noreply.github.com>
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
  • fix(settings): correct Gemini default visibility to true (#818)
    Frontend fallback value for visibleApps had gemini: false, which was
    inconsistent with backend default (gemini: true). This caused Gemini
    to be hidden by default on first install.
    
    Fixes #817
    
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
  • chore(presets): upgrade Kimi/Moonshot providers to k2.5 model
    - Update Moonshot preset models from kimi-k2-thinking to kimi-k2.5
    - Update OpenCode Kimi preset name and model to k2.5
    - Remove explicit model config from Kimi preset (use API defaults)
  • docs(sponsors): add AICodeMirror and reorder sponsor list
    - Add AICodeMirror as new sponsor with logo
    - Sync changes across all README languages (EN/ZH/JA)
  • fix(settings): correct footer layout in advanced settings tab
    - Establish proper flexbox height chain from App to SettingsPage
    - Move save button to fixed footer outside scrollable area
    - Align footer styling with FullScreenPanel for consistency
  • Feat/pricing config enhancement (#781)
    * feat(db): add pricing config fields to proxy_config table
    
    - Add default_cost_multiplier field per app type
    - Add pricing_model_source field (request/response)
    - Add request_model field to proxy_request_logs table
    - Implement schema migration v5
    
    * feat(api): add pricing config commands and provider meta fields
    
    - Add get/set commands for default cost multiplier
    - Add get/set commands for pricing model source
    - Extend ProviderMeta with cost_multiplier and pricing_model_source
    - Register new commands in Tauri invoke handler
    
    * fix(proxy): apply cost multiplier to total cost only
    
    - Move multiplier calculation from per-item to total cost
    - Add resolve_pricing_config for provider-level override
    - Include request_model and cost_multiplier in usage logs
    - Return new fields in get_request_logs API
    
    * feat(ui): add pricing config UI and usage log enhancements
    
    - Add pricing config section to provider advanced settings
    - Refactor PricingConfigPanel to compact table layout
    - Display all three apps (Claude/Codex/Gemini) in one view
    - Add multiplier column and request model display to logs
    - Add frontend API wrappers for pricing config
    
    * feat(i18n): add pricing config translations
    
    - Add zh/en/ja translations for pricing defaults config
    - Add translations for multiplier, requestModel, responseModel
    - Add provider pricing config translations
    
    * fix(pricing): align backfill cost calculation with real-time logic
    
    - Fix backfill to deduct cache_read_tokens from input (avoid double billing)
    - Apply multiplier only to total cost, not to each item
    - Add multiplier display in request detail panel with i18n support
    - Use AppError::localized for backend error messages
    - Fix init_proxy_config_rows to use per-app default values
    - Fix silent failure in set_default_cost_multiplier/set_pricing_model_source
    - Add clippy allow annotation for test mutex across await
    
    * style: format code with cargo fmt and prettier
    
    * fix(tests): correct error type assertions in proxy DAO tests
    
    The tests expected AppError::InvalidInput but the DAO functions use
    AppError::localized() which returns AppError::Localized variant.
    Updated assertions to match the correct error type with key validation.
    
    ---------
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • feat(opencode): sync all providers to live config on directory change
    Add additive mode support for OpenCode in sync_current_to_live:
    - Add AppType::is_additive_mode() to distinguish switch vs additive mode
    - Add AppType::all() iterator to avoid hardcoding app lists
    - Add sync_all_providers_to_live() for additive mode apps
    - Refactor sync_current_to_live to handle both modes
    
    Frontend changes (directory settings):
    - Track opencodeDirChanged in useDirectorySettings
    - Trigger syncCurrentProvidersLiveSafe when OpenCode dir changes
    - Add i18n strings for OpenCode directory settings
  • refactor(config): consolidate get_home_dir into single public function
    Follow-up to #644: Extract duplicate get_home_dir() implementations
    into a single pub fn in config.rs, reducing code duplication across
    codex_config.rs, gemini_config.rs, and settings.rs.
    
    Also adds documentation comments to build.rs explaining the Windows
    manifest workaround for test binaries.
  • feat(settings): add preferred terminal selection
    Allow users to choose their preferred terminal app for opening
    provider terminals. Supports platform-specific options:
    - macOS: Terminal.app, iTerm2, Alacritty, Kitty, Ghostty
    - Windows: cmd, PowerShell, Windows Terminal
    - Linux: GNOME Terminal, Konsole, Xfce4, Alacritty, Kitty, Ghostty
    
    Falls back to system default if selected terminal is unavailable.
  • refactor(terminal): consolidate redundant terminal launch functions
    Merge macOS Alacritty/Kitty/Ghostty launchers into a single generic
    `launch_macos_open_app` function with a `use_e_flag` parameter.
    Replace Windows cmd/PowerShell/wt launchers with a shared
    `run_windows_start_command` helper. Reduces ~98 lines of duplicate code.
  • fix(windows): stabilize test environment (#644)
    * fix(windows): embed common-controls manifest
    
    * fix(windows): prefer HOME for config paths
    
    * test(windows): fix export_sql invalid path
    
    * fix(windows): remove unused env import in config.rs
  • fix(skills): prevent duplicate skill installation from different repos (#778)
    - Add directory conflict detection before installation
    - Fix installed status check to match repo owner and name
    - Add i18n translations for conflict error messages
  • feat(ui): replace update badge dot with ArrowUpCircle icon
    - Replace blue dot indicator with lucide ArrowUpCircle icon
    - Change color scheme from blue to green for better visibility
    - Enlarge button (h-8 w-8) and icon (h-5 w-5) for better UX
    - Move UpdateBadge from title area to after settings icon
  • feat(skills): add skill sync method setting (symlink/copy)
    - Add SyncMethod enum (Auto/Symlink/Copy) in Rust backend
    - Implement sync_to_app_dir with symlink support (cross-platform)
    - Add SkillSyncMethodSettings UI component (simplified 2-button selector)
    - Add i18n support for zh/en/ja
    - Replace copy_to_app with configurable sync_to_app_dir
    - Add skill_sync_method field to AppSettings
    
    User can now choose between symlink (disk space saving) or copy (best compatibility) in Settings > General.
  • feat(partner): add RightCode as official partner
    Update RightCode referral link to use CCSWITCH affiliate code and mark
    as official partner with promotional messages in all supported languages.
  • fix(prompt): clear prompt file when all prompts are disabled
    When disabling a prompt, check if any other prompts remain enabled.
    If all prompts are disabled, clear the prompt file to ensure UI state
    matches the actual configuration that Claude Code reads.
  • fix(opencode): preserve extra model fields during serialization
    Add `extra` field with serde flatten to OpenCodeModel struct to capture
    custom fields like cost, modalities, thinking, and variants that were
    previously lost during save operations.