Skip to content

Commit ac95ee3

Browse files
author
catlog22
committed
feat: update CLI mode toggle for improved UI and functionality; refactor RecommendedMcpWizard API call; add new localization strings for installation wizard and tools
1 parent 8454ae4 commit ac95ee3

4 files changed

Lines changed: 100 additions & 46 deletions

File tree

ccw/frontend/src/components/mcp/CliModeToggle.tsx

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
// ========================================
22
// CLI Mode Toggle Component
33
// ========================================
4-
// Toggle between Claude and Codex CLI modes with config path display
4+
// Compact badge-style toggle between Claude and Codex CLI modes
55

66
import { useIntl } from 'react-intl';
77
import { Terminal, Cpu } from 'lucide-react';
8-
import { Button } from '@/components/ui/Button';
9-
import { Badge } from '@/components/ui/Badge';
108
import { cn } from '@/lib/utils';
119

1210
// ========== Types ==========
@@ -24,51 +22,35 @@ export interface CliModeToggleProps {
2422
export function CliModeToggle({
2523
currentMode,
2624
onModeChange,
27-
codexConfigPath,
2825
}: CliModeToggleProps) {
2926
const { formatMessage } = useIntl();
3027

3128
return (
32-
<div className="space-y-3">
33-
{/* Mode Toggle Buttons */}
34-
<div className="flex gap-2 p-1 bg-muted rounded-lg">
35-
<Button
36-
variant={currentMode === 'claude' ? 'default' : 'ghost'}
37-
size="sm"
38-
onClick={() => onModeChange('claude')}
39-
className={cn(
40-
'flex-1 gap-2',
41-
currentMode === 'claude' && 'shadow-sm'
42-
)}
43-
>
44-
<Terminal className="w-4 h-4" />
45-
<span>{formatMessage({ id: 'mcp.mode.claude' })}</span>
46-
</Button>
47-
<Button
48-
variant={currentMode === 'codex' ? 'default' : 'ghost'}
49-
size="sm"
50-
onClick={() => onModeChange('codex')}
51-
className={cn(
52-
'flex-1 gap-2',
53-
currentMode === 'codex' && 'shadow-sm'
54-
)}
55-
>
56-
<Cpu className="w-4 h-4" />
57-
<span>{formatMessage({ id: 'mcp.mode.codex' })}</span>
58-
</Button>
59-
</div>
60-
61-
{/* Codex Config Path Display */}
62-
{currentMode === 'codex' && codexConfigPath && (
63-
<div className="flex items-center gap-2 px-3 py-2 bg-muted/50 rounded-md border border-border">
64-
<Badge variant="outline" className="text-xs">
65-
{formatMessage({ id: 'mcp.codex.configPath' })}
66-
</Badge>
67-
<code className="text-xs text-muted-foreground font-mono truncate flex-1">
68-
{codexConfigPath}
69-
</code>
70-
</div>
71-
)}
29+
<div className="inline-flex items-center rounded-full border border-border bg-muted/50 p-0.5">
30+
<button
31+
onClick={() => onModeChange('claude')}
32+
className={cn(
33+
'inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium transition-all',
34+
currentMode === 'claude'
35+
? 'bg-primary text-primary-foreground shadow-sm'
36+
: 'text-muted-foreground hover:text-foreground'
37+
)}
38+
>
39+
<Terminal className="w-3.5 h-3.5" />
40+
{formatMessage({ id: 'mcp.mode.claude' })}
41+
</button>
42+
<button
43+
onClick={() => onModeChange('codex')}
44+
className={cn(
45+
'inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium transition-all',
46+
currentMode === 'codex'
47+
? 'bg-primary text-primary-foreground shadow-sm'
48+
: 'text-muted-foreground hover:text-foreground'
49+
)}
50+
>
51+
<Cpu className="w-3.5 h-3.5" />
52+
{formatMessage({ id: 'mcp.mode.codex' })}
53+
</button>
7254
</div>
7355
);
7456
}

ccw/frontend/src/components/mcp/RecommendedMcpWizard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { Label } from '@/components/ui/Label';
2121
import { Badge } from '@/components/ui/Badge';
2222
import {
2323
addGlobalMcpServer,
24-
addProjectMcpServer,
24+
copyMcpServerToProject,
2525
} from '@/lib/api';
2626
import { mcpServersKeys } from '@/hooks';
2727
import { useNotifications } from '@/hooks/useNotifications';
@@ -131,7 +131,7 @@ export function RecommendedMcpWizard({
131131
if (selectedScope === 'global') {
132132
return addGlobalMcpServer(mcpDefinition.id, serverConfig);
133133
} else {
134-
return addProjectMcpServer(mcpDefinition.id, serverConfig);
134+
return copyMcpServerToProject(mcpDefinition.id, serverConfig);
135135
}
136136
},
137137
onSuccess: (result) => {

ccw/frontend/src/locales/en/mcp-manager.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,42 @@
294294
"step2": "Or manually add the JSON config to your configuration file",
295295
"step3": "Restart your CLI to load the new server"
296296
},
297+
"configRequired": "config required",
298+
"noConfigNeeded": "No configuration needed",
299+
"reconfigure": "Reconfigure",
300+
"wizard": {
301+
"install": "Install",
302+
"installing": "Installing...",
303+
"installSuccess": "Server installed successfully",
304+
"installError": "Failed to install server",
305+
"validation": "Validation error",
306+
"requiredFields": "Please fill in all required fields",
307+
"scope": "Installation Scope",
308+
"scope.global": "Global (All projects)",
309+
"scope.project": "Project (Current project only)"
310+
},
311+
"ace-tool": {
312+
"name": "ACE Tool",
313+
"desc": "Advanced code search and context engine for intelligent code discovery",
314+
"field": {
315+
"baseUrl": "Base URL",
316+
"baseUrl.desc": "ACE MCP relay server endpoint",
317+
"token": "API Token",
318+
"token.desc": "Your ACE API token for authentication"
319+
}
320+
},
321+
"chrome-devtools": {
322+
"name": "Chrome DevTools",
323+
"desc": "Browser automation and debugging tools for web development"
324+
},
325+
"exa": {
326+
"name": "Exa Search",
327+
"desc": "AI-powered web search with real-time crawling capabilities",
328+
"field": {
329+
"apiKey": "API Key",
330+
"apiKey.desc": "Your Exa API key (optional, some features may require it)"
331+
}
332+
},
297333
"enterprise": {
298334
"label": "Enterprise",
299335
"tooltip": "Enterprise MCP server"

ccw/frontend/src/locales/zh/mcp-manager.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,42 @@
294294
"step2": "或将 JSON 配置手动添加到您的配置文件中",
295295
"step3": "重启您的 CLI 以加载新服务器"
296296
},
297+
"configRequired": "项配置",
298+
"noConfigNeeded": "无需配置",
299+
"reconfigure": "重新配置",
300+
"wizard": {
301+
"install": "安装",
302+
"installing": "安装中...",
303+
"installSuccess": "服务器安装成功",
304+
"installError": "服务器安装失败",
305+
"validation": "验证错误",
306+
"requiredFields": "请填写所有必填字段",
307+
"scope": "安装范围",
308+
"scope.global": "全局(所有项目)",
309+
"scope.project": "项目(仅当前项目)"
310+
},
311+
"ace-tool": {
312+
"name": "ACE 工具",
313+
"desc": "高级代码搜索和上下文引擎,用于智能代码发现",
314+
"field": {
315+
"baseUrl": "服务器地址",
316+
"baseUrl.desc": "ACE MCP 中继服务器端点",
317+
"token": "API 令牌",
318+
"token.desc": "用于认证的 ACE API 令牌"
319+
}
320+
},
321+
"chrome-devtools": {
322+
"name": "Chrome 开发者工具",
323+
"desc": "浏览器自动化和调试工具,用于 Web 开发"
324+
},
325+
"exa": {
326+
"name": "Exa 搜索",
327+
"desc": "AI 驱动的网络搜索,支持实时抓取",
328+
"field": {
329+
"apiKey": "API 密钥",
330+
"apiKey.desc": "您的 Exa API 密钥(可选,部分功能可能需要)"
331+
}
332+
},
297333
"enterprise": {
298334
"label": "企业版",
299335
"tooltip": "企业版 MCP 服务器"

0 commit comments

Comments
 (0)