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.
9.3 KiB
9.3 KiB
当前代码状态与结构审计
用途:处理结构、命名、模块边界或技术债任务前读取。本文只记录已经由源码确认的现状;精确实现仍以当前源码为准。修复顺序和验收要求见 REPAIR_BACKLOG.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 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 的硬性边界 |
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__、数据库、日志和锁等运行产物。当前不做清理工程;测试必须使用临时位置,避免继续污染生产数据。
应保持的边界
core/agent/保持 GUI-free;纯 agent 行为可不创建QApplication直接测试。- 浏览器差异留在 WebView2/QtWebEngine 适配层,不把后端判断散落到业务逻辑。
- 系统热键、截图和 shell 通过最小平台适配接口选择实现;Windows 模块与 Linux 模块只在对应平台延迟导入。
- 数据库存取继续由
core/db_manager.py承担;新的 UI 功能不要增加直接 SQL。 - Python↔JavaScript 载荷使用完整、可测试的描述符;DOM 只保存当前窗口,不承担持久化或完整会话真相。
- 运行时秘密边界、任务范围和验证要求分别以本目录的
README.md、REPAIR_BACKLOG.md和VERIFICATION.md为准。
本阶段明确延后
- 拆分
main_window.py、app.js或迁移现有模块。 - 批量重命名文件、类或公开跨语言接口。
- PyInstaller/其他打包配置、安装器、AppData/XDG 数据目录迁移。
- WebKitGTK 或其 Qt 封装。
- 通用键盘钩子框架;Linux 只实现现有截图快捷键需要的能力。
- agent shell 沙盒、命令审批、路径权限边界。
- 新工具注册系统、参考其他 harness 增加功能或改变 pi 对齐目标。
- Ubuntu 以外 Linux 发行版的支持承诺。
结构或命名任务只有在“发现的问题已逐项归类为确定缺陷、已接受技术债或明确延后,并且没有借机移动/拆分模块”时才算审计完成。