870 lines
21 KiB
Markdown
870 lines
21 KiB
Markdown
# DesktopPet 本地工作区 Agent 施工计划
|
|
|
|
## 1. 定位
|
|
|
|
本地工作区 Agent 是下一阶段核心功能。它不是继续维护旧版“文件操作 v1”,而是新增一个独立的工作区系统:
|
|
|
|
> 用户选择一个本地工作区目录后,桌宠可以读取、搜索、分析该目录内的文件,并在用户确认后创建、修改、复制、移动、重命名或删除到回收站。
|
|
|
|
第一阶段优先实现文件级工具,不做 Shell 命令执行,不做脚本执行,不做自动安装依赖。
|
|
|
|
## 2. 总原则
|
|
|
|
- 不允许 AI 直接获得全盘文件权限。
|
|
- 不允许 AI 自由执行系统命令。
|
|
- 不允许永久删除文件。
|
|
- 不允许绕过用户确认修改本地文件。
|
|
- 不允许默认读取敏感文件。
|
|
- 所有写操作必须先生成计划,展示路径、动作和风险,用户确认后才能执行。
|
|
- 所有文件路径必须限制在用户选择的工作区内。
|
|
- `PetWindow` 只负责 UI 入口、展示和确认,不承载复杂业务逻辑。
|
|
- 新模块先新增、后替换旧 `src/fileops/`。
|
|
|
|
## 3. 分期目标
|
|
|
|
当前执行状态:
|
|
|
|
- v1a.1/v1b/v1b.5 已落地到 `src/workspace/` 和 `src/ui/WorkspaceAgentWindow.*`。
|
|
- 当前不持久化工作区路径,不执行写操作,不替换旧 `src/fileops/`。
|
|
- v1b 已支持打开工作区内普通文件、打开文件夹、显示文件所在位置。
|
|
- v1b.5 已提供独立 Agent 工作区窗口、右键/托盘入口和默认 `Alt+A` 呼出快捷键;窗口包含左侧结果导航、中间任务对话、右侧详情/上下文和 v1c 预留变更区。
|
|
|
|
### v1a:只读工作区
|
|
|
|
目标:
|
|
|
|
- 选择工作区。
|
|
- 显示当前工作区。
|
|
- 扫描工作区文件树。
|
|
- 搜索文件名。
|
|
- 搜索文本内容。
|
|
- 读取文本文件。
|
|
- 分析项目结构。
|
|
- 总结文件内容。
|
|
|
|
验收:
|
|
|
|
- 工作区外路径被拒绝。
|
|
- 系统目录被拒绝。
|
|
- `.git/build/node_modules/dist/release_packages` 等目录被跳过。
|
|
- 敏感文件默认拒绝读取。
|
|
- 二进制文件拒绝读取。
|
|
|
|
### v1b:打开和定位
|
|
|
|
状态:已落地。
|
|
|
|
目标:
|
|
|
|
- 打开工作区内普通文件。
|
|
- 打开工作区内文件夹。
|
|
- 显示文件所在位置。
|
|
|
|
验收:
|
|
|
|
- 危险后缀拒绝打开。
|
|
- `.lnk` 不直接打开。
|
|
- 工作区外路径拒绝。
|
|
- 打开文件必须二次确认,打开文件夹作为低风险操作直接执行。
|
|
|
|
### v1c:低风险写入
|
|
|
|
进入 v1c 前已完成:
|
|
|
|
- `创建 test.txt / 新建文件 / 写入 README / 修改 main.cpp` 明确拒绝,不再误进入旧 fileops 读取文件流程。
|
|
- 独立 Agent 窗口可以分区展示上一轮结果、文本命中、上下文、选中项详情和最近读取文件。
|
|
- 窗口支持对选中结果执行读取、打开和显示位置。
|
|
- 窗口可通过桌宠右键菜单、托盘菜单和可配置全局快捷键呼出。
|
|
|
|
目标:
|
|
|
|
- 创建文本文件。
|
|
- 创建文件夹。
|
|
- 复制单个文件。
|
|
- 同目录重命名文件。
|
|
|
|
验收:
|
|
|
|
- 所有写操作必须确认。
|
|
- 目标文件或目录已存在时拒绝覆盖。
|
|
- 文件名非法时拒绝。
|
|
- 危险后缀拒绝创建或写入。
|
|
|
|
### v1d:高风险写入
|
|
|
|
目标:
|
|
|
|
- 修改已有文本文件。
|
|
- 移动单个文件。
|
|
- 删除文件到回收站。
|
|
- 删除文件夹到回收站。
|
|
|
|
验收:
|
|
|
|
- 修改前必须备份。
|
|
- 移动和删除必须强确认。
|
|
- 删除只进入回收站。
|
|
- 批量删除第一阶段拒绝。
|
|
- 失败时不能破坏原文件。
|
|
|
|
### v1e:替换旧文件操作
|
|
|
|
目标:
|
|
|
|
- `FileOperation` 意图迁移为 `Workspace`。
|
|
- `PetWindow::handleFileOperationChatMessage()` 过渡为调用 `WorkspaceController`。
|
|
- 新模块覆盖旧能力后删除旧 `src/fileops/`。
|
|
|
|
验收:
|
|
|
|
- 无 `FileOperationManager` 有效引用。
|
|
- CMake 不再登记旧 fileops 文件。
|
|
- README 和测试文档改为“本地工作区 Agent”。
|
|
|
|
## 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
|
|
```
|
|
|
|
第一阶段继续保持 `CMAKE_AUTOMOC OFF`,新增业务类不使用 `Q_OBJECT`。
|
|
|
|
## 5. 核心类型
|
|
|
|
```cpp
|
|
enum class WorkspacePermissionMode
|
|
{
|
|
ReadOnly,
|
|
ConfirmBeforeWrite,
|
|
Advanced
|
|
};
|
|
```
|
|
|
|
第一阶段默认 `ConfirmBeforeWrite`,但所有写操作仍必须确认。`Advanced` 只预留,不启用自动写入。
|
|
|
|
```cpp
|
|
enum class WorkspaceToolRisk
|
|
{
|
|
ReadOnly,
|
|
Low,
|
|
Medium,
|
|
High,
|
|
Dangerous
|
|
};
|
|
```
|
|
|
|
风险定义:
|
|
|
|
- `ReadOnly`:列目录、搜索、读取普通文本文件。
|
|
- `Low`:打开文件夹、显示文件所在位置。
|
|
- `Medium`:打开普通文件、创建文件、创建文件夹、复制文件。
|
|
- `High`:修改文件、移动文件、重命名文件、删除到回收站。
|
|
- `Dangerous`:永久删除、执行命令、运行脚本、修改系统目录。
|
|
|
|
第一阶段遇到 `Dangerous` 直接拒绝。
|
|
|
|
```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;
|
|
};
|
|
```
|
|
|
|
```cpp
|
|
enum class WorkspaceActionType
|
|
{
|
|
Unknown,
|
|
ListFiles,
|
|
SearchFiles,
|
|
SearchText,
|
|
ReadFile,
|
|
OpenFile,
|
|
OpenDirectory,
|
|
RevealInExplorer,
|
|
CreateFile,
|
|
CreateDirectory,
|
|
WriteFile,
|
|
CopyFile,
|
|
MoveFile,
|
|
RenameFile,
|
|
DeleteToTrash
|
|
};
|
|
```
|
|
|
|
```cpp
|
|
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;
|
|
};
|
|
```
|
|
|
|
```cpp
|
|
struct WorkspaceToolResult
|
|
{
|
|
bool success = false;
|
|
QString message;
|
|
QString errorMessage;
|
|
QString outputText;
|
|
QString targetPath;
|
|
QVector<WorkspaceFileInfo> files;
|
|
};
|
|
```
|
|
|
|
## 6. 安全策略
|
|
|
|
`WorkspaceAccessPolicy` 是最重要的模块,所有工具必须经过它校验。
|
|
|
|
职责:
|
|
|
|
- 路径标准化。
|
|
- 判断路径是否在工作区内。
|
|
- 阻止 `../` 跳出工作区。
|
|
- 阻止符号链接跳出工作区。
|
|
- 阻止系统目录。
|
|
- 阻止危险文件类型。
|
|
- 阻止敏感文件默认读取。
|
|
- 限制写入行为。
|
|
- 限制删除行为。
|
|
|
|
建议接口:
|
|
|
|
```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;
|
|
};
|
|
```
|
|
|
|
禁止危险后缀:
|
|
|
|
```text
|
|
.exe .bat .cmd .ps1 .vbs .msi .scr .reg .com .pif .lnk
|
|
```
|
|
|
|
敏感文件默认拒绝:
|
|
|
|
```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` 第一版使用 `QDir` + 手动目录栈扫描工作区,后续如需取消、进度回调或更细粒度过滤,再考虑替换为 `QDirIterator` 或异步扫描。
|
|
|
|
默认限制:
|
|
|
|
- 最大递归深度:8。
|
|
- 最大文件数量:5000。
|
|
- 跳过隐藏目录。
|
|
- 跳过常见产物目录。
|
|
|
|
跳过目录:
|
|
|
|
```text
|
|
.git
|
|
.vs
|
|
.idea
|
|
build
|
|
cmake-build-debug
|
|
cmake-build-release
|
|
node_modules
|
|
dist
|
|
release
|
|
release_packages
|
|
logs
|
|
```
|
|
|
|
`WorkspaceIndex` 第一版只做内存索引:
|
|
|
|
```cpp
|
|
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;
|
|
};
|
|
```
|
|
|
|
## 8. 工具清单
|
|
|
|
### 8.1 只读工具
|
|
|
|
`ListFilesTool`
|
|
|
|
- 列出工作区内目录。
|
|
- 最多显示 200 项。
|
|
- 不递归或浅递归。
|
|
|
|
`ReadFileTool`
|
|
|
|
- 只读文本文件。
|
|
- 最大读取 128KB。
|
|
- 超出截断。
|
|
- 敏感文件默认拒绝。
|
|
- 不读二进制文件。
|
|
|
|
支持后缀:
|
|
|
|
```text
|
|
.cpp .h .hpp .c .cc .py .js .ts .json .md .txt .ini .xml .yaml .yml .cmake .pro .css .html
|
|
```
|
|
|
|
`SearchFilesTool`
|
|
|
|
- 只搜索当前工作区索引。
|
|
- 最多返回 30 个结果。
|
|
- 按相关性和最近修改时间排序。
|
|
|
|
`SearchTextTool`
|
|
|
|
- 最多扫描 1000 个文本文件。
|
|
- 单文件最大读取 128KB。
|
|
- 最多返回 50 条匹配。
|
|
- 每条显示文件路径、行号、片段。
|
|
|
|
### 8.2 打开工具
|
|
|
|
`OpenFileTool`
|
|
|
|
- 用系统默认程序打开文件。
|
|
- 只能打开工作区内普通文件。
|
|
- 危险后缀拒绝。
|
|
- 敏感文件需要确认或第一版拒绝。
|
|
|
|
`OpenDirectoryTool`
|
|
|
|
- 打开工作区内目录。
|
|
- 工作区外路径拒绝。
|
|
|
|
`RevealInExplorerTool`
|
|
|
|
- 第一版可以先打开所在文件夹。
|
|
- 如果后续使用 `explorer.exe /select`,必须固定程序路径和参数,不接受聊天文本命令。
|
|
|
|
### 8.3 写入工具
|
|
|
|
`CreateFileTool`
|
|
|
|
- 只能在工作区内创建。
|
|
- 目标不能已存在。
|
|
- 文件名必须合法。
|
|
- 危险后缀拒绝。
|
|
- 必须确认。
|
|
|
|
`CreateDirectoryTool`
|
|
|
|
- 只能在工作区内创建。
|
|
- 目标不能已存在。
|
|
- 必须确认。
|
|
|
|
`WriteFileTool`
|
|
|
|
- 修改已有文本文件前自动备份。
|
|
- 禁止覆盖二进制文件。
|
|
- 禁止写敏感文件。
|
|
- 禁止写危险后缀。
|
|
- 必须确认。
|
|
|
|
备份目录:
|
|
|
|
```text
|
|
<workspaceRoot>/.desktoppet/backups/
|
|
```
|
|
|
|
备份命名:
|
|
|
|
```text
|
|
relative_path.replace("/", "__") + "." + yyyyMMdd-HHmmss + ".bak"
|
|
```
|
|
|
|
`CopyFileTool`
|
|
|
|
- 只复制单文件。
|
|
- 源和目标都必须在工作区内。
|
|
- 不覆盖。
|
|
- 必须确认。
|
|
|
|
`MoveFileTool`
|
|
|
|
- 只移动单文件。
|
|
- 源和目标都必须在工作区内。
|
|
- 不覆盖。
|
|
- 必须确认。
|
|
|
|
`RenameFileTool`
|
|
|
|
- 只允许同目录重命名。
|
|
- 文件名不能包含路径分隔符。
|
|
- 不覆盖。
|
|
- 必须确认。
|
|
|
|
`DeleteToTrashTool`
|
|
|
|
- 只移动到系统回收站。
|
|
- 不永久删除。
|
|
- 单文件删除第一阶段可支持。
|
|
- 文件夹删除需要强确认。
|
|
- 批量删除第一阶段拒绝。
|
|
|
|
## 9. WorkspaceAgent
|
|
|
|
第一版采用半自动 Agent,不做复杂工具循环。
|
|
|
|
推荐流程:
|
|
|
|
```text
|
|
用户输入
|
|
↓
|
|
WorkspaceController 判断工作区任务
|
|
↓
|
|
程序根据关键词和索引检索相关文件
|
|
↓
|
|
读取少量相关文件
|
|
↓
|
|
把文件树摘要、相关文件内容、用户问题交给模型
|
|
↓
|
|
模型返回分析结果或修改建议
|
|
↓
|
|
涉及写操作时生成 WorkspaceActionPlan
|
|
↓
|
|
用户确认
|
|
↓
|
|
执行工具
|
|
```
|
|
|
|
工作区专用系统提示词:
|
|
|
|
```text
|
|
你是 QtDesktopPet 的本地工作区助手。
|
|
|
|
你只能基于用户授权的工作区文件进行分析。
|
|
你不能假设自己看过未读取的文件。
|
|
你不能要求访问工作区外路径。
|
|
你不能执行系统命令。
|
|
你不能生成危险操作指令。
|
|
涉及创建、修改、移动、重命名、删除文件时,必须先生成清晰的操作计划,等待用户确认。
|
|
涉及敏感文件、密钥、凭证时,必须提醒风险。
|
|
回答代码问题时要引用具体文件路径。
|
|
当信息不足时,说明还需要读取哪些文件。
|
|
```
|
|
|
|
后续可升级为工具循环,但第一版不做。
|
|
|
|
## 10. WorkspaceController
|
|
|
|
建议接口:
|
|
|
|
```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<WorkspaceActionPlan> m_pendingPlan;
|
|
};
|
|
```
|
|
|
|
原则:
|
|
|
|
- `handleMessage()` 不直接执行高风险写操作。
|
|
- 需要确认时保存到 `m_pendingPlan`。
|
|
- UI 调用 `confirmPendingPlan()` 后才执行。
|
|
- 所有错误通过 `WorkspaceToolResult` 返回,不在工具层弹窗。
|
|
|
|
## 11. UI 接入
|
|
|
|
聊天入口支持:
|
|
|
|
```text
|
|
打开工作区
|
|
选择工作区
|
|
当前工作区
|
|
扫描工作区
|
|
分析这个项目
|
|
搜索当前工作区
|
|
读取 main.cpp
|
|
打开第一个
|
|
```
|
|
|
|
如果没有选择工作区,提示用户选择目录。
|
|
|
|
气泡只显示短状态:
|
|
|
|
```text
|
|
已打开工作区。
|
|
正在扫描文件。
|
|
找到了 12 个相关文件。
|
|
需要你确认修改计划。
|
|
操作已完成。
|
|
```
|
|
|
|
复杂结果不全部塞进气泡,当前通过独立 Agent 窗口展示。
|
|
|
|
当前独立 Agent 窗口可显示:
|
|
|
|
- 当前工作区路径。
|
|
- 文件树。
|
|
- 搜索结果。
|
|
- 已读取文件。
|
|
- AI 分析结果。
|
|
- 待确认操作计划。
|
|
- 执行结果。
|
|
- 最近操作历史。
|
|
|
|
## 12. 意图分发
|
|
|
|
后续建议新增:
|
|
|
|
```cpp
|
|
enum class UserIntentType
|
|
{
|
|
Chat,
|
|
Reminder,
|
|
Weather,
|
|
Workspace,
|
|
FileOperation,
|
|
LaunchApp
|
|
};
|
|
```
|
|
|
|
意图原则:
|
|
|
|
- `Reminder` 保持最高优先级。
|
|
- 明确天气问答走 `Weather`。
|
|
- 明确工作区、代码、项目分析走 `Workspace`。
|
|
- 当前阶段,未明确“工作区/项目/代码”且没有工作区文件名特征的普通文件读写请求仍可走旧 `FileOperation`。
|
|
- 明确应用名启动走 `LaunchApp`。
|
|
- 其余走 `Chat` 或输入框联网模式。
|
|
|
|
不能用宽关键词简单吞掉所有请求:
|
|
|
|
- “打开微信”应走 `LaunchApp`。
|
|
- “打开文件夹”这种泛请求不走 `Workspace`;“打开 docs / 打开这个项目里的 docs”走 `Workspace`。
|
|
- “搜索 Qt 最新版本”不应走工作区搜索。
|
|
- “搜索这个项目里的 main”应走工作区搜索。
|
|
|
|
## 13. 迁移步骤
|
|
|
|
1. 新增 `src/workspace/`,不改旧 `src/fileops/`。
|
|
2. CMake 登记 workspace 新文件。
|
|
3. `PetWindow` 增加 `WorkspaceController` 成员。
|
|
4. 新增工作区打开、扫描、搜索、读取入口。
|
|
5. v1b 支持打开和定位;写操作计划和确认框从后续阶段开始。
|
|
6. 新模块覆盖旧文件操作能力后,`handleFileOperationChatMessage()` 转发到 `WorkspaceController`。
|
|
7. 确认无旧引用后删除 `src/fileops/`。
|
|
8. 更新 CMake、README、测试文档。
|
|
|
|
删除旧文件前必须执行:
|
|
|
|
```text
|
|
rg "FileOperationManager|FileSandbox|FileBackupManager|src/fileops|FileOperation"
|
|
```
|
|
|
|
确认没有有效代码引用后再删。
|
|
|
|
## 14. 日志要求
|
|
|
|
允许记录:
|
|
|
|
- 打开工作区路径。
|
|
- 扫描文件数量。
|
|
- 执行的工具名称。
|
|
- 操作是否成功。
|
|
- 错误摘要。
|
|
|
|
禁止记录:
|
|
|
|
- API Key。
|
|
- Authorization Header。
|
|
- 完整敏感文件内容。
|
|
- `.env` 内容。
|
|
- 密钥文件内容。
|
|
- 用户完整隐私文本。
|
|
|
|
使用项目已有 `Logger`,不要新增零散调试输出。
|
|
|
|
## 15. 测试清单
|
|
|
|
### 工作区选择
|
|
|
|
- 选择普通项目目录。
|
|
- 选择空目录。
|
|
- 选择不存在目录。
|
|
- 选择 `C:/Windows`,应拒绝。
|
|
- 选择 `Program Files`,应拒绝。
|
|
- 选择中文路径。
|
|
- 选择包含空格的路径。
|
|
|
|
### 扫描
|
|
|
|
- 扫描普通 Qt 项目。
|
|
- 扫描包含 build 目录的项目。
|
|
- 扫描包含 `.git` 的项目。
|
|
- 扫描大量文件目录。
|
|
- 扫描中文文件名。
|
|
- 扫描深层目录。
|
|
|
|
要求:
|
|
|
|
- 不崩溃。
|
|
- 不扫系统目录。
|
|
- 不进入跳过目录。
|
|
- 结果数量受限制。
|
|
|
|
### 搜索文件
|
|
|
|
- 搜索 `main`。
|
|
- 搜索 `.cpp`。
|
|
- 搜索 `README`。
|
|
- 搜索不存在文件。
|
|
- 搜索中文文件名。
|
|
|
|
要求:
|
|
|
|
- 最多返回 30 条。
|
|
- 显示相对路径。
|
|
- 结果可用于后续“打开第几个”。
|
|
|
|
### 搜索文本
|
|
|
|
- 搜索 `class`。
|
|
- 搜索 `include`。
|
|
- 搜索中文关键词。
|
|
- 搜索不存在关键词。
|
|
- 搜索超大文件。
|
|
|
|
要求:
|
|
|
|
- 显示路径、行号、片段。
|
|
- 跳过二进制文件。
|
|
- 跳过超大文件。
|
|
- 不读取敏感文件。
|
|
|
|
### 读取文件
|
|
|
|
- 读取 `.cpp`。
|
|
- 读取 `.md`。
|
|
- 读取 `.json`。
|
|
- 读取图片应拒绝。
|
|
- 读取 `.exe` 应拒绝。
|
|
- 读取 `.env` 应拒绝或强确认。
|
|
- 读取工作区外文件应拒绝。
|
|
|
|
### 创建文件
|
|
|
|
- 在工作区创建 `test.txt`。
|
|
- 创建已存在文件应拒绝。
|
|
- 创建非法文件名应拒绝。
|
|
- 创建 `.bat` 应拒绝。
|
|
- 创建到工作区外应拒绝。
|
|
|
|
### 修改文件
|
|
|
|
- 修改普通 `.txt`。
|
|
- 修改 `.cpp`。
|
|
- 修改前生成备份。
|
|
- 修改二进制文件应拒绝。
|
|
- 修改敏感文件应拒绝。
|
|
|
|
要求:
|
|
|
|
- 必须确认。
|
|
- 必须备份。
|
|
- 失败不能破坏原文件。
|
|
|
|
### 移动和重命名
|
|
|
|
- 移动普通文件。
|
|
- 移动到已存在目标应拒绝。
|
|
- 重命名普通文件。
|
|
- 重命名为非法文件名应拒绝。
|
|
- 移动到工作区外应拒绝。
|
|
|
|
### 删除到回收站
|
|
|
|
- 删除普通文件到回收站。
|
|
- 删除文件夹到回收站。
|
|
- 删除工作区外文件应拒绝。
|
|
- 永久删除请求应拒绝。
|
|
- 批量删除请求第一阶段应拒绝。
|
|
|
|
### 对话上下文
|
|
|
|
```text
|
|
用户:搜索 README
|
|
用户:打开第一个
|
|
|
|
用户:搜索 fileops
|
|
用户:读取第二个
|
|
|
|
用户:找一下包含 FileOperationManager 的文件
|
|
用户:总结这些文件的作用
|
|
```
|
|
|
|
要求:
|
|
|
|
- 系统能记住上一轮搜索结果。
|
|
- “第一个”“第二个”能正确解析。
|
|
- 上下文过期后要求用户重新选择。
|
|
|
|
## 16. 静态推演要求
|
|
|
|
每完成一个阶段,需要记录:
|
|
|
|
- 入口路径。
|
|
- 业务模块调用链。
|
|
- 路径校验点。
|
|
- 用户确认点。
|
|
- 失败回滚策略。
|
|
- 不支持能力的拒绝话术。
|
|
- 对提醒、天气、联网模式、应用启动的回归影响。
|
|
|
|
## 17. 最终验收标准
|
|
|
|
本轮重构完成后至少达到:
|
|
|
|
1. 用户可以选择一个本地项目目录作为工作区。
|
|
2. 程序可以扫描工作区并建立文件索引。
|
|
3. 用户可以通过对话搜索文件。
|
|
4. 用户可以通过对话读取和分析文本文件。
|
|
5. 用户可以要求分析项目结构。
|
|
6. 用户可以创建文本文件和文件夹。
|
|
7. 用户可以移动、重命名、删除到回收站。
|
|
8. 所有写操作必须展示计划并等待确认。
|
|
9. 所有路径必须限制在工作区内。
|
|
10. 不允许永久删除。
|
|
11. 不允许执行脚本或命令。
|
|
12. 不允许默认读取敏感文件。
|
|
13. 旧文件操作功能被新 Workspace 系统替代。
|
|
14. 项目可以由用户手动构建通过。
|