Compare commits
9 Commits
v3.7.0
...
feat/add-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a87daebe14 | ||
|
|
ec04132303 | ||
|
|
bbb356a948 | ||
|
|
f582bd58b1 | ||
|
|
a7f1461a33 | ||
|
|
956e723781 | ||
|
|
461ba6f418 | ||
|
|
6b5752db24 | ||
|
|
ec1ae7073f |
222
CHANGELOG.md
222
CHANGELOG.md
@@ -5,222 +5,6 @@ All notable changes to CC Switch will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [3.7.0] - 2025-11-19
|
|
||||||
|
|
||||||
### Major Features
|
|
||||||
|
|
||||||
#### Gemini CLI Integration
|
|
||||||
|
|
||||||
- **Complete Gemini CLI support** - Third major application added alongside Claude Code and Codex
|
|
||||||
- **Dual-file configuration** - Support for both `.env` and `settings.json` file formats
|
|
||||||
- **Environment variable detection** - Auto-detect `GOOGLE_GEMINI_BASE_URL`, `GEMINI_MODEL`, etc.
|
|
||||||
- **MCP management** - Full MCP configuration capabilities for Gemini
|
|
||||||
- **Provider presets**
|
|
||||||
- Google Official (OAuth authentication)
|
|
||||||
- PackyCode (partner integration)
|
|
||||||
- Custom endpoint support
|
|
||||||
- **Deep link support** - Import Gemini providers via `ccswitch://` protocol
|
|
||||||
- **System tray integration** - Quick-switch Gemini providers from tray menu
|
|
||||||
- **Backend modules** - New `gemini_config.rs` (20KB) and `gemini_mcp.rs`
|
|
||||||
|
|
||||||
#### MCP v3.7.0 Unified Architecture
|
|
||||||
|
|
||||||
- **Unified management panel** - Single interface for Claude/Codex/Gemini MCP servers
|
|
||||||
- **SSE transport type** - New Server-Sent Events support alongside stdio/http
|
|
||||||
- **Smart JSON parser** - Fault-tolerant parsing of various MCP config formats
|
|
||||||
- **Extended field support** - Preserve custom fields in Codex TOML conversion
|
|
||||||
- **Codex format correction** - Proper `[mcp_servers]` format (auto-cleanup of incorrect `[mcp.servers]`)
|
|
||||||
- **Import/export system** - Unified import from Claude/Codex/Gemini live configs
|
|
||||||
- **UX improvements**
|
|
||||||
- Default app selection in forms
|
|
||||||
- JSON formatter for config validation
|
|
||||||
- Improved layout and visual hierarchy
|
|
||||||
- Better validation error messages
|
|
||||||
|
|
||||||
#### Claude Skills Management System
|
|
||||||
|
|
||||||
- **GitHub repository integration** - Auto-scan and discover skills from GitHub repos
|
|
||||||
- **Pre-configured repositories**
|
|
||||||
- `ComposioHQ/awesome-claude-skills` (curated collection)
|
|
||||||
- `anthropics/skills` (official Anthropic skills)
|
|
||||||
- `cexll/myclaude` (community, with subdirectory scanning)
|
|
||||||
- **Lifecycle management**
|
|
||||||
- One-click install to `~/.claude/skills/`
|
|
||||||
- Safe uninstall with state tracking
|
|
||||||
- Update checking (infrastructure ready)
|
|
||||||
- **Custom repository support** - Add any GitHub repo as a skill source
|
|
||||||
- **Subdirectory scanning** - Optional `skillsPath` for repos with nested skill directories
|
|
||||||
- **Backend architecture** - `SkillService` (526 lines) with GitHub API integration
|
|
||||||
- **Frontend interface**
|
|
||||||
- SkillsPage: Browse and manage skills
|
|
||||||
- SkillCard: Visual skill presentation
|
|
||||||
- RepoManager: Repository management dialog
|
|
||||||
- **State persistence** - Installation state stored in `skills.json`
|
|
||||||
- **Full i18n support** - Complete Chinese/English translations (47+ keys)
|
|
||||||
|
|
||||||
#### Prompts (System Prompts) Management
|
|
||||||
|
|
||||||
- **Multi-preset management** - Create, edit, and switch between multiple system prompts
|
|
||||||
- **Cross-app support**
|
|
||||||
- Claude: `~/.claude/CLAUDE.md`
|
|
||||||
- Codex: `~/.codex/AGENTS.md`
|
|
||||||
- Gemini: `~/.gemini/GEMINI.md`
|
|
||||||
- **Markdown editor** - Full-featured CodeMirror 6 editor with syntax highlighting
|
|
||||||
- **Smart synchronization**
|
|
||||||
- Auto-write to live files on enable
|
|
||||||
- Content backfill protection (save current before switching)
|
|
||||||
- First-launch auto-import from live files
|
|
||||||
- **Single-active enforcement** - Only one prompt can be active at a time
|
|
||||||
- **Delete protection** - Cannot delete active prompts
|
|
||||||
- **Backend service** - `PromptService` (213 lines) with CRUD operations
|
|
||||||
- **Frontend components**
|
|
||||||
- PromptPanel: Main management interface (177 lines)
|
|
||||||
- PromptFormModal: Edit dialog with validation (160 lines)
|
|
||||||
- MarkdownEditor: CodeMirror integration (159 lines)
|
|
||||||
- usePromptActions: Business logic hook (152 lines)
|
|
||||||
- **Full i18n support** - Complete Chinese/English translations (41+ keys)
|
|
||||||
|
|
||||||
#### Deep Link Protocol (ccswitch://)
|
|
||||||
|
|
||||||
- **Protocol registration** - `ccswitch://` URL scheme for one-click imports
|
|
||||||
- **Provider import** - Import provider configurations from URLs or shared links
|
|
||||||
- **Lifecycle integration** - Deep link handling integrated into app startup
|
|
||||||
- **Cross-platform support** - Works on Windows, macOS, and Linux
|
|
||||||
|
|
||||||
#### Environment Variable Conflict Detection
|
|
||||||
|
|
||||||
- **Claude & Codex detection** - Identify conflicting environment variables
|
|
||||||
- **Gemini auto-detection** - Automatic environment variable discovery
|
|
||||||
- **Conflict management** - UI for resolving configuration conflicts
|
|
||||||
- **Prevention system** - Warn before overwriting existing configurations
|
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
#### Provider Management
|
|
||||||
|
|
||||||
- **DouBaoSeed preset** - Added ByteDance's DouBao provider
|
|
||||||
- **Kimi For Coding** - Moonshot AI coding assistant
|
|
||||||
- **BaiLing preset** - BaiLing AI integration
|
|
||||||
- **Removed AnyRouter preset** - Discontinued provider
|
|
||||||
- **Model configuration** - Support for custom model names in Codex and Gemini
|
|
||||||
- **Provider notes field** - Add custom notes to providers for better organization
|
|
||||||
|
|
||||||
#### Configuration Management
|
|
||||||
|
|
||||||
- **Common config migration** - Moved Claude common config snippets from localStorage to `config.json`
|
|
||||||
- **Unified persistence** - Common config snippets now shared across all apps
|
|
||||||
- **Auto-import on first launch** - Automatically import configs from live files on first run
|
|
||||||
- **Backfill priority fix** - Correct priority handling when enabling prompts
|
|
||||||
|
|
||||||
#### UI/UX Improvements
|
|
||||||
|
|
||||||
- **macOS native design** - Migrated color scheme to macOS native design system
|
|
||||||
- **Window centering** - Default window position centered on screen
|
|
||||||
- **Password input fixes** - Disabled Edge/IE reveal and clear buttons
|
|
||||||
- **URL overflow prevention** - Fixed overflow in provider cards
|
|
||||||
- **Error notification enhancement** - Copy-to-clipboard for error messages
|
|
||||||
- **Tray menu sync** - Real-time sync after drag-and-drop sorting
|
|
||||||
|
|
||||||
### Improvements
|
|
||||||
|
|
||||||
#### Architecture
|
|
||||||
|
|
||||||
- **MCP v3.7.0 cleanup** - Removed legacy code and warnings
|
|
||||||
- **Unified structure** - Default initialization with v3.7.0 unified structure
|
|
||||||
- **Backward compatibility** - Compilation fixes for older configs
|
|
||||||
- **Code formatting** - Applied consistent formatting across backend and frontend
|
|
||||||
|
|
||||||
#### Platform Compatibility
|
|
||||||
|
|
||||||
- **Windows fix** - Resolved winreg API compatibility issue (v0.52)
|
|
||||||
- **Safe pattern matching** - Replaced `unwrap()` with safe patterns in tray menu
|
|
||||||
|
|
||||||
#### Configuration
|
|
||||||
|
|
||||||
- **MCP sync on switch** - Sync MCP configs for all apps when switching providers
|
|
||||||
- **Gemini form sync** - Fixed form fields syncing with environment editor
|
|
||||||
- **Gemini config reading** - Read from both `.env` and `settings.json`
|
|
||||||
- **Validation improvements** - Enhanced input validation and boundary checks
|
|
||||||
|
|
||||||
#### Internationalization
|
|
||||||
|
|
||||||
- **JSON syntax fixes** - Resolved syntax errors in locale files
|
|
||||||
- **App name i18n** - Added internationalization support for app names
|
|
||||||
- **Deduplicated labels** - Reused providerForm keys to reduce duplication
|
|
||||||
- **Gemini MCP title** - Added missing Gemini MCP panel title
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
#### Critical Fixes
|
|
||||||
|
|
||||||
- **Usage script validation** - Added input validation and boundary checks
|
|
||||||
- **Gemini validation** - Relaxed validation when adding providers
|
|
||||||
- **TOML quote normalization** - Handle CJK quotes to prevent parsing errors
|
|
||||||
- **MCP field preservation** - Preserve custom fields in Codex TOML editor
|
|
||||||
- **Password input** - Fixed white screen crash (FormLabel → Label)
|
|
||||||
|
|
||||||
#### Stability
|
|
||||||
|
|
||||||
- **Tray menu safety** - Replaced unwrap with safe pattern matching
|
|
||||||
- **Error isolation** - Tray menu update failures don't block main operations
|
|
||||||
- **Import classification** - Set category to custom for imported default configs
|
|
||||||
|
|
||||||
#### UI Fixes
|
|
||||||
|
|
||||||
- **Model placeholders** - Removed misleading model input placeholders
|
|
||||||
- **Base URL population** - Auto-fill base URL for non-official providers
|
|
||||||
- **Drag sort sync** - Fixed tray menu order after drag-and-drop
|
|
||||||
|
|
||||||
### Technical Improvements
|
|
||||||
|
|
||||||
#### Code Quality
|
|
||||||
|
|
||||||
- **Type safety** - Complete TypeScript type coverage across codebase
|
|
||||||
- **Test improvements** - Simplified boolean assertions in tests
|
|
||||||
- **Clippy warnings** - Fixed `uninlined_format_args` warnings
|
|
||||||
- **Code refactoring** - Extracted templates, optimized logic flows
|
|
||||||
|
|
||||||
#### Dependencies
|
|
||||||
|
|
||||||
- **Tauri** - Updated to 2.8.x series
|
|
||||||
- **Rust dependencies** - Added `anyhow`, `zip`, `serde_yaml`, `tempfile` for Skills
|
|
||||||
- **Frontend dependencies** - Added CodeMirror 6 packages for Markdown editor
|
|
||||||
- **winreg** - Updated to v0.52 (Windows compatibility)
|
|
||||||
|
|
||||||
#### Performance
|
|
||||||
|
|
||||||
- **Startup optimization** - Removed legacy migration scanning
|
|
||||||
- **Lock management** - Improved RwLock usage to prevent deadlocks
|
|
||||||
- **Background query** - Enabled background mode for usage polling
|
|
||||||
|
|
||||||
### Statistics
|
|
||||||
|
|
||||||
- **Total commits**: 85 commits from v3.6.0 to v3.7.0
|
|
||||||
- **Code changes**: 152 files changed, 18,104 insertions(+), 3,732 deletions(-)
|
|
||||||
- **New modules**:
|
|
||||||
- Skills: 2,034 lines (21 files)
|
|
||||||
- Prompts: 1,302 lines (20 files)
|
|
||||||
- Gemini: ~1,000 lines (multiple files)
|
|
||||||
- MCP refactor: ~3,000 lines (refactored)
|
|
||||||
|
|
||||||
### Strategic Positioning
|
|
||||||
|
|
||||||
v3.7.0 represents a major evolution from "Provider Switcher" to **"All-in-One AI CLI Management Platform"**:
|
|
||||||
|
|
||||||
1. **Capability Extension** - Skills provide external ability integration
|
|
||||||
2. **Behavior Customization** - Prompts enable AI personality presets
|
|
||||||
3. **Configuration Unification** - MCP v3.7.0 eliminates app silos
|
|
||||||
4. **Ecosystem Openness** - Deep links enable community sharing
|
|
||||||
5. **Multi-AI Support** - Claude/Codex/Gemini trinity
|
|
||||||
6. **Intelligent Detection** - Auto-discovery of environment conflicts
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
|
|
||||||
- Users upgrading from v3.1.0 or earlier should first upgrade to v3.2.x for one-time migration
|
|
||||||
- Skills and Prompts management are new features requiring no migration
|
|
||||||
- Gemini CLI support requires Gemini CLI to be installed separately
|
|
||||||
- MCP v3.7.0 unified structure is backward compatible with previous configs
|
|
||||||
|
|
||||||
## [3.6.0] - 2025-11-07
|
## [3.6.0] - 2025-11-07
|
||||||
|
|
||||||
### ✨ New Features
|
### ✨ New Features
|
||||||
@@ -289,7 +73,6 @@ v3.7.0 represents a major evolution from "Provider Switcher" to **"All-in-One AI
|
|||||||
### 🏗️ Technical Improvements (For Developers)
|
### 🏗️ Technical Improvements (For Developers)
|
||||||
|
|
||||||
**Backend Refactoring (Rust)** - Completed 5-phase refactoring:
|
**Backend Refactoring (Rust)** - Completed 5-phase refactoring:
|
||||||
|
|
||||||
- **Phase 1**: Unified error handling (`AppError` + i18n error messages)
|
- **Phase 1**: Unified error handling (`AppError` + i18n error messages)
|
||||||
- **Phase 2**: Command layer split by domain (`commands/{provider,mcp,config,settings,plugin,misc}.rs`)
|
- **Phase 2**: Command layer split by domain (`commands/{provider,mcp,config,settings,plugin,misc}.rs`)
|
||||||
- **Phase 3**: Integration tests and transaction mechanism (config snapshot + failure rollback)
|
- **Phase 3**: Integration tests and transaction mechanism (config snapshot + failure rollback)
|
||||||
@@ -297,20 +80,17 @@ v3.7.0 represents a major evolution from "Provider Switcher" to **"All-in-One AI
|
|||||||
- **Phase 5**: Concurrency optimization (`RwLock` instead of `Mutex`, scoped guard to avoid deadlock)
|
- **Phase 5**: Concurrency optimization (`RwLock` instead of `Mutex`, scoped guard to avoid deadlock)
|
||||||
|
|
||||||
**Frontend Refactoring (React + TypeScript)** - Completed 4-stage refactoring:
|
**Frontend Refactoring (React + TypeScript)** - Completed 4-stage refactoring:
|
||||||
|
|
||||||
- **Stage 1**: Test infrastructure (vitest + MSW + @testing-library/react)
|
- **Stage 1**: Test infrastructure (vitest + MSW + @testing-library/react)
|
||||||
- **Stage 2**: Extracted custom hooks (`useProviderActions`, `useMcpActions`, `useSettings`, `useImportExport`, etc.)
|
- **Stage 2**: Extracted custom hooks (`useProviderActions`, `useMcpActions`, `useSettings`, `useImportExport`, etc.)
|
||||||
- **Stage 3**: Component splitting and business logic extraction
|
- **Stage 3**: Component splitting and business logic extraction
|
||||||
- **Stage 4**: Code cleanup and formatting unification
|
- **Stage 4**: Code cleanup and formatting unification
|
||||||
|
|
||||||
**Testing System**:
|
**Testing System**:
|
||||||
|
|
||||||
- Hooks unit tests 100% coverage
|
- Hooks unit tests 100% coverage
|
||||||
- Integration tests covering key processes (App, SettingsDialog, MCP Panel)
|
- Integration tests covering key processes (App, SettingsDialog, MCP Panel)
|
||||||
- MSW mocking backend API to ensure test independence
|
- MSW mocking backend API to ensure test independence
|
||||||
|
|
||||||
**Code Quality**:
|
**Code Quality**:
|
||||||
|
|
||||||
- Unified parameter format: All Tauri commands migrated to camelCase (Tauri 2 specification)
|
- Unified parameter format: All Tauri commands migrated to camelCase (Tauri 2 specification)
|
||||||
- `AppType` renamed to `AppId`: Semantically clearer
|
- `AppType` renamed to `AppId`: Semantically clearer
|
||||||
- Unified parsing with `FromStr` trait: Centralized `app` parameter parsing
|
- Unified parsing with `FromStr` trait: Centralized `app` parameter parsing
|
||||||
@@ -318,7 +98,6 @@ v3.7.0 represents a major evolution from "Provider Switcher" to **"All-in-One AI
|
|||||||
- Remove unused code: `missing_param` helper function, deprecated `tauri-api.ts`, redundant `KimiModelSelector` component
|
- Remove unused code: `missing_param` helper function, deprecated `tauri-api.ts`, redundant `KimiModelSelector` component
|
||||||
|
|
||||||
**Internal Optimizations**:
|
**Internal Optimizations**:
|
||||||
|
|
||||||
- **Removed Legacy Migration Logic**: v3.6 removed v1 config auto-migration and copy file scanning logic
|
- **Removed Legacy Migration Logic**: v3.6 removed v1 config auto-migration and copy file scanning logic
|
||||||
- ✅ **Impact**: Improved startup performance, cleaner code
|
- ✅ **Impact**: Improved startup performance, cleaner code
|
||||||
- ✅ **Compatibility**: v2 format configs fully compatible, no action required
|
- ✅ **Compatibility**: v2 format configs fully compatible, no action required
|
||||||
@@ -582,7 +361,6 @@ For users upgrading from v2.x (Electron version):
|
|||||||
- Basic provider management
|
- Basic provider management
|
||||||
- Claude Code integration
|
- Claude Code integration
|
||||||
- Configuration file handling
|
- Configuration file handling
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### ⚠️ Breaking Changes
|
### ⚠️ Breaking Changes
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
# All-in-One Assistant for Claude Code, Codex & Gemini CLI
|
# Claude Code & Codex Provider Switcher
|
||||||
|
|
||||||
[](https://github.com/farion1231/cc-switch/releases)
|
[](https://github.com/farion1231/cc-switch/releases)
|
||||||
[](https://github.com/trending/typescript)
|
[](https://github.com/trending/typescript)
|
||||||
[](https://github.com/farion1231/cc-switch/releases)
|
[](https://github.com/farion1231/cc-switch/releases)
|
||||||
[](https://tauri.app/)
|
[](https://tauri.app/)
|
||||||
@@ -43,7 +43,7 @@ Get 10% OFF the GLM CODING PLAN with [this link](https://z.ai/subscribe?ic=8JVLJ
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
### Current Version: v3.7.0 | [Full Changelog](CHANGELOG.md)
|
### Current Version: v3.6.2 | [Full Changelog](CHANGELOG.md)
|
||||||
|
|
||||||
**Core Capabilities**
|
**Core Capabilities**
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
# Claude Code / Codex / Gemini CLI 全方位辅助工具
|
# Claude Code & Codex 供应商管理器
|
||||||
|
|
||||||
[](https://github.com/farion1231/cc-switch/releases)
|
[](https://github.com/farion1231/cc-switch/releases)
|
||||||
[](https://github.com/trending/typescript)
|
[](https://github.com/trending/typescript)
|
||||||
[](https://github.com/farion1231/cc-switch/releases)
|
[](https://github.com/farion1231/cc-switch/releases)
|
||||||
[](https://tauri.app/)
|
[](https://tauri.app/)
|
||||||
@@ -43,7 +43,7 @@ CC Switch 已经预设了智谱GLM,只需要填写 key 即可一键导入编
|
|||||||
|
|
||||||
## 功能特性
|
## 功能特性
|
||||||
|
|
||||||
### 当前版本:v3.7.0 | [完整更新日志](CHANGELOG.md)
|
### 当前版本:v3.6.2 | [完整更新日志](CHANGELOG.md)
|
||||||
|
|
||||||
**核心功能**
|
**核心功能**
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 204 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 205 KiB |
@@ -1,439 +0,0 @@
|
|||||||
# CC Switch v3.7.0
|
|
||||||
|
|
||||||
> From Provider Switcher to All-in-One AI CLI Management Platform
|
|
||||||
|
|
||||||
**[中文更新说明 Chinese Documentation →](release-note-v3.7.0-zh.md)**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
CC Switch v3.7.0 introduces six major features with over 18,000 lines of new code.
|
|
||||||
|
|
||||||
**Release Date**: 2025-11-19
|
|
||||||
**Commits**: 85 from v3.6.0
|
|
||||||
**Code Changes**: 152 files, +18,104 / -3,732 lines
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## New Features
|
|
||||||
|
|
||||||
### Gemini CLI Integration
|
|
||||||
|
|
||||||
Complete support for Google Gemini CLI, becoming the third supported application (Claude Code, Codex, Gemini).
|
|
||||||
|
|
||||||
**Core Capabilities**:
|
|
||||||
|
|
||||||
- **Dual-file configuration** - Support for both `.env` and `settings.json` formats
|
|
||||||
- **Auto-detection** - Automatically detect `GOOGLE_GEMINI_BASE_URL`, `GEMINI_MODEL`, etc.
|
|
||||||
- **Full MCP support** - Complete MCP server management for Gemini
|
|
||||||
- **Deep link integration** - Import via `ccswitch://` protocol
|
|
||||||
- **System tray** - Quick-switch from tray menu
|
|
||||||
|
|
||||||
**Provider Presets**:
|
|
||||||
|
|
||||||
- **Google Official** - OAuth authentication support
|
|
||||||
- **PackyCode** - Partner integration
|
|
||||||
- **Custom** - Full customization support
|
|
||||||
|
|
||||||
**Technical Implementation**:
|
|
||||||
|
|
||||||
- New backend modules: `gemini_config.rs` (20KB), `gemini_mcp.rs`
|
|
||||||
- Form synchronization with environment editor
|
|
||||||
- Dual-file atomic writes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### MCP v3.7.0 Unified Architecture
|
|
||||||
|
|
||||||
Complete refactoring of MCP management system for cross-application unification.
|
|
||||||
|
|
||||||
**Architecture Improvements**:
|
|
||||||
|
|
||||||
- **Unified panel** - Single interface for Claude/Codex/Gemini MCP servers
|
|
||||||
- **SSE transport** - New Server-Sent Events support
|
|
||||||
- **Smart parser** - Fault-tolerant JSON parsing
|
|
||||||
- **Format correction** - Auto-fix Codex `[mcp_servers]` format
|
|
||||||
- **Extended fields** - Preserve custom TOML fields
|
|
||||||
|
|
||||||
**User Experience**:
|
|
||||||
|
|
||||||
- Default app selection in forms
|
|
||||||
- JSON formatter for validation
|
|
||||||
- Improved visual hierarchy
|
|
||||||
- Better error messages
|
|
||||||
|
|
||||||
**Import/Export**:
|
|
||||||
|
|
||||||
- Unified import from all three apps
|
|
||||||
- Bidirectional synchronization
|
|
||||||
- State preservation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Claude Skills Management System
|
|
||||||
|
|
||||||
**Approximately 2,000 lines of code** - A complete skill ecosystem platform.
|
|
||||||
|
|
||||||
**GitHub Integration**:
|
|
||||||
|
|
||||||
- Auto-scan skills from GitHub repositories
|
|
||||||
- Pre-configured repos:
|
|
||||||
- `ComposioHQ/awesome-claude-skills` - Curated collection
|
|
||||||
- `anthropics/skills` - Official Anthropic skills
|
|
||||||
- `cexll/myclaude` - Community contributions
|
|
||||||
- Add custom repositories
|
|
||||||
- Subdirectory scanning support (`skillsPath`)
|
|
||||||
|
|
||||||
**Lifecycle Management**:
|
|
||||||
|
|
||||||
- **Discover** - Auto-detect `SKILL.md` files
|
|
||||||
- **Install** - One-click to `~/.claude/skills/`
|
|
||||||
- **Uninstall** - Safe removal with tracking
|
|
||||||
- **Update** - Check for updates (infrastructure ready)
|
|
||||||
|
|
||||||
**Technical Architecture**:
|
|
||||||
|
|
||||||
- **Backend**: `SkillService` (526 lines) with GitHub API integration
|
|
||||||
- **Frontend**: SkillsPage, SkillCard, RepoManager
|
|
||||||
- **UI Components**: Badge, Card, Table (shadcn/ui)
|
|
||||||
- **State**: Persistent storage in `skills.json`
|
|
||||||
- **i18n**: 47+ translation keys
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Prompts Management System
|
|
||||||
|
|
||||||
**Approximately 1,300 lines of code** - Complete system prompt management.
|
|
||||||
|
|
||||||
**Multi-Preset Management**:
|
|
||||||
|
|
||||||
- Create unlimited prompt presets
|
|
||||||
- Quick switch between presets
|
|
||||||
- One active prompt at a time
|
|
||||||
- Delete protection for active prompts
|
|
||||||
|
|
||||||
**Cross-App Support**:
|
|
||||||
|
|
||||||
- **Claude**: `~/.claude/CLAUDE.md`
|
|
||||||
- **Codex**: `~/.codex/AGENTS.md`
|
|
||||||
- **Gemini**: `~/.gemini/GEMINI.md`
|
|
||||||
|
|
||||||
**Markdown Editor**:
|
|
||||||
|
|
||||||
- Full-featured CodeMirror 6 integration
|
|
||||||
- Syntax highlighting
|
|
||||||
- Dark theme (One Dark)
|
|
||||||
- Real-time preview
|
|
||||||
|
|
||||||
**Smart Synchronization**:
|
|
||||||
|
|
||||||
- **Auto-write** - Immediately write to live files
|
|
||||||
- **Backfill protection** - Save current content before switching
|
|
||||||
- **Auto-import** - Import from live files on first launch
|
|
||||||
- **Modification protection** - Preserve manual modifications
|
|
||||||
|
|
||||||
**Technical Implementation**:
|
|
||||||
|
|
||||||
- **Backend**: `PromptService` (213 lines)
|
|
||||||
- **Frontend**: PromptPanel (177), PromptFormModal (160), MarkdownEditor (159)
|
|
||||||
- **Hooks**: usePromptActions (152 lines)
|
|
||||||
- **i18n**: 41+ translation keys
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Deep Link Protocol (ccswitch://)
|
|
||||||
|
|
||||||
One-click provider configuration import via URL scheme.
|
|
||||||
|
|
||||||
**Features**:
|
|
||||||
|
|
||||||
- Protocol registration on all platforms
|
|
||||||
- Import from shared links
|
|
||||||
- Lifecycle integration
|
|
||||||
- Security validation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Environment Variable Conflict Detection
|
|
||||||
|
|
||||||
Intelligent detection and management of configuration conflicts.
|
|
||||||
|
|
||||||
**Detection Scope**:
|
|
||||||
|
|
||||||
- **Claude & Codex** - Cross-app conflicts
|
|
||||||
- **Gemini** - Auto-discovery
|
|
||||||
- **MCP** - Server configuration conflicts
|
|
||||||
|
|
||||||
**Management Features**:
|
|
||||||
|
|
||||||
- Visual conflict indicators
|
|
||||||
- Resolution suggestions
|
|
||||||
- Override warnings
|
|
||||||
- Backup before changes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Improvements
|
|
||||||
|
|
||||||
### Provider Management
|
|
||||||
|
|
||||||
**New Presets**:
|
|
||||||
|
|
||||||
- **DouBaoSeed** - ByteDance's DouBao
|
|
||||||
- **Kimi For Coding** - Moonshot AI
|
|
||||||
- **BaiLing** - BaiLing AI
|
|
||||||
- **Removed AnyRouter** - To avoid confusion
|
|
||||||
|
|
||||||
**Enhancements**:
|
|
||||||
|
|
||||||
- Model name configuration for Codex and Gemini
|
|
||||||
- Provider notes field for organization
|
|
||||||
- Enhanced preset metadata
|
|
||||||
|
|
||||||
### Configuration Management
|
|
||||||
|
|
||||||
- **Common config migration** - From localStorage to `config.json`
|
|
||||||
- **Unified persistence** - Shared across all apps
|
|
||||||
- **Auto-import** - First launch configuration import
|
|
||||||
- **Backfill priority** - Correct handling of live files
|
|
||||||
|
|
||||||
### UI/UX Improvements
|
|
||||||
|
|
||||||
**Design System**:
|
|
||||||
|
|
||||||
- **macOS native** - System-aligned color scheme
|
|
||||||
- **Window centering** - Default centered position
|
|
||||||
- **Visual polish** - Improved spacing and hierarchy
|
|
||||||
|
|
||||||
**Interactions**:
|
|
||||||
|
|
||||||
- **Password input** - Fixed Edge/IE reveal buttons
|
|
||||||
- **URL overflow** - Fixed card overflow
|
|
||||||
- **Error copying** - Copy-to-clipboard errors
|
|
||||||
- **Tray sync** - Real-time drag-and-drop sync
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bug Fixes
|
|
||||||
|
|
||||||
### Critical Fixes
|
|
||||||
|
|
||||||
- **Usage script validation** - Boundary checks
|
|
||||||
- **Gemini validation** - Relaxed constraints
|
|
||||||
- **TOML parsing** - CJK quote handling
|
|
||||||
- **MCP fields** - Custom field preservation
|
|
||||||
- **White screen** - FormLabel crash fix
|
|
||||||
|
|
||||||
### Stability
|
|
||||||
|
|
||||||
- **Tray safety** - Pattern matching instead of unwrap
|
|
||||||
- **Error isolation** - Tray failures don't block operations
|
|
||||||
- **Import classification** - Correct category assignment
|
|
||||||
|
|
||||||
### UI Fixes
|
|
||||||
|
|
||||||
- **Model placeholders** - Removed misleading hints
|
|
||||||
- **Base URL** - Auto-fill for third-party providers
|
|
||||||
- **Drag sort** - Tray menu synchronization
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Technical Improvements
|
|
||||||
|
|
||||||
### Architecture
|
|
||||||
|
|
||||||
**MCP v3.7.0**:
|
|
||||||
|
|
||||||
- Removed legacy code (~1,000 lines)
|
|
||||||
- Unified initialization structure
|
|
||||||
- Backward compatibility maintained
|
|
||||||
- Comprehensive code formatting
|
|
||||||
|
|
||||||
**Platform Compatibility**:
|
|
||||||
|
|
||||||
- Windows winreg API fix (v0.52)
|
|
||||||
- Safe pattern matching (no `unwrap()`)
|
|
||||||
- Cross-platform tray handling
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
**Synchronization**:
|
|
||||||
|
|
||||||
- MCP sync across all apps
|
|
||||||
- Gemini form-editor sync
|
|
||||||
- Dual-file reading (.env + settings.json)
|
|
||||||
|
|
||||||
**Validation**:
|
|
||||||
|
|
||||||
- Input boundary checks
|
|
||||||
- TOML quote normalization (CJK)
|
|
||||||
- Custom field preservation
|
|
||||||
- Enhanced error messages
|
|
||||||
|
|
||||||
### Code Quality
|
|
||||||
|
|
||||||
**Type Safety**:
|
|
||||||
|
|
||||||
- Complete TypeScript coverage
|
|
||||||
- Rust type refinements
|
|
||||||
- API contract validation
|
|
||||||
|
|
||||||
**Testing**:
|
|
||||||
|
|
||||||
- Simplified assertions
|
|
||||||
- Better test coverage
|
|
||||||
- Integration test updates
|
|
||||||
|
|
||||||
**Dependencies**:
|
|
||||||
|
|
||||||
- Tauri 2.8.x
|
|
||||||
- Rust: `anyhow`, `zip`, `serde_yaml`, `tempfile`
|
|
||||||
- Frontend: CodeMirror 6 packages
|
|
||||||
- winreg 0.52 (Windows)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Technical Statistics
|
|
||||||
|
|
||||||
```
|
|
||||||
Total Changes:
|
|
||||||
- Commits: 85
|
|
||||||
- Files: 152 changed
|
|
||||||
- Additions: +18,104 lines
|
|
||||||
- Deletions: -3,732 lines
|
|
||||||
|
|
||||||
New Modules:
|
|
||||||
- Skills Management: 2,034 lines (21 files)
|
|
||||||
- Prompts Management: 1,302 lines (20 files)
|
|
||||||
- Gemini Integration: ~1,000 lines
|
|
||||||
- MCP Refactor: ~3,000 lines refactored
|
|
||||||
|
|
||||||
Code Distribution:
|
|
||||||
- Backend (Rust): ~4,500 lines new
|
|
||||||
- Frontend (React): ~3,000 lines new
|
|
||||||
- Configuration: ~1,500 lines refactored
|
|
||||||
- Tests: ~500 lines
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Strategic Positioning
|
|
||||||
|
|
||||||
### From Tool to Platform
|
|
||||||
|
|
||||||
v3.7.0 represents a shift in CC Switch's positioning:
|
|
||||||
|
|
||||||
| Aspect | v3.6 | v3.7.0 |
|
|
||||||
| ----------------- | ------------------------ | ---------------------------- |
|
|
||||||
| **Identity** | Provider Switcher | AI CLI Management Platform |
|
|
||||||
| **Scope** | Configuration Management | Ecosystem Management |
|
|
||||||
| **Applications** | Claude + Codex | Claude + Codex + Gemini |
|
|
||||||
| **Capabilities** | Switch configs | Extend capabilities (Skills) |
|
|
||||||
| **Customization** | Manual editing | Visual management (Prompts) |
|
|
||||||
| **Integration** | Isolated apps | Unified management (MCP) |
|
|
||||||
|
|
||||||
### Six Pillars of AI CLI Management
|
|
||||||
|
|
||||||
1. **Configuration Management** - Provider switching and management
|
|
||||||
2. **Capability Extension** - Skills installation and lifecycle
|
|
||||||
3. **Behavior Customization** - System prompt presets
|
|
||||||
4. **Ecosystem Integration** - Deep links and sharing
|
|
||||||
5. **Multi-AI Support** - Claude/Codex/Gemini
|
|
||||||
6. **Intelligent Detection** - Conflict prevention
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Download & Installation
|
|
||||||
|
|
||||||
### System Requirements
|
|
||||||
|
|
||||||
- **Windows**: Windows 10+
|
|
||||||
- **macOS**: macOS 10.15 (Catalina)+
|
|
||||||
- **Linux**: Ubuntu 22.04+ / Debian 11+ / Fedora 34+
|
|
||||||
|
|
||||||
### Download Links
|
|
||||||
|
|
||||||
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download:
|
|
||||||
|
|
||||||
- **Windows**: `CC-Switch-v3.7.0-Windows.msi` or `-Portable.zip`
|
|
||||||
- **macOS**: `CC-Switch-v3.7.0-macOS.tar.gz` or `.zip`
|
|
||||||
- **Linux**: `CC-Switch-v3.7.0-Linux.AppImage` or `.deb`
|
|
||||||
|
|
||||||
### Homebrew (macOS)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew tap farion1231/ccswitch
|
|
||||||
brew install --cask cc-switch
|
|
||||||
```
|
|
||||||
|
|
||||||
Update:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew upgrade --cask cc-switch
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Migration Notes
|
|
||||||
|
|
||||||
### From v3.6.x
|
|
||||||
|
|
||||||
**Automatic migration** - No action required, configs are fully compatible
|
|
||||||
|
|
||||||
### From v3.1.x or Earlier
|
|
||||||
|
|
||||||
**Two-step migration required**:
|
|
||||||
|
|
||||||
1. First upgrade to v3.2.x (performs one-time migration)
|
|
||||||
2. Then upgrade to v3.7.0
|
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
- **Skills**: No migration needed, start fresh
|
|
||||||
- **Prompts**: Auto-import from live files on first launch
|
|
||||||
- **Gemini**: Install Gemini CLI separately if needed
|
|
||||||
- **MCP v3.7.0**: Backward compatible with previous configs
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Acknowledgments
|
|
||||||
|
|
||||||
### Contributors
|
|
||||||
|
|
||||||
Thanks to all contributors who made this release possible:
|
|
||||||
|
|
||||||
- [@YoVinchen](https://github.com/YoVinchen) - Skills & Prompts & Gemini integration implementation
|
|
||||||
- [@farion1231](https://github.com/farion1231) - From developer to issue responder
|
|
||||||
- Community members for testing and feedback
|
|
||||||
|
|
||||||
### Sponsors
|
|
||||||
|
|
||||||
**Z.ai** - GLM CODING PLAN sponsor
|
|
||||||
[Get 10% OFF with this link](https://z.ai/subscribe?ic=8JVLJQFSKB)
|
|
||||||
|
|
||||||
**PackyCode** - API relay service partner
|
|
||||||
[Register with "cc-switch" code for 10% discount](https://www.packyapi.com/register?aff=cc-switch)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Feedback & Support
|
|
||||||
|
|
||||||
- **Issues**: [GitHub Issues](https://github.com/farion1231/cc-switch/issues)
|
|
||||||
- **Discussions**: [GitHub Discussions](https://github.com/farion1231/cc-switch/discussions)
|
|
||||||
- **Documentation**: [README](../README.md)
|
|
||||||
- **Changelog**: [CHANGELOG.md](../CHANGELOG.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## What's Next
|
|
||||||
|
|
||||||
**v3.8.0 Preview** (Tentative):
|
|
||||||
|
|
||||||
- Local proxy functionality
|
|
||||||
|
|
||||||
Stay tuned for more updates!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Happy Coding!**
|
|
||||||
@@ -1,435 +0,0 @@
|
|||||||
# CC Switch v3.7.0
|
|
||||||
|
|
||||||
> 从供应商切换器到 AI CLI 一体化管理平台
|
|
||||||
|
|
||||||
**[English Version →](release-note-v3.7.0-en.md)**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 概览
|
|
||||||
|
|
||||||
CC Switch v3.7.0 新增六大核心功能,新增超过 18,000 行代码。
|
|
||||||
|
|
||||||
**发布日期**:2025-11-19
|
|
||||||
**提交数量**:从 v3.6.0 开始 85 个提交
|
|
||||||
**代码变更**:152 个文件,+18,104 / -3,732 行
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 新增功能
|
|
||||||
|
|
||||||
### Gemini CLI 集成
|
|
||||||
|
|
||||||
完整支持 Google Gemini CLI,成为第三个支持的应用(Claude Code、Codex、Gemini)。
|
|
||||||
|
|
||||||
**核心能力**:
|
|
||||||
|
|
||||||
- **双文件配置** - 同时支持 `.env` 和 `settings.json` 格式
|
|
||||||
- **自动检测** - 自动检测 `GOOGLE_GEMINI_BASE_URL`、`GEMINI_MODEL` 等环境变量
|
|
||||||
- **完整 MCP 支持** - 为 Gemini 提供完整的 MCP 服务器管理
|
|
||||||
- **深度链接集成** - 通过 `ccswitch://` 协议导入配置
|
|
||||||
- **系统托盘** - 从托盘菜单快速切换
|
|
||||||
|
|
||||||
**供应商预设**:
|
|
||||||
|
|
||||||
- **Google Official** - 支持 OAuth 认证
|
|
||||||
- **PackyCode** - 合作伙伴集成
|
|
||||||
- **自定义** - 完全自定义支持
|
|
||||||
|
|
||||||
**技术实现**:
|
|
||||||
|
|
||||||
- 新增后端模块:`gemini_config.rs`(20KB)、`gemini_mcp.rs`
|
|
||||||
- 表单与环境编辑器同步
|
|
||||||
- 双文件原子写入
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### MCP v3.7.0 统一架构
|
|
||||||
|
|
||||||
MCP 管理系统完整重构,实现跨应用统一管理。
|
|
||||||
|
|
||||||
**架构改进**:
|
|
||||||
|
|
||||||
- **统一管理面板** - 单一界面管理 Claude/Codex/Gemini MCP 服务器
|
|
||||||
- **SSE 传输类型** - 新增 Server-Sent Events 支持
|
|
||||||
- **智能解析器** - 容错性 JSON 解析
|
|
||||||
- **格式修正** - 自动修复 Codex `[mcp_servers]` 格式
|
|
||||||
- **扩展字段** - 保留自定义 TOML 字段
|
|
||||||
|
|
||||||
**用户体验**:
|
|
||||||
|
|
||||||
- 表单中的默认应用选择
|
|
||||||
- JSON 格式化器用于验证
|
|
||||||
- 改进的视觉层次
|
|
||||||
- 更好的错误消息
|
|
||||||
|
|
||||||
**导入/导出**:
|
|
||||||
|
|
||||||
- 统一从三个应用导入
|
|
||||||
- 双向同步
|
|
||||||
- 状态保持
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Claude Skills 管理系统
|
|
||||||
|
|
||||||
**约 2,000 行代码** - 完整的技能生态平台。
|
|
||||||
|
|
||||||
**GitHub 集成**:
|
|
||||||
|
|
||||||
- 从 GitHub 仓库自动扫描技能
|
|
||||||
- 预配置仓库:
|
|
||||||
- `ComposioHQ/awesome-claude-skills` - 精选集合
|
|
||||||
- `anthropics/skills` - Anthropic 官方技能
|
|
||||||
- `cexll/myclaude` - 社区贡献
|
|
||||||
- 添加自定义仓库
|
|
||||||
- 子目录扫描支持(`skillsPath`)
|
|
||||||
|
|
||||||
**生命周期管理**:
|
|
||||||
|
|
||||||
- **发现** - 自动检测 `SKILL.md` 文件
|
|
||||||
- **安装** - 一键安装到 `~/.claude/skills/`
|
|
||||||
- **卸载** - 安全移除并跟踪状态
|
|
||||||
- **更新** - 检查更新(基础设施已就绪)
|
|
||||||
|
|
||||||
**技术架构**:
|
|
||||||
|
|
||||||
- **后端**:`SkillService`(526 行)集成 GitHub API
|
|
||||||
- **前端**:SkillsPage、SkillCard、RepoManager
|
|
||||||
- **UI 组件**:Badge、Card、Table(shadcn/ui)
|
|
||||||
- **状态**:持久化存储在 `skills.json`
|
|
||||||
- **国际化**:47+ 个翻译键
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Prompts 管理系统
|
|
||||||
|
|
||||||
**约 1,300 行代码** - 完整的系统提示词管理。
|
|
||||||
|
|
||||||
**多预设管理**:
|
|
||||||
|
|
||||||
- 创建无限数量的提示词预设
|
|
||||||
- 快速在预设间切换
|
|
||||||
- 同时只能激活一个提示词
|
|
||||||
- 活动提示词删除保护
|
|
||||||
|
|
||||||
**跨应用支持**:
|
|
||||||
|
|
||||||
- **Claude**:`~/.claude/CLAUDE.md`
|
|
||||||
- **Codex**:`~/.codex/AGENTS.md`
|
|
||||||
- **Gemini**:`~/.gemini/GEMINI.md`
|
|
||||||
|
|
||||||
**Markdown 编辑器**:
|
|
||||||
|
|
||||||
- 完整的 CodeMirror 6 集成
|
|
||||||
- 语法高亮
|
|
||||||
- 暗色主题(One Dark)
|
|
||||||
- 实时预览
|
|
||||||
|
|
||||||
**智能同步**:
|
|
||||||
|
|
||||||
- **自动写入** - 立即写入 live 文件
|
|
||||||
- **回填保护** - 切换前保存当前内容
|
|
||||||
- **自动导入** - 首次启动从 live 文件导入
|
|
||||||
- **修改保护** - 保留手动修改
|
|
||||||
|
|
||||||
**技术实现**:
|
|
||||||
|
|
||||||
- **后端**:`PromptService`(213 行)
|
|
||||||
- **前端**:PromptPanel(177)、PromptFormModal(160)、MarkdownEditor(159)
|
|
||||||
- **Hooks**:usePromptActions(152 行)
|
|
||||||
- **国际化**:41+ 个翻译键
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 深度链接协议(ccswitch://)
|
|
||||||
|
|
||||||
通过 URL 方案一键导入供应商配置。
|
|
||||||
|
|
||||||
**功能特性**:
|
|
||||||
|
|
||||||
- 所有平台的协议注册
|
|
||||||
- 从共享链接导入
|
|
||||||
- 生命周期集成
|
|
||||||
- 安全验证
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 环境变量冲突检测
|
|
||||||
|
|
||||||
智能检测和管理配置冲突。
|
|
||||||
|
|
||||||
**检测范围**:
|
|
||||||
|
|
||||||
- **Claude & Codex** - 跨应用冲突
|
|
||||||
- **Gemini** - 自动发现
|
|
||||||
- **MCP** - 服务器配置冲突
|
|
||||||
|
|
||||||
**管理功能**:
|
|
||||||
|
|
||||||
- 可视化冲突指示器
|
|
||||||
- 解决建议
|
|
||||||
- 覆盖警告
|
|
||||||
- 更改前备份
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 改进优化
|
|
||||||
|
|
||||||
### 供应商管理
|
|
||||||
|
|
||||||
**新增预设**:
|
|
||||||
|
|
||||||
- **DouBaoSeed** - 字节跳动的豆包
|
|
||||||
- **Kimi For Coding** - 月之暗面
|
|
||||||
- **BaiLing** - 百灵 AI
|
|
||||||
- **移除 AnyRouter** - 避免误导
|
|
||||||
|
|
||||||
**增强功能**:
|
|
||||||
|
|
||||||
- Codex 和 Gemini 的模型名称配置
|
|
||||||
- 供应商备注字段用于组织
|
|
||||||
- 增强的预设元数据
|
|
||||||
|
|
||||||
### 配置管理
|
|
||||||
|
|
||||||
- **通用配置迁移** - 从 localStorage 迁移到 `config.json`
|
|
||||||
- **统一持久化** - 跨所有应用共享
|
|
||||||
- **自动导入** - 首次启动配置导入
|
|
||||||
- **回填优先级** - 正确处理 live 文件
|
|
||||||
|
|
||||||
### UI/UX 改进
|
|
||||||
|
|
||||||
**设计系统**:
|
|
||||||
|
|
||||||
- **macOS 原生** - 与系统对齐的配色方案
|
|
||||||
- **窗口居中** - 默认居中位置
|
|
||||||
- **视觉优化** - 改进的间距和层次
|
|
||||||
|
|
||||||
**交互优化**:
|
|
||||||
|
|
||||||
- **密码输入** - 修复 Edge/IE 显示按钮
|
|
||||||
- **URL 溢出** - 修复卡片溢出
|
|
||||||
- **错误复制** - 可复制到剪贴板的错误
|
|
||||||
- **托盘同步** - 实时拖放同步
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bug 修复
|
|
||||||
|
|
||||||
### 关键修复
|
|
||||||
|
|
||||||
- **用量脚本验证** - 边界检查
|
|
||||||
- **Gemini 验证** - 放宽约束
|
|
||||||
- **TOML 解析** - CJK 引号处理
|
|
||||||
- **MCP 字段** - 自定义字段保留
|
|
||||||
- **白屏** - FormLabel 崩溃修复
|
|
||||||
|
|
||||||
### 稳定性
|
|
||||||
|
|
||||||
- **托盘安全** - 模式匹配替代 unwrap
|
|
||||||
- **错误隔离** - 托盘失败不阻塞操作
|
|
||||||
- **导入分类** - 正确的类别分配
|
|
||||||
|
|
||||||
### UI 修复
|
|
||||||
|
|
||||||
- **模型占位符** - 移除误导性提示
|
|
||||||
- **Base URL** - 第三方供应商自动填充
|
|
||||||
- **拖拽排序** - 托盘菜单同步
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 技术改进
|
|
||||||
|
|
||||||
### 架构
|
|
||||||
|
|
||||||
**MCP v3.7.0**:
|
|
||||||
|
|
||||||
- 移除遗留代码(约 1,000 行)
|
|
||||||
- 统一初始化结构
|
|
||||||
- 保持向后兼容性
|
|
||||||
- 全面的代码格式化
|
|
||||||
|
|
||||||
**平台兼容性**:
|
|
||||||
|
|
||||||
- Windows winreg API 修复(v0.52)
|
|
||||||
- 安全模式匹配(无 `unwrap()`)
|
|
||||||
- 跨平台托盘处理
|
|
||||||
|
|
||||||
### 配置
|
|
||||||
|
|
||||||
**同步机制**:
|
|
||||||
|
|
||||||
- 跨所有应用的 MCP 同步
|
|
||||||
- Gemini 表单-编辑器同步
|
|
||||||
- 双文件读取(.env + settings.json)
|
|
||||||
|
|
||||||
**验证增强**:
|
|
||||||
|
|
||||||
- 输入边界检查
|
|
||||||
- TOML 引号规范化(CJK)
|
|
||||||
- 自定义字段保留
|
|
||||||
- 增强的错误消息
|
|
||||||
|
|
||||||
### 代码质量
|
|
||||||
|
|
||||||
**类型安全**:
|
|
||||||
|
|
||||||
- 完整的 TypeScript 覆盖
|
|
||||||
- Rust 类型改进
|
|
||||||
- API 契约验证
|
|
||||||
|
|
||||||
**测试**:
|
|
||||||
|
|
||||||
- 简化的断言
|
|
||||||
- 更好的测试覆盖
|
|
||||||
- 集成测试更新
|
|
||||||
|
|
||||||
**依赖项**:
|
|
||||||
|
|
||||||
- Tauri 2.8.x
|
|
||||||
- Rust:`anyhow`、`zip`、`serde_yaml`、`tempfile`
|
|
||||||
- 前端:CodeMirror 6 包
|
|
||||||
- winreg 0.52(Windows)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 技术统计
|
|
||||||
|
|
||||||
```
|
|
||||||
总体变更:
|
|
||||||
- 提交数:85
|
|
||||||
- 文件数:152 个文件变更
|
|
||||||
- 新增:+18,104 行
|
|
||||||
- 删除:-3,732 行
|
|
||||||
|
|
||||||
新增模块:
|
|
||||||
- Skills 管理:2,034 行(21 个文件)
|
|
||||||
- Prompts 管理:1,302 行(20 个文件)
|
|
||||||
- Gemini 集成:约 1,000 行
|
|
||||||
- MCP 重构:约 3,000 行重构
|
|
||||||
|
|
||||||
代码分布:
|
|
||||||
- 后端(Rust):约 4,500 行新增
|
|
||||||
- 前端(React):约 3,000 行新增
|
|
||||||
- 配置:约 1,500 行重构
|
|
||||||
- 测试:约 500 行
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 战略定位
|
|
||||||
|
|
||||||
### 从工具到平台
|
|
||||||
|
|
||||||
v3.7.0 代表了 CC Switch 定位的转变:
|
|
||||||
|
|
||||||
| 方面 | v3.6 | v3.7.0 |
|
|
||||||
| -------- | -------------- | ----------------------- |
|
|
||||||
| **身份** | 供应商切换器 | AI CLI 管理平台 |
|
|
||||||
| **范围** | 配置管理 | 生态系统管理 |
|
|
||||||
| **应用** | Claude + Codex | Claude + Codex + Gemini |
|
|
||||||
| **能力** | 切换配置 | 扩展能力(Skills) |
|
|
||||||
| **定制** | 手动编辑 | 可视化管理(Prompts) |
|
|
||||||
| **集成** | 孤立应用 | 统一管理(MCP) |
|
|
||||||
|
|
||||||
### AI CLI 管理六大支柱
|
|
||||||
|
|
||||||
1. **配置管理** - 供应商切换和管理
|
|
||||||
2. **能力扩展** - Skills 安装和生命周期
|
|
||||||
3. **行为定制** - 系统提示词预设
|
|
||||||
4. **生态集成** - 深度链接和共享
|
|
||||||
5. **多 AI 支持** - Claude/Codex/Gemini
|
|
||||||
6. **智能检测** - 冲突预防
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 下载与安装
|
|
||||||
|
|
||||||
### 系统要求
|
|
||||||
|
|
||||||
- **Windows**:Windows 10+
|
|
||||||
- **macOS**:macOS 10.15(Catalina)+
|
|
||||||
- **Linux**:Ubuntu 22.04+ / Debian 11+ / Fedora 34+
|
|
||||||
|
|
||||||
### 下载链接
|
|
||||||
|
|
||||||
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载:
|
|
||||||
|
|
||||||
- **Windows**:`CC-Switch-v3.7.0-Windows.msi` 或 `-Portable.zip`
|
|
||||||
- **macOS**:`CC-Switch-v3.7.0-macOS.tar.gz` 或 `.zip`
|
|
||||||
- **Linux**:`CC-Switch-v3.7.0-Linux.AppImage` 或 `.deb`
|
|
||||||
|
|
||||||
### Homebrew(macOS)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew tap farion1231/ccswitch
|
|
||||||
brew install --cask cc-switch
|
|
||||||
```
|
|
||||||
|
|
||||||
更新:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew upgrade --cask cc-switch
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 迁移说明
|
|
||||||
|
|
||||||
### 从 v3.6.x 升级
|
|
||||||
|
|
||||||
**自动迁移** - 无需任何操作,配置完全兼容
|
|
||||||
|
|
||||||
### 从 v3.1.x 或更早版本升级
|
|
||||||
|
|
||||||
**需要两步迁移**:
|
|
||||||
|
|
||||||
1. 首先升级到 v3.2.x(执行一次性迁移)
|
|
||||||
2. 然后升级到 v3.7.0
|
|
||||||
|
|
||||||
### 新功能
|
|
||||||
|
|
||||||
- **Skills**:无需迁移,全新开始
|
|
||||||
- **Prompts**:首次启动时从 live 文件自动导入
|
|
||||||
- **Gemini**:需要单独安装 Gemini CLI
|
|
||||||
- **MCP v3.7.0**:与之前的配置向后兼容
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 致谢
|
|
||||||
|
|
||||||
### 贡献者
|
|
||||||
|
|
||||||
感谢所有让这个版本成为可能的贡献者:
|
|
||||||
|
|
||||||
- [@YoVinchen](https://github.com/YoVinchen) - Skills & Prompts & Geimini 集成实现
|
|
||||||
- [@farion1231](https://github.com/farion1231) - 从开发沦为 issue 回复机
|
|
||||||
- 社区成员的测试和反馈
|
|
||||||
|
|
||||||
### 赞助商
|
|
||||||
|
|
||||||
**Z.ai** - GLM CODING PLAN 赞助商
|
|
||||||
[通过此链接获得 10% 折扣](https://z.ai/subscribe?ic=8JVLJQFSKB)
|
|
||||||
|
|
||||||
**PackyCode** - API 中继服务合作伙伴
|
|
||||||
[使用 "cc-switch" 代码注册可享受 10% 折扣](https://www.packyapi.com/register?aff=cc-switch)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 反馈与支持
|
|
||||||
|
|
||||||
- **问题反馈**:[GitHub Issues](https://github.com/farion1231/cc-switch/issues)
|
|
||||||
- **讨论**:[GitHub Discussions](https://github.com/farion1231/cc-switch/discussions)
|
|
||||||
- **文档**:[README](../README_ZH.md)
|
|
||||||
- **更新日志**:[CHANGELOG.md](../CHANGELOG.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 未来展望
|
|
||||||
|
|
||||||
**v3.8.0 预览**(暂定):
|
|
||||||
|
|
||||||
- 本地代理功能
|
|
||||||
|
|
||||||
敬请期待更多更新!
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cc-switch",
|
"name": "cc-switch",
|
||||||
"version": "3.7.0",
|
"version": "3.6.2",
|
||||||
"description": "All-in-One Assistant for Claude Code, Codex & Gemini CLI",
|
"description": "Claude Code & Codex 供应商切换工具",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm tauri dev",
|
"dev": "pnpm tauri dev",
|
||||||
"build": "pnpm tauri build",
|
"build": "pnpm tauri build",
|
||||||
|
|||||||
2
src-tauri/Cargo.lock
generated
2
src-tauri/Cargo.lock
generated
@@ -595,7 +595,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc-switch"
|
name = "cc-switch"
|
||||||
version = "3.7.0"
|
version = "3.6.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cc-switch"
|
name = "cc-switch"
|
||||||
version = "3.7.0"
|
version = "3.6.2"
|
||||||
description = "All-in-One Assistant for Claude Code, Codex & Gemini CLI"
|
description = "Claude Code & Codex 供应商配置管理工具"
|
||||||
authors = ["Jason Young"]
|
authors = ["Jason Young"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/farion1231/cc-switch"
|
repository = "https://github.com/farion1231/cc-switch"
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ mod tests {
|
|||||||
# Comment line
|
# Comment line
|
||||||
GOOGLE_GEMINI_BASE_URL=https://example.com
|
GOOGLE_GEMINI_BASE_URL=https://example.com
|
||||||
GEMINI_API_KEY=sk-test123
|
GEMINI_API_KEY=sk-test123
|
||||||
GEMINI_MODEL=gemini-3-pro-preview
|
GEMINI_MODEL=gemini-2.5-pro
|
||||||
|
|
||||||
# Another comment
|
# Another comment
|
||||||
"#;
|
"#;
|
||||||
@@ -381,25 +381,19 @@ GEMINI_MODEL=gemini-3-pro-preview
|
|||||||
Some(&"https://example.com".to_string())
|
Some(&"https://example.com".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(map.get("GEMINI_API_KEY"), Some(&"sk-test123".to_string()));
|
assert_eq!(map.get("GEMINI_API_KEY"), Some(&"sk-test123".to_string()));
|
||||||
assert_eq!(
|
assert_eq!(map.get("GEMINI_MODEL"), Some(&"gemini-2.5-pro".to_string()));
|
||||||
map.get("GEMINI_MODEL"),
|
|
||||||
Some(&"gemini-3-pro-preview".to_string())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_env_file() {
|
fn test_serialize_env_file() {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert("GEMINI_API_KEY".to_string(), "sk-test".to_string());
|
map.insert("GEMINI_API_KEY".to_string(), "sk-test".to_string());
|
||||||
map.insert(
|
map.insert("GEMINI_MODEL".to_string(), "gemini-2.5-pro".to_string());
|
||||||
"GEMINI_MODEL".to_string(),
|
|
||||||
"gemini-3-pro-preview".to_string(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let content = serialize_env_file(&map);
|
let content = serialize_env_file(&map);
|
||||||
|
|
||||||
assert!(content.contains("GEMINI_API_KEY=sk-test"));
|
assert!(content.contains("GEMINI_API_KEY=sk-test"));
|
||||||
assert!(content.contains("GEMINI_MODEL=gemini-3-pro-preview"));
|
assert!(content.contains("GEMINI_MODEL=gemini-2.5-pro"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -423,7 +417,7 @@ GEMINI_MODEL=gemini-3-pro-preview
|
|||||||
# Comment line
|
# Comment line
|
||||||
GOOGLE_GEMINI_BASE_URL=https://example.com
|
GOOGLE_GEMINI_BASE_URL=https://example.com
|
||||||
GEMINI_API_KEY=sk-test123
|
GEMINI_API_KEY=sk-test123
|
||||||
GEMINI_MODEL=gemini-3-pro-preview
|
GEMINI_MODEL=gemini-2.5-pro
|
||||||
|
|
||||||
# Another comment
|
# Another comment
|
||||||
"#;
|
"#;
|
||||||
@@ -438,10 +432,7 @@ GEMINI_MODEL=gemini-3-pro-preview
|
|||||||
Some(&"https://example.com".to_string())
|
Some(&"https://example.com".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(map.get("GEMINI_API_KEY"), Some(&"sk-test123".to_string()));
|
assert_eq!(map.get("GEMINI_API_KEY"), Some(&"sk-test123".to_string()));
|
||||||
assert_eq!(
|
assert_eq!(map.get("GEMINI_MODEL"), Some(&"gemini-2.5-pro".to_string()));
|
||||||
map.get("GEMINI_MODEL"),
|
|
||||||
Some(&"gemini-3-pro-preview".to_string())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -607,7 +598,7 @@ KEY_WITH-DASH=value";
|
|||||||
let settings = serde_json::json!({
|
let settings = serde_json::json!({
|
||||||
"env": {
|
"env": {
|
||||||
"GEMINI_API_KEY": "sk-test123",
|
"GEMINI_API_KEY": "sk-test123",
|
||||||
"GEMINI_MODEL": "gemini-3-pro-preview"
|
"GEMINI_MODEL": "gemini-2.5-pro"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -620,7 +611,7 @@ KEY_WITH-DASH=value";
|
|||||||
// 测试缺少 API Key 的非空配置在基本验证中可以通过(用户稍后填写)
|
// 测试缺少 API Key 的非空配置在基本验证中可以通过(用户稍后填写)
|
||||||
let settings = serde_json::json!({
|
let settings = serde_json::json!({
|
||||||
"env": {
|
"env": {
|
||||||
"GEMINI_MODEL": "gemini-3-pro-preview"
|
"GEMINI_MODEL": "gemini-2.5-pro"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@@ -36,7 +35,6 @@ fn get_keywords_for_app(app: &str) -> Vec<&str> {
|
|||||||
match app.to_lowercase().as_str() {
|
match app.to_lowercase().as_str() {
|
||||||
"claude" => vec!["ANTHROPIC"],
|
"claude" => vec!["ANTHROPIC"],
|
||||||
"codex" => vec!["OPENAI"],
|
"codex" => vec!["OPENAI"],
|
||||||
"gemini" => vec!["GEMINI", "GOOGLE_GEMINI"],
|
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,12 +48,14 @@ fn check_system_env(keywords: &[&str]) -> Result<Vec<EnvConflict>, String> {
|
|||||||
if let Ok(hkcu) = RegKey::predef(HKEY_CURRENT_USER).open_subkey("Environment") {
|
if let Ok(hkcu) = RegKey::predef(HKEY_CURRENT_USER).open_subkey("Environment") {
|
||||||
for (name, value) in hkcu.enum_values().filter_map(Result::ok) {
|
for (name, value) in hkcu.enum_values().filter_map(Result::ok) {
|
||||||
if keywords.iter().any(|k| name.to_uppercase().contains(k)) {
|
if keywords.iter().any(|k| name.to_uppercase().contains(k)) {
|
||||||
conflicts.push(EnvConflict {
|
if let Ok(val) = value.to_string() {
|
||||||
var_name: name.clone(),
|
conflicts.push(EnvConflict {
|
||||||
var_value: value.to_string(),
|
var_name: name.clone(),
|
||||||
source_type: "system".to_string(),
|
var_value: val,
|
||||||
source_path: "HKEY_CURRENT_USER\\Environment".to_string(),
|
source_type: "system".to_string(),
|
||||||
});
|
source_path: "HKEY_CURRENT_USER\\Environment".to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,12 +66,14 @@ fn check_system_env(keywords: &[&str]) -> Result<Vec<EnvConflict>, String> {
|
|||||||
{
|
{
|
||||||
for (name, value) in hklm.enum_values().filter_map(Result::ok) {
|
for (name, value) in hklm.enum_values().filter_map(Result::ok) {
|
||||||
if keywords.iter().any(|k| name.to_uppercase().contains(k)) {
|
if keywords.iter().any(|k| name.to_uppercase().contains(k)) {
|
||||||
conflicts.push(EnvConflict {
|
if let Ok(val) = value.to_string() {
|
||||||
var_name: name.clone(),
|
conflicts.push(EnvConflict {
|
||||||
var_value: value.to_string(),
|
var_name: name.clone(),
|
||||||
source_type: "system".to_string(),
|
var_value: val,
|
||||||
source_path: "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment".to_string(),
|
source_type: "system".to_string(),
|
||||||
});
|
source_path: "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment".to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,10 +161,6 @@ mod tests {
|
|||||||
fn test_get_keywords() {
|
fn test_get_keywords() {
|
||||||
assert_eq!(get_keywords_for_app("claude"), vec!["ANTHROPIC"]);
|
assert_eq!(get_keywords_for_app("claude"), vec!["ANTHROPIC"]);
|
||||||
assert_eq!(get_keywords_for_app("codex"), vec!["OPENAI"]);
|
assert_eq!(get_keywords_for_app("codex"), vec!["OPENAI"]);
|
||||||
assert_eq!(
|
|
||||||
get_keywords_for_app("gemini"),
|
|
||||||
vec!["GEMINI", "GOOGLE_GEMINI"]
|
|
||||||
);
|
|
||||||
assert_eq!(get_keywords_for_app("unknown"), Vec::<&str>::new());
|
assert_eq!(get_keywords_for_app("unknown"), Vec::<&str>::new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -847,37 +847,19 @@ impl ProviderService {
|
|||||||
v
|
v
|
||||||
}
|
}
|
||||||
AppType::Gemini => {
|
AppType::Gemini => {
|
||||||
use crate::gemini_config::{
|
// 新增
|
||||||
env_to_json, get_gemini_env_path, get_gemini_settings_path, read_gemini_env,
|
use crate::gemini_config::{env_to_json, get_gemini_env_path, read_gemini_env};
|
||||||
};
|
|
||||||
|
|
||||||
// 读取 .env 文件(环境变量)
|
let path = get_gemini_env_path();
|
||||||
let env_path = get_gemini_env_path();
|
if !path.exists() {
|
||||||
if !env_path.exists() {
|
|
||||||
return Err(AppError::localized(
|
return Err(AppError::localized(
|
||||||
"gemini.live.missing",
|
"gemini.live.missing",
|
||||||
"Gemini 配置文件不存在",
|
"Gemini 配置文件不存在",
|
||||||
"Gemini configuration file is missing",
|
"Gemini configuration file is missing",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let env_map = read_gemini_env()?;
|
let env_map = read_gemini_env()?;
|
||||||
let env_json = env_to_json(&env_map);
|
env_to_json(&env_map)
|
||||||
let env_obj = env_json.get("env").cloned().unwrap_or_else(|| json!({}));
|
|
||||||
|
|
||||||
// 读取 settings.json 文件(MCP 配置等)
|
|
||||||
let settings_path = get_gemini_settings_path();
|
|
||||||
let config_obj = if settings_path.exists() {
|
|
||||||
read_json_file(&settings_path)?
|
|
||||||
} else {
|
|
||||||
json!({})
|
|
||||||
};
|
|
||||||
|
|
||||||
// 返回完整结构:{ "env": {...}, "config": {...} }
|
|
||||||
json!({
|
|
||||||
"env": env_obj,
|
|
||||||
"config": config_obj
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -932,13 +914,11 @@ impl ProviderService {
|
|||||||
read_json_file(&path)
|
read_json_file(&path)
|
||||||
}
|
}
|
||||||
AppType::Gemini => {
|
AppType::Gemini => {
|
||||||
use crate::gemini_config::{
|
// 新增
|
||||||
env_to_json, get_gemini_env_path, get_gemini_settings_path, read_gemini_env,
|
use crate::gemini_config::{env_to_json, get_gemini_env_path, read_gemini_env};
|
||||||
};
|
|
||||||
|
|
||||||
// 读取 .env 文件(环境变量)
|
let path = get_gemini_env_path();
|
||||||
let env_path = get_gemini_env_path();
|
if !path.exists() {
|
||||||
if !env_path.exists() {
|
|
||||||
return Err(AppError::localized(
|
return Err(AppError::localized(
|
||||||
"gemini.env.missing",
|
"gemini.env.missing",
|
||||||
"Gemini .env 文件不存在",
|
"Gemini .env 文件不存在",
|
||||||
@@ -947,22 +927,7 @@ impl ProviderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let env_map = read_gemini_env()?;
|
let env_map = read_gemini_env()?;
|
||||||
let env_json = env_to_json(&env_map);
|
Ok(env_to_json(&env_map))
|
||||||
let env_obj = env_json.get("env").cloned().unwrap_or_else(|| json!({}));
|
|
||||||
|
|
||||||
// 读取 settings.json 文件(MCP 配置等)
|
|
||||||
let settings_path = get_gemini_settings_path();
|
|
||||||
let config_obj = if settings_path.exists() {
|
|
||||||
read_json_file(&settings_path)?
|
|
||||||
} else {
|
|
||||||
json!({})
|
|
||||||
};
|
|
||||||
|
|
||||||
// 返回完整结构:{ "env": {...}, "config": {...} }
|
|
||||||
Ok(json!({
|
|
||||||
"env": env_obj,
|
|
||||||
"config": config_obj
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "CC Switch",
|
"productName": "CC Switch",
|
||||||
"version": "3.7.0",
|
"version": "3.6.2",
|
||||||
"identifier": "com.ccswitch.desktop",
|
"identifier": "com.ccswitch.desktop",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../dist",
|
"frontendDist": "../dist",
|
||||||
|
|||||||
@@ -498,8 +498,8 @@ url = "https://example.com"
|
|||||||
.expect("unified servers should exist");
|
.expect("unified servers should exist");
|
||||||
|
|
||||||
let echo = servers.get("echo_server").expect("echo server");
|
let echo = servers.get("echo_server").expect("echo server");
|
||||||
assert!(
|
assert_eq!(
|
||||||
echo.apps.codex,
|
echo.apps.codex, true,
|
||||||
"Codex app should be enabled for echo_server"
|
"Codex app should be enabled for echo_server"
|
||||||
);
|
);
|
||||||
let server_spec = echo.server.as_object().expect("server spec");
|
let server_spec = echo.server.as_object().expect("server spec");
|
||||||
@@ -512,8 +512,8 @@ url = "https://example.com"
|
|||||||
);
|
);
|
||||||
|
|
||||||
let http = servers.get("http_server").expect("http server");
|
let http = servers.get("http_server").expect("http server");
|
||||||
assert!(
|
assert_eq!(
|
||||||
http.apps.codex,
|
http.apps.codex, true,
|
||||||
"Codex app should be enabled for http_server"
|
"Codex app should be enabled for http_server"
|
||||||
);
|
);
|
||||||
let http_spec = http.server.as_object().expect("http spec");
|
let http_spec = http.server.as_object().expect("http spec");
|
||||||
@@ -577,7 +577,10 @@ command = "echo"
|
|||||||
.expect("existing entry");
|
.expect("existing entry");
|
||||||
|
|
||||||
// 验证 Codex 应用已启用
|
// 验证 Codex 应用已启用
|
||||||
assert!(entry.apps.codex, "Codex app should be enabled after import");
|
assert_eq!(
|
||||||
|
entry.apps.codex, true,
|
||||||
|
"Codex app should be enabled after import"
|
||||||
|
);
|
||||||
|
|
||||||
// 验证现有配置被保留(server 不应被覆盖)
|
// 验证现有配置被保留(server 不应被覆盖)
|
||||||
let spec = entry.server.as_object().expect("server spec");
|
let spec = entry.server.as_object().expect("server spec");
|
||||||
@@ -699,8 +702,8 @@ fn import_from_claude_merges_into_config() {
|
|||||||
.expect("entry exists");
|
.expect("entry exists");
|
||||||
|
|
||||||
// 验证 Claude 应用已启用
|
// 验证 Claude 应用已启用
|
||||||
assert!(
|
assert_eq!(
|
||||||
entry.apps.claude,
|
entry.apps.claude, true,
|
||||||
"Claude app should be enabled after import"
|
"Claude app should be enabled after import"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export const GeminiEnvSection: React.FC<GeminiEnvSectionProps> = ({
|
|||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
placeholder={`GOOGLE_GEMINI_BASE_URL=https://your-api-endpoint.com/
|
placeholder={`GOOGLE_GEMINI_BASE_URL=https://your-api-endpoint.com/
|
||||||
GEMINI_API_KEY=sk-your-api-key-here
|
GEMINI_API_KEY=sk-your-api-key-here
|
||||||
GEMINI_MODEL=gemini-3-pro-preview`}
|
GEMINI_MODEL=gemini-2.5-pro`}
|
||||||
rows={6}
|
rows={6}
|
||||||
className="w-full px-3 py-2 border border-border-default dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 transition-colors resize-y min-h-[8rem]"
|
className="w-full px-3 py-2 border border-border-default dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 transition-colors resize-y min-h-[8rem]"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export function GeminiFormFields({
|
|||||||
id="gemini-model"
|
id="gemini-model"
|
||||||
value={model}
|
value={model}
|
||||||
onChange={(e) => onModelChange(e.target.value)}
|
onChange={(e) => onModelChange(e.target.value)}
|
||||||
placeholder="gemini-3-pro-preview"
|
placeholder="gemini-2.5-pro"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const GEMINI_DEFAULT_CONFIG = JSON.stringify(
|
|||||||
env: {
|
env: {
|
||||||
GOOGLE_GEMINI_BASE_URL: "",
|
GOOGLE_GEMINI_BASE_URL: "",
|
||||||
GEMINI_API_KEY: "",
|
GEMINI_API_KEY: "",
|
||||||
GEMINI_MODEL: "gemini-3-pro-preview",
|
GEMINI_MODEL: "gemini-2.5-pro",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
@@ -171,16 +171,18 @@ export function ProviderForm({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 使用 Base URL hook (Claude, Codex, Gemini)
|
// 使用 Base URL hook (Claude, Codex, Gemini)
|
||||||
const { baseUrl, handleClaudeBaseUrlChange } = useBaseUrlState({
|
const { baseUrl, handleClaudeBaseUrlChange, handleGeminiBaseUrlChange } =
|
||||||
appType: appId,
|
useBaseUrlState({
|
||||||
category,
|
appType: appId,
|
||||||
settingsConfig: form.watch("settingsConfig"),
|
category,
|
||||||
codexConfig: "",
|
settingsConfig: form.watch("settingsConfig"),
|
||||||
onSettingsConfigChange: (config) => form.setValue("settingsConfig", config),
|
codexConfig: "",
|
||||||
onCodexConfigChange: () => {
|
onSettingsConfigChange: (config) =>
|
||||||
/* noop */
|
form.setValue("settingsConfig", config),
|
||||||
},
|
onCodexConfigChange: () => {
|
||||||
});
|
/* noop */
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// 使用 Model hook(新:主模型 + Haiku/Sonnet/Opus 默认模型)
|
// 使用 Model hook(新:主模型 + Haiku/Sonnet/Opus 默认模型)
|
||||||
const {
|
const {
|
||||||
@@ -315,13 +317,9 @@ export function ProviderForm({
|
|||||||
const {
|
const {
|
||||||
geminiEnv,
|
geminiEnv,
|
||||||
geminiConfig,
|
geminiConfig,
|
||||||
geminiApiKey,
|
|
||||||
geminiBaseUrl,
|
|
||||||
geminiModel,
|
geminiModel,
|
||||||
envError,
|
envError,
|
||||||
configError: geminiConfigError,
|
configError: geminiConfigError,
|
||||||
handleGeminiApiKeyChange: originalHandleGeminiApiKeyChange,
|
|
||||||
handleGeminiBaseUrlChange: originalHandleGeminiBaseUrlChange,
|
|
||||||
handleGeminiEnvChange,
|
handleGeminiEnvChange,
|
||||||
handleGeminiConfigChange,
|
handleGeminiConfigChange,
|
||||||
resetGeminiConfig,
|
resetGeminiConfig,
|
||||||
@@ -331,39 +329,6 @@ export function ProviderForm({
|
|||||||
initialData: appId === "gemini" ? initialData : undefined,
|
initialData: appId === "gemini" ? initialData : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 包装 Gemini handlers 以同步 settingsConfig
|
|
||||||
const handleGeminiApiKeyChange = useCallback(
|
|
||||||
(key: string) => {
|
|
||||||
originalHandleGeminiApiKeyChange(key);
|
|
||||||
// 同步更新 settingsConfig
|
|
||||||
try {
|
|
||||||
const config = JSON.parse(form.watch("settingsConfig") || "{}");
|
|
||||||
if (!config.env) config.env = {};
|
|
||||||
config.env.GEMINI_API_KEY = key.trim();
|
|
||||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[originalHandleGeminiApiKeyChange, form],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleGeminiBaseUrlChange = useCallback(
|
|
||||||
(url: string) => {
|
|
||||||
originalHandleGeminiBaseUrlChange(url);
|
|
||||||
// 同步更新 settingsConfig
|
|
||||||
try {
|
|
||||||
const config = JSON.parse(form.watch("settingsConfig") || "{}");
|
|
||||||
if (!config.env) config.env = {};
|
|
||||||
config.env.GOOGLE_GEMINI_BASE_URL = url.trim().replace(/\/+$/, "");
|
|
||||||
form.setValue("settingsConfig", JSON.stringify(config, null, 2));
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[originalHandleGeminiBaseUrlChange, form],
|
|
||||||
);
|
|
||||||
|
|
||||||
// 使用 Gemini 通用配置 hook (仅 Gemini 模式)
|
// 使用 Gemini 通用配置 hook (仅 Gemini 模式)
|
||||||
const {
|
const {
|
||||||
useCommonConfig: useGeminiCommonConfigFlag,
|
useCommonConfig: useGeminiCommonConfigFlag,
|
||||||
@@ -739,15 +704,15 @@ export function ProviderForm({
|
|||||||
form.watch("settingsConfig"),
|
form.watch("settingsConfig"),
|
||||||
isEditMode,
|
isEditMode,
|
||||||
)}
|
)}
|
||||||
apiKey={geminiApiKey}
|
apiKey={apiKey}
|
||||||
onApiKeyChange={handleGeminiApiKeyChange}
|
onApiKeyChange={handleApiKeyChange}
|
||||||
category={category}
|
category={category}
|
||||||
shouldShowApiKeyLink={shouldShowGeminiApiKeyLink}
|
shouldShowApiKeyLink={shouldShowGeminiApiKeyLink}
|
||||||
websiteUrl={geminiWebsiteUrl}
|
websiteUrl={geminiWebsiteUrl}
|
||||||
isPartner={isGeminiPartner}
|
isPartner={isGeminiPartner}
|
||||||
partnerPromotionKey={geminiPartnerPromotionKey}
|
partnerPromotionKey={geminiPartnerPromotionKey}
|
||||||
shouldShowSpeedTest={shouldShowSpeedTest}
|
shouldShowSpeedTest={shouldShowSpeedTest}
|
||||||
baseUrl={geminiBaseUrl}
|
baseUrl={baseUrl}
|
||||||
onBaseUrlChange={handleGeminiBaseUrlChange}
|
onBaseUrlChange={handleGeminiBaseUrlChange}
|
||||||
isEndpointModalOpen={isEndpointModalOpen}
|
isEndpointModalOpen={isEndpointModalOpen}
|
||||||
onEndpointModalToggle={setIsEndpointModalOpen}
|
onEndpointModalToggle={setIsEndpointModalOpen}
|
||||||
|
|||||||
@@ -230,23 +230,6 @@ export const providerPresets: ProviderPreset[] = [
|
|||||||
},
|
},
|
||||||
category: "cn_official",
|
category: "cn_official",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "DouBaoSeed",
|
|
||||||
websiteUrl: "https://www.volcengine.com/product/doubao",
|
|
||||||
apiKeyUrl: "https://www.volcengine.com/product/doubao",
|
|
||||||
settingsConfig: {
|
|
||||||
env: {
|
|
||||||
ANTHROPIC_BASE_URL: "https://ark.cn-beijing.volces.com/api/coding",
|
|
||||||
ANTHROPIC_AUTH_TOKEN: "",
|
|
||||||
API_TIMEOUT_MS: "3000000",
|
|
||||||
ANTHROPIC_MODEL: "doubao-seed-code-preview-latest",
|
|
||||||
ANTHROPIC_DEFAULT_SONNET_MODEL: "doubao-seed-code-preview-latest",
|
|
||||||
ANTHROPIC_DEFAULT_OPUS_MODEL: "doubao-seed-code-preview-latest",
|
|
||||||
ANTHROPIC_DEFAULT_HAIKU_MODEL: "doubao-seed-code-preview-latest",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
category: "cn_official",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "BaiLing",
|
name: "BaiLing",
|
||||||
websiteUrl: "https://alipaytbox.yuque.com/sxs0ba/ling/get_started",
|
websiteUrl: "https://alipaytbox.yuque.com/sxs0ba/ling/get_started",
|
||||||
@@ -311,4 +294,22 @@ export const providerPresets: ProviderPreset[] = [
|
|||||||
isPartner: true, // 合作伙伴
|
isPartner: true, // 合作伙伴
|
||||||
partnerPromotionKey: "packycode", // 促销信息 i18n key
|
partnerPromotionKey: "packycode", // 促销信息 i18n key
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "AnyRouter",
|
||||||
|
websiteUrl: "https://anyrouter.top",
|
||||||
|
apiKeyUrl: "https://anyrouter.top/register?aff=PCel",
|
||||||
|
settingsConfig: {
|
||||||
|
env: {
|
||||||
|
ANTHROPIC_BASE_URL: "https://anyrouter.top",
|
||||||
|
ANTHROPIC_AUTH_TOKEN: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 请求地址候选(用于地址管理/测速)
|
||||||
|
endpointCandidates: [
|
||||||
|
"https://q.quuvv.cn",
|
||||||
|
"https://pmpjfbhq.cn-nb1.rainapp.top",
|
||||||
|
"https://anyrouter.top",
|
||||||
|
],
|
||||||
|
category: "third_party",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -143,4 +143,20 @@ requires_openai_auth = true`,
|
|||||||
isPartner: true, // 合作伙伴
|
isPartner: true, // 合作伙伴
|
||||||
partnerPromotionKey: "packycode", // 促销信息 i18n key
|
partnerPromotionKey: "packycode", // 促销信息 i18n key
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "AnyRouter",
|
||||||
|
websiteUrl: "https://anyrouter.top",
|
||||||
|
category: "third_party",
|
||||||
|
auth: generateThirdPartyAuth(""),
|
||||||
|
config: generateThirdPartyConfig(
|
||||||
|
"anyrouter",
|
||||||
|
"https://anyrouter.top/v1",
|
||||||
|
"gpt-5-codex",
|
||||||
|
),
|
||||||
|
endpointCandidates: [
|
||||||
|
"https://anyrouter.top/v1",
|
||||||
|
"https://q.quuvv.cn/v1",
|
||||||
|
"https://pmpjfbhq.cn-nb1.rainapp.top/v1",
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -33,11 +33,14 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
|||||||
websiteUrl: "https://ai.google.dev/",
|
websiteUrl: "https://ai.google.dev/",
|
||||||
apiKeyUrl: "https://aistudio.google.com/apikey",
|
apiKeyUrl: "https://aistudio.google.com/apikey",
|
||||||
settingsConfig: {
|
settingsConfig: {
|
||||||
env: {},
|
env: {
|
||||||
|
GEMINI_MODEL: "gemini-2.5-pro",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
description: "Google 官方 Gemini API (OAuth)",
|
description: "Google 官方 Gemini API (OAuth)",
|
||||||
category: "official",
|
category: "official",
|
||||||
partnerPromotionKey: "google-official",
|
partnerPromotionKey: "google-official",
|
||||||
|
model: "gemini-2.5-pro",
|
||||||
theme: {
|
theme: {
|
||||||
icon: "gemini",
|
icon: "gemini",
|
||||||
backgroundColor: "#4285F4",
|
backgroundColor: "#4285F4",
|
||||||
@@ -51,11 +54,11 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
|||||||
settingsConfig: {
|
settingsConfig: {
|
||||||
env: {
|
env: {
|
||||||
GOOGLE_GEMINI_BASE_URL: "https://www.packyapi.com",
|
GOOGLE_GEMINI_BASE_URL: "https://www.packyapi.com",
|
||||||
GEMINI_MODEL: "gemini-3-pro-preview",
|
GEMINI_MODEL: "gemini-2.5-pro",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
baseURL: "https://www.packyapi.com",
|
baseURL: "https://www.packyapi.com",
|
||||||
model: "gemini-3-pro-preview",
|
model: "gemini-2.5-pro",
|
||||||
description: "PackyCode",
|
description: "PackyCode",
|
||||||
category: "third_party",
|
category: "third_party",
|
||||||
isPartner: true,
|
isPartner: true,
|
||||||
@@ -71,10 +74,10 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
|||||||
settingsConfig: {
|
settingsConfig: {
|
||||||
env: {
|
env: {
|
||||||
GOOGLE_GEMINI_BASE_URL: "",
|
GOOGLE_GEMINI_BASE_URL: "",
|
||||||
GEMINI_MODEL: "gemini-3-pro-preview",
|
GEMINI_MODEL: "gemini-2.5-pro",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
model: "gemini-3-pro-preview",
|
model: "gemini-2.5-pro",
|
||||||
description: "自定义 Gemini API 端点",
|
description: "自定义 Gemini API 端点",
|
||||||
category: "custom",
|
category: "custom",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"title": "CC Switch",
|
"title": "CC Switch",
|
||||||
"description": "All-in-One Assistant for Claude Code, Codex & Gemini CLI"
|
"description": "Claude Code & Codex Provider Switching Tool"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"title": "CC Switch",
|
"title": "CC Switch",
|
||||||
"description": "Claude Code / Codex / Gemini CLI 全方位辅助工具"
|
"description": "Claude Code & Codex 供应商切换工具"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "添加",
|
"add": "添加",
|
||||||
|
|||||||
Reference in New Issue
Block a user