mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-05-09 04:31:24 +08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce9e5e25d3 | |||
| 01eee0ae22 | |||
| 37239f292c | |||
| d954df0c76 |
@@ -56,8 +56,7 @@ jobs:
|
||||
libssl-dev \
|
||||
rpm \
|
||||
flatpak \
|
||||
flatpak-builder \
|
||||
elfutils
|
||||
flatpak-builder
|
||||
# GTK/GLib stack for gdk-3.0, glib-2.0, gio-2.0
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libgtk-3-dev \
|
||||
@@ -284,6 +283,19 @@ jobs:
|
||||
else
|
||||
echo "No .rpm found (optional)"
|
||||
fi
|
||||
# 额外上传 .flatpak(跨发行版;不参与 Updater)
|
||||
if [ -n "$DEB" ]; then
|
||||
echo "Building Flatpak bundle from .deb..."
|
||||
cp "$DEB" flatpak/cc-switch.deb
|
||||
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install -y --user flathub org.gnome.Platform//46 org.gnome.Sdk//46
|
||||
flatpak-builder --force-clean --user --disable-cache --repo flatpak-repo flatpak-build flatpak/com.ccswitch.desktop.yml
|
||||
NEW_FLATPAK="CC-Switch-${VERSION}-Linux.flatpak"
|
||||
flatpak build-bundle --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo flatpak-repo "release-assets/$NEW_FLATPAK" com.ccswitch.desktop
|
||||
echo "Flatpak bundle created: $NEW_FLATPAK"
|
||||
else
|
||||
echo "Skip Flatpak build: no .deb found"
|
||||
fi
|
||||
|
||||
- name: List prepared assets
|
||||
shell: bash
|
||||
@@ -312,7 +324,7 @@ jobs:
|
||||
|
||||
- **macOS**: `CC-Switch-${{ github.ref_name }}-macOS.zip`(解压即用)或 `CC-Switch-${{ github.ref_name }}-macOS.tar.gz`(Homebrew)
|
||||
- **Windows**: `CC-Switch-${{ github.ref_name }}-Windows.msi`(安装版)或 `CC-Switch-${{ github.ref_name }}-Windows-Portable.zip`(绿色版)
|
||||
- **Linux**: `CC-Switch-${{ github.ref_name }}-Linux.AppImage`(AppImage)或 `CC-Switch-${{ github.ref_name }}-Linux.deb`(Debian/Ubuntu)或 `CC-Switch-${{ github.ref_name }}-Linux.rpm`(Fedora/RHEL/openSUSE)
|
||||
- **Linux**: `CC-Switch-${{ github.ref_name }}-Linux.AppImage`(AppImage)或 `CC-Switch-${{ github.ref_name }}-Linux.deb`(Debian/Ubuntu)或 `CC-Switch-${{ github.ref_name }}-Linux.rpm`(Fedora/RHEL/openSUSE)或 `CC-Switch-${{ github.ref_name }}-Linux.flatpak`(Flatpak)
|
||||
|
||||
---
|
||||
提示:macOS 如遇"已损坏"提示,可在终端执行:`xattr -cr "/Applications/CC Switch.app"`
|
||||
|
||||
@@ -9,30 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [3.9.1] - 2026-01-09
|
||||
|
||||
### Bug Fix Release
|
||||
|
||||
This release focuses on stability improvements and crash prevention.
|
||||
|
||||
### Added
|
||||
|
||||
- **Crash Logging** - Panic hook captures crash info to `~/.cc-switch/crash.log` with full stack traces (#562)
|
||||
- **Release Logging** - Enable logging for release builds with automatic rotation (keeps 2 most recent files)
|
||||
- **AIGoCode Icon** - Added colored icon for AIGoCode provider preset
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Proxy Panic Prevention** - Graceful degradation when HTTP client initialization fails due to invalid proxy settings; falls back to no_proxy mode (#560)
|
||||
- **UTF-8 Safety** - Fix potential panic when masking API keys or truncating logs containing multi-byte characters (Chinese, emoji, etc.) (#560)
|
||||
- **Default Proxy Port** - Change default port from 5000 to 15721 to avoid conflict with macOS AirPlay Receiver (#560)
|
||||
- **Windows Title** - Display "CC Switch" instead of default "Tauri app" in window title
|
||||
- **Windows/Linux Spacing** - Remove extra 28px blank space below native titlebar introduced in v3.9.0
|
||||
- **Flatpak Tray Icon** - Bundle libayatana-appindicator for tray icon support on Flatpak (#556)
|
||||
- **Provider Preset** - Correct casing from "AiGoCode" to "AIGoCode" to match official branding
|
||||
|
||||
---
|
||||
|
||||
## [3.9.0] - 2026-01-07
|
||||
|
||||
### Stable Release
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# All-in-One Assistant for Claude Code, Codex & Gemini CLI
|
||||
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://tauri.app/)
|
||||
[](https://github.com/farion1231/cc-switch/releases/latest)
|
||||
@@ -52,7 +52,7 @@ This project is sponsored by Z.ai, supporting us with their GLM CODING PLAN.GLM
|
||||
|
||||
## Features
|
||||
|
||||
### Current Version: v3.9.1 | [Full Changelog](CHANGELOG.md) | [Release Notes](docs/release-note-v3.9.0-en.md)
|
||||
### Current Version: v3.9.0 | [Full Changelog](CHANGELOG.md) | [Release Notes](docs/release-note-v3.9.0-en.md)
|
||||
|
||||
**v3.8.0 Major Update (2025-11-28)**
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
# Claude Code / Codex / Gemini CLI オールインワン・アシスタント
|
||||
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://tauri.app/)
|
||||
[](https://github.com/farion1231/cc-switch/releases/latest)
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
## 特長
|
||||
|
||||
### 現在のバージョン:v3.9.1 | [完全な更新履歴](CHANGELOG.md) | [リリースノート](docs/release-note-v3.9.0-ja.md)
|
||||
### 現在のバージョン:v3.9.0 | [完全な更新履歴](CHANGELOG.md) | [リリースノート](docs/release-note-v3.9.0-ja.md)
|
||||
|
||||
**v3.8.0 メジャーアップデート (2025-11-28)**
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
# Claude Code / Codex / Gemini CLI 全方位辅助工具
|
||||
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://github.com/farion1231/cc-switch/releases)
|
||||
[](https://tauri.app/)
|
||||
[](https://github.com/farion1231/cc-switch/releases/latest)
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 当前版本:v3.9.1 | [完整更新日志](CHANGELOG.md) | [发布说明](docs/release-note-v3.9.0-zh.md)
|
||||
### 当前版本:v3.9.0 | [完整更新日志](CHANGELOG.md) | [发布说明](docs/release-note-v3.9.0-zh.md)
|
||||
|
||||
**v3.8.0 重大更新(2025-11-28)**
|
||||
|
||||
|
||||
@@ -22,15 +22,6 @@ finish-args:
|
||||
- --filesystem=home
|
||||
|
||||
modules:
|
||||
# Required for libdbusmenu build (intltool was removed from GNOME SDK since 2019)
|
||||
- name: intltool
|
||||
cleanup:
|
||||
- "*"
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz
|
||||
sha256: 67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd
|
||||
|
||||
# Required for tray icon support
|
||||
- name: libayatana-ido
|
||||
buildsystem: cmake-ninja
|
||||
@@ -49,7 +40,7 @@ modules:
|
||||
- --with-gtk=3
|
||||
- --disable-dumper
|
||||
- --disable-static
|
||||
- --disable-nls
|
||||
- --enable-tests=no
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://launchpad.net/libdbusmenu/16.04/16.04.0/+download/libdbusmenu-16.04.0.tar.gz
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cc-switch",
|
||||
"version": "3.9.1",
|
||||
"version": "3.9.0",
|
||||
"description": "All-in-One Assistant for Claude Code, Codex & Gemini CLI",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cc-switch"
|
||||
version = "3.9.1"
|
||||
version = "3.9.0"
|
||||
description = "All-in-One Assistant for Claude Code, Codex & Gemini CLI"
|
||||
authors = ["Jason Young"]
|
||||
license = "MIT"
|
||||
@@ -77,8 +77,7 @@ objc2-app-kit = { version = "0.2", features = ["NSColor"] }
|
||||
codegen-units = 1
|
||||
lto = "thin"
|
||||
opt-level = "s"
|
||||
# 使用 unwind 以便 panic hook 能捕获 backtrace(abort 会直接终止无法捕获)
|
||||
panic = "unwind"
|
||||
panic = "abort"
|
||||
strip = "symbols"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
+9
-67
@@ -13,7 +13,6 @@ mod gemini_config;
|
||||
mod gemini_mcp;
|
||||
mod init_status;
|
||||
mod mcp;
|
||||
mod panic_hook;
|
||||
mod prompt;
|
||||
mod prompt_files;
|
||||
mod provider;
|
||||
@@ -55,37 +54,6 @@ use tauri::tray::{TrayIconBuilder, TrayIconEvent};
|
||||
use tauri::RunEvent;
|
||||
use tauri::{Emitter, Manager};
|
||||
|
||||
fn redact_url_for_log(url_str: &str) -> String {
|
||||
match url::Url::parse(url_str) {
|
||||
Ok(url) => {
|
||||
let mut output = format!("{}://", url.scheme());
|
||||
if let Some(host) = url.host_str() {
|
||||
output.push_str(host);
|
||||
}
|
||||
output.push_str(url.path());
|
||||
|
||||
let mut keys: Vec<String> = url.query_pairs().map(|(k, _)| k.to_string()).collect();
|
||||
keys.sort();
|
||||
keys.dedup();
|
||||
|
||||
if !keys.is_empty() {
|
||||
output.push_str("?[keys:");
|
||||
output.push_str(&keys.join(","));
|
||||
output.push(']');
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
Err(_) => {
|
||||
let base = url_str.split('#').next().unwrap_or(url_str);
|
||||
match base.split_once('?') {
|
||||
Some((prefix, _)) => format!("{prefix}?[redacted]"),
|
||||
None => base.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 统一处理 ccswitch:// 深链接 URL
|
||||
///
|
||||
/// - 解析 URL
|
||||
@@ -101,9 +69,7 @@ fn handle_deeplink_url(
|
||||
return false;
|
||||
}
|
||||
|
||||
let redacted_url = redact_url_for_log(url_str);
|
||||
log::info!("✓ Deep link URL detected from {source}: {redacted_url}");
|
||||
log::debug!("Deep link URL (raw) from {source}: {url_str}");
|
||||
log::info!("✓ Deep link URL detected from {source}: {url_str}");
|
||||
|
||||
match crate::deeplink::parse_deeplink_url(url_str) {
|
||||
Ok(request) => {
|
||||
@@ -184,18 +150,15 @@ fn macos_tray_icon() -> Option<Image<'static>> {
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
// 设置 panic hook,在应用崩溃时记录日志到 <app_config_dir>/crash.log(默认 ~/.cc-switch/crash.log)
|
||||
panic_hook::setup_panic_hook();
|
||||
|
||||
let mut builder = tauri::Builder::default();
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))]
|
||||
{
|
||||
builder = builder.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
||||
log::info!("=== Single Instance Callback Triggered ===");
|
||||
log::debug!("Args count: {}", args.len());
|
||||
log::info!("Args count: {}", args.len());
|
||||
for (i, arg) in args.iter().enumerate() {
|
||||
log::debug!(" arg[{i}]: {}", redact_url_for_log(arg));
|
||||
log::info!(" arg[{i}]: {arg}");
|
||||
}
|
||||
|
||||
// Check for deep link URL in args (mainly for Windows/Linux command line)
|
||||
@@ -249,10 +212,6 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
.setup(|app| {
|
||||
// 预先刷新 Store 覆盖配置,确保后续路径读取正确(日志/数据库等)
|
||||
app_store::refresh_app_config_dir_override(app.handle());
|
||||
panic_hook::init_app_config_dir(crate::config::get_app_config_dir());
|
||||
|
||||
// 注册 Updater 插件(桌面端)
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
@@ -264,35 +223,18 @@ pub fn run() {
|
||||
log::warn!("初始化 Updater 插件失败,已跳过:{e}");
|
||||
}
|
||||
}
|
||||
// 初始化日志(Debug 和 Release 模式都启用 Info 级别)
|
||||
// 日志同时输出到控制台和文件(<app_config_dir>/logs/;若设置了覆盖则使用覆盖目录)
|
||||
{
|
||||
use tauri_plugin_log::{RotationStrategy, Target, TargetKind, TimezoneStrategy};
|
||||
|
||||
let log_dir = panic_hook::get_log_dir();
|
||||
|
||||
// 初始化日志
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
.targets([
|
||||
// 输出到控制台
|
||||
Target::new(TargetKind::Stdout),
|
||||
// 输出到日志文件
|
||||
Target::new(TargetKind::Folder {
|
||||
path: log_dir,
|
||||
file_name: Some("cc-switch".into()),
|
||||
}),
|
||||
])
|
||||
.rotation_strategy(RotationStrategy::KeepAll)
|
||||
.max_file_size(5_000_000) // 5MB 单文件上限
|
||||
.timezone_strategy(TimezoneStrategy::UseLocal)
|
||||
.build(),
|
||||
)?;
|
||||
|
||||
// 清理旧日志文件,只保留最近 2 个
|
||||
panic_hook::cleanup_old_logs();
|
||||
}
|
||||
|
||||
// 预先刷新 Store 覆盖配置,确保 AppState 初始化时可读取到最新路径
|
||||
app_store::refresh_app_config_dir_override(app.handle());
|
||||
|
||||
// 初始化数据库
|
||||
let app_config_dir = crate::config::get_app_config_dir();
|
||||
let db_path = app_config_dir.join("cc-switch.db");
|
||||
@@ -587,7 +529,7 @@ pub fn run() {
|
||||
|
||||
for (i, url) in urls.iter().enumerate() {
|
||||
let url_str = url.as_str();
|
||||
log::debug!(" URL[{i}]: {}", redact_url_for_log(url_str));
|
||||
log::info!(" URL[{i}]: {url_str}");
|
||||
|
||||
if handle_deeplink_url(&app_handle, url_str, true, "on_open_url") {
|
||||
break; // Process only first ccswitch:// URL
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
//! Panic Hook 模块
|
||||
//!
|
||||
//! 在应用崩溃时捕获 panic 信息并记录到 `<app_config_dir>/crash.log` 文件中(默认 `~/.cc-switch/crash.log`)。
|
||||
//! 便于用户和开发者诊断闪退问题。
|
||||
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::panic;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
/// 应用版本号(从 Cargo.toml 读取)
|
||||
const APP_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// 日志文件保留数量
|
||||
const LOG_FILES_TO_KEEP: usize = 2;
|
||||
|
||||
static APP_CONFIG_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
||||
pub fn init_app_config_dir(dir: PathBuf) {
|
||||
let _ = APP_CONFIG_DIR.set(dir);
|
||||
}
|
||||
|
||||
/// 获取默认应用配置目录(不会 panic)
|
||||
fn default_app_config_dir() -> PathBuf {
|
||||
dirs::home_dir()
|
||||
.unwrap_or_else(|| PathBuf::from("."))
|
||||
.join(".cc-switch")
|
||||
}
|
||||
|
||||
/// 获取应用配置目录(优先使用初始化时写入的值;不会 panic)
|
||||
fn get_app_config_dir() -> PathBuf {
|
||||
APP_CONFIG_DIR
|
||||
.get()
|
||||
.cloned()
|
||||
.unwrap_or_else(default_app_config_dir)
|
||||
}
|
||||
|
||||
/// 获取崩溃日志文件路径
|
||||
fn get_crash_log_path() -> PathBuf {
|
||||
get_app_config_dir().join("crash.log")
|
||||
}
|
||||
|
||||
/// 获取日志目录路径
|
||||
pub fn get_log_dir() -> PathBuf {
|
||||
get_app_config_dir().join("logs")
|
||||
}
|
||||
|
||||
/// 清理旧日志文件,只保留最近 N 个
|
||||
///
|
||||
/// 在应用启动时调用,确保日志文件不会无限增长。
|
||||
pub fn cleanup_old_logs() {
|
||||
let log_dir = get_log_dir();
|
||||
|
||||
if !log_dir.exists() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取目录中的所有 .log 文件
|
||||
let mut log_files: Vec<_> = match std::fs::read_dir(&log_dir) {
|
||||
Ok(entries) => entries
|
||||
.filter_map(|e| e.ok())
|
||||
.map(|e| e.path())
|
||||
.filter(|p| p.extension().map(|ext| ext == "log").unwrap_or(false))
|
||||
.collect(),
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
// 如果文件数量不超过保留数量,无需清理
|
||||
if log_files.len() <= LOG_FILES_TO_KEEP {
|
||||
return;
|
||||
}
|
||||
|
||||
// 按修改时间排序(最新的在前)
|
||||
log_files.sort_by(|a, b| {
|
||||
let time_a = a.metadata().and_then(|m| m.modified()).ok();
|
||||
let time_b = b.metadata().and_then(|m| m.modified()).ok();
|
||||
time_b.cmp(&time_a) // 降序
|
||||
});
|
||||
|
||||
// 删除多余的旧文件
|
||||
for old_file in log_files.into_iter().skip(LOG_FILES_TO_KEEP) {
|
||||
if let Err(e) = std::fs::remove_file(&old_file) {
|
||||
log::warn!("清理旧日志文件失败 {}: {e}", old_file.display());
|
||||
} else {
|
||||
log::info!("已清理旧日志文件: {}", old_file.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 安全获取环境信息(不会 panic)
|
||||
fn get_system_info() -> String {
|
||||
let os = std::env::consts::OS;
|
||||
let arch = std::env::consts::ARCH;
|
||||
let family = std::env::consts::FAMILY;
|
||||
|
||||
// 安全获取当前工作目录
|
||||
let cwd = std::env::current_dir()
|
||||
.map(|p| p.display().to_string())
|
||||
.unwrap_or_else(|_| "unknown".to_string());
|
||||
|
||||
// 安全获取当前线程信息
|
||||
let thread = std::thread::current();
|
||||
let thread_name = thread.name().unwrap_or("unnamed");
|
||||
let thread_id = format!("{:?}", thread.id());
|
||||
|
||||
format!(
|
||||
"OS: {os} ({family})\n\
|
||||
Arch: {arch}\n\
|
||||
App Version: {APP_VERSION}\n\
|
||||
Working Dir: {cwd}\n\
|
||||
Thread: {thread_name} (ID: {thread_id})"
|
||||
)
|
||||
}
|
||||
|
||||
/// 设置 panic hook,捕获崩溃信息并写入日志文件
|
||||
///
|
||||
/// 在应用启动时调用此函数,确保任何 panic 都会被记录。
|
||||
/// 日志格式包含:
|
||||
/// - 时间戳
|
||||
/// - 应用版本和系统信息
|
||||
/// - Panic 信息
|
||||
/// - 发生位置(文件:行号)
|
||||
/// - Backtrace(完整调用栈)
|
||||
pub fn setup_panic_hook() {
|
||||
// 启用 backtrace(确保 release 模式也能捕获)
|
||||
if std::env::var("RUST_BACKTRACE").is_err() {
|
||||
std::env::set_var("RUST_BACKTRACE", "1");
|
||||
}
|
||||
|
||||
let default_hook = panic::take_hook();
|
||||
|
||||
panic::set_hook(Box::new(move |panic_info| {
|
||||
let log_path = get_crash_log_path();
|
||||
|
||||
// 确保目录存在
|
||||
if let Some(parent) = log_path.parent() {
|
||||
let _ = std::fs::create_dir_all(parent);
|
||||
}
|
||||
|
||||
// 构建崩溃信息(使用 catch_unwind 保护时间格式化,避免嵌套 panic)
|
||||
let timestamp = std::panic::catch_unwind(|| {
|
||||
chrono::Local::now()
|
||||
.format("%Y-%m-%d %H:%M:%S%.3f")
|
||||
.to_string()
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
// chrono panic 时回退到 unix timestamp
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.map(|d| format!("unix:{}.{:03}", d.as_secs(), d.subsec_millis()))
|
||||
.unwrap_or_else(|_| "unknown".to_string())
|
||||
});
|
||||
|
||||
// 获取系统信息
|
||||
let system_info = std::panic::catch_unwind(get_system_info)
|
||||
.unwrap_or_else(|_| "Failed to get system info".to_string());
|
||||
|
||||
// 获取 panic 消息(尝试多种方式提取)
|
||||
let message = if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
|
||||
s.to_string()
|
||||
} else if let Some(s) = panic_info.payload().downcast_ref::<String>() {
|
||||
s.clone()
|
||||
} else {
|
||||
// 尝试使用 Display trait
|
||||
format!("{panic_info}")
|
||||
};
|
||||
|
||||
// 获取位置信息
|
||||
let location = if let Some(loc) = panic_info.location() {
|
||||
format!(
|
||||
"File: {}\n Line: {}\n Column: {}",
|
||||
loc.file(),
|
||||
loc.line(),
|
||||
loc.column()
|
||||
)
|
||||
} else {
|
||||
"Unknown location".to_string()
|
||||
};
|
||||
|
||||
// 捕获 backtrace(完整调用栈)
|
||||
let backtrace = std::backtrace::Backtrace::force_capture();
|
||||
let backtrace_str = format!("{backtrace}");
|
||||
|
||||
// 格式化日志条目
|
||||
let separator = "=".repeat(80);
|
||||
let sub_separator = "-".repeat(40);
|
||||
let crash_entry = format!(
|
||||
r#"
|
||||
{separator}
|
||||
[CRASH REPORT] {timestamp}
|
||||
{separator}
|
||||
|
||||
{sub_separator}
|
||||
System Information
|
||||
{sub_separator}
|
||||
{system_info}
|
||||
|
||||
{sub_separator}
|
||||
Error Details
|
||||
{sub_separator}
|
||||
Message: {message}
|
||||
|
||||
Location: {location}
|
||||
|
||||
{sub_separator}
|
||||
Stack Trace (Backtrace)
|
||||
{sub_separator}
|
||||
{backtrace_str}
|
||||
|
||||
{separator}
|
||||
"#
|
||||
);
|
||||
|
||||
// 写入文件(追加模式)
|
||||
if let Ok(mut file) = OpenOptions::new().create(true).append(true).open(&log_path) {
|
||||
let _ = file.write_all(crash_entry.as_bytes());
|
||||
let _ = file.flush();
|
||||
|
||||
// 记录日志文件位置到 stderr
|
||||
eprintln!("\n[CC-Switch] Crash log saved to: {}", log_path.display());
|
||||
}
|
||||
|
||||
// 同时输出到 stderr(便于开发调试)
|
||||
eprintln!("{crash_entry}");
|
||||
|
||||
// 调用默认 hook
|
||||
default_hook(panic_info);
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_crash_log_path() {
|
||||
let path = get_crash_log_path();
|
||||
assert!(path.ends_with("crash.log"));
|
||||
assert!(path.to_string_lossy().contains(".cc-switch"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_system_info() {
|
||||
let info = get_system_info();
|
||||
assert!(info.contains("OS:"));
|
||||
assert!(info.contains("Arch:"));
|
||||
assert!(info.contains("App Version:"));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "CC Switch",
|
||||
"version": "3.9.1",
|
||||
"version": "3.9.0",
|
||||
"identifier": "com.ccswitch.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"windows": [
|
||||
{
|
||||
"label": "main",
|
||||
"title": "CC Switch",
|
||||
"titleBarStyle": "Visible",
|
||||
"minWidth": 900,
|
||||
"minHeight": 600
|
||||
|
||||
+1
-3
@@ -31,7 +31,6 @@ import { useProxyStatus } from "@/hooks/useProxyStatus";
|
||||
import { useLastValidValue } from "@/hooks/useLastValidValue";
|
||||
import { extractErrorMessage } from "@/utils/errorUtils";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { isWindows, isLinux } from "@/lib/platform";
|
||||
import { AppSwitcher } from "@/components/AppSwitcher";
|
||||
import { ProviderList } from "@/components/providers/ProviderList";
|
||||
import { AddProviderDialog } from "@/components/providers/AddProviderDialog";
|
||||
@@ -61,8 +60,7 @@ type View =
|
||||
| "agents"
|
||||
| "universal";
|
||||
|
||||
// macOS Overlay mode needs space for traffic light buttons, Windows/Linux use native titlebar
|
||||
const DRAG_BAR_HEIGHT = isWindows() || isLinux() ? 0 : 28; // px
|
||||
const DRAG_BAR_HEIGHT = 28; // px
|
||||
const HEADER_HEIGHT = 64; // px
|
||||
const CONTENT_TOP_OFFSET = DRAG_BAR_HEIGHT + HEADER_HEIGHT;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { createPortal } from "react-dom";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { isWindows, isLinux } from "@/lib/platform";
|
||||
|
||||
interface FullScreenPanelProps {
|
||||
isOpen: boolean;
|
||||
@@ -13,7 +12,7 @@ interface FullScreenPanelProps {
|
||||
footer?: React.ReactNode;
|
||||
}
|
||||
|
||||
const DRAG_BAR_HEIGHT = isWindows() || isLinux() ? 0 : 28; // px - match App.tsx
|
||||
const DRAG_BAR_HEIGHT = 28; // px - match App.tsx
|
||||
const HEADER_HEIGHT = 64; // px - match App.tsx
|
||||
|
||||
/**
|
||||
|
||||
@@ -394,26 +394,6 @@ export const providerPresets: ProviderPreset[] = [
|
||||
icon: "cubence",
|
||||
iconColor: "#000000",
|
||||
},
|
||||
{
|
||||
name: "AIGoCode",
|
||||
websiteUrl: "https://aigocode.com",
|
||||
apiKeyUrl: "https://aigocode.com/invite/CC-SWITCH",
|
||||
settingsConfig: {
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: "https://api.aigocode.com/api",
|
||||
ANTHROPIC_AUTH_TOKEN: "",
|
||||
},
|
||||
},
|
||||
// 请求地址候选(用于地址管理/测速)
|
||||
endpointCandidates: [
|
||||
"https://api.aigocode.com",
|
||||
],
|
||||
category: "third_party",
|
||||
isPartner: true, // 合作伙伴
|
||||
partnerPromotionKey: "aigocode", // 促销信息 i18n key
|
||||
icon: "aigocode",
|
||||
iconColor: "#5B7FFF",
|
||||
},
|
||||
{
|
||||
name: "OpenRouter",
|
||||
websiteUrl: "https://openrouter.ai",
|
||||
|
||||
@@ -171,23 +171,10 @@ requires_openai_auth = true`,
|
||||
],
|
||||
category: "third_party",
|
||||
isPartner: true, // 合作伙伴
|
||||
partnerPromotionKey: "cubence", // 促销信息 i18n key
|
||||
partnerPromotionKey: "cubence", // 促销信息 i18n key
|
||||
icon: "cubence",
|
||||
iconColor: "#000000",
|
||||
},
|
||||
{
|
||||
name: "AIGoCode",
|
||||
websiteUrl: "https://aigocode.com",
|
||||
apiKeyUrl: "https://aigocode.com/invite/CC-SWITCH",
|
||||
category: "third_party",
|
||||
auth: generateThirdPartyAuth(""),
|
||||
config: generateThirdPartyConfig("aigocode", "https://api.aigocode.com/openai", "gpt-5.2"),
|
||||
endpointCandidates: ["https://api.aigocode.com"],
|
||||
isPartner: true, // 合作伙伴
|
||||
partnerPromotionKey: "aigocode", // 促销信息 i18n key
|
||||
icon: "aigocode",
|
||||
iconColor: "#5B7FFF",
|
||||
},
|
||||
{
|
||||
name: "OpenRouter",
|
||||
websiteUrl: "https://openrouter.ai",
|
||||
@@ -201,5 +188,5 @@ requires_openai_auth = true`,
|
||||
category: "aggregator",
|
||||
icon: "openrouter",
|
||||
iconColor: "#6566F1",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -70,7 +70,7 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
||||
"https://www.packyapi.com",
|
||||
],
|
||||
icon: "packycode",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Cubence",
|
||||
websiteUrl: "https://cubence.com",
|
||||
@@ -96,26 +96,6 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
||||
icon: "cubence",
|
||||
iconColor: "#000000",
|
||||
},
|
||||
{
|
||||
name: "AIGoCode",
|
||||
websiteUrl: "https://aigocode.com",
|
||||
apiKeyUrl: "https://aigocode.com/invite/CC-SWITCH",
|
||||
settingsConfig: {
|
||||
env: {
|
||||
GOOGLE_GEMINI_BASE_URL: "https://api.aigocode.com/gemini",
|
||||
GEMINI_MODEL: "gemini-3-pro",
|
||||
},
|
||||
},
|
||||
baseURL: "https://api.aigocode.com/gemini",
|
||||
model: "gemini-3-pro",
|
||||
description: "AIGoCode",
|
||||
category: "third_party",
|
||||
isPartner: true,
|
||||
partnerPromotionKey: "aigocode",
|
||||
endpointCandidates: ["https://api.aigocode.com/gemini"],
|
||||
icon: "aigocode",
|
||||
iconColor: "#5B7FFF",
|
||||
},
|
||||
{
|
||||
name: "OpenRouter",
|
||||
websiteUrl: "https://openrouter.ai",
|
||||
@@ -125,7 +105,7 @@ export const geminiProviderPresets: GeminiProviderPreset[] = [
|
||||
GOOGLE_GEMINI_BASE_URL: "https://openrouter.ai/api",
|
||||
GEMINI_MODEL: "gemini-3-pro-preview",
|
||||
},
|
||||
},
|
||||
},
|
||||
baseURL: "https://openrouter.ai/api",
|
||||
model: "gemini-3-pro",
|
||||
description: "OpenRouter",
|
||||
|
||||
@@ -324,8 +324,7 @@
|
||||
"minimax_cn": "MiniMax Coding Plan Special Offer, Starter from ¥9.9",
|
||||
"minimax_en": "MiniMax Coding Plan Black Friday, Starter is now $2/mo (80% OFF!)",
|
||||
"dmxapi": "Claude Code exclusive model 66% OFF now!",
|
||||
"cubence": "Cubence is an official partner of CC Switch. Register using this link and enter \"CCSWITCH\" promo code during recharge to get 10% off every top-up",
|
||||
"aigocode": "AIGoCode is an official partner of CC Switch. Register using this link and get 10% bonus credit on your first top-up!"
|
||||
"cubence": "Cubence is an official partner of CC Switch. Register using this link and enter \"CCSWITCH\" promo code during recharge to get 10% off every top-up"
|
||||
},
|
||||
"parameterConfig": "Parameter Config - {{name}} *",
|
||||
"mainModel": "Main Model (optional)",
|
||||
|
||||
@@ -324,8 +324,7 @@
|
||||
"minimax_cn": "MiniMax Coding Plan 特別価格、Starter ¥9.9 から",
|
||||
"minimax_en": "MiniMax Coding Plan Black Friday、Starter が月額 $2(80% OFF)",
|
||||
"dmxapi": "Claude Code 専用モデル 66% OFF 実施中!",
|
||||
"cubence": "Cubence は CC Switch の公式パートナーです。登録後チャージ時に \"CCSWITCH\" を入力すると、毎回 10% オフ",
|
||||
"aigocode": "AIGoCode は CC Switch の公式パートナーです。このリンクから登録すると、初回チャージ時に 10% のボーナスクレジットがもらえます!"
|
||||
"cubence": "Cubence は CC Switch の公式パートナーです。登録後チャージ時に \"CCSWITCH\" を入力すると、毎回 10% オフ"
|
||||
},
|
||||
"parameterConfig": "パラメーター設定 - {{name}} *",
|
||||
"mainModel": "メインモデル(任意)",
|
||||
|
||||
@@ -324,8 +324,7 @@
|
||||
"minimax_cn": "MiniMax Coding Plan 特惠,Starter 套餐 9.9 元起",
|
||||
"minimax_en": "MiniMax Coding Plan 黑五特惠,Starter 套餐现仅 $2/月(2折优惠!)",
|
||||
"dmxapi": "Claude Code 专属模型 3.4 折优惠进行中!",
|
||||
"cubence": "Cubence 是 CC Switch 的官方合作伙伴,使用此链接注册并在充值时填写 \"CCSWITCH\" 优惠码,每次充值均可享受9折优惠",
|
||||
"aigocode": "AIGoCode 是 CC Switch 的官方合作伙伴,使用此链接注册首次充值时可以获得10%额度奖励!"
|
||||
"cubence": "Cubence 是 CC Switch 的官方合作伙伴,使用此链接注册并在充值时填写 \"CCSWITCH\" 优惠码,每次充值均可享受9折优惠"
|
||||
},
|
||||
"parameterConfig": "参数配置 - {{name}} *",
|
||||
"mainModel": "主模型 (可选)",
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="648.000000pt" height="564.000000pt" viewBox="0 0 648.000000 564.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,564.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M5392 5379 c-26 -10 -36 -28 -56 -108 -24 -94 -47 -140 -101 -199
|
||||
-56 -62 -117 -96 -219 -121 -101 -25 -116 -35 -116 -75 0 -45 21 -60 123 -89
|
||||
190 -53 271 -147 336 -384 13 -46 38 -61 85 -49 25 6 36 28 56 111 7 28 23 72
|
||||
36 99 13 28 21 54 18 58 -3 5 -2 7 3 6 4 -2 29 18 55 44 41 41 145 110 173
|
||||
114 56 8 126 27 131 36 4 6 7 30 8 54 1 49 -5 54 -104 74 -164 33 -280 148
|
||||
-320 320 -23 101 -52 129 -108 109z"/>
|
||||
<path d="M1770 4814 c-138 -25 -301 -93 -425 -177 -80 -55 -227 -197 -280
|
||||
-272 -98 -138 -161 -279 -201 -447 -16 -66 -18 -164 -21 -1098 -4 -1130 -4
|
||||
-1144 57 -1331 80 -242 222 -434 444 -598 l56 -42 0 -337 c0 -309 2 -340 19
|
||||
-379 31 -66 87 -93 158 -74 22 6 202 117 404 249 200 131 398 259 439 285 144
|
||||
89 48 81 1095 88 912 5 932 6 1012 27 243 64 441 178 599 344 166 176 274 408
|
||||
304 648 13 110 13 2016 0 2120 -25 190 -83 347 -183 498 -160 240 -384 400
|
||||
-677 484 l-75 22 -1325 2 c-1086 2 -1339 0 -1400 -12z m1068 -1455 l-3 -751
|
||||
-71 -18 c-71 -18 -154 -55 -205 -91 -14 -10 -29 -16 -33 -12 -3 3 -6 91 -6
|
||||
195 l0 188 -306 0 -305 0 -21 -47 c-11 -27 -33 -75 -48 -108 -16 -33 -44 -96
|
||||
-62 -140 l-34 -80 -172 -3 c-101 -1 -172 1 -172 7 0 5 14 40 31 78 31 68 101
|
||||
227 254 578 335 769 358 814 434 874 94 74 122 79 449 80 l272 1 -2 -751z
|
||||
m794 717 c41 -13 103 -42 139 -62 67 -40 202 -168 232 -221 l17 -31 -77 -65
|
||||
c-43 -35 -101 -80 -129 -101 l-52 -36 -39 57 c-79 116 -204 177 -313 154 -66
|
||||
-14 -105 -42 -130 -91 -19 -37 -20 -60 -20 -400 0 -339 1 -363 20 -399 26 -51
|
||||
61 -78 128 -97 143 -42 327 52 366 186 l13 45 -163 3 -163 2 -3 157 c-2 111 0
|
||||
157 9 160 6 2 263 3 570 1 487 -3 562 -5 593 -19 98 -45 125 -159 58 -244 -39
|
||||
-50 -66 -55 -322 -55 l-236 0 -6 -27 c-18 -83 -29 -115 -62 -183 -69 -143
|
||||
-230 -269 -402 -316 -81 -22 -271 -25 -350 -5 -173 43 -289 145 -341 298 -19
|
||||
57 -20 81 -17 534 l3 474 33 67 c55 112 168 199 307 235 79 20 246 10 337 -21z
|
||||
m828 -1515 c67 -71 67 -73 -62 -396 -45 -110 -102 -254 -128 -320 -254 -639
|
||||
-272 -681 -298 -702 -74 -62 -192 -15 -192 77 0 12 39 116 86 233 48 117 97
|
||||
239 110 272 119 311 336 833 354 852 36 37 85 32 130 -16z m-1574 -205 c16
|
||||
-13 19 -29 22 -128 l3 -113 -195 -155 c-108 -85 -196 -158 -196 -161 0 -4 17
|
||||
-19 38 -35 128 -96 327 -272 339 -301 16 -39 17 -143 2 -177 -15 -33 -34 -39
|
||||
-67 -22 -48 26 -566 446 -584 474 -23 35 -23 89 1 128 16 27 150 143 376 326
|
||||
39 31 79 65 90 75 44 41 128 103 139 103 7 0 21 -6 32 -14z m713 -25 c52 -37
|
||||
53 -33 -92 -551 -36 -129 -80 -289 -98 -355 -39 -143 -62 -175 -129 -175 -47
|
||||
0 -92 20 -114 52 -24 34 -19 90 18 217 19 64 78 271 131 461 53 190 98 353
|
||||
101 364 6 16 14 18 79 14 54 -4 81 -11 104 -27z m1116 -351 c55 -45 117 -98
|
||||
138 -120 61 -64 48 -115 -50 -192 -32 -25 -118 -94 -191 -152 -136 -108 -163
|
||||
-120 -217 -100 -26 10 -47 62 -39 97 10 46 22 62 94 119 36 29 93 77 128 106
|
||||
l62 55 -65 59 c-71 65 -77 84 -49 141 24 47 44 67 68 67 12 0 66 -36 121 -80z"/>
|
||||
<path d="M2328 3755 c-37 -20 -54 -53 -153 -280 -48 -110 -96 -219 -106 -242
|
||||
l-18 -43 234 0 235 0 0 290 0 290 -82 0 c-53 -1 -93 -6 -110 -15z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.3 KiB |
@@ -2,7 +2,6 @@
|
||||
// Do not edit manually
|
||||
|
||||
export const icons: Record<string, string> = {
|
||||
aigocode: `<svg height="1em" width="1em" style="flex:none;line-height:1" viewBox="0 0 648 564" xmlns="http://www.w3.org/2000/svg"><title>AiGoCode</title><g transform="translate(0,564) scale(0.1,-0.1)"><path fill="#7C6AEF" d="M5392 5379 c-26 -10 -36 -28 -56 -108 -24 -94 -47 -140 -101 -199 -56 -62 -117 -96 -219 -121 -101 -25 -116 -35 -116 -75 0 -45 21 -60 123 -89 190 -53 271 -147 336 -384 13 -46 38 -61 85 -49 25 6 36 28 56 111 7 28 23 72 36 99 13 28 21 54 18 58 -3 5 -2 7 3 6 4 -2 29 18 55 44 41 41 145 110 173 114 56 8 126 27 131 36 4 6 7 30 8 54 1 49 -5 54 -104 74 -164 33 -280 148 -320 320 -23 101 -52 129 -108 109z"/><path fill="#5B7FFF" d="M1770 4814 c-138 -25 -301 -93 -425 -177 -80 -55 -227 -197 -280 -272 -98 -138 -161 -279 -201 -447 -16 -66 -18 -164 -21 -1098 -4 -1130 -4 -1144 57 -1331 80 -242 222 -434 444 -598 l56 -42 0 -337 c0 -309 2 -340 19 -379 31 -66 87 -93 158 -74 22 6 202 117 404 249 200 131 398 259 439 285 144 89 48 81 1095 88 912 5 932 6 1012 27 243 64 441 178 599 344 166 176 274 408 304 648 13 110 13 2016 0 2120 -25 190 -83 347 -183 498 -160 240 -384 400 -677 484 l-75 22 -1325 2 c-1086 2 -1339 0 -1400 -12z m1068 -1455 l-3 -751 -71 -18 c-71 -18 -154 -55 -205 -91 -14 -10 -29 -16 -33 -12 -3 3 -6 91 -6 195 l0 188 -306 0 -305 0 -21 -47 c-11 -27 -33 -75 -48 -108 -16 -33 -44 -96 -62 -140 l-34 -80 -172 -3 c-101 -1 -172 1 -172 7 0 5 14 40 31 78 31 68 101 227 254 578 335 769 358 814 434 874 94 74 122 79 449 80 l272 1 -2 -751z m794 717 c41 -13 103 -42 139 -62 67 -40 202 -168 232 -221 l17 -31 -77 -65 c-43 -35 -101 -80 -129 -101 l-52 -36 -39 57 c-79 116 -204 177 -313 154 -66 -14 -105 -42 -130 -91 -19 -37 -20 -60 -20 -400 0 -339 1 -363 20 -399 26 -51 61 -78 128 -97 143 -42 327 52 366 186 l13 45 -163 3 -163 2 -3 157 c-2 111 0 157 9 160 6 2 263 3 570 1 487 -3 562 -5 593 -19 98 -45 125 -159 58 -244 -39 -50 -66 -55 -322 -55 l-236 0 -6 -27 c-18 -83 -29 -115 -62 -183 -69 -143 -230 -269 -402 -316 -81 -22 -271 -25 -350 -5 -173 43 -289 145 -341 298 -19 57 -20 81 -17 534 l3 474 33 67 c55 112 168 199 307 235 79 20 246 10 337 -21z m828 -1515 c67 -71 67 -73 -62 -396 -45 -110 -102 -254 -128 -320 -254 -639 -272 -681 -298 -702 -74 -62 -192 -15 -192 77 0 12 39 116 86 233 48 117 97 239 110 272 119 311 336 833 354 852 36 37 85 32 130 -16z m-1574 -205 c16 -13 19 -29 22 -128 l3 -113 -195 -155 c-108 -85 -196 -158 -196 -161 0 -4 17 -19 38 -35 128 -96 327 -272 339 -301 16 -39 17 -143 2 -177 -15 -33 -34 -39 -67 -22 -48 26 -566 446 -584 474 -23 35 -23 89 1 128 16 27 150 143 376 326 39 31 79 65 90 75 44 41 128 103 139 103 7 0 21 -6 32 -14z m713 -25 c52 -37 53 -33 -92 -551 -36 -129 -80 -289 -98 -355 -39 -143 -62 -175 -129 -175 -47 0 -92 20 -114 52 -24 34 -19 90 18 217 19 64 78 271 131 461 53 190 98 353 101 364 6 16 14 18 79 14 54 -4 81 -11 104 -27z m1116 -351 c55 -45 117 -98 138 -120 61 -64 48 -115 -50 -192 -32 -25 -118 -94 -191 -152 -136 -108 -163 -120 -217 -100 -26 10 -47 62 -39 97 10 46 22 62 94 119 36 29 93 77 128 106 l62 55 -65 59 c-71 65 -77 84 -49 141 24 47 44 67 68 67 12 0 66 -36 121 -80z"/><path fill="#5B7FFF" d="M2328 3755 c-37 -20 -54 -53 -153 -280 -48 -110 -96 -219 -106 -242 l-18 -43 234 0 235 0 0 290 0 290 -82 0 c-53 -1 -93 -6 -110 -15z"/></g></svg>`,
|
||||
alibaba: `<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Alibaba</title><path d="M24 14.014c-2.8 1.512-5.62 2.896-8.759 3.524-.7.139-1.476.139-2.187.043-.678-.085-1.017-.682-.776-1.31.23-.585.536-1.181.93-1.671.852-1.065 1.814-2.034 2.678-3.088a15.75 15.75 0 001.422-2.054c.306-.511.164-1.129-.372-1.384-.897-.437-1.859-.745-2.81-1.075-.11-.043-.274.074-.492.149.273.244.47.425.743.67-2.821.48-5.49 1.16-8.08 2.098-.012.053-.033.095-.023.117.383.585.208 1.032-.35 1.394a2.365 2.365 0 00-.568.522c1.706.5 3.226.213 4.68-.735-.087-.127-.175-.244-.262-.372.546.096.874.394.918.862.011.107-.054.213-.087.32-.077-.086-.175-.17-.24-.267-.045-.064-.056-.138-.088-.245-1.728 1.15-3.587 1.438-5.632.842 0 .404-.022.745.011 1.075.022.287-.098.415-.36.564-.591.362-1.204.735-1.696 1.214-.59.585-.371 1.299.427 1.597.907.34 1.859.35 2.81.234 1.126-.139 2.23-.32 3.456-.49-1.433.67-2.844 1.14-4.33 1.33-1.04.14-2.078.214-3.106-.084-1.476-.415-2.133-1.501-1.75-2.96.361-1.363 1.236-2.449 2.176-3.45 3.139-3.332 7.108-5.024 11.7-5.365 1.072-.074 2.155.064 3.16.511 1.411.639 2.002 1.99 1.313 3.354-.448.905-1.072 1.735-1.695 2.555-.612.809-1.301 1.554-1.946 2.331-.186.234-.361.48-.503.745-.274.5-.088.83.492.778 1.213-.118 2.45-.213 3.62-.511 1.716-.437 3.389-1.054 5.084-1.597.175-.043.339-.107.492-.17z" fill="#FF6003" fill-rule="evenodd"></path></svg>`,
|
||||
anthropic: `<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Anthropic</title><path d="M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z"></path></svg>`,
|
||||
aws: `<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>AWS</title><path d="M6.763 11.212c0 .296.032.535.088.71.064.176.144.368.256.576.04.063.056.127.056.183 0 .08-.048.16-.152.24l-.503.335a.383.383 0 01-.208.072c-.08 0-.16-.04-.239-.112a2.47 2.47 0 01-.287-.375 6.18 6.18 0 01-.248-.471c-.622.734-1.405 1.101-2.347 1.101-.67 0-1.205-.191-1.596-.574-.39-.384-.59-.894-.59-1.533 0-.678.24-1.23.726-1.644.487-.415 1.133-.623 1.955-.623.272 0 .551.024.846.064.296.04.6.104.918.176v-.583c0-.607-.127-1.03-.375-1.277-.255-.248-.686-.367-1.3-.367-.28 0-.568.031-.863.103-.295.072-.583.16-.862.272a2.4 2.4 0 01-.28.104.488.488 0 01-.127.023c-.112 0-.168-.08-.168-.247v-.391c0-.128.016-.224.056-.28a.597.597 0 01.224-.167 4.577 4.577 0 011.005-.36 4.84 4.84 0 011.246-.151c.95 0 1.644.216 2.091.647.44.43.662 1.085.662 1.963v2.586h.016zm-3.24 1.214c.263 0 .534-.048.822-.144a1.78 1.78 0 00.758-.51 1.27 1.27 0 00.272-.512c.047-.191.08-.423.08-.694v-.335a6.66 6.66 0 00-.735-.136 6.02 6.02 0 00-.75-.048c-.535 0-.926.104-1.19.32-.263.215-.39.518-.39.917 0 .375.095.655.295.846.191.2.47.296.838.296zm6.41.862c-.144 0-.24-.024-.304-.08-.064-.048-.12-.16-.168-.311L7.586 6.726a1.398 1.398 0 01-.072-.32c0-.128.064-.2.191-.2h.783c.151 0 .255.025.31.08.065.048.113.16.16.312l1.342 5.284 1.245-5.284c.04-.16.088-.264.151-.312a.549.549 0 01.32-.08h.638c.152 0 .256.025.32.08.063.048.12.16.151.312l1.261 5.348 1.381-5.348c.048-.16.104-.264.16-.312a.52.52 0 01.311-.08h.743c.127 0 .2.065.2.2 0 .04-.009.08-.017.128a1.137 1.137 0 01-.056.2l-1.923 6.17c-.048.16-.104.263-.168.311a.51.51 0 01-.303.08h-.687c-.15 0-.255-.024-.32-.08-.063-.056-.119-.16-.15-.32L12.32 7.747l-1.23 5.14c-.04.16-.087.264-.15.32-.065.056-.177.08-.32.08l-.686.001zm10.256.215c-.415 0-.83-.048-1.229-.143-.399-.096-.71-.2-.918-.32-.128-.071-.215-.151-.247-.223a.563.563 0 01-.048-.224v-.407c0-.167.064-.247.183-.247.048 0 .096.008.144.024.048.016.12.048.2.08.271.12.566.215.878.279.32.064.63.096.95.096.502 0 .894-.088 1.165-.264a.86.86 0 00.415-.758.777.777 0 00-.215-.559c-.144-.151-.416-.287-.807-.415l-1.157-.36c-.583-.183-1.014-.454-1.277-.813a1.902 1.902 0 01-.4-1.158c0-.335.073-.63.216-.886.144-.255.335-.479.575-.654.24-.184.51-.32.83-.415.32-.096.655-.136 1.006-.136.175 0 .36.008.535.032.183.024.35.056.518.088.16.04.312.08.455.127.144.048.256.096.336.144a.69.69 0 01.24.2.43.43 0 01.071.263v.375c0 .168-.064.256-.184.256a.83.83 0 01-.303-.096 3.652 3.652 0 00-1.532-.311c-.455 0-.815.071-1.062.223-.248.152-.375.383-.375.71 0 .224.08.416.24.567.16.152.454.304.877.44l1.134.358c.574.184.99.44 1.237.767.247.327.367.702.367 1.117 0 .343-.072.655-.207.926a2.157 2.157 0 01-.583.703c-.248.2-.543.343-.886.447-.36.111-.734.167-1.142.167z"></path><path d="M.378 15.475c3.384 1.963 7.56 3.153 11.877 3.153 2.914 0 6.114-.607 9.06-1.852.44-.2.814.287.383.607-2.626 1.94-6.442 2.969-9.722 2.969-4.598 0-8.74-1.7-11.87-4.526-.247-.223-.024-.527.272-.351zm23.531-.2c.287.36-.08 2.826-1.485 4.007-.215.184-.423.088-.327-.151l.175-.439c.343-.88.802-2.198.52-2.555-.336-.43-2.22-.207-3.074-.103-.255.032-.295-.192-.063-.36 1.5-1.053 3.967-.75 4.254-.399z" fill="#F90"></path></svg>`,
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
import { IconMetadata } from "@/types/icon";
|
||||
|
||||
export const iconMetadata: Record<string, IconMetadata> = {
|
||||
aigocode: {
|
||||
name: "aigocode",
|
||||
displayName: "AIGoCode",
|
||||
category: "ai-provider",
|
||||
keywords: ["aigocode", "aigo", "code", "third-party"],
|
||||
defaultColor: "#5B7FFF",
|
||||
},
|
||||
alibaba: {
|
||||
name: "alibaba",
|
||||
displayName: "Alibaba",
|
||||
|
||||
Reference in New Issue
Block a user