Commit Graph

9 Commits

  • feat(opencode): complete Phase 4 - MCP sync module
    Add mcp/opencode.rs with format conversion between CC Switch and OpenCode:
    - stdio ↔ local type conversion
    - command+args ↔ command array format
    - env ↔ environment field mapping
    - sse/http ↔ remote type conversion
    
    Public API:
    - sync_enabled_to_opencode: Batch sync all enabled servers
    - sync_single_server_to_opencode: Sync individual server
    - remove_server_from_opencode: Remove from live config
    - import_from_opencode: Import servers from OpenCode config
    
    Also fix test files to include new opencode field in McpApps struct.
    All 4 unit tests pass for format conversion.
  • 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(provider): add backfill and Gemini security flags to switch function
    The switch function was missing two important features after the SQLite
    migration:
    
    1. Backfill mechanism: Before switching providers, read the current live
       config and save it back to the current provider. This preserves any
       manual edits users made to the live config file.
    
    2. Gemini security flags: When switching to a Gemini provider, set the
       appropriate security.auth.selectedType:
       - PackyCode providers: "gemini-api-key"
       - Google OAuth providers: "oauth-personal"
    
    Also update tests to:
    - Use the new unified MCP structure (mcp.servers) instead of the legacy
      per-app structure (mcp.codex.servers)
    - Expect backfill behavior (was incorrectly marked as "no backfill")
    - Remove assertions for provider-specific file deletion (v3.7.0+ uses
      SSOT, no longer creates per-provider config files)
  • Merge feat/sqlite-migration: add database schema migration system
    This merge brings the SQLite migration system from feat/sqlite-migration branch:
    
    ## New Features
    - Schema version control with SCHEMA_VERSION constant
    - Automatic migration of missing columns for providers table
    - Dry-run validation mode for schema compatibility checks
    - JSON→SQLite migration feature gate (CC_SWITCH_ENABLE_JSON_DB_MIGRATION)
    - Settings reload mechanism after imports
    
    ## Test Updates
    - Updated tests to use SQLite database instead of config.json
    - Removed obsolete import_config_from_path tests (replaced by db.import_sql)
    - Fixed MCP tests to use unified McpServer structure (v3.7.0+)
    - Updated provider switch tests to reflect no-backfill behavior
    - Adjusted error type matching for new error variants
  • test: migrate tests to SQLite database architecture
    This commit refactors all tests to work with the new database-based
    architecture, replacing the previous JSON config approach.
    
    Key changes:
    - Add Database export to lib.rs for test access
    - Create test helper functions in support.rs:
      - create_test_state(): Creates empty test state with fresh DB
      - create_test_state_with_config(): Migrates JSON config to DB
    - Fix environment isolation in provider_service tests:
      - provider_service_switch_missing_provider_returns_error
      - provider_service_switch_codex_missing_auth_returns_error
    - Replace ignored export tests with working alternatives:
      - export_sql_writes_to_target_path (tests Database::export_sql)
      - export_sql_returns_error_for_invalid_path (tests error handling)
    - Update error type matching to align with current implementation
    
    All tests now:
    - Use isolated test environments (test_mutex + reset_test_fs)
    - Access data via Database API instead of RwLock<MultiAppConfig>
    - Work with SQLite persistence layer
    - Pass without environment pollution or race conditions
    
    Fixes test compilation errors after database migration.
  • refactor(backend): phase 5 - optimize concurrency with RwLock and async IO
    Replace Mutex with RwLock for AppState.config to enable concurrent reads,
    improving performance for tray menu building and query operations that
    previously blocked each other unnecessarily.
    
    Key changes:
    - Migrate AppState.config from Mutex<MultiAppConfig> to RwLock<MultiAppConfig>
    - Distinguish read-only operations (read()) from mutations (write()) across
      all command handlers and service layers
    - Offload blocking file I/O in import/export commands to spawn_blocking threads,
      minimizing lock hold time and preventing main thread blocking
    - Extract load_config_for_import() to separate I/O logic from state updates
    - Update all integration tests to use RwLock semantics
    
    Performance impact:
    - Concurrent reads: Multiple threads can now query config simultaneously
      (tray menu, provider list, MCP config)
    - Reduced contention: Write locks only acquired during actual mutations
    - Non-blocking I/O: Config import/export no longer freezes UI thread
    
    All existing tests pass with new locking semantics.
  • refactor(backend): phase 4 - add test hooks and extend service layer
    - Extract internal functions in commands/mcp.rs and commands/provider.rs
      to enable unit testing without Tauri context
    - Add test hooks: set_mcp_enabled_test_hook, import_mcp_from_claude_test_hook,
      import_mcp_from_codex_test_hook, import_default_config_test_hook
    - Migrate error types from String to AppError for precise error matching in tests
    - Extend ProviderService with delete() method to unify Codex/Claude cleanup logic
    - Add comprehensive test coverage:
      - tests/mcp_commands.rs: command-level tests for MCP operations
      - tests/provider_service.rs: service-level tests for switch/delete operations
    - Run cargo fmt to fix formatting issues (EOF newlines)
    - Update BACKEND_REFACTOR_PLAN.md to mark phase 3 complete
  • refactor(backend): phase 4 - extract provider service layer
    Architecture improvements:
    - Extract ProviderService with switch/backfill/write methods
    - Reduce command layer from 160 to 13 lines via delegation
    - Separate business logic (services) from state management (commands)
    - Introduce precise error handling with structured validation
    
    Refactoring details:
    - Split Codex/Claude switching into symmetric private methods
    - Add multi-layer validation for Codex auth field (existence + type)
    - Extract import_config_from_path for command and test reuse
    - Expose export_config_to_file and ProviderService in public API
    
    Test coverage:
    - Add 10+ integration tests for Claude/Codex switching flows
    - Cover import/export success and failure scenarios (JSON parse, missing file)
    - Verify state consistency on error paths (current remains unchanged)
    - Test snapshot backfill for both old and new providers after switching
  • refactor(backend): phase 3 - unify error handling and fix backup timestamp bug
    Key improvements:
    - Extract switch_provider_internal() returning AppError for better testability
    - Fix backup mtime inheritance: use read+write instead of fs::copy to ensure latest backup survives cleanup
    - Add 15+ integration tests covering provider commands, atomic writes, and rollback scenarios
    - Expose write_codex_live_atomic, AppState, and test hooks in public API
    - Extract tests/support.rs with isolated HOME and mutex utilities
    
    Test coverage:
    - Provider switching with live config backfill and MCP sync
    - Codex atomic write success and failure rollback
    - Backup retention policy with proper mtime ordering
    - Negative cases: missing auth field, invalid provider ID