mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-07 06:57:40 +00:00
feat: Google's gemini-cli integration (#422)
* feat: integrate Gemini AI agent provider - Core Backend: Ported gemini-cli.js and gemini-response-handler.js to establish the CLI bridge. Registered 'gemini' as an active provider within index.js. - Core Frontend: Extended QuickSettingsPanel.jsx, Settings.jsx, and AgentListItem.jsx to render the Gemini provider option, models (gemini-pro, gemini-flash, etc.), and handle OAuth states. - WebSocket Pipeline: Added support for gemini-command executions in backend and payload processing of gemini-response and gemini-error streams in useChatRealtimeHandlers.ts. Resolved JSON double-stringification and sessionId stripping issues in the transmission handler. - Platform Compatibility: Added scripts/fix-node-pty.js postinstall script and modified posix_spawnp calls with sh -c wrapper to prevent ENOEXEC and MacOS permission errors when spawning the gemini headless binary. - UX & Design: Imported official Google Gemini branding via GeminiLogo.jsx and gemini-ai-icon.svg. Updated translations (chat.json) for en, zh-CN, and ko locales. * fix: propagate gemini permission mode from settings to cli - Added Gemini Permissions UI in Settings to toggle Auto Edit and YOLO modes - Synced gemini permission mode to localStorage - Passed permissionMode in useChatComposerState for Gemini commands - Mapped frontend permission modes to --yolo and --approval-mode options in gemini-cli.js * feat(gemini): Refactor Gemini CLI integration to use stream-json - Replaced regex buffering text-system with NDJSON stream parsing - Added fallback for restricted models like gemini-3.1-pro-preview * feat(gemini): Render tool_use and tool_result UI bubbles - Forwarded gemini tool NDJSON objects to the websocket - Added React state handlers in useChatRealtimeHandlers to match Claude's tool UI behavior * feat(gemini): Add native session resumption and UI token tracking - Captured cliSessionId from init events to map ClaudeCodeUI's chat sessionId directly into Gemini's internal session manager. - Updated gemini-cli.js spawn arguments to append the --resume proxy flag instead of naively dumping the accumulated chat history into the command prompt. - Handled result stream objects by proxying total_tokens back into the frontend's claude-status tracker to natively populate the UI label. - Eliminated gemini-3 model proxy filter entirely. * fix(gemini): Fix static 'Claude' name rendering in chat UI header - Added "gemini": "Gemini" translation strings to messageTypes across English, Korean, and Chinese loc dictionaries. - Updated AssistantThinkingIndicator and MessageComponent ternary checks to identify provider === 'gemini' and render the appropriate brand label instead of statically defaulting to Claude. * feat: Add Gemini session persistence API mapping and Sidebar UI * fix(gemini): Watch ~/.gemini/sessions for live UI updates Added the .gemini/sessions directory to PROVIDER_WATCH_PATHS so that Chokidar emits projects_updated websocket events when new Gemini sessions are created or modified, fixing live sidebar updates. * fix(gemini): Fix Gemini authentication status display in Settings UI - Injected 'checkGeminiAuthStatus' into the Settings.jsx React effect hook so that the UI can poll and render the 'geminiAuthStatus' state. - Updated 'checkGeminiCredentials()' inside server/routes/cli-auth.js to read from '~/.gemini/oauth_creds.json' and '~/.gemini/google_accounts.json', resolving the email address correctly. * Use logo-only icon for gemini * feat(gemini): Add Gemini 3 preview models to UI selection list * Fix Gemini CLI session resume bug and PR #422 review nitpicks * Fix Gemini tool calls disappearing from UI after completion * fix(gemini): resolve outstanding PR #422 feedback and stabilize gemini CLI timeouts * fix(gemini): resolve resume flag and shell session initialization issues This commit addresses the remaining PR comments for the Gemini CLI integration: - Moves the `--resume` flag logic outside the prompt command block, ensuring Gemini sessions correctly resume even when a new prompt isn't passed. - Updates `handleShellConnection` to correctly lookup the native `cliSessionId` from the internal `sessionId` when spawning Gemini sessions in a plain shell. - Refactors dynamic import of `sessionManager.js` back to a native static import for code consistency. * chore: fix TypeScript errors and remove gemini CLI dependency * fix: use cross-spawn on Windows to resolve gemini.cmd correctly --------- Co-authored-by: Haileyesus <118998054+blackmammoth@users.noreply.github.com>
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
"tool": "Tool",
|
||||
"claude": "Claude",
|
||||
"cursor": "Cursor",
|
||||
"codex": "Codex"
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini"
|
||||
},
|
||||
"tools": {
|
||||
"settings": "Tool Settings",
|
||||
@@ -93,6 +94,24 @@
|
||||
},
|
||||
"technicalDetails": "Technical details"
|
||||
},
|
||||
"gemini": {
|
||||
"permissionMode": "Gemini Permission Mode",
|
||||
"description": "Control how Gemini CLI handles operation approvals.",
|
||||
"modes": {
|
||||
"default": {
|
||||
"title": "Standard (Ask for Approval)",
|
||||
"description": "Gemini will prompt for approval before executing commands, writing files, and fetching web resources."
|
||||
},
|
||||
"autoEdit": {
|
||||
"title": "Auto Edit (Skip File Approvals)",
|
||||
"description": "Gemini will automatically approve file edits and web fetches, but will still prompt for shell commands."
|
||||
},
|
||||
"yolo": {
|
||||
"title": "YOLO (Bypass All Permissions)",
|
||||
"description": "Gemini will execute all operations without asking for approval. Exercise caution."
|
||||
}
|
||||
}
|
||||
},
|
||||
"input": {
|
||||
"placeholder": "Type / for commands, @ for files, or ask {{provider}} anything...",
|
||||
"placeholderDefault": "Type your message...",
|
||||
@@ -153,12 +172,14 @@
|
||||
"providerInfo": {
|
||||
"anthropic": "by Anthropic",
|
||||
"openai": "by OpenAI",
|
||||
"cursorEditor": "AI Code Editor"
|
||||
"cursorEditor": "AI Code Editor",
|
||||
"google": "by Google"
|
||||
},
|
||||
"readyPrompt": {
|
||||
"claude": "Ready to use Claude with {{model}}. Start typing your message below.",
|
||||
"cursor": "Ready to use Cursor with {{model}}. Start typing your message below.",
|
||||
"codex": "Ready to use Codex with {{model}}. Start typing your message below.",
|
||||
"gemini": "Ready to use Gemini with {{model}}. Start typing your message below.",
|
||||
"default": "Select a provider above to begin"
|
||||
}
|
||||
},
|
||||
@@ -214,4 +235,4 @@
|
||||
"tasks": {
|
||||
"nextTaskPrompt": "Start the next task"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,8 @@
|
||||
"tool": "도구",
|
||||
"claude": "Claude",
|
||||
"cursor": "Cursor",
|
||||
"codex": "Codex"
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini"
|
||||
},
|
||||
"tools": {
|
||||
"settings": "도구 설정",
|
||||
@@ -151,15 +152,17 @@
|
||||
"description": "새 대화를 시작할 프로바이더를 선택하세요",
|
||||
"selectModel": "모델 선택",
|
||||
"providerInfo": {
|
||||
"anthropic": "by Anthropic",
|
||||
"openai": "by OpenAI",
|
||||
"cursorEditor": "AI 코드 에디터"
|
||||
"anthropic": "Anthropic 제공",
|
||||
"openai": "OpenAI 제공",
|
||||
"cursorEditor": "AI 코드 에디터",
|
||||
"google": "Google 제공"
|
||||
},
|
||||
"readyPrompt": {
|
||||
"claude": "{{model}}로 Claude를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"cursor": "{{model}}로 Cursor를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"codex": "{{model}}로 Codex를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"default": "시작하려면 위에서 프로바이더를 선택하세요"
|
||||
"claude": "{{model}} 모델로 Claude를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"cursor": "{{model}} 모델로 Cursor를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"codex": "{{model}} 모델로 Codex를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"gemini": "{{model}} 모델로 Gemini를 사용할 준비가 되었습니다. 아래에 메시지를 입력하세요.",
|
||||
"default": "시작하려면 위에서 제공자를 선택하세요"
|
||||
}
|
||||
},
|
||||
"session": {
|
||||
@@ -214,4 +217,4 @@
|
||||
"tasks": {
|
||||
"nextTaskPrompt": "다음 작업 시작"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,8 @@
|
||||
"tool": "工具",
|
||||
"claude": "Claude",
|
||||
"cursor": "Cursor",
|
||||
"codex": "Codex"
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini"
|
||||
},
|
||||
"tools": {
|
||||
"settings": "工具设置",
|
||||
@@ -151,15 +152,17 @@
|
||||
"description": "选择一个供应商以开始新对话",
|
||||
"selectModel": "选择模型",
|
||||
"providerInfo": {
|
||||
"anthropic": "Anthropic",
|
||||
"openai": "OpenAI",
|
||||
"cursorEditor": "AI 代码编辑器"
|
||||
"anthropic": "由 Anthropic 提供",
|
||||
"openai": "由 OpenAI 提供",
|
||||
"cursorEditor": "AI 代码编辑器",
|
||||
"google": "由 Google 提供"
|
||||
},
|
||||
"readyPrompt": {
|
||||
"claude": "已准备好使用 Claude {{model}}。在下方输入您的消息。",
|
||||
"cursor": "已准备好使用 Cursor {{model}}。在下方输入您的消息。",
|
||||
"codex": "已准备好使用 Codex {{model}}。在下方输入您的消息。",
|
||||
"default": "请在上方选择一个供应商以开始"
|
||||
"claude": "准备好使用带有 {{model}} 的 Claude。请在下方开始输入您的消息。",
|
||||
"cursor": "准备好使用带有 {{model}} 的 Cursor。请在下方开始输入您的消息。",
|
||||
"codex": "准备好使用带有 {{model}} 的 Codex。请在下方开始输入您的消息。",
|
||||
"gemini": "准备好使用带有 {{model}} 的 Gemini。请在下方开始输入您的消息。",
|
||||
"default": "请在上方选择一个提供者以开始"
|
||||
}
|
||||
},
|
||||
"session": {
|
||||
@@ -214,4 +217,4 @@
|
||||
"tasks": {
|
||||
"nextTaskPrompt": "开始下一个任务"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user