Files
CC-Switch/src/types.ts
T
YoVinchen 3d69da5b66 feat: add model configuration support and fix Gemini deeplink bug (#251)
* feat(providers): add notes field for provider management

- Add notes field to Provider model (backend and frontend)
- Display notes with higher priority than URL in provider card
- Style notes as non-clickable text to differentiate from URLs
- Add notes input field in provider form
- Add i18n support (zh/en) for notes field

* chore: format code and clean up unused props

- Run cargo fmt on Rust backend code
- Format TypeScript imports and code style
- Remove unused appId prop from ProviderPresetSelector
- Clean up unused variables in tests
- Integrate notes field handling in provider dialogs

* feat(deeplink): implement ccswitch:// protocol for provider import

Add deep link support to enable one-click provider configuration import via ccswitch:// URLs.

Backend:
- Implement URL parsing and validation (src-tauri/src/deeplink.rs)
- Add Tauri commands for parse and import (src-tauri/src/commands/deeplink.rs)
- Register ccswitch:// protocol in macOS Info.plist
- Add comprehensive unit tests (src-tauri/tests/deeplink_import.rs)

Frontend:
- Create confirmation dialog with security review UI (src/components/DeepLinkImportDialog.tsx)
- Add API wrapper (src/lib/api/deeplink.ts)
- Integrate event listeners in App.tsx

Configuration:
- Update Tauri config for deep link handling
- Add i18n support for Chinese and English
- Include test page for deep link validation (deeplink-test.html)

Files: 15 changed, 1312 insertions(+)

* chore(deeplink): integrate deep link handling into app lifecycle

Wire up deep link infrastructure with app initialization and event handling.

Backend Integration:
- Register deep link module and commands in mod.rs
- Add URL handling in app setup (src-tauri/src/lib.rs:handle_deeplink_url)
- Handle deep links from single instance callback (Windows/Linux CLI)
- Handle deep links from macOS system events
- Add tauri-plugin-deep-link dependency (Cargo.toml)

Frontend Integration:
- Listen for deeplink-import/deeplink-error events in App.tsx
- Update DeepLinkImportDialog component imports

Configuration:
- Enable deep link plugin in tauri.conf.json
- Update Cargo.lock for new dependencies

Localization:
- Add Chinese translations for deep link UI (zh.json)
- Add English translations for deep link UI (en.json)

Files: 9 changed, 359 insertions(+), 18 deletions(-)

* refactor(deeplink): enhance Codex provider template generation

Align deep link import with UI preset generation logic by:
- Adding complete config.toml template matching frontend defaults
- Generating safe provider name from sanitized input
- Including model_provider, reasoning_effort, and wire_api settings
- Removing minimal template that only contained base_url
- Cleaning up deprecated test file deeplink-test.html

* style: fix clippy uninlined_format_args warnings

Apply clippy --fix to use inline format arguments in:
- src/mcp.rs (8 fixes)
- src/services/env_manager.rs (10 fixes)

* style: apply code formatting and cleanup

- Format TypeScript files with Prettier (App.tsx, EnvWarningBanner.tsx, formatters.ts)
- Organize Rust imports and module order alphabetically
- Add newline at end of JSON files (en.json, zh.json)
- Update Cargo.lock for dependency changes

* feat: add model name configuration support for Codex and fix Gemini model handling

- Add visual model name input field for Codex providers
  - Add model name extraction and update utilities in providerConfigUtils
  - Implement model name state management in useCodexConfigState hook
  - Add conditional model field rendering in CodexFormFields (non-official only)
  - Integrate model name sync with TOML config in ProviderForm

- Fix Gemini deeplink model injection bug
  - Correct environment variable name from GOOGLE_GEMINI_MODEL to GEMINI_MODEL
  - Add test cases for Gemini model injection (with/without model)
  - All tests passing (9/9)

- Fix Gemini model field binding in edit mode
  - Add geminiModel state to useGeminiConfigState hook
  - Extract model value during initialization and reset
  - Sync model field with geminiEnv state to prevent data loss on submit
  - Fix missing model value display when editing Gemini providers

Changes:
  - 6 files changed, 245 insertions(+), 13 deletions(-)
2025-11-19 09:03:18 +08:00

168 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export type ProviderCategory =
| "official" // 官方
| "cn_official" // 开源官方(原"国产官方")
| "aggregator" // 聚合网站
| "third_party" // 第三方供应商
| "custom"; // 自定义
export interface Provider {
id: string;
name: string;
settingsConfig: Record<string, any>; // 应用配置对象:Claude 为 settings.jsonCodex 为 { auth, config }
websiteUrl?: string;
// 新增:供应商分类(用于差异化提示/能力开关)
category?: ProviderCategory;
createdAt?: number; // 添加时间戳(毫秒)
sortIndex?: number; // 排序索引(用于自定义拖拽排序)
// 备注信息
notes?: string;
// 新增:是否为商业合作伙伴
isPartner?: boolean;
// 可选:供应商元数据(仅存于 ~/.cc-switch/config.json,不写入 live 配置)
meta?: ProviderMeta;
}
export interface AppConfig {
providers: Record<string, Provider>;
current: string;
}
// 自定义端点配置
export interface CustomEndpoint {
url: string;
addedAt: number;
lastUsed?: number;
}
// 端点候选项(用于端点测速弹窗)
export interface EndpointCandidate {
id?: string;
url: string;
isCustom?: boolean;
}
// 用量查询脚本配置
export interface UsageScript {
enabled: boolean; // 是否启用用量查询
language: "javascript"; // 脚本语言
code: string; // 脚本代码(JSON 格式配置)
timeout?: number; // 超时时间(秒,默认 10
apiKey?: string; // 用量查询专用的 API Key(通用模板使用)
baseUrl?: string; // 用量查询专用的 Base URL(通用和 NewAPI 模板使用)
accessToken?: string; // 访问令牌(NewAPI 模板使用)
userId?: string; // 用户IDNewAPI 模板使用)
autoQueryInterval?: number; // 自动查询间隔(单位:分钟,0 表示禁用)
}
// 单个套餐用量数据
export interface UsageData {
planName?: string; // 套餐名称(可选)
extra?: string; // 扩展字段,可自由补充需要展示的文本(可选)
isValid?: boolean; // 套餐是否有效(可选)
invalidMessage?: string; // 失效原因说明(可选,当 isValid 为 false 时显示)
total?: number; // 总额度(可选)
used?: number; // 已用额度(可选)
remaining?: number; // 剩余额度(可选)
unit?: string; // 单位(可选)
}
// 用量查询结果(支持多套餐)
export interface UsageResult {
success: boolean;
data?: UsageData[]; // 改为数组,支持返回多个套餐
error?: string;
}
// 供应商元数据(字段名与后端一致,保持 snake_case
export interface ProviderMeta {
// 自定义端点:以 URL 为键,值为端点信息
custom_endpoints?: Record<string, CustomEndpoint>;
// 用量查询脚本配置
usage_script?: UsageScript;
// 是否为官方合作伙伴
isPartner?: boolean;
// 合作伙伴促销 key(用于后端识别 PackyCode 等)
partnerPromotionKey?: string;
}
// 应用设置类型(用于设置对话框与 Tauri API)
export interface Settings {
// 是否在系统托盘(macOS 菜单栏)显示图标
showInTray: boolean;
// 点击关闭按钮时是否最小化到托盘而不是关闭应用
minimizeToTrayOnClose: boolean;
// 启用 Claude 插件联动(写入 ~/.claude/config.json 的 primaryApiKey
enableClaudePluginIntegration?: boolean;
// 覆盖 Claude Code 配置目录(可选)
claudeConfigDir?: string;
// 覆盖 Codex 配置目录(可选)
codexConfigDir?: string;
// 首选语言(可选,默认中文)
language?: "en" | "zh";
// Claude 自定义端点列表
customEndpointsClaude?: Record<string, CustomEndpoint>;
// Codex 自定义端点列表
customEndpointsCodex?: Record<string, CustomEndpoint>;
// 安全设置(兼容未来扩展)
security?: {
auth?: {
selectedType?: string;
};
};
}
// MCP 服务器连接参数(宽松:允许扩展字段)
export interface McpServerSpec {
// 可选:社区常见 .mcp.json 中 stdio 配置可不写 type
type?: "stdio" | "http" | "sse";
// stdio 字段
command?: string;
args?: string[];
env?: Record<string, string>;
cwd?: string;
// http 和 sse 字段
url?: string;
headers?: Record<string, string>;
// 通用字段
[key: string]: any;
}
// v3.7.0: MCP 服务器应用启用状态
export interface McpApps {
claude: boolean;
codex: boolean;
gemini: boolean;
}
// MCP 服务器条目(v3.7.0 统一结构)
export interface McpServer {
id: string;
name: string;
server: McpServerSpec;
apps: McpApps; // v3.7.0: 标记应用到哪些客户端
description?: string;
tags?: string[];
homepage?: string;
docs?: string;
// 兼容旧字段(v3.6.x 及以前)
enabled?: boolean; // 已废弃,v3.7.0 使用 apps 字段
source?: string;
[key: string]: any;
}
// MCP 服务器映射(id -> McpServer
export type McpServersMap = Record<string, McpServer>;
// MCP 配置状态
export interface McpStatus {
userConfigPath: string;
userConfigExists: boolean;
serverCount: number;
}
// 新:来自 config.json 的 MCP 列表响应
export interface McpConfigResponse {
configPath: string;
servers: Record<string, McpServer>;
}