Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src-tauri/src/app_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ pub(crate) async fn check_app_update(
let unsupported_reason = if auto_update_supported {
None
} else if portable_support != Some(true) {
Some("当前程序不是支持自动升级的便携版,请手动下载首个支持版本".to_string())
Some("Current application is not a portable build supporting automatic updates; please download manually".to_string())
} else {
Some("更新清单不包含当前平台或架构".to_string())
Some("Update manifest does not include current platform or architecture".to_string())
};

let pending = if update_available && auto_update_supported {
Expand Down Expand Up @@ -244,7 +244,7 @@ pub(crate) async fn fetch_portable_update_manifest(
Err(error) => failures.push(format!("{}: {error}", candidate.display_name())),
}
}
Err(format!("所有软件版本检测源均失败: {}", failures.join("; ")))
Err(format!("All application version check sources failed: {}", failures.join("; ")))
}

pub(crate) async fn fetch_portable_update_manifest_from_gitcode(
Expand Down Expand Up @@ -291,11 +291,11 @@ pub(crate) async fn fetch_portable_update_manifest_url(
}

pub(crate) fn configured_gitcode_gui_repository() -> Option<&'static str> {
configured_gitcode_repository(option_env!("GITCODE_GUI_REPOSITORY"))
configured_gitcode_repository(option_env!("GITCODE_GUI_REPOSITORY").or(Some("lzt404/EasyCLIProxyAPI")))
}

pub(crate) fn configured_gitcode_core_repository() -> Option<&'static str> {
configured_gitcode_repository(option_env!("GITCODE_CORE_REPOSITORY"))
configured_gitcode_repository(option_env!("GITCODE_CORE_REPOSITORY").or(Some("lzt404/CLIProxyAPI")))
}

pub(crate) fn configured_gitcode_repository(
Expand Down Expand Up @@ -1072,7 +1072,7 @@ pub(crate) async fn download_portable_update_archive(
Err(error) => failures.push(error),
}
}
Err(format!("所有应用更新下载源均失败: {}", failures.join("; ")))
Err(format!("All application update download sources failed: {}", failures.join("; ")))
}

pub(crate) fn portable_update_download_urls(
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/core_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ pub(crate) async fn fetch_release(
Err(error) => failures.push(format!("{}: {error}", candidate.display_name())),
}
}
Err(format!("所有内核版本检测源均失败: {}", failures.join("")))
Err(format!("All core version check sources failed: {}", failures.join("; ")))
}

pub(crate) async fn fetch_release_from_github(
Expand Down Expand Up @@ -1016,7 +1016,7 @@ pub(crate) async fn download_asset(
let _ = fs::remove_file(archive_path);
return Err("内核发行版没有可用的下载地址".to_string());
}
Err(format!("所有内核下载源均失败: {}", failures.join("")))
Err(format!("All core download sources failed: {}", failures.join("; ")))
}

