Commit Graph

738 Commits

  • 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.
  • fix(linux): resolve WebKitGTK DMA-BUF rendering issue and preserve user .desktop customizations
    - Set WEBKIT_DISABLE_DMABUF_RENDERER=1 at startup to fix blank screen on Debian 13.2 and Nvidia GPUs
    - Only register deep-link handler on first run to avoid overwriting user customizations
    - Use correct Tauri path API (app.path().data_dir()) instead of dirs::data_dir() to match plugin's actual .desktop file location
  • feat(migration): add error dialog for config.json loading failure
    - Show system dialog when config.json fails to load during migration
    - User can retry loading or exit the program
    - Exit before database creation ensures clean retry on next launch
    - Support Chinese/English localization based on system locale
  • fix(provider): validate current provider ID existence before use
    Add get_effective_current_provider() to validate local settings ID
    against database, with automatic cleanup and fallback to DB is_current.
    
    This fixes edge cases in multi-device cloud sync scenarios where local
    settings may contain stale provider IDs:
    
    - current(): now returns validated effective provider ID
    - update(): correctly syncs live config when local ID differs from DB
    - delete(): checks both local settings and DB to prevent deletion
    - switch(): backfill logic now targets valid provider
    - sync_current_to_live(): uses validated ID with auto-fallback
    - tray menu: displays correct checkmark on startup
    
    Also fixes test issues:
    - Add missing test setup calls (mutex, reset_test_fs, ensure_test_home)
    - Correct Gemini security settings path to ~/.gemini/settings.json
  • refactor(provider): use local settings for current provider selection
    Complete the device-level settings separation for cloud sync support.
    
    Backend changes:
    - Modify switch() to update both local settings and database is_current
    - Modify current() to read from local settings first, fallback to database
    - Rename sync_current_from_db() to sync_current_to_live()
    - Update tray menu to read current provider from local settings
    
    Frontend changes:
    - Update Settings interface: remove legacy fields (customEndpoints*, security)
    - Add currentProviderClaude/Codex/Gemini fields
    - Update settings schema accordingly
    
    Test fixes:
    - Update Gemini security tests to check ~/.gemini/settings.json
      instead of ~/.cc-switch/settings.json (security field was never
      stored in CC Switch settings)
    
    This ensures each device maintains its own current provider selection
    independently when database is synced across devices.
  • refactor(settings): move device-level settings to local file storage
    Separate device-level settings from database to support cloud sync scenarios
    where multiple devices share the same database but need independent settings.
    
    Changes:
    - Remove database storage logic (bind_db, save_to_db, load_from_db)
    - Remove legacy custom_endpoints_claude/codex fields (actual data in provider.meta)
    - Add current_provider_claude/codex/gemini fields for device-level provider selection
    - Add get_current_provider() and set_current_provider() helper functions
    - Settings now stored only in ~/.cc-switch/settings.json
    
    This ensures that when database is synced across devices, each device
    maintains its own current provider selection independently.
  • refactor(gemini): improve config handling and code consistency
    - Fix envObjToString to preserve custom environment variables
    - Add bidirectional MCP format conversion (httpUrl <-> url)
    - Merge provider config with existing settings.json instead of overwriting
    - Remove redundant is_packycode_gemini function
    - Simplify is_google_official_gemini using detect_gemini_auth_type
    - Add handleGeminiModelChange for consistent field handling
  • fix(gemini): correctly write custom provider env to .env file
    write_live_snapshot was incorrectly passing the already-extracted env
    sub-field to json_to_env, which expects the full settings_config object.
    This caused json_to_env to look for env.env (nested), returning an empty
    HashMap and writing an empty .env file.
    
    Fix by delegating to write_gemini_live which correctly handles env file
    writing and security flag configuration in one place.
  • fix(gemini): write security auth config only to Gemini settings file
    - Remove redundant security.auth.selectedType from CC Switch settings
    - Fix Generic provider type not writing security flag on switch
    - All non-Google Official providers now correctly write "gemini-api-key"
    - Delete unused ensure_packycode_security_flag function
    - Clean up SecuritySettings and SecurityAuthSettings types from AppSettings
  • feat(preset): add MiniMax as official partner with Black Friday promotion
    - Mark MiniMax as partner with custom theme color (#f64551)
    - Add Black Friday promotional text for Starter plan ($2/mo, 80% OFF)
    - Update apiKeyUrl to MiniMax coding plan subscription page
  • fix(query): prevent redundant usage queries when switching apps
    Add staleTime and gcTime to useUsageQuery to avoid triggering
    unnecessary API calls when switching between app tabs. The staleTime
    is set dynamically based on the auto-refresh interval (or 5 minutes
    by default), and gcTime is set to 10 minutes to preserve cache after
    component unmount.
  • fix(ui): improve ConfirmDialog styling for better visual consistency
    - Remove header/footer borders and backgrounds for compact alert style
    - Use theme-aware overlay color (bg-background/80) instead of black
    - Add zIndex="alert" to ensure dialog appears above other dialogs
  • refactor(provider): unify validation errors to use toast notifications
    Change template parameter validation from form.setError to toast.error
    for consistent UX across all required field validations.
  • feat(provider): add required field validation with toast notifications
    - Add validation for provider name (required for all providers)
    - Add validation for API endpoint and API Key (required for non-official providers)
    - Use toast notifications instead of inline form errors for better visibility
    - Move name validation from zod schema to handleSubmit for consistent UX
    - Add i18n keys: endpointRequired, apiKeyRequired
  • fix(preset): use ANTHROPIC_AUTH_TOKEN for DMXAPI and correct endpoint candidates
    - Change DMXAPI preset from ANTHROPIC_API_KEY to ANTHROPIC_AUTH_TOKEN
    - Fix endpointCandidates that were incorrectly copied from AiHubMix
  • refactor(config): remove dead code from JSON-era import/export
    Remove obsolete methods that were superseded by SQLite-based
    import/export in v3.7.0:
    
    - export_config_to_path: replaced by Database::export_sql
    - load_config_for_import: no longer used
    - import_config_from_path: stub that only returned error
    
    Also remove unused AppState import.
  • fix(provider): preserve custom endpoints when updating provider
    - Replace INSERT OR REPLACE with UPDATE for existing providers to avoid
      triggering ON DELETE CASCADE on provider_endpoints table
    - Fix endpoint merging logic to correctly mark database endpoints as
      isCustom when they overlap with preset endpoints
    
    The root cause was that INSERT OR REPLACE performs DELETE + INSERT under
    the hood, which triggered the foreign key cascade and deleted all
    associated endpoints from provider_endpoints table.
  • refactor(ui): improve header toolbar layout and transitions
    - Reorder toolbar buttons to keep Prompts and MCP icons aligned right
      (consistent position between Claude and Codex apps)
    - Add smooth fade-in/out transition for Skills button with opacity,
      width, scale, and padding animations
    - Hide Agents button temporarily (feature in development)
    - Remove two divider lines for cleaner appearance
  • fix(ui): disable overscroll bounce effect on main view
    Prevents the top border line from being pulled down when scrolling
    past the top of the page by setting overscroll-behavior: none on html.
  • feat(migration): enable silent JSON to SQLite migration with toast notification
    - Remove environment variable feature gate (CC_SWITCH_ENABLE_JSON_DB_MIGRATION)
    - Automatically migrate config.json to SQLite when db doesn't exist
    - Archive migrated config.json as config.json.migrated for recovery
    - Add migration success flag in init_status.rs (one-time consumption)
    - Add get_migration_result command for frontend to query
    - Show toast notification on successful migration in App.tsx