Files
sorrow404null bc0b92bcdc docs: add agent handoff docs, verification guide, and repair evidence
Add docs/agent-handoff (backlog, execution state, verification, platform plan, per-task evidence), repo AGENTS.md, and architecture notes updated for the dual-renderer design.
2026-09-17 16:40:06 +08:00

111 lines
9.3 KiB
Markdown
Raw Permalink 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.
# 当前代码状态与结构审计
> 用途:处理结构、命名、模块边界或技术债任务前读取。本文只记录已经由源码确认的现状;精确实现仍以当前源码为准。修复顺序和验收要求见 [REPAIR_BACKLOG.md](REPAIR_BACKLOG.md) 与 [VERIFICATION.md](VERIFICATION.md)。
## 结论
项目的目录分层和文件命名总体符合 Python、JavaScript 与 Qt 项目的常见习惯,不需要为了“看起来规范”而批量改名或搬目录。当前主要风险不在命名,而在以下位置:
- `ui/views/main_window.py` 承担窗口组装、浏览器选择、会话、附件、截图、弹层和大量事件处理,已经形成高耦合中心。
- `ui/web/app.js` 同时负责渲染、流式更新、历史、分支和交互状态,Python 与 JavaScript 之间没有显式协议定义。
- Windows 专用的 WebView2、全局热键、进程终止和路径假设尚未被完整隔离,Linux 不能仅凭“Python 跨平台”获得支持。
- 测试入口聚合不完整(P2-04 待实施);配置重定向与运行时数据隔离已由 P0-01 统一(见 [REPAIR_BACKLOG.md](REPAIR_BACKLOG.md) P0-01 与 evidence/P0-01.md)。
- 根目录旧文档混有过时描述;它们不能继续作为实现依据。
当前阶段允许修复错误、添加测试和添加小型平台适配器,但不移动或拆分现有模块。超大文件是已记录技术债,不是本轮重构授权。
## 目录职责
| 路径 | 当前职责 | 审计判断 |
| --- | --- | --- |
| `main.py` | 进程入口、标准输出保护、QtWebEngine 启动参数、`QApplication` 和主窗口创建 | 入口职责基本合理;渲染参数需要区分平台 |
| `core/` | 数据库、LLM 工作线程、日志和 WebView2 后端 | 名称规范;仍含 Windows 专用实现和配置路径旁路 |
| `core/agent/` | 与 pi 对齐的 agent 循环、上下文、压缩、恢复和内置工具 | 应继续保持 GUI-free、可离线测试 |
| `ui/views/` | PyQt6 窗口、桥接层和浏览器包装 | 边界最薄弱;`main_window.py` 是主要风险点 |
| `ui/views/system_tools/` | 文件读取、全局热键、屏幕截图 | 适合作为平台适配落点;当前实现以 Windows 为中心 |
| `ui/web/` | 离线 HTML/CSS/JavaScript 聊天界面和 vendored 前端库 | 无需构建步骤;历史窗口状态机尚未独立 |
| `tools/builtin_tools/` | 面向 agent 的独立实用工具 | 当前仅有 PDF 读取器;与其他两类“工具”需用全路径区分 |
| `tests/` | 纯逻辑测试、offscreen smoke、诊断与人工验证脚本 | 命名前缀有约定,但聚合入口没有覆盖全部自动化测试 |
| `data/` | 源码运行时的配置、数据库和附件 | 本阶段保留项目内路径;凭据处理遵循 [README.md](README.md) 的硬性边界 |
| `vendor/webview2/``WebView2Loader.dll` | Windows WebView2 运行依赖 | 只允许 Windows 路径加载,不能成为 Linux 启动前置条件 |
| `svg/` | UI 图标 | 目录职责清晰 |
## 命名规范审计
| 范围 | 现状 | 结论 |
| --- | --- | --- |
| Python 文件、函数、变量 | 基本使用 `snake_case` | 符合 PEP 8 常规写法 |
| Python 类 | 基本使用 `PascalCase` | 符合惯例 |
| Qt 覆盖方法 | 使用 `eventFilter``closeEvent` 等 Qt 固定名称 | 正确例外,不应改成 `snake_case` |
| QWebChannel/JS 可调用接口 | 存在 camelCase 名称 | 跨语言协议名称可保留,但必须集中记录 |
| JavaScript | 主要使用 `camelCase` | 符合惯例 |
| CSS | 选择器和属性使用 Web 常规形式 | 符合惯例 |
| 测试文件 | `test_*``smoke_*``diag_*``verify_*``tune_*` | 前缀表达运行性质,约定合理 |
以下名称有可读性或发布规范问题,但不应在当前修复阶段批量改名:
- `Frame.md` 语义过宽,且与 `readme.md``ARCHITECTURE.md` 的职责重叠。旧文档只作历史资料。
- `readme.md` 的大小写不影响源码运行;是否改成 `README.md` 留到仓库整理阶段。
- `db_manager.py``llm_engine.py` 等名称合规,但 “manager/engine” 隐藏了较宽职责;先通过边界文档约束新增代码。
- `core/agent` 的版本字符串不是标准 PEP 440 形式;打包阶段再统一。
- “工具”同时指 agent 的 `read/bash/write/edit``tools/builtin_tools/` 实用工具和 `ui/views/system_tools/` 桌面集成。任务与文档必须使用完整路径或明确类别,不能只写“tool”。
## 已确认的结构与行为缺陷
### 配置和测试隔离
- 已解决(P0-01):所有运行时配置读取统一经 `core/config_paths``HAOCODE_CONFIG_FILE` 优先);`tests/test_config_isolation.py` 用打开路径拦截器证明真实配置从未被打开。
- 新测试必须在导入 `MainWindow` 及相关模块前同时重定向数据库和配置(统一用 `tests/_test_env.py``isolate()`),并检查被测模块是否缓存了路径常量。
- 少数 GUI 测试(`smoke_offscreen.py``smoke_mode.py``smoke_copy_session.py`)自身只重定向数据库、未设置 `HAOCODE_CONFIG_FILE`;独立运行时由环境注入临时配置,P2-04 聚合入口将按子进程强制注入。
- `tests/run_tests.py` 当前不是全套测试聚合器,不能把一次成功运行等同于整个 `tests/` 目录通过。
### UI 和事件处理
- 已解决(P0-02):`MainWindow` 重复定义的 `eventFilter` 已合并为一份;发送规则收进 `send_message(from_enter=...)` 单一实现(见 evidence/P0-02.md)。
- UI 层存在直接 SQL 和跨模块私有成员访问,导致数据库、窗口和渲染状态相互渗透。当前只修复会造成实际错误的调用,不展开分层重构。
- 原生窗口型 WebView2 与 Qt 弹层的遮挡关系需要逐个验证;重命名弹层是已确认案例,不能假定所有 QWidget 弹层都会自然显示在 WebView2 之上。
### Python 与 JavaScript 边界
- 当前通过 `ui/views/chat_bridge.py`、直接 JavaScript 执行以及硬编码函数名传递状态,没有协议版本、载荷 schema 或统一错误回传。
- 当前没有“按边界消息 ID + 方向”请求历史页的 JS→Python 协议。现有消息缓冲也不足以重建附件、时间线、工具输出和分支关系完整的历史项。
- 建立历史滑动窗口时,必须传递完整消息描述符,并用会话/分支 generation 丢弃过期响应;不能让前端自行拼接不完整历史。
- 跨语言公开名称一旦落地即视为协议。实现 Agent 应把请求、响应、错误和重置事件集中列在同一处,并用契约测试锁定。
### 平台边界
- `core/webview2.py``ui/views/wv2_view.py` 和相关进程处理是 Windows 专用路径;Linux 只能选择 QtWebEngine。
- `ui/views/system_tools/global_hotkey.py` 使用 Windows 原生 API,Linux 导入和运行路径尚未隔离。
- agent 的 bash 工具使用隐式 shell 选择:Windows 通常落到 `cmd.exe`Linux 通常落到 `/bin/sh`,不满足既定的 `/bin/bash -lc` 契约。
- Windows 使用进程树终止手段;POSIX 侧尚无对完整进程组的等价取消/超时保证。
- 项目中的 Windows 路径、动态库和 WebView2 探测不能在 Linux 启动阶段被无条件访问。
### 文档和仓库状态
- `ARCHITECTURE.md` 仍含旧产品名和失效目录;误拼接的外部修复文档已经移除,文件顶部已明确标记为历史资料。
- 第三方修复要求提到的 `haocode.spec``pyi_rth_trace.py``tests/diag_render_scale.py``tests/diag_panel_scrollbar.py``tests/diag_rename_overlay.py` 当前不存在。上述三个 `tests/diag_*` 脚本可按任务新建;两个打包文件属于后续阶段。
- 工作区没有可用 Git 历史,不能引用不存在的基线提交,也不应擅自初始化仓库。任务清单仍按可独立提交的粒度书写,供未来接入版本控制。
- 源码树存在 `__pycache__`、数据库、日志和锁等运行产物。当前不做清理工程;测试必须使用临时位置,避免继续污染生产数据。
## 应保持的边界
1. `core/agent/` 保持 GUI-free;纯 agent 行为可不创建 `QApplication` 直接测试。
2. 浏览器差异留在 WebView2/QtWebEngine 适配层,不把后端判断散落到业务逻辑。
3. 系统热键、截图和 shell 通过最小平台适配接口选择实现;Windows 模块与 Linux 模块只在对应平台延迟导入。
4. 数据库存取继续由 `core/db_manager.py` 承担;新的 UI 功能不要增加直接 SQL。
5. Python↔JavaScript 载荷使用完整、可测试的描述符;DOM 只保存当前窗口,不承担持久化或完整会话真相。
6. 运行时秘密边界、任务范围和验证要求分别以本目录的 `README.md``REPAIR_BACKLOG.md``VERIFICATION.md` 为准。
## 本阶段明确延后
- 拆分 `main_window.py``app.js` 或迁移现有模块。
- 批量重命名文件、类或公开跨语言接口。
- PyInstaller/其他打包配置、安装器、AppData/XDG 数据目录迁移。
- WebKitGTK 或其 Qt 封装。
- 通用键盘钩子框架;Linux 只实现现有截图快捷键需要的能力。
- agent shell 沙盒、命令审批、路径权限边界。
- 新工具注册系统、参考其他 harness 增加功能或改变 pi 对齐目标。
- Ubuntu 以外 Linux 发行版的支持承诺。
结构或命名任务只有在“发现的问题已逐项归类为确定缺陷、已接受技术债或明确延后,并且没有借机移动/拆分模块”时才算审计完成。