mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 06:30:10 +08:00
feat: add Git Bash detection and requirement check for Windows agents (#11388)
* feat: add Git Bash detection and requirement check for Windows agents - Add System_CheckGitBash IPC channel for detecting Git Bash installation - Implement detection logic checking common installation paths and PATH environment - Display non-closable error alert in AgentModal when Git Bash is not found - Disable agent creation/edit button until Git Bash is installed - Add recheck functionality to verify installation without restarting app Git Bash is required for agents to function properly on Windows systems. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * i18n: add Git Bash requirement translations for agent modal - Add English translations for Git Bash detection warnings - Add Simplified Chinese (zh-cn) translations - Add Traditional Chinese (zh-tw) translations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * format code --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
eee49d1580
commit
852192dce6
@ -235,6 +235,7 @@ export enum IpcChannel {
|
||||
System_GetDeviceType = 'system:getDeviceType',
|
||||
System_GetHostname = 'system:getHostname',
|
||||
System_GetCpuName = 'system:getCpuName',
|
||||
System_CheckGitBash = 'system:checkGitBash',
|
||||
|
||||
// DevTools
|
||||
System_ToggleDevTools = 'system:toggleDevTools',
|
||||
|
||||
@ -493,6 +493,44 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
||||
ipcMain.handle(IpcChannel.System_GetDeviceType, () => (isMac ? 'mac' : isWin ? 'windows' : 'linux'))
|
||||
ipcMain.handle(IpcChannel.System_GetHostname, () => require('os').hostname())
|
||||
ipcMain.handle(IpcChannel.System_GetCpuName, () => require('os').cpus()[0].model)
|
||||
ipcMain.handle(IpcChannel.System_CheckGitBash, () => {
|
||||
if (!isWin) {
|
||||
return true // Non-Windows systems don't need Git Bash
|
||||
}
|
||||
|
||||
try {
|
||||
// Check common Git Bash installation paths
|
||||
const commonPaths = [
|
||||
path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Git', 'bin', 'bash.exe'),
|
||||
path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'Git', 'bin', 'bash.exe'),
|
||||
path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Git', 'bin', 'bash.exe')
|
||||
]
|
||||
|
||||
// Check if any of the common paths exist
|
||||
for (const bashPath of commonPaths) {
|
||||
if (fs.existsSync(bashPath)) {
|
||||
logger.debug('Git Bash found', { path: bashPath })
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check if git is in PATH
|
||||
const { execSync } = require('child_process')
|
||||
try {
|
||||
execSync('git --version', { stdio: 'ignore' })
|
||||
logger.debug('Git found in PATH')
|
||||
return true
|
||||
} catch {
|
||||
// Git not in PATH
|
||||
}
|
||||
|
||||
logger.debug('Git Bash not found on Windows system')
|
||||
return false
|
||||
} catch (error) {
|
||||
logger.error('Error checking Git Bash', error as Error)
|
||||
return false
|
||||
}
|
||||
})
|
||||
ipcMain.handle(IpcChannel.System_ToggleDevTools, (e) => {
|
||||
const win = BrowserWindow.fromWebContents(e.sender)
|
||||
win && win.webContents.toggleDevTools()
|
||||
|
||||
@ -122,7 +122,8 @@ const api = {
|
||||
system: {
|
||||
getDeviceType: () => ipcRenderer.invoke(IpcChannel.System_GetDeviceType),
|
||||
getHostname: () => ipcRenderer.invoke(IpcChannel.System_GetHostname),
|
||||
getCpuName: () => ipcRenderer.invoke(IpcChannel.System_GetCpuName)
|
||||
getCpuName: () => ipcRenderer.invoke(IpcChannel.System_GetCpuName),
|
||||
checkGitBash: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.System_CheckGitBash)
|
||||
},
|
||||
devTools: {
|
||||
toggle: () => ipcRenderer.invoke(IpcChannel.System_ToggleDevTools)
|
||||
|
||||
@ -15,7 +15,7 @@ import type {
|
||||
UpdateAgentForm
|
||||
} from '@renderer/types'
|
||||
import { AgentConfigurationSchema, isAgentType } from '@renderer/types'
|
||||
import { Button, Input, Modal, Select } from 'antd'
|
||||
import { Alert, Button, Input, Modal, Select } from 'antd'
|
||||
import { AlertTriangleIcon } from 'lucide-react'
|
||||
import type { ChangeEvent, FormEvent } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
@ -58,6 +58,7 @@ const PopupContainer: React.FC<Props> = ({ agent, afterSubmit, resolve }) => {
|
||||
const isEditing = (agent?: AgentWithTools) => agent !== undefined
|
||||
|
||||
const [form, setForm] = useState<BaseAgentForm>(() => buildAgentForm(agent))
|
||||
const [hasGitBash, setHasGitBash] = useState<boolean>(true)
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
@ -65,6 +66,30 @@ const PopupContainer: React.FC<Props> = ({ agent, afterSubmit, resolve }) => {
|
||||
}
|
||||
}, [agent, open])
|
||||
|
||||
const checkGitBash = useCallback(
|
||||
async (showToast = false) => {
|
||||
try {
|
||||
const gitBashInstalled = await window.api.system.checkGitBash()
|
||||
setHasGitBash(gitBashInstalled)
|
||||
if (showToast) {
|
||||
if (gitBashInstalled) {
|
||||
window.toast.success(t('agent.gitBash.success', 'Git Bash detected successfully!'))
|
||||
} else {
|
||||
window.toast.error(t('agent.gitBash.notFound', 'Git Bash not found. Please install it first.'))
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to check Git Bash:', error as Error)
|
||||
setHasGitBash(true) // Default to true on error to avoid false warnings
|
||||
}
|
||||
},
|
||||
[t]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
checkGitBash()
|
||||
}, [checkGitBash])
|
||||
|
||||
const selectedPermissionMode = form.configuration?.permission_mode ?? 'default'
|
||||
|
||||
const onPermissionModeChange = useCallback((value: PermissionMode) => {
|
||||
@ -275,6 +300,36 @@ const PopupContainer: React.FC<Props> = ({ agent, afterSubmit, resolve }) => {
|
||||
footer={null}>
|
||||
<StyledForm onSubmit={onSubmit}>
|
||||
<FormContent>
|
||||
{!hasGitBash && (
|
||||
<Alert
|
||||
message={t('agent.gitBash.error.title', 'Git Bash Required')}
|
||||
description={
|
||||
<div>
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
{t(
|
||||
'agent.gitBash.error.description',
|
||||
'Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from'
|
||||
)}{' '}
|
||||
<a
|
||||
href="https://git-scm.com/download/win"
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
window.api.openWebsite('https://git-scm.com/download/win')
|
||||
}}
|
||||
style={{ textDecoration: 'underline' }}>
|
||||
git-scm.com
|
||||
</a>
|
||||
</div>
|
||||
<Button size="small" onClick={() => checkGitBash(true)}>
|
||||
{t('agent.gitBash.error.recheck', 'Recheck Git Bash Installation')}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
type="error"
|
||||
showIcon
|
||||
style={{ marginBottom: 16 }}
|
||||
/>
|
||||
)}
|
||||
<FormRow>
|
||||
<FormItem style={{ flex: 1 }}>
|
||||
<Label>
|
||||
@ -377,7 +432,7 @@ const PopupContainer: React.FC<Props> = ({ agent, afterSubmit, resolve }) => {
|
||||
|
||||
<FormFooter>
|
||||
<Button onClick={onCancel}>{t('common.close')}</Button>
|
||||
<Button type="primary" htmlType="submit" loading={loadingRef.current}>
|
||||
<Button type="primary" htmlType="submit" loading={loadingRef.current} disabled={!hasGitBash}>
|
||||
{isEditing(agent) ? t('common.confirm') : t('common.add')}
|
||||
</Button>
|
||||
</FormFooter>
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "Agent ID is null."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "Recheck Git Bash Installation",
|
||||
"title": "Git Bash Required"
|
||||
},
|
||||
"notFound": "Git Bash not found. Please install it first.",
|
||||
"success": "Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "智能体 ID 为空。"
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "在 Windows 上运行智能体需要 Git Bash。没有它智能体无法运行。请从以下地址安装 Git for Windows",
|
||||
"recheck": "重新检测 Git Bash 安装",
|
||||
"title": "需要 Git Bash"
|
||||
},
|
||||
"notFound": "未找到 Git Bash。请先安装。",
|
||||
"success": "成功检测到 Git Bash!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "在这里输入消息,按 {{key}} 发送 - @ 选择路径, / 选择命令"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "代理程式 ID 為空。"
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "在 Windows 上執行代理程式需要 Git Bash。沒有它代理程式無法運作。請從以下地址安裝 Git for Windows",
|
||||
"recheck": "重新檢測 Git Bash 安裝",
|
||||
"title": "需要 Git Bash"
|
||||
},
|
||||
"notFound": "找不到 Git Bash。請先安裝。",
|
||||
"success": "成功偵測到 Git Bash!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "Agent ID ist leer."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "Το ID του πράκτορα είναι null."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "El ID del agente es nulo."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "L'ID de l'agent est nul."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "エージェント ID が null です。"
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "O ID do agente é nulo."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
@ -27,6 +27,15 @@
|
||||
"null_id": "ID агента равен null."
|
||||
}
|
||||
},
|
||||
"gitBash": {
|
||||
"error": {
|
||||
"description": "[to be translated]:Git Bash is required to run agents on Windows. The agent cannot function without it. Please install Git for Windows from",
|
||||
"recheck": "[to be translated]:Recheck Git Bash Installation",
|
||||
"title": "[to be translated]:Git Bash Required"
|
||||
},
|
||||
"notFound": "[to be translated]:Git Bash not found. Please install it first.",
|
||||
"success": "[to be translated]:Git Bash detected successfully!"
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "[to be translated]:Enter your message here, send with {{key}} - @ select path, / select command"
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user