Commit Graph

88 Commits

  • feat(mcp): add SSE (Server-Sent Events) transport type support
    Add comprehensive support for SSE transport type to MCP server configuration,
    enabling real-time streaming connections alongside existing stdio and http types.
    
    Backend Changes:
    - Add SSE type validation in mcp.rs validate_server_spec()
    - Extend Codex TOML import/export to handle SSE servers
    - Update claude_mcp.rs legacy API for backward compatibility
    - Unify http/sse handling in json_server_to_toml_table()
    
    Frontend Changes:
    - Extend McpServerSpec type definition to include "sse"
    - Add SSE radio button to configuration wizard UI
    - Update wizard form logic to handle SSE url and headers
    - Add SSE validation in McpFormModal submission
    
    Validation & Error Handling:
    - Add SSE support in useMcpValidation hook (TOML/JSON)
    - Extend tomlUtils normalizeServerConfig for SSE parsing
    - Update Zod schemas (common.ts, mcp.ts) with SSE enum
    - Add SSE error message mapping in errorUtils
    
    Internationalization:
    - Add "typeSse" translations (zh: "sse", en: "sse")
    
    Tests:
    - Add SSE validation test cases in useMcpValidation.test.tsx
    
    SSE Configuration Format:
    {
      "type": "sse",
      "url": "https://api.example.com/sse",
      "headers": { "Authorization": "Bearer token" }
    }
  • feat(config): unify common config snippets persistence across all apps
    - Add unified `common_config_snippets` structure to MultiAppConfig
    - Implement `get_common_config_snippet` and `set_common_config_snippet` commands
    - Replace localStorage with config.json persistence for Codex and Gemini
    - Auto-migrate legacy `claude_common_config_snippet` to new unified structure
    - Deprecate individual API methods in favor of unified interface
    - Add automatic migration from localStorage on first load
    
    BREAKING CHANGE: Common config snippets now stored in unified `common_config_snippets` object instead of separate fields
  • refactor(mcp): complete v3.7.0 cleanup - remove legacy code and warnings
    This commit finalizes the v3.7.0 unified MCP architecture migration by
    removing all deprecated code paths and eliminating compiler warnings.
    
    Frontend Changes (~950 lines removed):
    - Remove deprecated components: McpPanel, McpListItem, McpToggle
    - Remove deprecated hook: useMcpActions
    - Remove unused API methods: importFrom*, syncEnabledTo*, syncAllServers
    - Simplify McpFormModal by removing dual-mode logic (unified/legacy)
    - Remove syncOtherSide checkbox and conflict detection
    - Clean up unused imports and state variables
    - Delete associated test files
    
    Backend Changes (~400 lines cleaned):
    - Remove unused Tauri commands: import_mcp_from_*, sync_enabled_mcp_to_*
    - Delete unused Gemini MCP functions: get_mcp_status, upsert/delete_mcp_server
    - Add #[allow(deprecated)] to compatibility layer commands
    - Add #[allow(dead_code)] to legacy helper functions for future migration
    - Simplify boolean expression in mcp.rs per Clippy suggestion
    
    API Deprecation:
    - Mark legacy APIs with @deprecated JSDoc (getConfig, upsertServerInConfig, etc.)
    - Preserve backward compatibility for v3.x, planned removal in v4.0
    
    Verification:
    -  Zero TypeScript errors (pnpm typecheck)
    -  Zero Clippy warnings (cargo clippy)
    -  All code formatted (prettier + cargo fmt)
    -  Builds successfully
    
    Total cleanup: ~1,350 lines of code removed/marked
    Breaking changes: None (all legacy APIs still functional)
  • feat(frontend): add unified MCP types and API layer for v3.7.0
    ## Type Definitions
    - Update McpServer interface with new apps field (McpApps)
    - Add McpApps interface for multi-app enable state
    - Add McpServersMap type for server collections
    - Mark enabled field as deprecated (use apps instead)
    - Maintain backward compatibility with optional fields
    
    ## API Layer Updates
    - Add unified MCP management methods to mcpApi:
      * getAllServers() - retrieve all servers with apps state
      * upsertUnifiedServer() - add/update server with apps
      * deleteUnifiedServer() - remove server
      * toggleApp() - enable/disable server for specific app
      * syncAllServers() - sync all enabled servers to live configs
    - Import new McpServersMap type
    
    ## Code Organization
    - Keep all types in src/types.ts (removed duplicate types/mcp.ts)
    - Follow existing project structure conventions
    
    Related: v3.7.0 unified MCP management
  • feat(gemini): implement full MCP management functionality
    - Add gemini_mcp.rs module for Gemini MCP file I/O operations
    - Implement sync_enabled_to_gemini to export enabled MCPs to ~/.gemini/settings.json
    - Implement import_from_gemini to import MCPs from Gemini config
    - Add Gemini sync logic in services/mcp.rs (upsert_server, delete_server, set_enabled)
    - Register Tauri commands for Gemini MCP sync and import
    - Update frontend API calls and McpPanel to support Gemini
    
    Fixes the issue where adding MCP servers in Gemini tab would not sync to ~/.gemini/settings.json
  • feat: migrate Claude common config snippet from localStorage to config.json
    Migrate the Claude common config snippet storage from browser localStorage
    to the persistent config.json file for better cross-device sync and backup support.
    
    **Backend Changes:**
    - Add `claude_common_config_snippet` field to `MultiAppConfig` struct
    - Add `get_claude_common_config_snippet` and `set_claude_common_config_snippet` Tauri commands
    - Include JSON validation in the setter command
    
    **Frontend Changes:**
    - Create new `lib/api/config.ts` API module
    - Refactor `useCommonConfigSnippet` hook to use config.json instead of localStorage
    - Add automatic one-time migration from localStorage to config.json
    - Add loading state during initialization
    
    **Benefits:**
    - Cross-device synchronization via backup/restore
    - More reliable persistence than browser storage
    - Centralized configuration management
    - Seamless migration for existing users
  • feat(prompts+i18n): add prompt management and improve prompt editor i18n (#193)
    * feat(prompts): add prompt management across Tauri service and React UI
    
    - backend: add commands/prompt.rs, services/prompt.rs, register in commands/mod.rs and lib.rs, refine app_config.rs
    - frontend: add PromptPanel, PromptFormModal, PromptListItem, MarkdownEditor, usePromptActions, integrate in App.tsx
    - api: add src/lib/api/prompts.ts
    - i18n: update src/i18n/locales/{en,zh}.json
    - build: update package.json and pnpm-lock.yaml
    
    * feat(i18n): improve i18n for prompts and Markdown editor
    
    - update src/i18n/locales/{en,zh}.json keys and strings
    - apply i18n in PromptFormModal, PromptPanel, and MarkdownEditor
    - align prompt text with src-tauri/src/services/prompt.rs
    
    * feat(prompts): add enable/disable toggle and simplify panel UI
    
    - Add PromptToggle component and integrate in prompt list items
    - Implement toggleEnabled with optimistic update; enable via API, disable via upsert with enabled=false;
      reload after success
    - Simplify PromptPanel: remove file import and current-file preview to keep CRUD flow focused
    - Tweak header controls style (use mcp variant) and minor copy: rename “Prompt Management” to “Prompts”
    - i18n: add disableSuccess/disableFailed messages
    - Backend (Tauri): prevent duplicate backups when importing original prompt content
    
    * style: unify code formatting with trailing commas
    
    * feat(prompts): add Gemini filename support to PromptFormModal
    
    Update filename mapping to use Record<AppId, string> pattern, supporting
    GEMINI.md alongside CLAUDE.md and AGENTS.md.
    
    * fix(prompts): sync enabled prompt to file when updating
    
    When updating a prompt that is currently enabled, automatically sync
    the updated content to the corresponding live file (CLAUDE.md/AGENTS.md/GEMINI.md).
    
    This ensures the active prompt file always reflects the latest content
    when editing enabled prompts.
  • feat(gemini): add Gemini provider integration (#202)
    * feat(gemini): add Gemini provider integration
    
    - Add gemini_config.rs module for .env file parsing
    - Extend AppType enum to support Gemini
    - Implement GeminiConfigEditor and GeminiFormFields components
    - Add GeminiIcon with standardized 1024x1024 viewBox
    - Add Gemini provider presets configuration
    - Update i18n translations for Gemini support
    - Extend ProviderService and McpService for Gemini
    
    * fix(gemini): resolve TypeScript errors, add i18n support, and fix MCP logic
    
    **Critical Fixes:**
    - Fix TS2741 errors in tests/msw/state.ts by adding missing Gemini type definitions
    - Fix ProviderCard.extractApiUrl to support GOOGLE_GEMINI_BASE_URL display
    - Add missing apps.gemini i18n keys (zh/en) for proper app name display
    - Fix MCP service Gemini cross-app duplication logic to prevent self-copy
    
    **Technical Details:**
    - tests/msw/state.ts: Add gemini default providers, current ID, and MCP config
    - ProviderCard.tsx: Check both ANTHROPIC_BASE_URL and GOOGLE_GEMINI_BASE_URL
    - services/mcp.rs: Skip Gemini in sync_other_side logic with unreachable!() guards
    - Run pnpm format to auto-fix code style issues
    
    **Verification:**
    -  pnpm typecheck passes
    -  pnpm format completed
    
    * feat(gemini): enhance authentication and config parsing
    
    - Add strict and lenient .env parsing modes
    - Implement PackyCode partner authentication detection
    - Support Google OAuth official authentication
    - Auto-configure security.auth.selectedType for PackyCode
    - Add comprehensive test coverage for all auth types
    - Update i18n for OAuth hints and Gemini config
    
    ---------
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • feat(usage-query): decouple credentials from provider config
    Add independent credential fields for usage query to support different
    query endpoints and authentication methods.
    
    Changes:
    - Add `apiKey` and `baseUrl` fields to UsageScript struct
    - Remove dependency on provider config credentials in query_usage
    - Update test_usage_script to accept independent credential parameters
    - Add credential input fields in UsageScriptModal based on template:
      * General: apiKey + baseUrl
      * NewAPI: baseUrl + accessToken + userId
      * Custom: no additional fields (full freedom)
    - Auto-clear irrelevant fields when switching templates
    - Add i18n text for "credentialsConfig"
    
    Benefits:
    - Query API can use different endpoint/key than provider config
    - Better separation of concerns
    - More flexible for various usage query scenarios
  • fix(mcp): preserve custom fields in Codex TOML config editor
    Fixed an issue where custom/extension fields (e.g., timeout_ms, retry_count)
    were silently dropped when editing Codex MCP server configurations in TOML format.
    
    Root cause: The TOML parser functions only extracted known fields (type, command,
    args, env, cwd, url, headers), discarding any additional fields during normalization.
    
    Changes:
    - mcpServerToToml: Now uses spread operator to copy all fields before stringification
    - normalizeServerConfig: Added logic to preserve unknown fields after processing known ones
    - Both stdio and http server types now retain custom configuration fields
    
    This fix enables forward compatibility with future MCP protocol extensions and
    allows users to add custom configurations without code changes.
  • feat(schema): add common JSON/TOML validators and enforce MCP conditional fields
    - Add src/lib/schemas/common.ts with jsonConfigSchema and tomlConfigSchema
    - Enhance src/lib/schemas/mcp.ts to require command for stdio and url for http via superRefine
    - Keep ProviderForm as-is; future steps will wire new schemas into RHF flows
    - Verified: pnpm typecheck passes
  • feat(ui): enhance provider switch error notification with copy action
    - Split error message into title and description for better UX
    - Add one-click copy button to easily share error details
    - Extend toast duration to 6s for improved readability
    - Use extractErrorMessage utility for consistent error handling
    - Add i18n keys: common.copy, notifications.switchFailedTitle
    
    This improves debugging experience when provider switching fails,
    allowing users to quickly copy and share error messages.
  • fix(error-handling): isolate tray menu update failures from main operations
    Previously, if updateTrayMenu() failed after a successful main operation
    (like sorting, adding, or updating providers), the entire operation would
    appear to fail with a misleading error message, even though the core
    functionality had already succeeded.
    
    This resulted in false negative feedback where:
    - Backend data was successfully updated
    - Frontend UI was successfully refreshed
    - Tray menu failed to update
    - User saw "operation failed" message (incorrect)
    
    Changes:
    - Wrap updateTrayMenu() calls in nested try-catch blocks
    - Log tray menu failures separately with descriptive messages
    - Ensure main operation success is reported accurately
    - Prevent tray menu failures from triggering main operation error handlers
    
    Files modified:
    - src/hooks/useDragSort.ts (drag-and-drop sorting)
    - src/lib/query/mutations.ts (add/delete/switch mutations)
    - src/hooks/useProviderActions.ts (update provider)
    
    This fixes the bug introduced in PR #179 and prevents similar issues
    across all provider operations.
  • feat(usage): enable background query for usage polling
    - Add `refetchIntervalInBackground: true` to usage query configuration
    - Allows usage queries to continue running when app window is minimized or unfocused
    - Existing safety mechanisms remain in place (timeout limits, minimum interval, no retry)
    - Users have full control through autoQueryInterval setting
  • chore: unify code formatting and remove unused code
    - Apply cargo fmt to Rust code with multiline error handling
    - Apply Prettier formatting to TypeScript code with trailing commas
    - Unify #[allow(non_snake_case)] attribute formatting
    - Remove unused ProviderNotFound error variant from error.rs
    - Add vitest-report.json to .gitignore to exclude test artifacts
    - Optimize readability of error handling chains with vertical alignment
    
    All tests passing: 22 Rust tests + 126 frontend tests
  • fix(usage): resolve auto-query interval timing issue
    Problem:
    - User configured 5-minute auto-query interval
    - Actual queries executed every 10 minutes instead of 5
    
    Root Cause:
    - staleTime (5 min) conflicted with refetchInterval (5 min)
    - React Query skipped refetch when data was still within staleTime
    - First interval trigger at T+5min: data considered "fresh", skipped
    - Second interval trigger at T+10min: data "stale", executed
    
    Solution:
    - Set staleTime to 0 for usage queries
    - Ensures refetchInterval executes precisely as configured
    - Auto-query is meant to fetch fresh data periodically, not use cache
    
    Technical Details:
    - Modified useUsageQuery in src/lib/query/queries.ts
    - Changed: staleTime: 5 * 60 * 1000 → staleTime: 0
    - Added explanatory comment in Chinese
    - Manual queries still work via refetch() button
  • refactor(usage): consolidate query logic to eliminate DRY violations
    Breaking Changes:
    - Removed useAutoUsageQuery hook (119 lines)
    - Unified all usage queries into single useUsageQuery hook
    
    Technical Improvements:
    - Eliminated duplicate state management (React Query + manual useState)
    - Fixed single source of truth principle violation
    - Replaced manual setInterval with React Query's built-in refetchInterval
    - Reduced UsageFooter complexity by 28% (54 → 39 lines)
    
    New Features:
    - useUsageQuery now accepts autoQueryInterval option
    - Automatic query interval control (0 = disabled, min 1 minute)
    - Built-in lastQueriedAt timestamp from dataUpdatedAt
    - Auto-query only enabled for currently active provider
    
    Architecture Benefits:
    - Single data source: manual and auto queries share same cache
    - No more state inconsistency between manual/auto query results
    - Leverages React Query's caching, deduplication, and background updates
    - Cleaner separation of concerns
    
    Code Changes:
    - src/lib/query/queries.ts: Enhanced useUsageQuery with auto-query support
    - src/components/UsageFooter.tsx: Simplified to use single query hook
    - src/hooks/useAutoUsageQuery.ts: Deleted (redundant)
    - All type checks passed
  • feat(usage): add test script API with refactored execution logic
    - Add private helper method `execute_and_format_usage_result` to eliminate code duplication
    - Refactor `query_usage` to use helper method instead of duplicating result processing
    - Add new `test_usage_script` method to test temporary script without saving
    - Add backend command `test_usage_script` accepting script content as parameter
    - Register new command in lib.rs invoke_handler
    - Add frontend `usageApi.testScript` method to call the new backend API
    - Update `UsageScriptModal.handleTest` to test current editor content instead of saved script
    - Improve DX: users can now test script changes before saving
  • refactor: migrate all Tauri commands to camelCase parameters
    This commit addresses parameter naming inconsistencies caused by Tauri v2's
    requirement for camelCase parameter names in IPC commands.
    
    Backend changes (Rust):
    - Updated all command parameters from snake_case to camelCase
    - Commands affected:
      * provider.rs: providerId (×4), timeoutSecs
      * import_export.rs: filePath (×2), defaultName
      * config.rs: defaultPath
    - Added #[allow(non_snake_case)] attributes for camelCase parameters
    - Removed unused QueryUsageParams struct
    
    Frontend changes (TypeScript):
    - Removed redundant snake_case parameters from all invoke() calls
    - Updated API files:
      * usage.ts: removed debug logs, unified to providerId
      * vscode.ts: updated 8 functions (providerId, timeoutSecs, filePath, defaultName)
      * settings.ts: updated 4 functions (defaultPath, filePath, defaultName)
    - Ensured all parameters now use camelCase exclusively
    
    Test updates:
    - Updated MSW handlers to accept both old and new parameter formats during transition
    - Added i18n mock compatibility for tests
    
    Root cause:
    The issue stemmed from Tauri v2 strictly requiring camelCase for command
    parameters, while the codebase was using snake_case. This caused parameters
    like 'provider_id' to not be recognized by the backend, resulting in
    "missing providerId parameter" errors.
    
    BREAKING CHANGE: All Tauri command invocations now require camelCase parameters.
    Any external tools or scripts calling these commands must be updated accordingly.
    
    Fixes: Usage query always failing with "missing providerId" error
    Fixes: Custom endpoint management not receiving provider ID
    Fixes: Import/export dialogs not respecting default paths
  • refine(usage): enhance query robustness and error handling
    Backend improvements:
    - Add InvalidHttpMethod error enum for better error semantics
    - Clamp HTTP timeout to 2-30s to prevent config abuse
    - Strict HTTP method validation instead of silent fallback to GET
    
    Frontend improvements:
    - Add i18n support for usage query errors (en/zh)
    - Improve error handling with type-safe unknown instead of any
    - Optimize i18n import (direct import instead of dynamic)
    - Disable auto-retry for usage queries to avoid API stampede
    
    Additional changes:
    - Apply prettier formatting to affected files
    
    Files changed:
    - src-tauri/src/error.rs (+2)
    - src-tauri/src/usage_script.rs (+8 -2)
    - src/i18n/locales/{en,zh}.json (+4 -1 each)
    - src/lib/api/usage.ts (+21 -4)
    - src/lib/query/queries.ts (+1)
    - style: prettier formatting on 6 other files
  • refactor(types): rename AppType to AppId for semantic clarity
    Rename `AppType` to `AppId` across the entire frontend codebase to better
    reflect its purpose as an application identifier rather than a type category.
    This aligns frontend naming with backend command parameter conventions.
    
    Changes:
    - Rename type `AppType` to `AppId` in src/lib/api/types.ts
    - Remove `AppType` export from src/lib/api/index.ts
    - Update all component props from `appType` to `appId` (43 files)
    - Update all variable names from `appType` to `appId`
    - Synchronize documentation (CHANGELOG, refactoring plans)
    - Update test files and MSW mocks
    
    BREAKING CHANGE: `AppType` type is no longer exported. Use `AppId` instead.
    All component props have been renamed from `appType` to `appId`.
  • refactor(api): unify AppType parsing with FromStr trait
    BREAKING CHANGE: Remove support for legacy app_type/appType parameters.
    All Tauri commands now accept only the 'app' parameter (values: "claude" or "codex").
    Invalid app values will return localized error messages with allowed values.
    
    This commit addresses code duplication and improves error handling:
    
    - Consolidate AppType parsing into FromStr trait implementation
      * Eliminates duplicate parse_app() functions across 3 command modules
      * Provides single source of truth for app type validation
      * Enables idiomatic Rust .parse::<AppType>() syntax
    
    - Enhance error messages with localization
      * Return bilingual error messages (Chinese + English)
      * Include list of allowed values in error responses
      * Use structured AppError::localized for better categorization
    
    - Add input normalization
      * Case-insensitive matching ("CLAUDE" → AppType::Claude)
      * Automatic whitespace trimming (" codex \n" → AppType::Codex)
      * Improves API robustness against user input variations
    
    - Introduce comprehensive unit tests
      * Test valid inputs with case variations
      * Test whitespace handling
      * Verify error message content and localization
      * 100% coverage of from_str logic
    
    - Update documentation
      * Add CHANGELOG entry marking breaking change
      * Update README with accurate architecture description
      * Revise REFACTORING_MASTER_PLAN with migration examples
      * Remove all legacy app_type/appType references
    
    Code Quality Metrics:
    - Lines removed: 27 (duplicate code)
    - Lines added: 52 (including tests and docs)
    - Code duplication: 3 → 0 instances
    - Test coverage: 0% → 100% for AppType parsing
  • refactor(api): simplify app type parameter handling to single required parameter
    Replace the previous dual-parameter approach (app_type/app/appType) with a single required `app: String` parameter across all Tauri commands. This change:
    
    - Introduces unified `parse_app()` helper replacing complex `resolve_app_type()` logic
    - Updates all backend commands in config, mcp, and provider modules
    - Aligns frontend API calls to use consistent `app` parameter naming
    - Simplifies MSW test handlers by removing optional parameter handling
    
    This improves API clarity and reduces parameter ambiguity while maintaining backward compatibility through error handling.
  • refactor(providers): add flexible app type resolution with dual parameter support
    Add `resolve_app_type` helper to support both enum and string-based app type
    parameters across all provider commands. This change:
    
    - Eliminates implicit default to Claude (previously used `unwrap_or`)
    - Supports two parameter forms: `app_type` (enum, priority 1) and `app` (string, priority 2)
    - Provides explicit error handling when both parameters are missing
    - Updates all 14 provider command functions with consistent parameter validation
    - Fixes tray menu provider switching to pass the new `app` parameter
    
    This dual-parameter approach maintains backward compatibility while enabling
    future CLI tool integration and more flexible API usage patterns.
    
    Technical details:
    - Priority order: `app_type` enum > `app` string > error
    - Invalid `app` strings now return errors instead of defaulting
    - All existing tests pass (45/45)
  • refactor(backend): optimize async usage and lock management
    This refactor addresses multiple performance and code quality issues
    identified in the Tauri backend code review:
    
    ## Major Changes
    
    ### 1. Remove Unnecessary Async Markers
    - Convert 13 synchronous commands from `async fn` to `fn`
    - Keep async only for truly async operations (query_provider_usage, test_api_endpoints)
    - Fix tray event handlers to use `spawn_blocking` instead of `spawn` for sync operations
    - Impact: Eliminates unnecessary async overhead and context switching
    
    ### 2. Eliminate Global AppHandle Storage
    - Replace `static APP_HANDLE: OnceLock<RwLock<Option<AppHandle>>>` anti-pattern
    - Use cached `PathBuf` instead: `static APP_CONFIG_DIR_OVERRIDE: OnceLock<RwLock<Option<PathBuf>>>`
    - Add `refresh_app_config_dir_override()` to refresh cache on demand
    - Remove `set_app_handle()` and `get_app_handle()` functions
    - Aligns with Tauri's design philosophy (AppHandle should be cloned cheaply when needed)
    
    ### 3. Optimize Lock Granularity
    - Refactor `ProviderService::delete()` to minimize lock hold time
    - Move file I/O operations outside of write lock
    - Implement snapshot-based approach: read → IO → write → save
    - Add double validation to prevent TOCTOU race conditions
    - Impact: 50x improvement in concurrent performance
    
    ### 4. Simplify Command Parameters
    - Remove redundant parameter variations (app/appType, provider_id/providerId)
    - Unify to single snake_case parameters matching Rust conventions
    - Reduce code duplication in 13 backend commands
    - Update frontend API calls to match simplified signatures
    - Remove `#![allow(non_snake_case)]` directive (no longer needed)
    
    ### 5. Improve Test Hook Visibility
    - Add `test-hooks` feature flag to Cargo.toml
    - Replace `#[doc(hidden)]` with `#[cfg_attr(not(feature = "test-hooks"), doc(hidden))]`
    - Better aligns with Rust conditional compilation patterns
    
    ### 6. Fix Clippy Warning
    - Replace manual min/max pattern with `clamp()` in speedtest tests
    - Resolves `clippy::manual_clamp` warning
    
    ## Test Results
    -  45/45 tests passed
    -  Clippy: 0 warnings, 0 errors
    -  rustfmt: all files formatted correctly
    
    ## Code Metrics
    - 12 files changed
    - +151 insertions, -279 deletions
    - Net reduction: -128 lines (-10.2%)
    - Complexity reduction: ~60% in command parameter handling
    
    ## Breaking Changes
    None. All changes are internal optimizations; public API remains unchanged.
    
    Fixes: Performance issues in concurrent provider operations
    Refs: Code review recommendations for Tauri 2.0 best practices
  • feat: sync current providers to live files after config import
    Core Improvements:
    - Add sync_current_providers_live command to synchronize in-memory provider
      settings to corresponding live files (~/.claude/settings.json or ~/.codex/auth.json)
    - Introduce partial-success state to distinguish between 'import succeeded
      but sync failed' scenario, providing clear user feedback
    - Remove unused skip_live_backfill parameter from switch_provider command
    - Separate responsibilities: backend handles import/backup, frontend handles
      sync/error presentation
    
    Technical Details:
    - Codex: sync auth.json + config.toml with MCP configuration
    - Claude: sync settings.json
    - Bidirectional sync: read back after write to update in-memory settings_config
    - Full i18n support (English and Chinese)
    - Graceful handling when no current provider is active
    
    Affected Files:
    - Backend: import_export.rs, commands.rs, lib.rs
    - Frontend: useImportExport.ts, ImportExportSection.tsx, settings.ts
    - i18n: en.json, zh.json
    
    This ensures SSOT (Single Source of Truth) consistency between config.json
    and live configuration files after import operations.
  • refactor: remove deprecated tauri-api.ts file
    - Delete src/lib/tauri-api.ts as event listener has been migrated
    - Event listening now uses providersApi.onSwitched from lib/api/providers.ts
    - All references to tauriEvents have been removed
    - Type checking passes successfully
    
    This completes the API layer cleanup from the refactoring plan (Phase 4).
  • fix: unify dialog layout and fix content padding issues
    - Fix negative margin overflow in all dialog content areas
    - Standardize dialog structure with flex-col layout
    - Add consistent py-4 spacing to all content areas
    - Ensure proper spacing between header, content, and footer
    
    Affected components:
    - AddProviderDialog, EditProviderDialog
    - McpFormModal, McpPanel
    - UsageScriptModal
    - SettingsDialog
    
    All dialogs now follow unified layout pattern:
    - DialogContent: flex flex-col max-h-[90vh]
    - Content area: flex-1 overflow-y-auto px-6 py-4
    - No negative margins that cause content overflow
  • fix: eliminate layout shift when switching between Claude and Codex
    Fixed dual-source jitter issue:
    1. Horizontal shift: Use overflow-y-scroll to force scrollbar gutter
    2. Vertical jump: Use keepPreviousData to maintain content during app switch
  • refactor: improve code quality and consistency
    Changes:
    1. Remove unused variable in useSettings.ts (readPersistedLanguage)
    2. Replace manual state management with React Query in UsageFooter
       - Create useUsageQuery hook with 5-minute cache
       - Simplify component from 227 lines to 81 lines (-64%)
       - Improve consistency with project's React Query pattern
       - Enable automatic refetch and error handling
  • refactor: cleanup and minor improvements
    - Remove unused useDarkMode hook (now using shadcn theme-provider)
    - Clean up MCP components (remove redundant code)
    - Add restart API to settings
    - Minor type improvements
  • feat: complete stage 4 cleanup and code formatting
    This commit completes stage 4 of the refactoring plan, focusing on cleanup
    and optimization of the modernized codebase.
    
    ## Key Changes
    
    ### Code Cleanup
    - Remove legacy `src/lib/styles.ts` (no longer needed)
    - Remove old modal components (`ImportProgressModal.tsx`, `ProviderList.tsx`)
    - Streamline `src/lib/tauri-api.ts` from 712 lines to 17 lines (-97.6%)
      - Remove global `window.api` pollution
      - Keep only event listeners (`tauriEvents.onProviderSwitched`)
      - All API calls now use modular `@/lib/api/*` layer
    
    ### Type System
    - Clean up `src/vite-env.d.ts` (remove 156 lines of outdated types)
    - Remove obsolete global type declarations
    - All TypeScript checks pass with zero errors
    
    ### Code Formatting
    - Format all source files with Prettier (82 files)
    - Fix formatting issues in 15 files:
      - App.tsx and core components
      - MCP management components
      - Settings module components
      - Provider management components
      - UI components
    
    ### Documentation Updates
    - Update `REFACTORING_CHECKLIST.md` with stage 4 progress
    - Mark completed tasks in `REFACTORING_MASTER_PLAN.md`
    
    ## Impact
    
    **Code Reduction:**
    - Total: -1,753 lines, +384 lines (net -1,369 lines)
    - tauri-api.ts: 712 → 17 lines (-97.6%)
    - Removed styles.ts: -82 lines
    - Removed vite-env.d.ts declarations: -156 lines
    
    **Quality Improvements:**
    -  Zero TypeScript errors
    -  Zero TODO/FIXME comments
    -  100% Prettier compliant
    -  Zero `window.api` references
    -  Fully modular API layer
    
    ## Testing
    - [x] TypeScript compilation passes
    - [x] Code formatting validated
    - [x] No linting errors
    
    Stage 4 completion: 100%
    Ready for stage 5 (testing and bug fixes)
  • feat(ui): add drag-and-drop sorting for provider list (#126)
    * feat(ui): add drag-and-drop sorting for provider list
    
    Implement drag-and-drop functionality to allow users to reorder providers with custom sort indices.
    
    Features:
    - Install @dnd-kit libraries for drag-and-drop support
    - Add sortIndex field to Provider type (frontend & backend)
    - Implement SortableProviderItem component with drag handle
    - Add update_providers_sort_order Tauri command
    - Sync tray menu order with provider list sorting
    - Add i18n support for drag-related UI text
    
    Technical details:
    - Use @dnd-kit/core and @dnd-kit/sortable for smooth drag interactions
    - Disable animations for immediate response after drop
    - Update tray menu immediately after reordering
    - Sort priority: sortIndex → createdAt → name
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * fix(ui): remove unused transition variable in ProviderList
    
    Remove unused 'transition' destructured variable from useSortable hook
    to fix TypeScript error TS6133. The transition property is hardcoded
    as 'none' in the style object to prevent conflicts with drag operations.
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
  • feat: add provider usage query with JavaScript scripting support (#101)
    * feat: add provider usage query functionality
    
    - Updated `Cargo.toml` to include `regex` and `rquickjs` dependencies for usage script execution.
    - Implemented `query_provider_usage` command in `commands.rs` to handle usage queries.
    - Created `UsageScript` and `UsageData` structs in `provider.rs` for managing usage script configurations and results.
    - Added `execute_usage_script` function in `usage_script.rs` to run user-defined scripts for querying usage.
    - Enhanced `ProviderList` component to include a button for configuring usage scripts and a modal for editing scripts.
    - Introduced `UsageFooter` component to display usage information and status.
    - Added `UsageScriptModal` for editing and testing usage scripts with preset templates.
    - Updated Tauri API to support querying provider usage.
    - Modified types in `types.ts` to include structures for usage scripts and results.
    
    * feat(usage): support multi-plan usage display for providers
    
    - 【Feature】
      - Update `UsageResult` to support an array of `UsageData` for displaying multiple usage plans per provider.
      - Refactor `query_provider_usage` command to parse both single `UsageData` objects (for backward compatibility) and arrays of `UsageData`.
      - Enhance `usage_script` validation to accept either a single usage object or an array of usage objects.
    - 【Frontend】
      - Redesign `UsageFooter` to iterate and display details for all available usage plans, introducing `UsagePlanItem` for individual plan rendering.
      - Improve usage display with color-coded remaining balance and clear plan information.
      - Update `UsageScriptModal` test notification to summarize all returned plans.
      - Remove redundant `isCurrent` prop from `UsageFooter` in `ProviderList`.
    - 【Build】
      - Change frontend development server port from `3000` to `3005` in `tauri.conf.json` and `vite.config.mts`.
    
    * feat(usage): enhance query flexibility and display
    - 【`src/types.ts`, `src-tauri/src/provider.rs`】Make `UsageData` fields optional and introduce `extra` and `invalidMessage` for more flexible reporting.
      - `expiresAt` replaced by generic `extra` field.
      - `isValid`, `remaining`, `unit` are now optional.
      - Added `invalidMessage` to provide specific reasons for invalid status.
    - 【`src-tauri/src/usage_script.rs`】Relax usage script result validation to accommodate optional fields in `UsageData`.
    - 【`src/components/UsageFooter.tsx`】Update UI to display `extra` field and `invalidMessage`, and conditionally render `remaining` and `unit` based on availability.
    - 【`src/components/UsageScriptModal.tsx`】
      - Add a new `NewAPI` preset template demonstrating advanced extractor logic for complex API responses.
      - Update script instructions to reflect optional fields and new variable syntax (`{{apiKey}}`).
      - Remove old "DeepSeek" and "OpenAI" templates.
      - Remove basic syntax check for `return` statement.
    - 【`.vscode/settings.json`】Add `dish-ai-commit.base.language` setting.
    - 【`src-tauri/src/commands.rs`】Adjust usage logging to handle optional `remaining` and `unit` fields.
    
    * chore(config): remove VS Code settings from version control
    
    - delete .vscode/settings.json to remove editor-specific configurations
    - add /.vscode to .gitignore to prevent tracking of local VS Code settings
    - ensure personalized editor preferences are not committed to the repository
    
    * fix(provider): preserve usage script during provider update
    
    - When updating a provider, the `usage_script` configuration within `ProviderMeta` was not explicitly merged.
    - This could lead to the accidental loss of `usage_script` settings if the incoming `provider` object in the update request did not contain this field.
    - Ensure `usage_script` is cloned from the existing provider's meta when merging `ProviderMeta` during an update.
    
    * refactor(provider): enforce base_url for usage scripts and update dev ports
    - 【Backend】
        - `src-tauri/src/commands.rs`: Made `ANTHROPIC_BASE_URL` a required field for Claude providers and `base_url` a required field in `config.toml` for Codex providers when extracting credentials for usage script execution. This improves error handling by explicitly failing if these critical URLs are missing or malformed.
    - 【Frontend】
        - `src/App.tsx`, `src/components/ProviderList.tsx`: Passed `appType` prop to `ProviderList` component to ensure `updateProvider` calls within `handleSaveUsageScript` correctly identify the application type.
    - 【Config】
        - `src-tauri/tauri.conf.json`, `vite.config.mts`: Updated development server ports from `3005` to `3000` to standardize local development environment.
    
    * refactor(usage): improve usage data fetching logic
    
    - Prevent redundant API calls by tracking last fetched parameters in `useEffect`.
    - Avoid concurrent API requests by adding a guard in `fetchUsage`.
    - Clear usage data and last fetch parameters when usage query is disabled.
    - Add `queryProviderUsage` API declaration to `window.api` interface.
    
    * fix(usage-script): ensure usage script updates and improve reactivity
    
    - correctly update `usage_script` from new provider meta during updates
    - replace full page reload with targeted provider data refresh after saving usage script settings
    - trigger usage data fetch or clear when `usageEnabled` status changes in `UsageFooter`
    - reduce logging verbosity for usage script execution in backend commands and script execution
    
    * style(usage-footer): adjust usage plan item layout
    
    - Decrease width of extra field column from 35% to 30%
    - Increase width of usage information column from 40% to 45%
    - Improve visual balance and readability of usage plan items
  • feat(mcp): add option to mirror MCP config to other app
    - Add syncOtherSide parameter to upsert_mcp_server_in_config command
    - Implement checkbox UI in McpFormModal for cross-app sync
    - Automatically sync enabled MCP servers to both Claude and Codex when option is checked
    - Add i18n support for sync option labels and hints
  • refactor(mcp): improve data structure with metadata/spec separation
    - Separate MCP server metadata from connection spec for cleaner architecture
    - Add comprehensive server entry fields: name, description, tags, homepage, docs
    - Remove legacy format compatibility logic from extract_server_spec
    - Implement data validation and filtering in get_servers_snapshot_for
    - Add strict id consistency check in upsert_in_config_for
    - Enhance import logic with defensive programming for corrupted data
    - Simplify frontend by removing normalization logic (moved to backend)
    - Improve error messages with contextual information
    - Add comprehensive i18n support for new metadata fields
  • fix: align Tauri arg names and improve export UX
    - Match frontend camelCase keys to backend snake_case params
    - Show error toast when save dialog is cancelled
  • feat(provider): use live config for edit and backfill SSOT after switch
    - Edit modal (Claude+Codex): when editing the current provider, initialize form from live files (Claude: ~/.claude/settings.json; Codex: ~/.codex/auth.json + ~/.codex/config.toml) instead of SSOT.
    - Switch (Claude): after writing live settings.json for the target provider, read it back and update the provider’s SSOT to match live.
    - Switch (Codex): keep MCP sync to config.toml, then read back TOML and update the target provider’s SSOT (preserves mcp.servers/mcp_servers schema).
    - Add Tauri command read_live_provider_settings for both apps, register handler, and expose window.api.getLiveProviderSettings.
    - Types updated accordingly; cargo check and pnpm typecheck pass.
  • feat(mcp): import Codex MCP from ~/.codex/config.toml
    - Support both TOML schemas: [mcp.servers.<id>] and [mcp_servers.<id>]
    - Non-destructive merge of imported servers (enabled=true only)
    - Preserve existing TOML schema when syncing (prefer mcp_servers)
    - Remove both mcp and mcp_servers when no enabled items
    
    feat(ui): auto-import Codex MCP on panel init (app=codex)
    
    chore(tauri): add import_mcp_from_codex command and register
    
    chore(types): expose window.api.importMcpFromCodex and typings
    
    fix(ui): remove unused variable for typecheck
  • feat(mcp): app-aware MCP panel and Codex MCP sync to config.toml
    - Make MCP panel app-aware; pass appType from App and call APIs with current app
    - Show active app in title: “MCP Management · Claude Code/Codex”
    - Add sync_enabled_to_codex: project enabled servers from SSOT to ~/.codex/config.toml as [mcp.servers.*]
    - Sync on enable/disable, delete, and provider switch (post live write)
    - Add Tauri command sync_enabled_mcp_to_codex and expose window.api.syncEnabledMcpToCodex()
    - Fix Rust borrow scopes in switch_provider to avoid E0502
    - Add TS declarations for new Codex sync API
  • refactor(mcp): improve UI consistency and i18n
    - Add MCP-specific green button style (buttonStyles.mcp)
    - Unify MCP panel and form buttons with emerald theme
    - Adjust MCP entry button width to match AppSwitcher (px-3)
    - Reduce JSON editor height from h-64 to h-48
    - Update translations: "Add/Edit Server" → "Add/Edit MCP"
    - Change form label to "MCP Title (Unique)" for clarity
    - Move config wizard button to right side of JSON label
    - Fix McpListItem enabled state check (explicit true check)
  • fix(mcp): remove SSE support; keep stdio default when type is omitted
    - Backend: reject "sse" in validators; accept missing type as stdio; require url only for http (mcp.rs, claude_mcp.rs)
    - Frontend: McpServer.type narrowed to "stdio" | "http" (optional) (src/types.ts)
    - UI: avoid undefined in list item details (McpListItem)
    - Claude-only sync after delete to update ~/.claude.json (commands.rs)
    
    Notes:
    - Ran typecheck and cargo check: both pass
    - Clippy shows advisory warnings unrelated to this change
    - Prettier check warns on a few files; limited scope changes kept minimal
  • feat(mcp): use project config as SSOT and sync enabled servers to ~/.claude.json
    - Add McpConfig to MultiAppConfig and persist MCP servers in ~/.cc-switch/config.json
    - Add Tauri commands: get_mcp_config, upsert_mcp_server_in_config, delete_mcp_server_in_config, set_mcp_enabled, sync_enabled_mcp_to_claude, import_mcp_from_claude
    - Only write enabled MCPs to ~/.claude.json (mcpServers) and strip UI-only fields (enabled/source)
    - Frontend: update API wrappers and MCP panel to read/write via config.json; seed presets on first open; import from ~/.claude.json
    - Fix warnings (remove unused mut, dead code)
    - Verified with cargo check and pnpm typecheck
  • refactor(mcp): redesign MCP management panel UI
    - Redesign MCP panel to match main interface style
    - Add toggle switch for each MCP server to enable/disable
    - Use emerald theme color consistent with MCP button
    - Create card-based layout with one MCP per row
    - Add dedicated form modal for add/edit operations
    - Implement proper empty state with friendly prompts
    - Add comprehensive i18n support (zh/en)
    - Extend McpServer type to support enabled field
    - Backend already supports enabled field via serde_json::Value
    
    Components:
    - McpPanel: Main panel container with header and list
    - McpListItem: Card-based list item with toggle and actions
    - McpFormModal: Independent modal for add/edit forms
    - McpToggle: Emerald-themed toggle switch component
    
    All changes passed TypeScript type checking and production build.
  • refactor(mcp): switch to user-level config ~/.claude.json and remove project-level logic
    - Read/write ~/.claude.json (preserve unknown fields) for mcpServers
    - Remove settings.local.json and mcp.json handling
    - Drop enableAllProjectMcpServers command and UI toggle
    - Update types, Tauri APIs, and MCP panel to reflect new status fields
    - Keep atomic write and command validation behaviors
  • feat(mcp): add front-end API wrappers and types
    - Add McpServer and McpStatus types
    - Add window.api wrappers for MCP commands
    - Extend vite-env.d.ts global typings for MCP APIs