feat: more granular local environment checks (#870)

* feat: more granular local environment checks

* refactor: improve PR #870 with i18n, shadcn Select, and testable helpers

- Extract is_valid_shell, is_valid_shell_flag, default_flag_for_shell
  to module-level #[cfg(windows)] functions for testability
- Add unit tests for extracted helper functions
- Replace native <select> with shadcn/ui Select components
- Extract env badge ternary to ENV_BADGE_CONFIG Record lookup
- Add i18n keys for env badges and WSL selectors (zh/en/ja)
- Unify initial useEffect load path with loadAllToolVersions()

* fix: prevent useEffect re-firing on wslShellByTool changes

The useEffect that loads initial tool versions depended on
loadAllToolVersions, which in turn depended on wslShellByTool.
This caused a full re-fetch of all 4 tools every time the user
changed a WSL shell or flag, racing with the single-tool refresh.

Fix: use empty deps [] since this is a mount-only effect. The
refresh button and shell/flag handlers cover subsequent updates.

---------

Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
Kelvin Chiu
2026-02-23 11:26:23 +08:00
committed by GitHub
parent 4c88174cb0
commit d11df17b5d
6 changed files with 471 additions and 58 deletions
+10 -1
View File
@@ -37,7 +37,8 @@
"search": "Search",
"reset": "Reset",
"actions": "Actions",
"deleting": "Deleting..."
"deleting": "Deleting...",
"auto": "Auto"
},
"apiKeyInput": {
"placeholder": "Enter API Key",
@@ -452,6 +453,14 @@
"oneClickInstall": "One-click Install",
"oneClickInstallHint": "Install Claude Code / Codex / Gemini CLI / OpenCode",
"localEnvCheck": "Local environment check",
"envBadge": {
"wsl": "WSL",
"windows": "Win",
"macos": "macOS",
"linux": "Linux"
},
"wslShell": "Shell",
"wslShellFlag": "Flag",
"installCommandsCopied": "Install commands copied",
"installCommandsCopyFailed": "Copy failed, please copy manually.",
"importFailedError": "Import config failed: {{message}}",
+10 -1
View File
@@ -37,7 +37,8 @@
"search": "検索",
"reset": "リセット",
"actions": "操作",
"deleting": "削除中..."
"deleting": "削除中...",
"auto": "自動"
},
"apiKeyInput": {
"placeholder": "API Key を入力",
@@ -452,6 +453,14 @@
"oneClickInstall": "ワンクリックインストール",
"oneClickInstallHint": "Claude Code / Codex / Gemini CLI / OpenCode をインストール",
"localEnvCheck": "ローカル環境チェック",
"envBadge": {
"wsl": "WSL",
"windows": "Win",
"macos": "macOS",
"linux": "Linux"
},
"wslShell": "Shell",
"wslShellFlag": "フラグ",
"installCommandsCopied": "インストールコマンドをコピーしました",
"installCommandsCopyFailed": "コピーに失敗しました。手動でコピーしてください。",
"importFailedError": "設定のインポートに失敗しました: {{message}}",
+10 -1
View File
@@ -37,7 +37,8 @@
"search": "查询",
"reset": "重置",
"actions": "操作",
"deleting": "删除中..."
"deleting": "删除中...",
"auto": "自动"
},
"apiKeyInput": {
"placeholder": "请输入API Key",
@@ -452,6 +453,14 @@
"oneClickInstall": "一键安装",
"oneClickInstallHint": "安装 Claude Code / Codex / Gemini CLI / OpenCode",
"localEnvCheck": "本地环境检查",
"envBadge": {
"wsl": "WSL",
"windows": "Win",
"macos": "macOS",
"linux": "Linux"
},
"wslShell": "Shell",
"wslShellFlag": "标志",
"installCommandsCopied": "安装命令已复制",
"installCommandsCopyFailed": "复制失败,请手动复制。",
"importFailedError": "导入配置失败:{{message}}",