diff --git a/src/components/ChatInterface.jsx b/src/components/ChatInterface.jsx index 37943c6..7314a74 100644 --- a/src/components/ChatInterface.jsx +++ b/src/components/ChatInterface.jsx @@ -238,6 +238,7 @@ const safeLocalStorage = { const CLAUDE_SETTINGS_KEY = 'claude-settings'; const TOOL_PERMISSION_ERROR_REGEX = /requested permissions? to use\s+([^.,\n]+)/i; +const BASH_APPROVAL_REGEX = /requires approval:\s*([^\n]+)/i; function safeJsonParse(value) { if (!value || typeof value !== 'string') return null; @@ -296,17 +297,38 @@ function buildClaudeToolPermissionEntry(toolName, toolInput) { return `Bash(${tokens[0]}:*)`; } +function getBashCommandLabel(command) { + if (!command || typeof command !== 'string') return 'Bash'; + const tokens = command.trim().split(/\s+/); + if (tokens.length === 0) return 'Bash'; + if (tokens[0] === 'git' && tokens[1]) { + return `git ${tokens[1]}`; + } + return tokens[0]; +} + function getClaudePermissionSuggestion(message, provider) { if (provider !== 'claude') return null; if (!message?.toolResult?.isError) return null; const content = String(message.toolResult.content || ''); - if (!TOOL_PERMISSION_ERROR_REGEX.test(content)) return null; + let toolName = null; + let entry = null; const match = content.match(TOOL_PERMISSION_ERROR_REGEX); - const requestedTool = match?.[1]?.trim(); - const toolName = requestedTool || message.toolName; - const entry = buildClaudeToolPermissionEntry(toolName, message.toolInput); + if (match) { + const requestedTool = match?.[1]?.trim(); + toolName = requestedTool || message.toolName; + entry = buildClaudeToolPermissionEntry(toolName, message.toolInput); + } else if (message.toolName === 'Bash') { + const approvalMatch = content.match(BASH_APPROVAL_REGEX); + const command = approvalMatch?.[1]?.trim(); + if (command) { + entry = buildClaudeToolPermissionEntry('Bash', JSON.stringify({ command })); + toolName = getBashCommandLabel(command); + } + } + if (!entry) return null; const settings = getClaudeSettings();