7.1 KiB
7.1 KiB
删除文件确认功能实现文档
1. 功能概述
在 AI 返回删除文件命令时,前端拦截并弹出确认对话框,用户确认后才执行删除操作。
2. 架构设计
2.1 消息流程
AI 后端 → 删除文件工具调用 → 前端拦截 → 用户确认对话框
↓
确定/取消
↓
执行删除/返回取消结果
↓
返回 TOOL_EXECUTION_RESULT
↓
AI 后端
2.2 关键原则
前端必须返回结果:无论用户选择什么,前端都必须向后端返回 TOOL_EXECUTION_RESULT,否则后端会等待超时。
3. 实现方案
3.1 修改位置
文件:src/utils/messageHandler.ts
在处理工具调用的函数中,找到删除文件的工具处理逻辑。
3.2 核心代码实现
/**
* 处理删除文件工具调用(带用户确认)
*/
async function handleDeleteFileTool(
toolCall: any,
panel: vscode.WebviewPanel
): Promise<ToolExecutionResult> {
const filePath = toolCall.arguments.filePath; // 根据实际参数名调整
// 弹出确认对话框
const confirmed = await vscode.window.showWarningMessage(
`确定要删除文件吗?\n\n${filePath}`,
{
modal: true, // 模态对话框,阻止其他操作
detail: '此操作不可撤销'
},
'确定删除',
'取消'
);
// 用户确认删除
if (confirmed === '确定删除') {
try {
// 执行删除操作
const uri = vscode.Uri.file(filePath);
await vscode.workspace.fs.delete(uri, {
recursive: false, // 如果是目录需要设置为 true
useTrash: true // 移到回收站而非永久删除(推荐)
});
// 返回成功结果
return {
type: 'TOOL_EXECUTION_RESULT',
toolCallId: toolCall.id,
result: JSON.stringify({
success: true,
message: `文件已删除: ${filePath}`
})
};
} catch (error) {
// 删除失败
return {
type: 'TOOL_EXECUTION_RESULT',
toolCallId: toolCall.id,
result: JSON.stringify({
success: false,
error: `删除失败: ${error.message}`
})
};
}
}
// 用户取消或关闭对话框
return {
type: 'TOOL_EXECUTION_RESULT',
toolCallId: toolCall.id,
result: JSON.stringify({
success: false,
message: '用户取消了删除操作'
})
};
}
3.3 集成到消息处理流程
在 messageHandler.ts 的工具调用处理逻辑中:
// 示例:在处理工具调用的地方
async function handleToolCall(toolCall: any, panel: vscode.WebviewPanel) {
switch (toolCall.name) {
case 'deleteFile': // 根据实际工具名称调整
return await handleDeleteFileTool(toolCall, panel);
case 'deleteDirectory': // 如果有删除目录的工具
return await handleDeleteDirectoryTool(toolCall, panel);
// ... 其他工具
}
}
4. 用户体验优化
4.1 对话框样式
const confirmed = await vscode.window.showWarningMessage(
`确定要删除文件吗?\n\n📄 ${path.basename(filePath)}\n📁 ${path.dirname(filePath)}`,
{
modal: true,
detail: '⚠️ 文件将被移到回收站,可以恢复'
},
'确定删除',
'取消'
);
4.2 批量删除优化
如果 AI 一次返回多个删除操作:
// 方案 1:逐个确认
for (const file of filesToDelete) {
await handleDeleteFileTool(file, panel);
}
// 方案 2:批量确认(推荐)
const confirmed = await vscode.window.showWarningMessage(
`确定要删除以下 ${filesToDelete.length} 个文件吗?\n\n${filesToDelete.join('\n')}`,
{ modal: true },
'全部删除',
'取消'
);
5. 安全考虑
5.1 使用回收站
await vscode.workspace.fs.delete(uri, {
useTrash: true // 移到回收站,可恢复
});
5.2 路径验证
// 防止删除工作区外的文件
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders) {
return { success: false, error: '未打开工作区' };
}
const isInWorkspace = workspaceFolders.some(folder =>
filePath.startsWith(folder.uri.fsPath)
);
if (!isInWorkspace) {
return { success: false, error: '只能删除工作区内的文件' };
}
5.3 敏感文件保护
const protectedFiles = [
'package.json',
'tsconfig.json',
'.git',
'node_modules'
];
const fileName = path.basename(filePath);
if (protectedFiles.includes(fileName)) {
vscode.window.showErrorMessage(`不允许删除系统文件: ${fileName}`);
return { success: false, error: '受保护的文件' };
}
6. 错误处理
6.1 常见错误
try {
await vscode.workspace.fs.delete(uri, { useTrash: true });
} catch (error) {
if (error.code === 'FileNotFound') {
return { success: false, error: '文件不存在' };
}
if (error.code === 'NoPermissions') {
return { success: false, error: '没有删除权限' };
}
return { success: false, error: error.message };
}
7. 测试场景
7.1 基本测试
- 用户点击"确定删除" → 文件被删除
- 用户点击"取消" → 文件保留,返回取消消息
- 用户关闭对话框 → 文件保留,返回取消消息
- 文件不存在 → 返回错误消息
- 没有删除权限 → 返回错误消息
7.2 边界测试
- 删除工作区外的文件 → 拒绝
- 删除受保护文件 → 拒绝
- 批量删除 → 正确处理
- 后端收到取消消息后继续对话 → 流程正常
8. 配置选项(可选)
可以添加用户设置来控制行为:
// package.json
"configuration": {
"properties": {
"ic-coder.confirmDelete": {
"type": "boolean",
"default": true,
"description": "删除文件前是否需要确认"
},
"ic-coder.useTrash": {
"type": "boolean",
"default": true,
"description": "删除文件时移到回收站而非永久删除"
}
}
}
读取配置:
const config = vscode.workspace.getConfiguration('ic-coder');
const needConfirm = config.get<boolean>('confirmDelete', true);
const useTrash = config.get<boolean>('useTrash', true);
if (needConfirm) {
// 弹出确认对话框
}
9. 总结
9.1 后端是否需要修改?
不需要。后端继续返回删除工具调用,前端负责:
- 拦截工具调用
- 弹出确认对话框
- 执行或取消删除
- 必须返回结果给后端
9.2 关键要点
- ✅ 前端必须返回
TOOL_EXECUTION_RESULT - ✅ 使用
useTrash: true提高安全性 - ✅ 验证文件路径在工作区内
- ✅ 保护敏感文件
- ✅ 提供清晰的错误消息
9.3 下一步
- 在
messageHandler.ts中找到工具调用处理逻辑 - 实现
handleDeleteFileTool函数 - 集成到现有流程
- 测试各种场景
- 考虑添加用户配置选项