2025-08-27 11:00:53 +08:00
|
|
|
|
import { invoke } from "@tauri-apps/api/core";
|
2025-09-06 16:21:21 +08:00
|
|
|
|
import { listen, UnlistenFn } from "@tauri-apps/api/event";
|
2025-10-09 11:04:36 +08:00
|
|
|
|
import {
|
|
|
|
|
|
Provider,
|
|
|
|
|
|
Settings,
|
|
|
|
|
|
CustomEndpoint,
|
|
|
|
|
|
McpStatus,
|
|
|
|
|
|
McpServer,
|
2025-10-09 21:08:42 +08:00
|
|
|
|
McpConfigResponse,
|
2025-10-09 11:04:36 +08:00
|
|
|
|
} from "../types";
|
2025-08-23 20:38:57 +08:00
|
|
|
|
|
2025-08-30 21:54:11 +08:00
|
|
|
|
// 应用类型
|
|
|
|
|
|
export type AppType = "claude" | "codex";
|
|
|
|
|
|
|
2025-08-23 20:38:57 +08:00
|
|
|
|
// 定义配置状态类型
|
|
|
|
|
|
interface ConfigStatus {
|
|
|
|
|
|
exists: boolean;
|
|
|
|
|
|
path: string;
|
|
|
|
|
|
error?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 定义导入结果类型
|
|
|
|
|
|
interface ImportResult {
|
|
|
|
|
|
success: boolean;
|
|
|
|
|
|
message?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
export interface EndpointLatencyResult {
|
|
|
|
|
|
url: string;
|
|
|
|
|
|
latency: number | null;
|
|
|
|
|
|
status?: number;
|
|
|
|
|
|
error?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-25 10:30:45 +08:00
|
|
|
|
// Tauri API 封装,提供统一的全局 API 接口
|
2025-08-23 20:38:57 +08:00
|
|
|
|
export const tauriAPI = {
|
|
|
|
|
|
// 获取所有供应商
|
2025-08-30 21:54:11 +08:00
|
|
|
|
getProviders: async (app?: AppType): Promise<Record<string, Provider>> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 16:43:33 +08:00
|
|
|
|
return await invoke("get_providers", { app_type: app, app });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("获取供应商列表失败:", error);
|
2025-08-23 20:38:57 +08:00
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前供应商ID
|
2025-08-30 21:54:11 +08:00
|
|
|
|
getCurrentProvider: async (app?: AppType): Promise<string> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 16:43:33 +08:00
|
|
|
|
return await invoke("get_current_provider", { app_type: app, app });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("获取当前供应商失败:", error);
|
|
|
|
|
|
return "";
|
2025-08-23 20:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 添加供应商
|
2025-08-30 21:54:11 +08:00
|
|
|
|
addProvider: async (provider: Provider, app?: AppType): Promise<boolean> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 16:43:33 +08:00
|
|
|
|
return await invoke("add_provider", { provider, app_type: app, app });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("添加供应商失败:", error);
|
2025-08-23 20:38:57 +08:00
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 更新供应商
|
2025-08-30 21:54:11 +08:00
|
|
|
|
updateProvider: async (
|
|
|
|
|
|
provider: Provider,
|
2025-09-06 23:13:01 +08:00
|
|
|
|
app?: AppType,
|
2025-08-30 21:54:11 +08:00
|
|
|
|
): Promise<boolean> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 16:43:33 +08:00
|
|
|
|
return await invoke("update_provider", { provider, app_type: app, app });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("更新供应商失败:", error);
|
2025-08-23 20:38:57 +08:00
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 删除供应商
|
2025-08-30 21:54:11 +08:00
|
|
|
|
deleteProvider: async (id: string, app?: AppType): Promise<boolean> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 16:43:33 +08:00
|
|
|
|
return await invoke("delete_provider", { id, app_type: app, app });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("删除供应商失败:", error);
|
2025-08-23 20:38:57 +08:00
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 切换供应商
|
2025-08-30 21:54:11 +08:00
|
|
|
|
switchProvider: async (
|
|
|
|
|
|
providerId: string,
|
2025-09-06 23:13:01 +08:00
|
|
|
|
app?: AppType,
|
2025-08-30 21:54:11 +08:00
|
|
|
|
): Promise<boolean> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 18:14:31 +08:00
|
|
|
|
return await invoke("switch_provider", {
|
|
|
|
|
|
id: providerId,
|
|
|
|
|
|
app_type: app,
|
|
|
|
|
|
app,
|
|
|
|
|
|
});
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-10-08 21:10:36 +08:00
|
|
|
|
// 让调用方拿到后端的详细错误信息
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("切换供应商失败:", error);
|
2025-10-08 21:10:36 +08:00
|
|
|
|
throw error;
|
2025-08-23 20:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 导入当前配置为默认供应商
|
2025-08-30 21:54:11 +08:00
|
|
|
|
importCurrentConfigAsDefault: async (
|
2025-09-06 23:13:01 +08:00
|
|
|
|
app?: AppType,
|
2025-08-30 21:54:11 +08:00
|
|
|
|
): Promise<ImportResult> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-08-31 18:14:31 +08:00
|
|
|
|
const success = await invoke<boolean>("import_default_config", {
|
|
|
|
|
|
app_type: app,
|
|
|
|
|
|
app,
|
|
|
|
|
|
});
|
2025-08-23 20:38:57 +08:00
|
|
|
|
return {
|
|
|
|
|
|
success,
|
2025-08-27 11:00:53 +08:00
|
|
|
|
message: success ? "成功导入默认配置" : "导入失败",
|
2025-08-23 20:38:57 +08:00
|
|
|
|
};
|
|
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("导入默认配置失败:", error);
|
2025-08-23 20:38:57 +08:00
|
|
|
|
return {
|
|
|
|
|
|
success: false,
|
2025-08-27 11:00:53 +08:00
|
|
|
|
message: String(error),
|
2025-08-23 20:38:57 +08:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 获取 Claude Code 配置文件路径
|
|
|
|
|
|
getClaudeCodeConfigPath: async (): Promise<string> => {
|
|
|
|
|
|
try {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
return await invoke("get_claude_code_config_path");
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("获取配置路径失败:", error);
|
|
|
|
|
|
return "";
|
2025-08-23 20:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-09-20 21:20:07 +08:00
|
|
|
|
// 获取当前生效的配置目录
|
|
|
|
|
|
getConfigDir: async (app?: AppType): Promise<string> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke("get_config_dir", { app_type: app, app });
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取配置目录失败:", error);
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
// 打开配置目录(按应用类型)
|
|
|
|
|
|
openConfigFolder: async (app?: AppType): Promise<void> => {
|
2025-08-30 21:54:11 +08:00
|
|
|
|
try {
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
await invoke("open_config_folder", { app_type: app, app });
|
2025-08-30 21:54:11 +08:00
|
|
|
|
} catch (error) {
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
console.error("打开配置目录失败:", error);
|
2025-08-30 21:54:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
// 选择配置目录(可选默认路径)
|
2025-10-08 21:22:56 +08:00
|
|
|
|
selectConfigDirectory: async (
|
|
|
|
|
|
defaultPath?: string,
|
|
|
|
|
|
): Promise<string | null> => {
|
2025-08-23 20:38:57 +08:00
|
|
|
|
try {
|
2025-10-08 21:10:36 +08:00
|
|
|
|
// 后端参数为 snake_case:default_path
|
|
|
|
|
|
return await invoke("pick_directory", { default_path: defaultPath });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
console.error("选择配置目录失败:", error);
|
|
|
|
|
|
return null;
|
2025-08-23 20:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 打开外部链接
|
|
|
|
|
|
openExternal: async (url: string): Promise<void> => {
|
|
|
|
|
|
try {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
await invoke("open_external", { url });
|
2025-08-23 20:38:57 +08:00
|
|
|
|
} catch (error) {
|
2025-08-27 11:00:53 +08:00
|
|
|
|
console.error("打开外部链接失败:", error);
|
2025-08-23 20:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-09-06 16:21:21 +08:00
|
|
|
|
// 更新托盘菜单
|
|
|
|
|
|
updateTrayMenu: async (): Promise<boolean> => {
|
|
|
|
|
|
try {
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
return await invoke<boolean>("update_tray_menu");
|
2025-09-06 16:21:21 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("更新托盘菜单失败:", error);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
// 获取应用设置
|
2025-09-07 11:36:09 +08:00
|
|
|
|
getSettings: async (): Promise<Settings> => {
|
2025-09-07 10:48:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
return await invoke("get_settings");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取设置失败:", error);
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
throw error;
|
2025-09-07 10:48:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 保存设置
|
2025-09-07 11:36:09 +08:00
|
|
|
|
saveSettings: async (settings: Settings): Promise<boolean> => {
|
2025-09-07 10:48:27 +08:00
|
|
|
|
try {
|
|
|
|
|
|
return await invoke("save_settings", { settings });
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("保存设置失败:", error);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 检查更新
|
|
|
|
|
|
checkForUpdates: async (): Promise<void> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await invoke("check_for_updates");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("检查更新失败:", error);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-09-07 11:36:09 +08:00
|
|
|
|
|
2025-09-24 11:25:33 +08:00
|
|
|
|
// 判断是否为便携模式
|
|
|
|
|
|
isPortable: async (): Promise<boolean> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("is_portable_mode");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("检测便携模式失败:", error);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-09-07 11:36:09 +08:00
|
|
|
|
// 获取应用配置文件路径
|
|
|
|
|
|
getAppConfigPath: async (): Promise<string> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke("get_app_config_path");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取应用配置路径失败:", error);
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 打开应用配置文件夹
|
|
|
|
|
|
openAppConfigFolder: async (): Promise<void> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await invoke("open_app_config_folder");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("打开应用配置文件夹失败:", error);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-09-19 08:30:29 +08:00
|
|
|
|
|
2025-10-01 21:23:55 +08:00
|
|
|
|
// Claude 插件:获取 ~/.claude/config.json 状态
|
|
|
|
|
|
getClaudePluginStatus: async (): Promise<ConfigStatus> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<ConfigStatus>("get_claude_plugin_status");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取 Claude 插件状态失败:", error);
|
|
|
|
|
|
return { exists: false, path: "", error: String(error) };
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Claude 插件:读取配置内容
|
|
|
|
|
|
readClaudePluginConfig: async (): Promise<string | null> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<string | null>("read_claude_plugin_config");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
throw new Error(`读取 Claude 插件配置失败: ${String(error)}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Claude 插件:应用或移除固定配置
|
|
|
|
|
|
applyClaudePluginConfig: async (options: {
|
|
|
|
|
|
official: boolean;
|
|
|
|
|
|
}): Promise<boolean> => {
|
|
|
|
|
|
const { official } = options;
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("apply_claude_plugin_config", { official });
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
throw new Error(`写入 Claude 插件配置失败: ${String(error)}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Claude 插件:检测是否已应用目标配置
|
|
|
|
|
|
isClaudePluginApplied: async (): Promise<boolean> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("is_claude_plugin_applied");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
throw new Error(`检测 Claude 插件配置失败: ${String(error)}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-10-05 23:33:07 +08:00
|
|
|
|
|
2025-10-08 23:22:19 +08:00
|
|
|
|
// Claude MCP:获取状态(用户级 ~/.claude.json)
|
2025-10-08 22:35:02 +08:00
|
|
|
|
getClaudeMcpStatus: async (): Promise<McpStatus> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<McpStatus>("get_claude_mcp_status");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取 MCP 状态失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-10-08 23:22:19 +08:00
|
|
|
|
// Claude MCP:读取 ~/.claude.json 文本
|
2025-10-08 22:35:02 +08:00
|
|
|
|
readClaudeMcpConfig: async (): Promise<string | null> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<string | null>("read_claude_mcp_config");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("读取 mcp.json 失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Claude MCP:新增/更新服务器定义
|
|
|
|
|
|
upsertClaudeMcpServer: async (
|
|
|
|
|
|
id: string,
|
|
|
|
|
|
spec: McpServer | Record<string, any>,
|
|
|
|
|
|
): Promise<boolean> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("upsert_claude_mcp_server", { id, spec });
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("保存 MCP 服务器失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Claude MCP:删除服务器定义
|
|
|
|
|
|
deleteClaudeMcpServer: async (id: string): Promise<boolean> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("delete_claude_mcp_server", { id });
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("删除 MCP 服务器失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Claude MCP:校验命令是否在 PATH 中
|
|
|
|
|
|
validateMcpCommand: async (cmd: string): Promise<boolean> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("validate_mcp_command", { cmd });
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("校验 MCP 命令失败:", error);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-10-09 22:02:56 +08:00
|
|
|
|
// 新:config.json 为 SSOT 的 MCP API(按客户端)
|
|
|
|
|
|
getMcpConfig: async (app: AppType = "claude"): Promise<McpConfigResponse> => {
|
2025-10-09 21:08:42 +08:00
|
|
|
|
try {
|
2025-10-09 22:02:56 +08:00
|
|
|
|
return await invoke<McpConfigResponse>("get_mcp_config", { app });
|
2025-10-09 21:08:42 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取 MCP 配置失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
upsertMcpServerInConfig: async (
|
2025-10-09 22:02:56 +08:00
|
|
|
|
app: AppType = "claude",
|
2025-10-09 21:08:42 +08:00
|
|
|
|
id: string,
|
|
|
|
|
|
spec: McpServer | Record<string, any>,
|
|
|
|
|
|
): Promise<boolean> => {
|
|
|
|
|
|
try {
|
2025-10-09 22:02:56 +08:00
|
|
|
|
return await invoke<boolean>("upsert_mcp_server_in_config", { app, id, spec });
|
2025-10-09 21:08:42 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("写入 MCP(config.json)失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-10-09 22:02:56 +08:00
|
|
|
|
deleteMcpServerInConfig: async (
|
|
|
|
|
|
app: AppType = "claude",
|
|
|
|
|
|
id: string,
|
|
|
|
|
|
): Promise<boolean> => {
|
2025-10-09 21:08:42 +08:00
|
|
|
|
try {
|
2025-10-09 22:02:56 +08:00
|
|
|
|
return await invoke<boolean>("delete_mcp_server_in_config", { app, id });
|
2025-10-09 21:08:42 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("删除 MCP(config.json)失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-10-09 22:02:56 +08:00
|
|
|
|
setMcpEnabled: async (
|
|
|
|
|
|
app: AppType = "claude",
|
|
|
|
|
|
id: string,
|
|
|
|
|
|
enabled: boolean,
|
|
|
|
|
|
): Promise<boolean> => {
|
2025-10-09 21:08:42 +08:00
|
|
|
|
try {
|
2025-10-09 22:02:56 +08:00
|
|
|
|
return await invoke<boolean>("set_mcp_enabled", { app, id, enabled });
|
2025-10-09 21:08:42 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("设置 MCP 启用状态失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
syncEnabledMcpToClaude: async (): Promise<boolean> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<boolean>("sync_enabled_mcp_to_claude");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("同步启用 MCP 到 .claude.json 失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
importMcpFromClaude: async (): Promise<number> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<number>("import_mcp_from_claude");
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("从 ~/.claude.json 导入 MCP 失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
// ours: 第三方/自定义供应商——测速与端点管理
|
|
|
|
|
|
// 第三方/自定义供应商:批量测试端点延迟
|
|
|
|
|
|
testApiEndpoints: async (
|
|
|
|
|
|
urls: string[],
|
|
|
|
|
|
options?: { timeoutSecs?: number },
|
|
|
|
|
|
): Promise<EndpointLatencyResult[]> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<EndpointLatencyResult[]>("test_api_endpoints", {
|
|
|
|
|
|
urls,
|
|
|
|
|
|
timeout_secs: options?.timeoutSecs,
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("测速调用失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 获取自定义端点列表
|
|
|
|
|
|
getCustomEndpoints: async (
|
|
|
|
|
|
appType: AppType,
|
|
|
|
|
|
providerId: string,
|
|
|
|
|
|
): Promise<CustomEndpoint[]> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await invoke<CustomEndpoint[]>("get_custom_endpoints", {
|
|
|
|
|
|
// 兼容不同后端参数命名
|
|
|
|
|
|
app_type: appType,
|
|
|
|
|
|
app: appType,
|
|
|
|
|
|
appType: appType,
|
|
|
|
|
|
provider_id: providerId,
|
|
|
|
|
|
providerId: providerId,
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取自定义端点列表失败:", error);
|
|
|
|
|
|
return [];
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 添加自定义端点
|
|
|
|
|
|
addCustomEndpoint: async (
|
|
|
|
|
|
appType: AppType,
|
|
|
|
|
|
providerId: string,
|
|
|
|
|
|
url: string,
|
|
|
|
|
|
): Promise<void> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await invoke("add_custom_endpoint", {
|
|
|
|
|
|
app_type: appType,
|
|
|
|
|
|
app: appType,
|
|
|
|
|
|
appType: appType,
|
|
|
|
|
|
provider_id: providerId,
|
|
|
|
|
|
providerId: providerId,
|
|
|
|
|
|
url,
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("添加自定义端点失败:", error);
|
|
|
|
|
|
// 尽量抛出可读信息
|
|
|
|
|
|
if (error instanceof Error) {
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error(String(error));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 删除自定义端点
|
|
|
|
|
|
removeCustomEndpoint: async (
|
|
|
|
|
|
appType: AppType,
|
|
|
|
|
|
providerId: string,
|
|
|
|
|
|
url: string,
|
|
|
|
|
|
): Promise<void> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await invoke("remove_custom_endpoint", {
|
|
|
|
|
|
app_type: appType,
|
|
|
|
|
|
app: appType,
|
|
|
|
|
|
appType: appType,
|
|
|
|
|
|
provider_id: providerId,
|
|
|
|
|
|
providerId: providerId,
|
|
|
|
|
|
url,
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("删除自定义端点失败:", error);
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 更新端点最后使用时间
|
|
|
|
|
|
updateEndpointLastUsed: async (
|
|
|
|
|
|
appType: AppType,
|
|
|
|
|
|
providerId: string,
|
|
|
|
|
|
url: string,
|
|
|
|
|
|
): Promise<void> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await invoke("update_endpoint_last_used", {
|
|
|
|
|
|
app_type: appType,
|
|
|
|
|
|
app: appType,
|
|
|
|
|
|
appType: appType,
|
|
|
|
|
|
provider_id: providerId,
|
|
|
|
|
|
providerId: providerId,
|
|
|
|
|
|
url,
|
|
|
|
|
|
});
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("更新端点最后使用时间失败:", error);
|
|
|
|
|
|
// 不抛出错误,因为这不是关键操作
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// theirs: 导入导出与文件对话框
|
2025-10-05 23:33:07 +08:00
|
|
|
|
// 导出配置到文件
|
2025-10-08 21:22:56 +08:00
|
|
|
|
exportConfigToFile: async (
|
|
|
|
|
|
filePath: string,
|
|
|
|
|
|
): Promise<{
|
2025-10-05 23:33:07 +08:00
|
|
|
|
success: boolean;
|
|
|
|
|
|
message: string;
|
|
|
|
|
|
filePath: string;
|
|
|
|
|
|
}> => {
|
|
|
|
|
|
try {
|
2025-10-08 21:10:36 +08:00
|
|
|
|
// 后端参数为 snake_case:file_path
|
|
|
|
|
|
return await invoke("export_config_to_file", { file_path: filePath });
|
2025-10-05 23:33:07 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
throw new Error(`导出配置失败: ${String(error)}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 从文件导入配置
|
2025-10-08 21:22:56 +08:00
|
|
|
|
importConfigFromFile: async (
|
|
|
|
|
|
filePath: string,
|
|
|
|
|
|
): Promise<{
|
2025-10-05 23:33:07 +08:00
|
|
|
|
success: boolean;
|
|
|
|
|
|
message: string;
|
|
|
|
|
|
backupId?: string;
|
|
|
|
|
|
}> => {
|
|
|
|
|
|
try {
|
2025-10-08 21:10:36 +08:00
|
|
|
|
// 后端参数为 snake_case:file_path
|
|
|
|
|
|
return await invoke("import_config_from_file", { file_path: filePath });
|
2025-10-05 23:33:07 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
throw new Error(`导入配置失败: ${String(error)}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 保存文件对话框
|
|
|
|
|
|
saveFileDialog: async (defaultName: string): Promise<string | null> => {
|
|
|
|
|
|
try {
|
2025-10-08 21:10:36 +08:00
|
|
|
|
// 后端参数为 snake_case:default_name
|
2025-10-08 21:22:56 +08:00
|
|
|
|
const result = await invoke<string | null>("save_file_dialog", {
|
|
|
|
|
|
default_name: defaultName,
|
|
|
|
|
|
});
|
2025-10-05 23:33:07 +08:00
|
|
|
|
return result;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("打开保存对话框失败:", error);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 打开文件对话框
|
|
|
|
|
|
openFileDialog: async (): Promise<string | null> => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const result = await invoke<string | null>("open_file_dialog");
|
|
|
|
|
|
return result;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("打开文件对话框失败:", error);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
|
|
|
|
|
|
// 监听供应商切换事件
|
|
|
|
|
|
onProviderSwitched: async (
|
|
|
|
|
|
callback: (data: { appType: string; providerId: string }) => void,
|
|
|
|
|
|
): Promise<UnlistenFn> => {
|
|
|
|
|
|
const unlisten = await listen("provider-switched", (event) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 事件 payload 形如 { appType: string, providerId: string }
|
|
|
|
|
|
callback(event.payload as any);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error("处理 provider-switched 事件失败: ", e);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
return unlisten;
|
|
|
|
|
|
},
|
2025-08-23 20:38:57 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 创建全局 API 对象,兼容现有代码
|
2025-08-27 11:00:53 +08:00
|
|
|
|
if (typeof window !== "undefined") {
|
2025-08-25 10:30:45 +08:00
|
|
|
|
// 绑定到 window.api,避免 Electron 命名造成误解
|
2025-08-24 23:04:55 +08:00
|
|
|
|
// API 内部已做 try/catch,非 Tauri 环境下也会安全返回默认值
|
2025-08-25 10:30:45 +08:00
|
|
|
|
(window as any).api = tauriAPI;
|
2025-08-23 20:38:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-23 23:11:39 +08:00
|
|
|
|
export default tauriAPI;
|