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