mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-10 07:19:02 +08:00
feat(CodeTools): add environment variable support for CLI tools; update UI to manage environment variables and enhance localization for related strings
This commit is contained in:
parent
29d4e37f6b
commit
2265ecab21
@ -283,12 +283,11 @@ class CodeToolsService {
|
||||
}
|
||||
|
||||
// Build command to execute
|
||||
let baseCommand: string
|
||||
let baseCommand = `${bunPath} "${executablePath}"`
|
||||
const bunInstallPath = path.join(os.homedir(), '.cherrystudio')
|
||||
|
||||
if (isInstalled) {
|
||||
// If already installed, run executable directly (with optional update message)
|
||||
baseCommand = `"${executablePath}"`
|
||||
if (updateMessage) {
|
||||
baseCommand = `echo "Checking ${cliTool} version..."${updateMessage} && ${baseCommand}`
|
||||
}
|
||||
@ -301,7 +300,7 @@ class CodeToolsService {
|
||||
: `export BUN_INSTALL="${bunInstallPath}" && export NPM_CONFIG_REGISTRY="${registryUrl}" &&`
|
||||
|
||||
const installCommand = `${installEnvPrefix} "${bunPath}" install -g ${packageName}`
|
||||
baseCommand = `echo "Installing ${packageName}..." && ${installCommand} && echo "Installation complete, starting ${cliTool}..." && "${executablePath}"`
|
||||
baseCommand = `echo "Installing ${packageName}..." && ${installCommand} && echo "Installation complete, starting ${cliTool}..." && "${baseCommand}"`
|
||||
}
|
||||
|
||||
switch (platform) {
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
removeDirectory,
|
||||
resetCodeTools,
|
||||
setCurrentDirectory,
|
||||
setEnvironmentVariables,
|
||||
setSelectedCliTool,
|
||||
setSelectedModel
|
||||
} from '@renderer/store/codeTools'
|
||||
@ -33,6 +34,14 @@ export const useCodeTools = () => {
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
// 设置环境变量
|
||||
const setEnvVars = useCallback(
|
||||
(envVars: string) => {
|
||||
dispatch(setEnvironmentVariables(envVars))
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
// 添加目录
|
||||
const addDir = useCallback(
|
||||
(directory: string) => {
|
||||
@ -85,6 +94,9 @@ export const useCodeTools = () => {
|
||||
// 获取当前CLI工具选择的模型
|
||||
const selectedModel = codeToolsState.selectedModels[codeToolsState.selectedCliTool] || null
|
||||
|
||||
// 获取当前CLI工具的环境变量
|
||||
const environmentVariables = codeToolsState?.environmentVariables?.[codeToolsState.selectedCliTool] || ''
|
||||
|
||||
// 检查是否可以启动(所有必需字段都已填写)
|
||||
const canLaunch = Boolean(codeToolsState.selectedCliTool && selectedModel && codeToolsState.currentDirectory)
|
||||
|
||||
@ -92,6 +104,7 @@ export const useCodeTools = () => {
|
||||
// 状态
|
||||
selectedCliTool: codeToolsState.selectedCliTool,
|
||||
selectedModel: selectedModel,
|
||||
environmentVariables: environmentVariables,
|
||||
directories: codeToolsState.directories,
|
||||
currentDirectory: codeToolsState.currentDirectory,
|
||||
canLaunch,
|
||||
@ -99,6 +112,7 @@ export const useCodeTools = () => {
|
||||
// 操作函数
|
||||
setCliTool,
|
||||
setModel,
|
||||
setEnvVars,
|
||||
addDir,
|
||||
removeDir,
|
||||
setCurrentDir,
|
||||
|
||||
@ -654,6 +654,8 @@
|
||||
"cli_tool": "CLI Tool",
|
||||
"cli_tool_placeholder": "Select the CLI tool to use",
|
||||
"description": "Quickly launch multiple code CLI tools to improve development efficiency",
|
||||
"env_vars_help": "Enter custom environment variables (one per line, format: KEY=value)",
|
||||
"environment_variables": "Environment Variables",
|
||||
"folder_placeholder": "Select working directory",
|
||||
"install_bun": "Install Bun",
|
||||
"installing_bun": "Installing...",
|
||||
|
||||
@ -654,6 +654,8 @@
|
||||
"cli_tool": "CLI ツール",
|
||||
"cli_tool_placeholder": "使用する CLI ツールを選択してください",
|
||||
"description": "開発効率を向上させるために、複数のコード CLI ツールを迅速に起動します",
|
||||
"env_vars_help": "環境変数を設定して、CLI ツールの実行時に使用します。各変数は 1 行ごとに設定してください。",
|
||||
"environment_variables": "環境変数",
|
||||
"folder_placeholder": "作業ディレクトリを選択してください",
|
||||
"install_bun": "Bun をインストール",
|
||||
"installing_bun": "インストール中...",
|
||||
|
||||
@ -654,6 +654,8 @@
|
||||
"cli_tool": "Инструмент",
|
||||
"cli_tool_placeholder": "Выберите CLI-инструмент для использования",
|
||||
"description": "Быстро запускает несколько CLI-инструментов для кода, повышая эффективность разработки",
|
||||
"env_vars_help": "Установите переменные окружения для использования при запуске CLI-инструментов. Каждая переменная должна быть на отдельной строке в формате KEY=value",
|
||||
"environment_variables": "Переменные окружения",
|
||||
"folder_placeholder": "Выберите рабочую директорию",
|
||||
"install_bun": "Установить Bun",
|
||||
"installing_bun": "Установка...",
|
||||
|
||||
@ -654,6 +654,8 @@
|
||||
"cli_tool": "CLI 工具",
|
||||
"cli_tool_placeholder": "选择要使用的 CLI 工具",
|
||||
"description": "快速启动多个代码 CLI 工具,提高开发效率",
|
||||
"env_vars_help": "输入自定义环境变量(每行一个,格式:KEY=value)",
|
||||
"environment_variables": "环境变量",
|
||||
"folder_placeholder": "选择工作目录",
|
||||
"install_bun": "安装 Bun",
|
||||
"installing_bun": "安装中...",
|
||||
|
||||
@ -654,6 +654,8 @@
|
||||
"cli_tool": "CLI 工具",
|
||||
"cli_tool_placeholder": "選擇要使用的 CLI 工具",
|
||||
"description": "快速啟動多個程式碼 CLI 工具,提高開發效率",
|
||||
"env_vars_help": "輸入自定義環境變數(每行一個,格式:KEY=value)",
|
||||
"environment_variables": "環境變數",
|
||||
"folder_placeholder": "選擇工作目錄",
|
||||
"install_bun": "安裝 Bun",
|
||||
"installing_bun": "安裝中...",
|
||||
|
||||
@ -10,7 +10,7 @@ import { getModelUniqId } from '@renderer/services/ModelService'
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
import { setIsBunInstalled } from '@renderer/store/mcp'
|
||||
import { Model } from '@renderer/types'
|
||||
import { Alert, Button, Checkbox, Select, Space } from 'antd'
|
||||
import { Alert, Button, Checkbox, Input, Select, Space } from 'antd'
|
||||
import { Download, Terminal, X } from 'lucide-react'
|
||||
import { FC, useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -35,11 +35,13 @@ const CodeToolsPage: FC = () => {
|
||||
const {
|
||||
selectedCliTool,
|
||||
selectedModel,
|
||||
environmentVariables,
|
||||
directories,
|
||||
currentDirectory,
|
||||
canLaunch,
|
||||
setCliTool,
|
||||
setModel,
|
||||
setEnvVars,
|
||||
setCurrentDir,
|
||||
removeDir,
|
||||
selectFolder
|
||||
@ -100,6 +102,11 @@ const CodeToolsPage: FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理环境变量更改
|
||||
const handleEnvVarsChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setEnvVars(e.target.value)
|
||||
}
|
||||
|
||||
// 处理文件夹选择
|
||||
const handleFolderSelect = async () => {
|
||||
try {
|
||||
@ -214,6 +221,22 @@ const CodeToolsPage: FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 解析用户自定义的环境变量
|
||||
if (environmentVariables) {
|
||||
const lines = environmentVariables.split('\n')
|
||||
for (const line of lines) {
|
||||
const trimmedLine = line.trim()
|
||||
if (trimmedLine && trimmedLine.includes('=')) {
|
||||
const [key, ...valueParts] = trimmedLine.split('=')
|
||||
const trimmedKey = key.trim()
|
||||
const value = valueParts.join('=').trim()
|
||||
if (trimmedKey) {
|
||||
env[trimmedKey] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 这里可以添加实际的启动逻辑
|
||||
logger.info('启动配置:', {
|
||||
@ -340,6 +363,18 @@ const CodeToolsPage: FC = () => {
|
||||
</Space.Compact>
|
||||
</SettingsItem>
|
||||
|
||||
<SettingsItem>
|
||||
<div className="settings-label">{t('code.environment_variables')}</div>
|
||||
<Input.TextArea
|
||||
placeholder={`KEY1=value1\nKEY2=value2`}
|
||||
value={environmentVariables}
|
||||
onChange={handleEnvVarsChange}
|
||||
rows={2}
|
||||
style={{ fontFamily: 'monospace' }}
|
||||
/>
|
||||
<div style={{ fontSize: 12, color: 'var(--color-text-3)', marginTop: 4 }}>{t('code.env_vars_help')}</div>
|
||||
</SettingsItem>
|
||||
|
||||
<SettingsItem>
|
||||
<div className="settings-label">{t('code.update_options')}</div>
|
||||
<Checkbox checked={autoUpdateToLatest} onChange={(e) => setAutoUpdateToLatest(e.target.checked)}>
|
||||
|
||||
@ -9,6 +9,8 @@ export interface CodeToolsState {
|
||||
selectedCliTool: string
|
||||
// 为每个 CLI 工具单独保存选择的模型
|
||||
selectedModels: Record<string, Model | null>
|
||||
// 为每个 CLI 工具单独保存环境变量
|
||||
environmentVariables: Record<string, string>
|
||||
// 记录用户选择过的所有目录,支持增删
|
||||
directories: string[]
|
||||
// 当前选择的目录
|
||||
@ -22,6 +24,11 @@ export const initialState: CodeToolsState = {
|
||||
'claude-code': null,
|
||||
'gemini-cli': null
|
||||
},
|
||||
environmentVariables: {
|
||||
'qwen-code': '',
|
||||
'claude-code': '',
|
||||
'gemini-cli': ''
|
||||
},
|
||||
directories: [],
|
||||
currentDirectory: ''
|
||||
}
|
||||
@ -40,6 +47,18 @@ const codeToolsSlice = createSlice({
|
||||
state.selectedModels[state.selectedCliTool] = action.payload
|
||||
},
|
||||
|
||||
// 设置环境变量(为当前 CLI 工具设置)
|
||||
setEnvironmentVariables: (state, action: PayloadAction<string>) => {
|
||||
if (!state.environmentVariables) {
|
||||
state.environmentVariables = {
|
||||
'qwen-code': '',
|
||||
'claude-code': '',
|
||||
'gemini-cli': ''
|
||||
}
|
||||
}
|
||||
state.environmentVariables[state.selectedCliTool] = action.payload
|
||||
},
|
||||
|
||||
// 添加目录到列表中
|
||||
addDirectory: (state, action: PayloadAction<string>) => {
|
||||
const directory = action.payload
|
||||
@ -87,14 +106,11 @@ const codeToolsSlice = createSlice({
|
||||
|
||||
// 重置所有设置
|
||||
resetCodeTools: (state) => {
|
||||
state.selectedCliTool = 'qwen-code'
|
||||
state.selectedModels = {
|
||||
'qwen-code': null,
|
||||
'claude-code': null,
|
||||
'gemini-cli': null
|
||||
}
|
||||
state.directories = []
|
||||
state.currentDirectory = ''
|
||||
state.selectedCliTool = initialState.selectedCliTool
|
||||
state.selectedModels = initialState.selectedModels
|
||||
state.environmentVariables = initialState.environmentVariables
|
||||
state.directories = initialState.directories
|
||||
state.currentDirectory = initialState.currentDirectory
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -102,6 +118,7 @@ const codeToolsSlice = createSlice({
|
||||
export const {
|
||||
setSelectedCliTool,
|
||||
setSelectedModel,
|
||||
setEnvironmentVariables,
|
||||
addDirectory,
|
||||
removeDirectory,
|
||||
setCurrentDirectory,
|
||||
|
||||
@ -2123,6 +2123,13 @@ const migrateConfig = {
|
||||
'133': (state: RootState) => {
|
||||
try {
|
||||
state.settings.sidebarIcons.visible.push('code_tools')
|
||||
if (state.codeTools) {
|
||||
state.codeTools.environmentVariables = {
|
||||
'qwen-code': '',
|
||||
'claude-code': '',
|
||||
'gemini-cli': ''
|
||||
}
|
||||
}
|
||||
return state
|
||||
} catch (error) {
|
||||
logger.error('migrate 133 error', error as Error)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user