pub(crate) fn core_download_source_name(url: &str) -> String {
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ const LEGACY_GUI_CONFIG_FILE: &str = "cpa-gui.yaml";
const MIN_MAIN_WINDOW_WIDTH: u32 = 640;
const MIN_MAIN_WINDOW_HEIGHT: u32 = 600;
const MAX_SAVED_WINDOW_DIMENSION: u32 = 16_384;
const DEFAULT_MAIN_WINDOW_WIDTH: u32 = 1280;
const DEFAULT_MAIN_WINDOW_HEIGHT: u32 = 800;
const DEFAULT_MAIN_WINDOW_WIDTH: u32 = 1400;
const DEFAULT_MAIN_WINDOW_HEIGHT: u32 = 860;
const LEGACY_DEFAULT_MAIN_WINDOW_WIDTH: u32 = 1531;
const LEGACY_DEFAULT_MAIN_WINDOW_HEIGHT: u32 = 891;
const OAUTH_DIR_NAME: &str = "oauth";
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/tests/app_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ fn gui_config_defaults_are_stable() {
assert!(content.contains("close-behavior = \"ask\""));
assert!(content.contains("default-terminal = \"auto\""));
assert_eq!(config.default_terminal, DEFAULT_AGENT_TERMINAL);
assert!(content.contains("window-width = 1280"));
assert!(content.contains("window-height = 800"));
assert!(content.contains("window-width = 1400"));
assert!(content.contains("window-height = 860"));
assert!(content.contains("auth-dir = \"../oauth\""));
assert!(content.contains("[[api-keys]]"));
assert!(content.contains("key = \"123456\""));
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3650,14 +3650,14 @@ fn api_key_category_label(remark: String, display: String) -> String {
} else if !display.is_empty() {
mask_api_key(&display)
} else {
"未记录密钥".to_string()
"Unrecorded Key".to_string()
}
}

fn usage_source_display(config: &GuiConfigFile, provider: &str, source: &str) -> String {
let source = source.trim();
if source.is_empty() {
return "未知来源".to_string();
return "Unknown Source".to_string();
}
if let Some(remark) = config.api_access_remark_for_source(provider, source) {
return remark.to_string();
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
{
"label": "main",
"title": "EasyCLIProxyAPI",
"width": 1280,
"height": 800,
"width": 1400,
"height": 860,
"minWidth": 640,
"minHeight": 600,
"visible": false
Expand Down
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ function AppContent() {
return;
}
} catch (error) {
console.error('读取关闭行为设置失败', error);
console.error('Failed to read close behavior settings', error);
}

setWindowsClosePrompt((current) =>
Expand All @@ -212,7 +212,7 @@ function AppContent() {
}
})
.catch((error) => {
console.error('监听 Windows 关闭确认事件失败', error);
console.error('Failed to listen for Windows close confirmation event', error);
});

return () => {
Expand Down Expand Up @@ -243,7 +243,7 @@ function AppContent() {
try {
await invoke('open_external_url', { url: CONTACT_URL });
} catch (error) {
console.error('打开联系我们链接失败', error);
console.error('Failed to open contact URL', error);
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/AppErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class AppErrorBoundary extends Component<Props, State> {
}

componentDidCatch(error: Error, info: ErrorInfo) {
console.error('EasyCLIProxyAPI 渲染异常', error, info.componentStack);
console.error('EasyCLIProxyAPI render exception', error, info.componentStack);
}

render() {
Expand Down
2 changes: 1 addition & 1 deletion src/coreRuntime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function CoreRuntimeProvider({ children }: { children: ReactNode }) {
export function useCoreRuntime() {
const context = useContext(CoreRuntimeContext);
if (!context) {
throw new Error('useCoreRuntime 必须在 CoreRuntimeProvider 内使用');
throw new Error('useCoreRuntime must be used within a CoreRuntimeProvider');
}
return context;
}
1 change: 1 addition & 0 deletions src/i18n/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { invoke } from '@tauri-apps/api/core';
import { en, ja, zhCN, zhTW, type MessageKey, type MessageVariables } from './resources';

export type AppLocale = 'zh-CN' | 'zh-TW' | 'ja' | 'en';
export type { MessageKey };

export const languageOptions: ReadonlyArray<{
value: AppLocale;
Expand Down
74 changes: 74 additions & 0 deletions src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,76 @@ export const jaOverrides = {
'easyMode.guide.step3Description': '「利用可能なモデル」一覧からモデルを選び、インストール済みのエージェントクライアントを選択して設定を適用します。',
'easyMode.navigation.back': '前へ',
'easyMode.navigation.next': '次へ',
'easyMode.subtitle': 'エージェントとモデルの簡単セットアップガイド',
'easyMode.guide.button': '操作ガイド',
'easyMode.guide.buttonActive': '操作ガイド(進行中)',
'easyMode.guide.tooltipOpen': 'クリックして操作ガイドを開く',
'easyMode.guide.tooltipClose': 'クリックして操作ガイドを閉じる',
'easyMode.exit.button': 'ビギナーモードを終了',
'easyMode.exit.tooltip': '通常ダッシュボードに戻る',
'easyMode.oauth.loggedInCount': '{count} 個のアカウントがログイン中',
'easyMode.oauth.recommended': 'おすすめ',
'easyMode.oauth.supportedProviders': 'Codex、Claude、Antigravity、Kimi、xAI に対応',
'easyMode.oauth.descCodex': 'OpenAI / ChatGPT アカウント認証ログイン',
'easyMode.oauth.descClaude': 'Anthropic / Claude アカウント認証ログイン',
'easyMode.oauth.descAntigravity': 'Antigravity アカウント認証ログイン',
'easyMode.oauth.descKimi': 'Moonshot / Kimi アカウント認証ログイン',
'easyMode.oauth.descXai': 'xAI / Grok アカウント認証ログイン',
'easyMode.oauth.notLoggedIn': '未ログイン',
'easyMode.oauth.startLogin': 'ログイン',
'easyMode.oauth.errorGetStatus': '認証ステータスの取得に失敗しました。もう一度お試しください。',
'easyMode.oauth.loginSuccess': 'ログインに成功しました!アカウントが認証され、利用枠が取得されました。',
'easyMode.oauth.errorWithDetail': '認証に失敗しました: {error}',
'easyMode.oauth.errorRetry': '認証に失敗しました。もう一度お試しください。',
'easyMode.api.connectedCount': '{count} 個のプラットフォームを接続済み',
'easyMode.api.supportedProviders': 'OpenAI、Anthropic、Codex、Gemini、DeepSeek に対応',
'easyMode.api.formatOpenAi': 'OpenAI 形式',
'easyMode.api.formatClaude': 'Anthropic 形式',
'easyMode.api.formatGemini': 'Gemini 形式',
'easyMode.api.remarkPlaceholder': '例: メイン DeepSeek V3、リレー API',
'easyMode.api.saveAndConnect': '保存して接続',
'easyMode.api.savedNotice': 'API 接続が正常に保存されました!',
'easyMode.api.errorBaseUrl': '先に API Base URL を入力してください',
'easyMode.api.errorApiKey': '先に API キーを入力してください',
'easyMode.api.errorNoModels': 'モデルが見つかりませんでした。API Base URL とキーをご確認ください。',
'easyMode.api.errorFetchModelsFirst': '先にモデル一覧を取得してください',
'easyMode.steps.configureAgent': 'エージェントを設定',
'easyMode.guide.badgeStep1': 'ステップ 1/4 · 接続方法の選択',
'easyMode.guide.badgeStep2OAuth': 'ステップ 2/4 · アカウント認証ログイン',
'easyMode.guide.badgeStep2Api': 'ステップ 2/4 · API 入力と接続',
'easyMode.guide.badgeStep3': 'ステップ 3/4 · 接続ソースの確認と次へ',
'easyMode.guide.badgeStep4': 'ステップ 4/4 · クライアント選択と設定適用',
'easyMode.guide.closeTooltip': 'ガイドを閉じる',
'easyMode.guide.finish': 'ガイド完了',
'easyMode.guide.step1.heading': 'ステップ 1:接続方法を選択',
'easyMode.guide.step1.oauthDesc': '一覧に表示されている OAuth プラットフォームに最適です。',
'easyMode.guide.step1.apiDesc': 'API Base URL と API キーをお持ちのプロバイダーや中継サービスに最適です。',
'easyMode.guide.step1.tipSelected': '接続方法を選択しました。「次へ」をクリックして続行してください。',
'easyMode.guide.step1.tipUnselected': '上のいずれかの接続方法をクリックして進んでください。',
'easyMode.guide.step2OAuth.heading': 'ステップ 2:OAuth 認証を完了',
'easyMode.guide.step2OAuth.desc1': 'プラットフォームを選び、右側の「ログイン」または「再ログイン」をクリックしてブラウザーで認証を行ってください。',
'easyMode.guide.step2OAuth.desc2': 'アプリに戻った後、プラットフォームが「ログイン済み」と表示されると完了です。',
'easyMode.guide.step2OAuth.tipSuccess': '{provider} の認証に成功しました。「次へ」をクリックしてください。',
'easyMode.guide.step2OAuth.tipPending': 'いずれかのプラットフォームのログインボタンをクリックし、認証完了をお待ちください。',
'easyMode.guide.step2Api.heading': 'ステップ 2:API 情報を入力して保存',
'easyMode.guide.step2Api.desc1': '1. インターフェース形式を確認します(デフォルトのままでも変更しても構いません)。',
'easyMode.guide.step2Api.desc2': '2. API Base URL と API キーを入力します。',
'easyMode.guide.step2Api.desc3': '3. 「モデル一覧を取得」をクリックし、取得されたモデルを確認して「保存して接続」をクリックします。',
'easyMode.guide.step2Api.tipSaved': 'API 接続が保存されました。「次へ」をクリックして続行してください。',
'easyMode.guide.step2Api.tipEmpty': 'モデルを取得する前に Base URL と API キーを入力してください。',
'easyMode.guide.step2Api.tipFetch': '「モデル一覧を取得」をクリックし、結果をお待ちください。',
'easyMode.guide.step2Api.tipNoSelected': 'モデルが選択されていません。少なくとも 1 つ選択して保存してください。',
'easyMode.guide.step2Api.tipSelectedCount': 'デフォルトで {count} 個のモデルが選択されています。必要に応じて変更し、「保存して接続」をクリックしてください。',
'easyMode.guide.step3.heading': 'ステップ 3:接続ソースの確認',
'easyMode.guide.step3.desc1': '現在 {count} 個の接続ソースが確認されています。これはアカウントや API が接続されたことを意味し、クライアントの設定はまだ完了していません。',
'easyMode.guide.step3.desc2': '下の強調表示された「次へ:エージェントを設定」をクリックして、クライアント選択とモデル設定に進んでください。',
'easyMode.guide.step3.tipReady': '接続ソースが確認されました。「次へ:エージェントを設定」をクリックしてください。',
'easyMode.guide.step3.tipWaiting': '前のステップで認証または API 保存を完了してください。',
'easyMode.guide.step4.heading': 'ステップ 4:クライアントを選択して設定を適用',
'easyMode.guide.step4.desc1': '左側の一覧に検出状況が表示されます。「検出済み」で対応しているクライアントを選び、右側の「使用するモデルを選択」でモデルを選んでください。',
'easyMode.guide.step4.desc2': 'Pi 以外のクライアントでは「設定を適用」または「設定を更新」、Pi では「プロバイダーをインストール」または「プロバイダーを修復」をクリックします。成功するとガイド完了となります。',
'easyMode.guide.step4.tipSuccess': '設定が正常に適用されました!操作ガイドを閉じるか、起動ボタンでクライアントを起動してください。',
'easyMode.guide.step4.tipWaiting': '検出されたクライアントとモデルを選択し、設定ボタンをクリックして完了をお待ちください。',
'error.render.title': 'ページの描画中にエラーが発生しました',
'error.unknown': '不明なエラー',
'error.reload': 'ページを再読み込み',
Expand Down Expand Up @@ -397,6 +467,9 @@ export const jaOverrides = {
'usage.column.total': '合計',
'usage.column.speed': '生成速度',
'usage.key.noRemark': 'メモなし',
'usage.key.unrecorded': '未記録キー',
'usage.source.unknown': '未知のソース',
'usage.provider.unknown': '未知の Provider',
'usage.previous': '前へ',
'usage.next': '次へ',
'usage.empty': '現在のフィルター範囲に使用履歴はありません',
Expand Down Expand Up @@ -946,6 +1019,7 @@ export const jaOverrides = {
'agents.clear.description': 'Codex 設定ディレクトリの auth.json と config.toml を完全に削除し、このアプリが記録した適用状態をリセットします。バックアップは作成されず、元に戻せません。',
'agents.clear.confirm': '設定を消去',
'agents.clear.success': 'Codex 設定を消去しました。',
'apiAccess.provider.openaiCompatibility': 'OpenAI 互換',
'apiAccess.compatibleName': 'OpenAI 互換 {number}',
'apiAccess.error.headerMissingColon': 'カスタムヘッダーの {number} 行目にコロンがありません',
'apiAccess.error.headerInvalid': 'カスタムヘッダーの {number} 行目の形式が無効です',
Expand Down
Loading