# DesktopPet 本地工作区 Agent 开发文档 ## 0. 文档目标 本次开发目标不是继续维护旧版“文件操作 v1”,而是将其重构升级为一个类似 Codex / Claude Code 思路的 **本地工作区 Agent**。 新的功能定位: > 用户选择一个本地工作区目录后,桌宠可以读取、搜索、分析该目录内的文件,并在用户确认后创建、修改、移动、重命名或删除文件。 注意: 1. 不允许 AI 直接获得全盘文件权限。 2. 不允许 AI 自由执行系统命令。 3. 不允许永久删除文件。 4. 不允许绕过用户确认修改本地文件。 5. 所有写操作必须先生成计划,展示路径和风险,用户确认后才能执行。 6. 当前阶段优先实现文件级工具,不做 shell 命令执行。 ------ ## 1. 当前项目背景 当前项目是 QtDesktopPet,技术栈为: - C++17 - Qt 6 Widgets - Qt 6 Network - Qt 6 Multimedia - CMake - Windows 优先 当前项目已有: - 桌宠窗口 - 动画状态 - AI 对话 - 天气 - 提醒 - 本地应用启动 - 简单文件操作 v1 旧版文件操作 v1 只适合简单功能,例如: - 读取文本文件 - 列出文件夹 - 复制文件 - 备份文件 - 重命名文件 新的目标不是在旧版基础上打补丁,而是设计一个独立的工作区系统。 ------ ## 2. 总体开发原则 ### 2.1 先新增,后替换 不要一上来删除旧文件。 推荐流程: ```text 新增 workspace 模块 ↓ 实现只读能力 ↓ 实现写入计划和确认 ↓ 接入 PetWindow ↓ 确认能编译运行 ↓ 替换旧 FileOperationManager ↓ 最后删除旧文件操作模块 ``` ### 2.2 PetWindow 不承载业务逻辑 `PetWindow` 只负责 UI 展示和用户交互,不应该直接处理复杂文件逻辑。 新的业务逻辑应放到: ```text src/workspace/ src/assistant/ ``` `PetWindow` 只调用控制器,例如: ```cpp m_workspaceController->handleUserMessage(message); ``` ### 2.3 AI 不直接操作文件 AI 不能直接拿到文件系统权限。 正确流程是: ```text 用户输入 ↓ WorkspaceAgent 分析任务 ↓ 生成文件操作计划 ↓ 展示计划 ↓ 用户确认 ↓ WorkspaceTool 执行 ↓ 返回结果 ``` ------ ## 3. 功能范围 ## 3.1 第一阶段必须实现 第一阶段目标:**只读工作区分析 + 安全文件操作基础能力**。 必须支持: ```text 选择工作区 显示当前工作区 扫描工作区文件树 搜索文件名 搜索文本内容 读取文本文件 分析项目结构 总结文件内容 打开文件 打开文件夹 显示文件所在位置 创建文本文件 创建文件夹 修改文本文件 复制文件 移动文件 重命名文件 删除到回收站 记录最近操作 ``` 其中: - 读操作可以直接执行。 - 打开文件建议确认。 - 创建、修改、移动、重命名、删除必须确认。 - 删除只能移动到回收站。 - 修改文件必须备份或使用安全写入策略。 ------ ## 3.2 第一阶段禁止实现 以下功能第一阶段不要做: ```text 全盘搜索 永久删除 批量删除 批量移动 批量重命名 执行 shell 命令 运行脚本 运行 exe 自动 git commit 自动安装依赖 自动联网下载并执行文件 读取系统敏感目录 读取工作区外文件 ``` 后续如果需要运行命令,应作为第二阶段或第三阶段功能,并单独设计命令白名单和权限系统。 ------ # 4. 新模块目录结构 新增目录: ```text src/workspace/ ├── WorkspaceTypes.h ├── WorkspaceSession.h ├── WorkspaceSession.cpp ├── WorkspaceIndex.h ├── WorkspaceIndex.cpp ├── WorkspaceScanner.h ├── WorkspaceScanner.cpp ├── WorkspaceAccessPolicy.h ├── WorkspaceAccessPolicy.cpp ├── WorkspaceTool.h ├── WorkspaceToolRegistry.h ├── WorkspaceToolRegistry.cpp ├── WorkspaceAgent.h ├── WorkspaceAgent.cpp ├── WorkspaceController.h ├── WorkspaceController.cpp ├── WorkspaceHistory.h ├── WorkspaceHistory.cpp └── tools/ ├── ListFilesTool.h ├── ListFilesTool.cpp ├── ReadFileTool.h ├── ReadFileTool.cpp ├── SearchFilesTool.h ├── SearchFilesTool.cpp ├── SearchTextTool.h ├── SearchTextTool.cpp ├── OpenFileTool.h ├── OpenFileTool.cpp ├── CreateFileTool.h ├── CreateFileTool.cpp ├── CreateDirectoryTool.h ├── CreateDirectoryTool.cpp ├── WriteFileTool.h ├── WriteFileTool.cpp ├── CopyFileTool.h ├── CopyFileTool.cpp ├── MoveFileTool.h ├── MoveFileTool.cpp ├── RenameFileTool.h ├── RenameFileTool.cpp ├── DeleteToTrashTool.h └── DeleteToTrashTool.cpp ``` 旧目录 `src/fileops/` 暂时不要删除。等新模块完全接入后,再移除旧模块。 ------ # 5. 核心类型设计 ## 5.1 WorkspacePermissionMode ```cpp enum class WorkspacePermissionMode { ReadOnly, ConfirmBeforeWrite, Advanced }; ``` 说明: - `ReadOnly`:只能读、搜索、分析。 - `ConfirmBeforeWrite`:允许写,但每次写操作都必须确认。 - `Advanced`:预留,不在第一阶段实现自动写入。 第一阶段默认使用: ```cpp WorkspacePermissionMode::ConfirmBeforeWrite ``` 但所有写操作仍然必须确认。 ------ ## 5.2 WorkspaceToolRisk ```cpp enum class WorkspaceToolRisk { ReadOnly, Low, Medium, High, Dangerous }; ``` 风险等级说明: ```text ReadOnly: 搜索、列目录、读取普通文本文件。 Low: 打开文件夹、显示文件所在位置。 Medium: 打开普通文件、创建文件、创建文件夹、复制文件。 High: 修改文件、移动文件、重命名文件、删除到回收站。 Dangerous: 永久删除、执行命令、运行脚本、修改系统目录。 ``` 第一阶段遇到 `Dangerous` 直接拒绝。 ------ ## 5.3 WorkspaceFileInfo ```cpp struct WorkspaceFileInfo { QString relativePath; QString absolutePath; QString fileName; QString suffix; qint64 sizeBytes = 0; QDateTime lastModified; bool isDirectory = false; bool isTextFile = false; bool isHidden = false; }; ``` 用途: - 文件树展示 - 文件名搜索 - 后缀过滤 - 快速判断是否可读 ------ ## 5.4 WorkspaceActionPlan ```cpp enum class WorkspaceActionType { Unknown, ListFiles, SearchFiles, SearchText, ReadFile, OpenFile, OpenDirectory, RevealInExplorer, CreateFile, CreateDirectory, WriteFile, CopyFile, MoveFile, RenameFile, DeleteToTrash }; struct WorkspaceActionPlan { QString id; WorkspaceActionType type = WorkspaceActionType::Unknown; WorkspaceToolRisk risk = WorkspaceToolRisk::ReadOnly; QString title; QString description; QString sourcePath; QString targetPath; QString relativeSourcePath; QString relativeTargetPath; QString content; QString searchKeyword; QStringList warnings; bool requiresConfirmation = false; bool allowOverwrite = false; bool confirmed = false; }; ``` 注意: - 所有路径都必须是工作区内路径。 - `sourcePath` 和 `targetPath` 必须经过 `WorkspaceAccessPolicy` 校验。 - 写操作默认 `requiresConfirmation = true`。 - 第一阶段禁止覆盖文件,所以 `allowOverwrite` 默认必须是 false。 ------ ## 5.5 WorkspaceToolResult ```cpp struct WorkspaceToolResult { bool success = false; QString message; QString errorMessage; QString outputText; QString targetPath; QVector files; }; ``` ------ # 6. WorkspaceAccessPolicy 设计 这是最重要的安全模块。 ## 6.1 职责 `WorkspaceAccessPolicy` 负责: ```text 路径标准化 判断路径是否在工作区内 阻止 ../ 跳出工作区 阻止符号链接跳出工作区 阻止系统目录 阻止危险文件类型 阻止敏感文件默认读取 限制写入行为 限制删除行为 ``` ------ ## 6.2 必须实现的方法 ```cpp class WorkspaceAccessPolicy { public: explicit WorkspaceAccessPolicy(const QString &workspaceRoot); QString workspaceRoot() const; QString normalizePath(const QString &path) const; QString toAbsolutePath(const QString &relativeOrAbsolutePath) const; QString toRelativePath(const QString &absolutePath) const; bool isInsideWorkspace(const QString &path, QString *errorMessage = nullptr) const; bool hasSymlinkSegment(const QString &path, QString *errorMessage = nullptr) const; bool isSystemPath(const QString &path) const; bool isDangerousSuffix(const QString &path) const; bool isSensitiveFile(const QString &path) const; bool isSupportedTextFile(const QString &path) const; bool canReadFile(const QString &path, QString *errorMessage = nullptr) const; bool canReadDirectory(const QString &path, QString *errorMessage = nullptr) const; bool canCreateFile(const QString &path, QString *errorMessage = nullptr) const; bool canCreateDirectory(const QString &path, QString *errorMessage = nullptr) const; bool canWriteFile(const QString &path, QString *errorMessage = nullptr) const; bool canMoveFile(const QString &sourcePath, const QString &targetPath, QString *errorMessage = nullptr) const; bool canDeleteToTrash(const QString &path, QString *errorMessage = nullptr) const; }; ``` ------ ## 6.3 路径限制 所有操作必须满足: ```text 目标路径在 workspaceRoot 内 不能包含符号链接路径段 不能是 Windows 系统目录 不能是 Program Files 不能是 ProgramData 不能是回收站目录 不能是工作区外路径 ``` 禁止通过以下方式绕过: ```text ../ ..\ 符号链接 快捷方式跳转 相对路径混淆 大小写混淆 ``` ------ ## 6.4 危险后缀 第一阶段默认禁止写入、打开或执行以下文件: ```text .exe .bat .cmd .ps1 .vbs .msi .scr .reg .com .pif .lnk ``` 其中 `.lnk` 不要直接打开,因为它可能指向工作区外路径或脚本。 ------ ## 6.5 敏感文件 以下文件读取时必须强确认,第一阶段可以先默认拒绝: ```text .env *.pem *.key id_rsa id_ed25519 *.pfx *.p12 credentials.json secrets.json token.json ``` 如果文件名包含以下关键词,也视为敏感: ```text secret token password credential private apikey api_key ``` ------ # 7. WorkspaceScanner 和 WorkspaceIndex ## 7.1 WorkspaceScanner 负责扫描工作区。 建议使用: ```cpp QDirIterator ``` 扫描规则: ```text 最大递归深度:8 最大文件数量:5000 跳过隐藏目录 跳过 build 目录 跳过 .git 目录 跳过 node_modules 跳过 dist 跳过 release_packages 跳过 .vs 跳过 .vscode 可选 ``` 建议跳过目录: ```text .git .vs .idea build cmake-build-debug cmake-build-release node_modules dist release release_packages logs ``` ------ ## 7.2 WorkspaceIndex 负责保存扫描结果。 ```cpp class WorkspaceIndex { public: void clear(); void setFiles(const QVector &files); QVector allFiles() const; QVector findByName(const QString &keyword, int maxResults) const; QVector findBySuffix(const QStringList &suffixes, int maxResults) const; QVector recentFiles(int maxResults) const; private: QVector m_files; }; ``` 第一版不需要数据库,不需要向量索引,内存索引即可。 ------ # 8. 工具系统设计 ## 8.1 WorkspaceTool 抽象 ```cpp class WorkspaceTool { public: virtual ~WorkspaceTool() = default; virtual QString name() const = 0; virtual QString displayName() const = 0; virtual WorkspaceToolRisk risk() const = 0; virtual WorkspaceToolResult run(const WorkspaceActionPlan &plan) = 0; }; ``` 所有工具必须通过 `WorkspaceAccessPolicy` 校验路径。 ------ ## 8.2 ListFilesTool 功能: ```text 列出工作区某个目录下的文件和文件夹。 ``` 限制: ```text 只允许工作区内目录 最多显示 200 项 不递归或浅递归 ``` ------ ## 8.3 ReadFileTool 功能: ```text 读取文本文件。 ``` 限制: ```text 只读文本文件 最大读取 128KB 超出部分截断 敏感文件默认拒绝或强确认 不读取二进制文件 ``` 支持后缀: ```text .cpp .h .hpp .c cc py js ts json md txt ini xml yaml yml cmake pro css html ``` ------ ## 8.4 SearchFilesTool 功能: ```text 按文件名搜索。 ``` 限制: ```text 只搜索当前工作区索引 最多返回 30 个结果 按相关性和最近修改时间排序 ``` ------ ## 8.5 SearchTextTool 功能: ```text 在文本文件中搜索关键词。 ``` 限制: ```text 最多扫描 1000 个文本文件 单文件最大读取 128KB 最多返回 50 条匹配 每条匹配显示文件路径、行号、片段 ``` ------ ## 8.6 OpenFileTool 功能: ```text 用系统默认程序打开文件。 ``` 实现建议: ```cpp QDesktopServices::openUrl(QUrl::fromLocalFile(path)); ``` 限制: ```text 只能打开工作区内文件 危险后缀拒绝 敏感文件需要确认 ``` 打开文件夹同理。 ------ ## 8.7 RevealInExplorer 功能: ```text 在资源管理器中显示文件所在位置。 ``` Windows 可使用: ```cpp explorer.exe /select,"path" ``` 但第一阶段如果不想涉及命令,可以先打开所在文件夹。 ------ ## 8.8 CreateFileTool 功能: ```text 创建文本文件。 ``` 限制: ```text 只能在工作区内创建 目标文件不能已存在 文件名必须合法 危险后缀拒绝 写操作必须确认 ``` 建议使用 `QSaveFile` 或 `QFile` 创建。 ------ ## 8.9 WriteFileTool 功能: ```text 写入文本文件。 ``` 第一阶段建议只支持: ```text 新建文件写入 或 修改已有文本文件,但写入前自动备份 ``` 要求: ```text 写入前必须确认 写入前创建备份 禁止覆盖二进制文件 禁止写敏感文件 禁止写危险后缀 ``` 备份目录建议: ```text /.desktoppet/backups/ ``` 备份文件名建议: ```text relative_path.replace("/", "__") + "." + timestamp + ".bak" ``` ------ ## 8.10 CopyFileTool 限制: ```text 只能复制单文件 不能覆盖目标文件 源和目标都必须在工作区内 写操作必须确认 ``` ------ ## 8.11 MoveFileTool 限制: ```text 只能移动单文件 不能覆盖目标文件 源和目标都必须在工作区内 写操作必须确认 ``` ------ ## 8.12 RenameFileTool 限制: ```text 只能在同目录内重命名 不能覆盖目标文件 文件名不能包含路径分隔符 写操作必须确认 ``` ------ ## 8.13 DeleteToTrashTool 功能: ```text 移动到系统回收站。 ``` 实现建议: ```cpp QFile file(path); file.moveToTrash(); ``` 或根据 Qt 版本使用对应的 `moveToTrash` 方法。 限制: ```text 只允许工作区内文件 不做永久删除 删除文件夹需要强确认 删除敏感文件需要强确认 删除危险后缀文件需要强确认 ``` 第一阶段禁止批量删除。 ------ # 9. WorkspaceAgent 设计 ## 9.1 第一版采用半自动 Agent 第一版不要急着实现复杂 function calling。 建议采用半自动流程: ```text 用户输入 ↓ WorkspaceController 判断是否是工作区任务 ↓ 程序先根据关键词和工作区索引检索相关文件 ↓ 读取少量相关文件 ↓ 把文件树摘要、相关文件内容、用户问题交给模型 ↓ 模型返回分析结果或修改建议 ↓ 涉及写操作时生成 WorkspaceActionPlan ↓ 用户确认 ↓ 执行工具 ``` 这样比完全由模型自由调用工具更容易控制。 ------ ## 9.2 后续可升级为工具循环 未来可以升级为: ```text model ↓ tool call ↓ tool result ↓ model ↓ tool call ↓ ... ``` 但第一版不强制做。 ------ ## 9.3 工作区模式系统提示词 工作区模式不要使用普通桌宠聊天提示词。 新增工作区专用提示词: ```text 你是 QtDesktopPet 的本地工作区助手。 你只能基于用户授权的工作区文件进行分析。 你不能假设自己看过未读取的文件。 你不能要求访问工作区外路径。 你不能执行系统命令。 你不能生成危险操作指令。 涉及创建、修改、移动、重命名、删除文件时,必须先生成清晰的操作计划,等待用户确认。 涉及敏感文件、密钥、凭证时,必须提醒风险。 回答代码问题时要引用具体文件路径。 当信息不足时,说明还需要读取哪些文件。 ``` ------ # 10. WorkspaceController 设计 `WorkspaceController` 负责连接 UI 和工作区 Agent。 建议接口: ```cpp class WorkspaceController { public: explicit WorkspaceController(); bool hasWorkspace() const; QString workspaceRoot() const; bool openWorkspace(const QString &rootPath, QString *errorMessage = nullptr); void closeWorkspace(); WorkspaceToolResult scanWorkspace(); WorkspaceToolResult handleMessage(const QString &message); bool hasPendingPlan() const; WorkspaceActionPlan pendingPlan() const; WorkspaceToolResult confirmPendingPlan(); void cancelPendingPlan(); private: WorkspaceSession m_session; WorkspaceAgent m_agent; std::optional m_pendingPlan; }; ``` 说明: - `handleMessage` 不直接执行高风险写操作。 - 如果需要确认,则保存到 `m_pendingPlan`。 - UI 调用 `confirmPendingPlan` 后才执行。 ------ # 11. UI 接入建议 ## 11.1 PetWindow 入口 在聊天系统中增加: ```text 工作区模式 ``` 可以通过以下方式触发: ```text 打开工作区 选择工作区 分析这个项目 搜索当前工作区 ``` 如果用户没有选择工作区,则提示选择目录。 第一版可以直接用: ```cpp QFileDialog::getExistingDirectory(...) ``` 让用户选择工作区。 ------ ## 11.2 气泡显示策略 桌宠气泡只显示简短状态: ```text 已打开工作区。 正在扫描文件。 找到了 12 个相关文件。 需要你确认修改计划。 操作已完成。 ``` 复杂结果不要全部塞进气泡。 ------ ## 11.3 工作区面板 建议新增: ```text WorkspacePanel ``` 第一版可以晚点做,先用对话框和聊天历史展示。 最终面板建议显示: ```text 当前工作区路径 文件树 搜索结果 读取过的文件 AI 分析结果 待确认操作计划 执行结果 最近操作历史 ``` ------ # 12. 和旧文件操作的迁移关系 当前旧入口可能是: ```cpp handleFileOperationChatMessage(...) ``` 新方案中应改为: ```cpp handleWorkspaceMessage(...) ``` 迁移步骤: ```text 第一步: 新增 workspace 模块,不改旧 fileops。 第二步: CMakeLists.txt 加入 workspace 新文件。 第三步: 在 PetWindow 中新增 WorkspaceController 成员。 第四步: IntentRouter 中把文件相关意图改为 Workspace。 第五步: handleFileOperationChatMessage 内部临时转发到 WorkspaceController。 第六步: 确认新模块可用后,删除旧 FileOperationManager 相关调用。 第七步: 删除旧 src/fileops 旧文件并更新 CMakeLists.txt。 ``` 注意:删除旧文件前必须确认没有任何 include 或成员变量引用旧类。 ------ # 13. IntentRouter 调整 当前 `IntentRouter` 只按关键词判断文件操作,后续应改成更宽泛的工作区意图。 建议: ```cpp enum class UserIntentType { Chat, Reminder, Weather, Workspace, LaunchApp }; ``` 工作区关键词: ```text 文件 文件夹 目录 项目 代码 源码 工作区 分析这个项目 搜索 读取 打开文件 创建文件 修改文件 删除文件 移动文件 重命名 ``` 注意: ```text 打开微信 打开浏览器 打开 QQ ``` 这类应该走 `LaunchApp`,不要误判成 Workspace。 建议优先级: ```text Reminder Weather Workspace LaunchApp Chat ``` 但如果文本中出现明确应用名,可优先 LaunchApp。 ------ # 14. CMake 修改计划 新增 workspace 文件后,需要在 `CMakeLists.txt` 中加入: ```text src/workspace/WorkspaceTypes.h src/workspace/WorkspaceSession.h src/workspace/WorkspaceSession.cpp src/workspace/WorkspaceIndex.h src/workspace/WorkspaceIndex.cpp src/workspace/WorkspaceScanner.h src/workspace/WorkspaceScanner.cpp src/workspace/WorkspaceAccessPolicy.h src/workspace/WorkspaceAccessPolicy.cpp src/workspace/WorkspaceTool.h src/workspace/WorkspaceToolRegistry.h src/workspace/WorkspaceToolRegistry.cpp src/workspace/WorkspaceAgent.h src/workspace/WorkspaceAgent.cpp src/workspace/WorkspaceController.h src/workspace/WorkspaceController.cpp src/workspace/WorkspaceHistory.h src/workspace/WorkspaceHistory.cpp src/workspace/tools/ListFilesTool.h src/workspace/tools/ListFilesTool.cpp src/workspace/tools/ReadFileTool.h src/workspace/tools/ReadFileTool.cpp src/workspace/tools/SearchFilesTool.h src/workspace/tools/SearchFilesTool.cpp src/workspace/tools/SearchTextTool.h src/workspace/tools/SearchTextTool.cpp src/workspace/tools/OpenFileTool.h src/workspace/tools/OpenFileTool.cpp src/workspace/tools/CreateFileTool.h src/workspace/tools/CreateFileTool.cpp src/workspace/tools/CreateDirectoryTool.h src/workspace/tools/CreateDirectoryTool.cpp src/workspace/tools/WriteFileTool.h src/workspace/tools/WriteFileTool.cpp src/workspace/tools/CopyFileTool.h src/workspace/tools/CopyFileTool.cpp src/workspace/tools/MoveFileTool.h src/workspace/tools/MoveFileTool.cpp src/workspace/tools/RenameFileTool.h src/workspace/tools/RenameFileTool.cpp src/workspace/tools/DeleteToTrashTool.h src/workspace/tools/DeleteToTrashTool.cpp ``` 注意: 当前项目 `CMAKE_AUTOMOC` 是关闭的。如果新增类不使用 `Q_OBJECT`,可以继续保持现状。如果新增 QWidget 并需要 signals / slots,则需要重新考虑 `CMAKE_AUTOMOC`。 第一阶段建议 workspace 业务类都不要使用 `Q_OBJECT`,避免牵连构建配置。 ------ # 15. 日志要求 不要记录敏感内容。 允许记录: ```text 打开工作区路径 扫描文件数量 执行的工具名称 操作是否成功 错误摘要 ``` 禁止记录: ```text API Key Authorization header 完整敏感文件内容 .env 内容 密钥文件内容 用户完整隐私文本 ``` 使用项目已有 Logger,不要使用 `OutputDebugStringA`。 ------ # 16. 错误处理 所有工具错误都必须返回 `WorkspaceToolResult`,不要直接弹窗。 错误示例: ```text 路径不在当前工作区内。 目标文件已存在。 该文件类型不允许写入。 该文件可能包含敏感信息,已拒绝读取。 删除操作已取消。 无法移动到回收站。 ``` UI 层负责展示错误。 ------ # 17. 测试清单 ## 17.1 工作区选择 测试: ```text 选择普通项目目录 选择空目录 选择不存在目录 选择 C:/Windows,应该拒绝 选择 Program Files,应该拒绝 选择包含中文路径的目录 选择包含空格路径的目录 ``` ------ ## 17.2 扫描 测试: ```text 扫描普通 Qt 项目 扫描包含 build 目录的项目 扫描包含 .git 的项目 扫描大量文件目录 扫描中文文件名 扫描深层目录 ``` 要求: ```text 不崩溃 不扫系统目录 不进入跳过目录 结果数量受限制 ``` ------ ## 17.3 搜索文件 测试: ```text 搜索 main 搜索 .cpp 搜索 README 搜索不存在文件 搜索中文文件名 ``` 要求: ```text 最多返回 30 条 显示相对路径 结果可用于后续“打开第几个” ``` ------ ## 17.4 搜索文本 测试: ```text 搜索 class 搜索 include 搜索中文关键词 搜索不存在关键词 搜索超大文件 ``` 要求: ```text 显示路径、行号、片段 跳过二进制文件 跳过超大文件 不读取敏感文件 ``` ------ ## 17.5 读取文件 测试: ```text 读取 .cpp 读取 .md 读取 .json 读取图片,应该拒绝 读取 exe,应该拒绝 读取 .env,应该拒绝或强确认 读取工作区外文件,应该拒绝 ``` ------ ## 17.6 创建文件 测试: ```text 在工作区创建 test.txt 创建已存在文件,应该拒绝 创建非法文件名,应该拒绝 创建 .bat,应该拒绝 创建到工作区外,应该拒绝 ``` ------ ## 17.7 修改文件 测试: ```text 修改普通 txt 修改 cpp 修改已存在文件前生成备份 修改二进制文件,应该拒绝 修改敏感文件,应该拒绝 ``` 要求: ```text 必须确认 必须备份 失败不能破坏原文件 ``` ------ ## 17.8 移动和重命名 测试: ```text 移动普通文件 移动到已存在目标,应该拒绝 重命名普通文件 重命名为非法文件名,应该拒绝 移动到工作区外,应该拒绝 ``` ------ ## 17.9 删除到回收站 测试: ```text 删除普通文件到回收站 删除文件夹到回收站 删除工作区外文件,应该拒绝 永久删除请求,应该拒绝 批量删除请求,第一阶段应该拒绝 ``` ------ ## 17.10 对话上下文 测试: ```text 用户:搜索 README 用户:打开第一个 用户:搜索 fileops 用户:读取第二个 用户:找一下包含 FileOperationManager 的文件 用户:总结这些文件的作用 ``` 要求: ```text 系统能记住上一轮搜索结果 “第一个”“第二个”能正确解析 上下文过期后要求用户重新选择 ``` ------ # 18. 推荐开发任务拆分 ## 任务 1:新增类型和安全策略 目标: ```text 新增 WorkspaceTypes.h 新增 WorkspaceAccessPolicy 不接 UI 保证项目可编译 ``` 验收: ```text 能判断路径是否在工作区内 能拒绝系统目录 能拒绝符号链接 能拒绝危险后缀 ``` ------ ## 任务 2:新增扫描和索引 目标: ```text 实现 WorkspaceScanner 实现 WorkspaceIndex 支持扫描工作区文件树 ``` 验收: ```text 可以扫描普通项目 可以跳过 build/.git/node_modules 可以按文件名搜索 ``` ------ ## 任务 3:新增只读工具 目标: ```text ListFilesTool ReadFileTool SearchFilesTool SearchTextTool ``` 验收: ```text 能列目录 能读文本文件 能搜索文件名 能搜索文本内容 不读取二进制和敏感文件 ``` ------ ## 任务 4:新增打开工具 目标: ```text OpenFileTool OpenDirectory RevealInExplorer ``` 验收: ```text 能打开普通文件 能打开文件夹 危险后缀拒绝 工作区外路径拒绝 ``` ------ ## 任务 5:新增写入工具 目标: ```text CreateFileTool CreateDirectoryTool WriteFileTool CopyFileTool MoveFileTool RenameFileTool DeleteToTrashTool ``` 验收: ```text 所有写操作必须要求 confirmed 未确认时拒绝执行 目标已存在时拒绝覆盖 删除只进回收站 写入前备份 ``` ------ ## 任务 6:新增 WorkspaceController 目标: ```text 统一管理工作区、索引、工具、待确认计划 ``` 验收: ```text 能 openWorkspace 能 scanWorkspace 能 handleMessage 能保存 pendingPlan 能确认执行 pendingPlan ``` ------ ## 任务 7:接入 PetWindow 目标: ```text PetWindow 增加 WorkspaceController 聊天消息中的工作区相关请求转发给 WorkspaceController ``` 验收: ```text 用户可以选择工作区 可以搜索文件 可以读取文件 写操作会弹确认 确认后执行 ``` ------ ## 任务 8:替换旧 fileops 目标: ```text 旧 handleFileOperationChatMessage 改为调用 workspace 删除旧 FileOperationManager 依赖 更新 CMake ``` 验收: ```text 项目无旧 FileOperationManager 引用 项目能编译 README 更新为“本地工作区助手” ``` ------ # 19. README 更新要求 README 中文件操作部分应改为: ```text 本地工作区助手: - 用户选择一个工作区目录后,桌宠可以读取、搜索和分析其中的文本文件。 - 支持文件名搜索、文本搜索、文件读取、项目结构分析。 - 支持创建、修改、移动、重命名和删除到回收站,但所有写操作都需要用户确认。 - 不支持永久删除。 - 不支持执行脚本或系统命令。 - 不允许访问工作区外路径。 - 敏感文件和危险后缀会被拦截或要求强确认。 ``` ------ # 20. 最终验收标准 本轮重构完成后,至少应达到: ```text 1. 用户可以选择一个本地项目目录作为工作区。 2. 程序可以扫描工作区并建立文件索引。 3. 用户可以通过对话搜索文件。 4. 用户可以通过对话读取和分析文本文件。 5. 用户可以要求分析项目结构。 6. 用户可以创建文本文件和文件夹。 7. 用户可以移动、重命名、删除到回收站。 8. 所有写操作必须展示计划并等待确认。 9. 所有路径必须限制在工作区内。 10. 不允许永久删除。 11. 不允许执行脚本或命令。 12. 不允许默认读取敏感文件。 13. 旧文件操作功能被新 Workspace 系统替代。 14. 项目可以正常编译。 ``` ------ # 21. 特别注意 这是一次架构升级,不是简单加几个文件函数。 不要把功能写成: ```text AI 说删就删 AI 说改就改 AI 说运行就运行 ``` 必须写成: ```text AI 提出计划 程序校验路径和风险 用户确认 程序执行白名单工具 ``` 这个边界必须守住。 最终目标是: > 让 DesktopPet 具备“读工作区、理解工作区、规划修改、确认后执行”的能力,形成桌宠形态的本地工作区 Agent。