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