# QtDesktopPet 本地工作区 Agent 独立窗口化施工文档 > 归档说明:该路线已于 2026-07-16 从 QtDesktopPet 当前产品方向中移除,本文仅保留历史设计,不再作为施工依据。 ## 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(); 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 m_workspaceAgentWindow; ``` ------ ## 6.2 新增方法 在 `PetWindow` 中新增: ```cpp void openWorkspaceAgentWindow(); ``` 实现逻辑: ```cpp void PetWindow::openWorkspaceAgentWindow() { if (!m_workspaceAgentWindow) { m_workspaceAgentWindow = std::make_unique(); } 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 indexedFiles() const; QVector lastSearchResults() const; QVector lastTextMatches() const; QVector 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 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 工作流的基础。