Skip to content

Commit 5068b55

Browse files
committed
Merge branch 'master' into 'opensource'
sync changes to latest See merge request ai_native/DeepVCode/DeepVcodeClient!337
2 parents 359c905 + 08a5a13 commit 5068b55

9 files changed

Lines changed: 369 additions & 175 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,4 @@
153153
"ink": "npm:@jrichman/ink@6.4.7",
154154
"wrap-ansi": "^7.0.0"
155155
}
156-
}
156+
}

packages/cli/src/ui/components/WelcomeScreen.tsx

Lines changed: 50 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { Box, Text } from 'ink';
1111
import { Colors } from '../colors.js';
1212
import { type Config, SessionManager, ProxyAuthManager } from 'deepv-code-core';
1313
import { t } from '../utils/i18n.js';
14-
import path from 'path';
1514
import { cuteVLogo } from './AsciiArt.js';
1615
import { getShortModelName } from '../utils/footerUtils.js';
1716

@@ -26,9 +25,8 @@ interface RecentSessionDisplay {
2625
description: string;
2726
}
2827

29-
// 每日技巧键名列表 - 从 i18n 中获取实际文本(只保留最有用的)
28+
// 每日技巧键名列表 - 从 i18n 中获取
3029
const DAILY_TIP_KEYS = [
31-
// 斜杠命令 - 最实用的
3230
'tip.help',
3331
'tip.theme',
3432
'tip.auth',
@@ -42,64 +40,37 @@ const DAILY_TIP_KEYS = [
4240
'tip.docs',
4341
'tip.session',
4442
'tip.restore',
45-
46-
// 特殊输入符号
4743
'tip.at.filepath',
4844
'tip.shell.command',
4945
'tip.shell.mode',
50-
51-
// 快捷键 - 只保留最常用的
5246
'tip.ctrl.j',
53-
54-
// CLI 启动参数
5547
'tip.cli.update',
5648
'tip.cli.cloud',
5749
];
5850

59-
// 格式化相对时间
60-
function formatRelativeTime(date: Date): string {
61-
const now = new Date();
62-
const diffMs = now.getTime() - date.getTime();
63-
const diffMins = Math.floor(diffMs / 60000);
64-
const diffHours = Math.floor(diffMs / 3600000);
65-
const diffDays = Math.floor(diffMs / 86400000);
66-
const diffWeeks = Math.floor(diffMs / 604800000);
67-
68-
if (diffMins < 1) return 'just now';
69-
if (diffMins < 60) return `${diffMins}m ago`;
70-
if (diffHours < 24) return `${diffHours}h ago`;
71-
if (diffDays < 7) return `${diffDays}d ago`;
72-
return `${diffWeeks}w ago`;
73-
}
74-
7551
export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({
7652
config,
7753
version,
78-
customProxyUrl,
7954
}) => {
80-
// 直接同步获取用户名,不使用 state
8155
const userName = useMemo(() => {
8256
const authManager = ProxyAuthManager.getInstance();
8357
const userInfo = authManager.getUserInfo();
8458
return userInfo?.name;
8559
}, []);
8660

87-
// 获取当前模型和 credits 信息
8861
const modelInfo = useMemo(() => {
8962
const currentModel = config.getModel();
9063
const cloudModelInfo = config.getCloudModelInfo(currentModel);
9164

9265
if (cloudModelInfo) {
9366
const credits = cloudModelInfo.creditsPerRequest;
94-
// 使用简化的模型名称(中等缩写)
9567
const shortName = getShortModelName(cloudModelInfo.displayName, true);
9668
return {
9769
displayName: shortName,
9870
creditsText: `${credits}x credits`,
9971
};
10072
}
10173

102-
// 如果没有 cloud model info,使用基本信息
10374
const modelName = currentModel === 'auto' ? 'Gemini' : currentModel;
10475
const shortName = getShortModelName(modelName, true);
10576
return {
@@ -110,113 +81,93 @@ export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({
11081

11182
const [recentSessions, setRecentSessions] = useState<RecentSessionDisplay[]>([]);
11283

113-
// 获取最近会话
11484
useEffect(() => {
11585
const loadRecentSessions = async () => {
116-
// 🚀 启动优化:将非核心任务推迟执行
11786
await new Promise(resolve => setTimeout(resolve, 1000));
11887
try {
11988
const sessionManager = new SessionManager(config.getProjectRoot());
12089
const sessions = await sessionManager.listSessions();
12190

12291
const recentDisplays: RecentSessionDisplay[] = sessions
123-
.slice(0, 4)
92+
.slice(0, 1)
12493
.map(session => ({
125-
time: formatRelativeTime(new Date(session.lastActiveAt)),
94+
time: '',
12695
description: session.title || session.firstUserMessage?.slice(0, 30) || 'Untitled session',
12796
}));
12897

12998
setRecentSessions(recentDisplays);
13099
} catch (error) {
131-
// 忽略错误,不显示历史
100+
// 忽略错误
132101
}
133102
};
134103

135104
loadRecentSessions();
136105
}, [config]);
137106

138-
// 获取当前目录名称
139-
const currentDir = useMemo(() => {
140-
const fullPath = config.getProjectRoot();
141-
return path.basename(fullPath);
142-
}, [config]);
143-
144-
// 获取完整路径
145-
const fullPath = config.getProjectRoot();
146-
147107
// 随机选择一条每日技巧
148108
const dailyTip = useMemo(() => {
149109
const randomIndex = Math.floor(Math.random() * DAILY_TIP_KEYS.length);
150110
const tipKey = DAILY_TIP_KEYS[randomIndex];
151-
return t(tipKey as any); // 类型断言,因为技巧键是动态的
111+
const rawTip = t(tipKey as any);
112+
return rawTip
113+
.replace(/^Tip:\s*/i, '')
114+
.replace(/[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu, '')
115+
.trim();
152116
}, []);
153117

154-
// 友好的欢迎消息
155-
const welcomeMessage = userName ? `Welcome back, ${userName}!` : 'Welcome to DeepV Code!';
118+
const fullPath = config.getProjectRoot();
119+
const welcomeMessage = userName ? `Welcome back, ${userName}!` : 'Welcome back!';
120+
121+
// 处理 Logo 字符串
122+
const trimmedLogo = cuteVLogo.trim();
123+
124+
// 🎯 极致紧凑宽度
125+
const COMPACT_WIDTH = 68;
156126

157127
return (
158-
<Box flexDirection="column" marginBottom={1} borderStyle="round" borderColor="gray" paddingX={1} minWidth={80}>
159-
{/* 顶部标题行 - 包含像素机器人 logo */}
160-
<Box flexDirection="row" marginBottom={1}>
161-
<Box marginRight={2}>
162-
<Text color={Colors.AccentBlue}>{cuteVLogo}</Text>
163-
</Box>
164-
<Box flexDirection="column" justifyContent="center">
165-
<Text>DeepV Code </Text>
166-
<Text dimColor>v{version}</Text>
167-
<Text dimColor>{modelInfo.displayName} · {modelInfo.creditsText}</Text>
168-
</Box>
128+
<Box flexDirection="column" width={COMPACT_WIDTH} marginBottom={0}>
129+
{/* 顶部标题行 */}
130+
<Box justifyContent="space-between" paddingX={1}>
131+
<Text color={Colors.AccentBlue} bold>DeepV Code v{version}</Text>
132+
<Text dimColor wrap="truncate-middle">{fullPath}</Text>
169133
</Box>
170134

171-
{/* 用户欢迎信息 */}
172-
<Box>
173-
<Text color={Colors.AccentGreen}>{welcomeMessage}</Text>
174-
</Box>
135+
{/* 内容主体 */}
136+
<Box
137+
flexDirection="column"
138+
borderStyle="round"
139+
borderColor="gray"
140+
paddingX={1}
141+
paddingY={0}
142+
>
143+
<Box flexDirection="row" paddingX={0}>
144+
{/* 左侧:Logo 区域收缩宽度,移除偏移,让整体更内敛 */}
145+
<Box flexDirection="column" width={18} justifyContent="center" alignItems="center">
146+
<Text color={Colors.AccentBlue}>{trimmedLogo}</Text>
147+
</Box>
175148

176-
{/* 主内容区 - 左对齐布局 */}
177-
<Box flexDirection="column">
178-
{/* 项目路径 */}
179-
<Box>
180-
<Text dimColor>{fullPath}</Text>
181-
</Box>
149+
{/* 右侧:内容右对齐 */}
150+
<Box flexDirection="column" flexGrow={1} justifyContent="center" alignItems="flex-end" paddingLeft={1}>
151+
<Box>
152+
<Text color={Colors.AccentBlue} bold wrap="truncate-end">{welcomeMessage}</Text>
153+
</Box>
182154

183-
{/* Custom server info */}
184-
{customProxyUrl && (
185-
<Box flexDirection="column" marginBottom={1}>
186-
<Text color={Colors.AccentOrange}>🔗 Custom server: {customProxyUrl}</Text>
187-
<Text color={Colors.AccentOrange}> Please verify trustworthiness and monitor your API usage.</Text>
188-
</Box>
189-
)}
190-
191-
{/* Recent activity */}
192-
{recentSessions.length > 0 && (
193-
<Box flexDirection="column">
194-
<Text color={Colors.AccentOrange}>Recent activity</Text>
195-
<Box flexDirection="column">
196-
{recentSessions.map((session, idx) => (
197-
<Box key={idx}>
198-
<Text dimColor>{session.time.padEnd(10)}</Text>
199-
<Text>{session.description.slice(0, 30)}</Text>
200-
</Box>
201-
))}
202-
<Box>
203-
<Text dimColor>... /resume for more</Text>
204-
</Box>
155+
<Box>
156+
<Text dimColor wrap="truncate-end">{modelInfo.displayName}</Text>
205157
</Box>
206-
</Box>
207-
)}
208158

209-
{/* 每日技巧 */}
210-
<Box flexDirection="column">
211-
<Text>💡 {t('welcome.daily.tip.title')}</Text>
212-
<Box flexDirection="column">
213-
<Text>{dailyTip}</Text>
214159
<Box>
215-
<Text dimColor>{t('welcome.daily.tip.more')}</Text>
160+
<Text color={Colors.AccentCyan} wrap="truncate-end">{dailyTip}</Text>
216161
</Box>
162+
163+
{recentSessions.length > 0 && (
164+
<Box>
165+
<Text dimColor wrap="truncate-end">Last: {recentSessions[0].description}</Text>
166+
</Box>
167+
)}
217168
</Box>
218169
</Box>
219170
</Box>
220171
</Box>
221172
);
222-
};
173+
};

packages/core/src/core/DeepVServerAdapter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,8 @@ export class DeepVServerAdapter implements ContentGenerator {
11441144

11451145
if (newFc) {
11461146
// 合并基础字段
1147-
if (newFc.name) accFc.name = newFc.name;
1147+
// 🛡️ FIX: trim 工具名称,防止模型返回带空格的工具名
1148+
if (newFc.name) accFc.name = newFc.name.trim();
11481149
// 如果新分片有 ID,覆盖旧的(通常 ID 在第一个分片)
11491150
if (newFc.id) accFc.id = newFc.id;
11501151

0 commit comments

Comments
 (0)