Files
Qt_DesktopPet/docs/QtDesktopPet 本地工作区 Agent 独立窗口化施工文档.md
T

1230 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QtDesktopPet 本地工作区 Agent 独立窗口化施工文档
## 0. 本次施工目标
当前项目已经有“本地工作区 Agent”面板雏形,能够显示:
- 当前工作区路径
- 索引项数量
- 最近扫描时间
- 上一轮搜索结果
- 选中文件详情
- 文本命中
- 最近读取
- 读取 / 打开 / 定位 等操作按钮
但当前形态更接近“文件搜索面板”,还不是类似 Codex / Claude Code 的工作区 Agent 面板。
本次施工目标:
> 将本地工作区 Agent 从桌宠窗口中独立出来,做成一个单独的非模态主窗口,并改造成“左侧工作区导航 + 中间 Agent 对话 + 右侧上下文 / 文件详情 / 变更确认 + 底部任务输入框”的 Codex 风格面板。
------
# 1. 产品定位
## 1.1 桌宠窗口职责
桌宠本体只负责:
```text
1. 桌宠动画显示
2. 气泡提示
3. 托盘控制
4. 打开设置窗口
5. 打开本地工作区 Agent 窗口
6. 显示任务状态,例如“正在分析”“等待确认”“修改完成”
```
桌宠窗口不应该承载:
```text
1. 文件树
2. 搜索结果列表
3. 多轮 Agent 对话
4. 文件内容预览
5. Diff 预览
6. 修改计划确认
7. 复杂任务日志
```
------
## 1.2 本地工作区 Agent 窗口职责
本地工作区 Agent 独立窗口负责:
```text
1. 选择 / 切换工作区
2. 扫描并索引工作区
3. 显示文件树 / 搜索结果 / 上下文文件
4. 支持用户输入任务
5. 显示 Agent 对话过程
6. 显示工具调用过程
7. 显示已读取文件
8. 显示待确认操作
9. 显示 Diff 或修改计划
10. 执行确认后的文件操作
```
------
# 2. 为什么必须做成独立窗口
## 2.1 当前问题
如果本地工作区 Agent 和桌宠共用一个窗口,会导致:
```text
1. PetWindow 职责继续膨胀
2. 桌宠动画逻辑和工作区 UI 强耦合
3. UI 尺寸冲突,桌宠本体不适合承载复杂面板
4. 复杂任务状态难以展示
5. 后续 Diff、文件树、搜索、日志、对话区很难布局
6. 用户无法像使用 IDE / Codex 一样长时间停留在 Agent 面板中
```
------
## 2.2 独立窗口优势
独立窗口可以获得:
```text
1. 更像 Codex / Claude Code 的工作流
2. 可最大化 / 最小化 / 单独移动
3. 不影响桌宠动画
4. 可以保存窗口大小和位置
5. 可以长期展示复杂任务
6. 可以后续加入 Diff 面板、文件树、任务日志
7. PetWindow 只作为入口,整体架构更干净
```
------
# 3. 总体架构
新的调用关系应为:
```text
PetWindow
openWorkspaceAgentWindow()
WorkspaceAgentWindow
WorkspacePanel
WorkspaceController
WorkspaceAgent
WorkspaceToolRegistry
Workspace Tools
```
其中:
```text
PetWindow:
只负责打开窗口和接收状态提示。
WorkspaceAgentWindow:
独立顶层窗口,负责窗口行为。
WorkspacePanel:
主 UI 容器,负责布局。
WorkspaceController:
UI 和业务逻辑之间的桥梁。
WorkspaceAgent:
处理用户任务、文件分析、工具调用计划。
WorkspaceToolRegistry:
管理文件工具。
Workspace Tools:
读取、搜索、打开、创建、移动、删除到回收站等具体工具。
```
------
# 4. 新增 UI 目录结构
建议新增:
```text
src/ui/workspace/
├── WorkspaceAgentWindow.h
├── WorkspaceAgentWindow.cpp
├── WorkspacePanel.h
├── WorkspacePanel.cpp
├── WorkspaceTopBar.h
├── WorkspaceTopBar.cpp
├── WorkspaceSidebar.h
├── WorkspaceSidebar.cpp
├── WorkspaceChatView.h
├── WorkspaceChatView.cpp
├── WorkspaceInspector.h
├── WorkspaceInspector.cpp
├── WorkspaceInputBar.h
├── WorkspaceInputBar.cpp
├── WorkspacePlanReviewWidget.h
├── WorkspacePlanReviewWidget.cpp
├── WorkspaceDiffView.h
└── WorkspaceDiffView.cpp
```
第一阶段可以先实现:
```text
WorkspaceAgentWindow
WorkspacePanel
WorkspaceTopBar
WorkspaceSidebar
WorkspaceChatView
WorkspaceInspector
WorkspaceInputBar
```
`WorkspacePlanReviewWidget``WorkspaceDiffView` 可以先放空壳,后续接写操作确认。
------
# 5. WorkspaceAgentWindow 设计
## 5.1 类型选择
建议使用:
```cpp
class WorkspaceAgentWindow : public QWidget
```
或者:
```cpp
class WorkspaceAgentWindow : public QMainWindow
```
推荐第一版使用 `QWidget`,因为当前项目 UI 结构大多基于 QWidget,迁移成本低。
窗口必须是独立顶层窗口,不要作为 PetWindow 的子控件。
创建时:
```cpp
m_workspaceAgentWindow = std::make_unique<WorkspaceAgentWindow>();
m_workspaceAgentWindow->show();
m_workspaceAgentWindow->raise();
m_workspaceAgentWindow->activateWindow();
```
不要传 `this` 作为 parent。
------
## 5.2 窗口行为
建议窗口属性:
```cpp
setWindowTitle(QStringLiteral("本地工作区 Agent"));
resize(1180, 760);
setMinimumSize(960, 600);
setWindowFlags(Qt::Window);
```
不要使用:
```cpp
Qt::Tool
```
原因:
`Qt::Tool` 更像附属工具窗,可能不显示在任务栏,不适合 Codex 风格主面板。
------
## 5.3 关闭行为
建议关闭窗口时只隐藏,不销毁。
实现思路:
```cpp
void WorkspaceAgentWindow::closeEvent(QCloseEvent *event)
{
event->ignore();
hide();
}
```
这样:
```text
1. 工作区上下文不会丢失
2. 搜索结果不会丢失
3. Agent 对话不会丢失
4. 再次打开速度更快
```
退出程序时由主程序统一析构。
------
# 6. PetWindow 接入方案
## 6.1 新增成员
`PetWindow.h` 中增加前置声明:
```cpp
class WorkspaceAgentWindow;
```
新增成员:
```cpp
std::unique_ptr<WorkspaceAgentWindow> m_workspaceAgentWindow;
```
------
## 6.2 新增方法
`PetWindow` 中新增:
```cpp
void openWorkspaceAgentWindow();
```
实现逻辑:
```cpp
void PetWindow::openWorkspaceAgentWindow()
{
if (!m_workspaceAgentWindow)
{
m_workspaceAgentWindow = std::make_unique<WorkspaceAgentWindow>();
}
m_workspaceAgentWindow->show();
m_workspaceAgentWindow->raise();
m_workspaceAgentWindow->activateWindow();
}
```
注意:
```text
WorkspaceAgentWindow 不要设置 PetWindow 为 parent。
```
------
## 6.3 菜单入口
在桌宠右键菜单增加:
```text
打开本地工作区 Agent
```
点击后调用:
```cpp
openWorkspaceAgentWindow();
```
后续也可以在聊天中识别:
```text
打开工作区
打开 Agent
打开本地工作区
```
然后调用该窗口。
------
# 7. WorkspacePanel 布局设计
## 7.1 总体布局
目标布局:
```text
┌─────────────────────────────────────────────────────────────┐
│ TopBar:工作区路径 / 索引状态 / 模式 / 按钮 │
├──────────────┬────────────────────────────┬─────────────────┤
│ Sidebar │ ChatView │ Inspector │
│ 文件树/搜索 │ Agent 对话 / 工具调用过程 │ 详情/命中/变更 │
├──────────────┴────────────────────────────┴─────────────────┤
│ InputBar:任务输入框 / 发送 / 停止 / 附加文件 / 模式切换 │
└─────────────────────────────────────────────────────────────┘
```
------
## 7.2 推荐 Qt 布局
使用:
```cpp
QVBoxLayout *rootLayout;
QHBoxLayout *bodyLayout;
```
结构:
```cpp
rootLayout
WorkspaceTopBar
bodyLayout
WorkspaceSidebar
WorkspaceChatView
WorkspaceInspector
WorkspaceInputBar
```
建议宽度比例:
```text
Sidebar: 280 px
ChatView: stretch 1
Inspector: 320 px
```
可以使用:
```cpp
bodyLayout->setStretch(0, 0);
bodyLayout->setStretch(1, 1);
bodyLayout->setStretch(2, 0);
```
------
# 8. 顶部栏 WorkspaceTopBar
## 8.1 显示内容
顶部栏显示:
```text
本地工作区 Agent
工作区:D:/programming/成品项目/项目/Qt_DesktopPet [切换工作区]
索引项:389 最近扫描:2026-06-23 09:49:02 [重新索引]
模式:只读 / 确认写入 [设置]
```
------
## 8.2 按钮
需要以下按钮:
```text
选择工作区
重新索引
清空上下文
停止任务
权限模式
```
第一版按钮可以先实现:
```text
选择工作区
重新索引
关闭
```
------
# 9. 左侧栏 WorkspaceSidebar
## 9.1 Tab 结构
左侧栏建议使用 `QTabWidget`
```text
文件
搜索
上下文
```
------
## 9.2 文件 Tab
显示文件树。
第一版可以先不用完整树形结构,继续使用当前已有的索引结果列表。
后续再升级为:
```cpp
QTreeView + QFileSystemModel
```
或自定义模型。
按钮:
```text
读取
打开
定位
加入上下文
复制路径
```
------
## 9.3 搜索 Tab
包含:
```text
搜索输入框
搜索类型:文件名 / 文本内容
搜索按钮
结果列表
```
搜索结果点击后:
```text
1. 更新右侧 Inspector
2. 可双击读取
3. 可加入上下文
```
------
## 9.4 上下文 Tab
显示 Agent 当前已经读取或参考过的文件:
```text
已加入上下文:
- README.md
- CMakeLists.txt
- src/workspace/WorkspaceController.cpp
```
每项支持:
```text
移出上下文
打开
定位
重新读取
```
------
# 10. 中间区 WorkspaceChatView
## 10.1 职责
中间区是 Agent 面板核心。
它负责显示:
```text
1. 用户输入
2. Agent 回复
3. 工具调用
4. 工具返回结果
5. 文件读取记录
6. 搜索结果摘要
7. 修改计划
8. 错误提示
```
------
## 10.2 消息类型
新增消息类型:
```cpp
enum class WorkspaceMessageType
{
User,
Assistant,
ToolCall,
ToolResult,
FileRead,
SearchResult,
Plan,
Diff,
Warning,
Error
};
```
消息结构:
```cpp
struct WorkspaceMessage
{
WorkspaceMessageType type = WorkspaceMessageType::Assistant;
QString title;
QString content;
QStringList relatedFiles;
QDateTime createdAt;
};
```
------
## 10.3 显示样式
第一版可以用:
```cpp
QTextEdit
```
或者:
```cpp
QScrollArea + QVBoxLayout + message widget
```
推荐第一版用 `QScrollArea + QVBoxLayout`
原因:
```text
1. 后续每种消息可以有不同样式
2. 工具调用可以做折叠
3. Diff 可以单独嵌入控件
4. 比 QTextEdit 更适合 Agent UI
```
------
# 11. 右侧栏 WorkspaceInspector
## 11.1 Tab 结构
右侧栏建议使用 `QTabWidget`
```text
详情
命中
变更
```
------
## 11.2 详情 Tab
显示当前选中文件:
```text
src/workspace/WorkspaceAccessPolicy.h
类型:文本文件
大小:1434 字节
修改时间:2026-06-23 04:59:27
相对路径:src/workspace/WorkspaceAccessPolicy.h
[读取] [打开] [定位] [加入上下文]
```
------
## 11.3 命中 Tab
显示文本搜索命中:
```text
README.dev.md:333
搜索包含 class 的文件:搜索文本内容,显示路径、行号和片段
src/workspace/WorkspaceAccessPolicy.h:5
class WorkspaceAccessPolicy
```
------
## 11.4 变更 Tab
用于后续显示待确认修改:
```text
待确认变更:
1. src/ui/workspace/WorkspacePanel.cpp
- 调整为三栏布局
2. src/ui/workspace/WorkspaceInputBar.cpp
- 新增任务输入栏
[查看 Diff] [确认应用] [取消]
```
第一版可以先显示:
```text
暂无待确认变更
```
------
# 12. 底部输入栏 WorkspaceInputBar
## 12.1 基本控件
底部输入栏包含:
```text
任务输入框
发送按钮
停止按钮
附加文件按钮
模式按钮
```
第一版可以只做:
```text
任务输入框
发送按钮
停止按钮
```
输入框 placeholder
```text
输入任务,例如:分析这个项目结构,搜索 workspace 相关代码,读取第二个文件……
```
------
## 12.2 快捷命令
后续支持:
```text
/scan 重新扫描工作区
/search 搜索文件或文本
/read 读取文件
/clear 清空上下文
/mode 切换权限模式
```
第一版不强制实现。
------
# 13. 当前面板迁移方案
当前截图中的内容迁移如下:
## 13.1 当前“上一轮结果”
迁移到:
```text
WorkspaceSidebar -> 搜索 Tab
```
------
## 13.2 当前“选中项”
迁移到:
```text
WorkspaceInspector -> 详情 Tab
```
------
## 13.3 当前“文本命中”
迁移到:
```text
WorkspaceInspector -> 命中 Tab
```
------
## 13.4 当前“最近读取”
迁移到:
```text
WorkspaceSidebar -> 上下文 Tab
```
或者:
```text
WorkspaceInspector -> 详情 Tab 下方
```
推荐放到左侧“上下文 Tab”。
------
## 13.5 当前底部按钮
当前按钮:
```text
读取
打开
位置
关闭
```
迁移为:
```text
详情 Tab:
读取
打开
定位
加入上下文
TopBar:
关闭
InputBar:
发送
停止
```
------
# 14. 样式建议
当前面板深色风格可以保留。
建议统一颜色变量:
```cpp
const QString BackgroundColor = "#0f172a";
const QString PanelColor = "#17233a";
const QString BorderColor = "#2b4164";
const QString PrimaryColor = "#2d5be3";
const QString TextColor = "#ffffff";
const QString MutedTextColor = "#b9c7dd";
```
不要在每个控件里到处写重复样式。
建议新建:
```text
src/ui/workspace/WorkspaceStyle.h
```
或在 `WorkspacePanel.cpp` 内先集中管理。
------
# 15. WorkspaceController 对接
UI 不直接调用底层文件工具。
UI 调用:
```cpp
WorkspaceController
```
建议接口:
```cpp
class WorkspaceController
{
public:
bool hasWorkspace() const;
QString workspaceRoot() const;
bool openWorkspace(const QString &rootPath, QString *errorMessage = nullptr);
bool rescan(QString *errorMessage = nullptr);
QVector<WorkspaceFileInfo> indexedFiles() const;
QVector<WorkspaceFileInfo> lastSearchResults() const;
QVector<WorkspaceTextMatch> lastTextMatches() const;
QVector<WorkspaceFileInfo> recentlyReadFiles() const;
WorkspaceToolResult searchFiles(const QString &keyword);
WorkspaceToolResult searchText(const QString &keyword);
WorkspaceToolResult readFile(const QString &relativeOrAbsolutePath);
WorkspaceToolResult openFile(const QString &relativeOrAbsolutePath);
WorkspaceToolResult revealFile(const QString &relativeOrAbsolutePath);
WorkspaceToolResult handleUserTask(const QString &message);
};
```
第一版 `handleUserTask` 可以先做规则分发,不必实现完整模型工具调用。
------
# 16. Agent 对话第一版行为
第一版不要急着做完整自动 Agent。
先做规则驱动:
```text
用户输入包含“搜索”:
调 searchFiles 或 searchText
用户输入包含“读取 / 打开第几个 / 第二个”:
使用上一轮搜索结果
用户输入包含“分析项目”:
读取 README.md、CMakeLists.txt、main.cpp、src 目录结构,然后交给 AI
用户输入普通问题:
作为普通 AI 对话,但附加当前工作区摘要
```
------
# 17. 确认机制
涉及写操作时,必须进入确认流程。
窗口中显示:
```text
Agent 准备执行以下操作:
操作:移动文件
源路径:src/old/FileOperationManager.cpp
目标路径:src/workspace/old/FileOperationManager.cpp
风险:高
是否确认?
```
按钮:
```text
确认执行
取消
```
第一版可以先只展示计划,不真正实现写操作。
------
# 18. 施工顺序
## 阶段 1:独立窗口
目标:
```text
新增 WorkspaceAgentWindow
新增 WorkspacePanel
PetWindow 右键菜单可以打开独立窗口
窗口可以独立移动、最小化、最大化
关闭窗口时隐藏,不销毁
```
验收:
```text
桌宠窗口和 Agent 窗口彼此独立
关闭 Agent 窗口不退出程序
再次打开保留状态
```
------
## 阶段 2:迁移现有面板
目标:
```text
把当前已有的工作区路径、索引项、搜索结果、选中项、文本命中、最近读取迁移到 WorkspacePanel
```
验收:
```text
新窗口中能看到当前截图已有功能
读取 / 打开 / 定位功能正常
```
------
## 阶段 3:三栏布局
目标:
```text
顶部 TopBar
左侧 Sidebar
中间 ChatView
右侧 Inspector
底部 InputBar
```
验收:
```text
界面从“文件检索器”变成“Agent 工作台”
中间区域为对话主区域
左侧和右侧为辅助区域
```
------
## 阶段 4:任务输入栏
目标:
```text
底部可以输入任务
点击发送后添加用户消息
系统根据规则返回 Agent 消息
```
验收:
```text
用户输入“搜索 workspace”
左侧显示搜索结果
中间显示工具调用过程
右侧显示选中文件详情
```
------
## 阶段 5:工作区选择
目标:
```text
顶部增加“选择工作区”
使用 QFileDialog 选择目录
选择后扫描索引
更新 TopBar 状态
```
验收:
```text
可以切换工作区
切换后搜索结果清空
索引数量更新
最近扫描时间更新
```
------
## 阶段 6:Agent 对话只读分析
目标:
```text
支持“分析这个项目”
自动读取 README.md、CMakeLists.txt、main.cpp 和 src 目录结构
调用现有 AI 对话能力返回分析结果
```
验收:
```text
用户可以在面板中输入“分析这个项目”
系统能显示读取了哪些文件
AI 能给出项目结构分析
```
------
## 阶段 7:确认计划与变更区
目标:
```text
右侧增加“变更”Tab
支持展示待确认操作计划
```
验收:
```text
写操作不会直接执行
会先显示计划
用户确认后才执行
```
------
# 19. CMake 修改
新增文件后,需要加入 `CMakeLists.txt`
第一阶段至少加入:
```text
src/ui/workspace/WorkspaceAgentWindow.h
src/ui/workspace/WorkspaceAgentWindow.cpp
src/ui/workspace/WorkspacePanel.h
src/ui/workspace/WorkspacePanel.cpp
src/ui/workspace/WorkspaceTopBar.h
src/ui/workspace/WorkspaceTopBar.cpp
src/ui/workspace/WorkspaceSidebar.h
src/ui/workspace/WorkspaceSidebar.cpp
src/ui/workspace/WorkspaceChatView.h
src/ui/workspace/WorkspaceChatView.cpp
src/ui/workspace/WorkspaceInspector.h
src/ui/workspace/WorkspaceInspector.cpp
src/ui/workspace/WorkspaceInputBar.h
src/ui/workspace/WorkspaceInputBar.cpp
```
注意:
当前项目 `CMAKE_AUTOMOC` 是关闭的。
所以第一版新增 UI 类尽量不要使用 `Q_OBJECT`
需要回调时优先使用:
```cpp
std::function
```
例如:
```cpp
void setSendCallback(std::function<void(const QString &)> callback);
```
------
# 20. 编码要求
## 20.1 大括号风格
使用 Allman 风格:
```cpp
if (condition)
{
doSomething();
}
```
------
## 20.2 不使用 OutputDebugStringA
不要使用:
```cpp
OutputDebugStringA
```
日志使用项目已有 Logger,或者在必要时使用控制台输出。
------
## 20.3 不引入复杂依赖
第一版不要引入:
```text
QML
WebView
第三方 Diff 库
SQLite
向量数据库
Everything SDK
```
先用 Qt Widgets 原生控件完成闭环。
------
# 21. 验收清单
完成后必须满足:
```text
1. Agent 面板是独立顶层窗口。
2. 桌宠窗口关闭 / 隐藏不影响 Agent 面板。
3. Agent 面板关闭时默认隐藏,不丢失状态。
4. 可从桌宠右键菜单打开 Agent 面板。
5. Agent 面板有顶部工作区栏。
6. Agent 面板有左侧文件 / 搜索 / 上下文区域。
7. Agent 面板有中间对话区。
8. Agent 面板有右侧详情 / 命中 / 变更区域。
9. Agent 面板有底部任务输入栏。
10. 可以选择工作区。
11. 可以重新索引。
12. 可以搜索文件。
13. 可以读取文件。
14. 可以打开文件。
15. 可以定位文件。
16. 可以显示最近读取。
17. 可以输入任务并在中间对话区显示用户消息和 Agent 回复。
18. 不发生 PetWindow 继续膨胀的问题。
19. 项目可以正常编译。
```
------
# 22. 最终目标
本次改造完成后,界面形态应从:
```text
文件检索面板
```
升级为:
```text
Codex 风格的本地工作区 Agent 面板
```
桌宠负责陪伴和入口,Agent 窗口负责复杂任务。
最终产品体验应类似:
```text
用户打开桌宠
点击“本地工作区 Agent”
弹出独立工作区窗口
选择项目目录
输入“分析这个项目”
Agent 搜索、读取、分析文件
在对话区展示过程和结论
需要修改时展示计划和 Diff
用户确认后执行
```
这是后续接近 Codex / Claude Code 工作流的基础。