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

9.3 KiB
Raw Permalink Blame History

当前代码状态与结构审计

用途:处理结构、命名、模块边界或技术债任务前读取。本文只记录已经由源码确认的现状;精确实现仍以当前源码为准。修复顺序和验收要求见 REPAIR_BACKLOG.mdVERIFICATION.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 覆盖方法 使用 eventFiltercloseEvent 等 Qt 固定名称 正确例外,不应改成 snake_case
QWebChannel/JS 可调用接口 存在 camelCase 名称 跨语言协议名称可保留,但必须集中记录
JavaScript 主要使用 camelCase 符合惯例
CSS 选择器和属性使用 Web 常规形式 符合惯例
测试文件 test_*smoke_*diag_*verify_*tune_* 前缀表达运行性质,约定合理

以下名称有可读性或发布规范问题,但不应在当前修复阶段批量改名:

  • Frame.md 语义过宽,且与 readme.mdARCHITECTURE.md 的职责重叠。旧文档只作历史资料。
  • readme.md 的大小写不影响源码运行;是否改成 README.md 留到仓库整理阶段。
  • db_manager.pyllm_engine.py 等名称合规,但 “manager/engine” 隐藏了较宽职责;先通过边界文档约束新增代码。
  • core/agent 的版本字符串不是标准 PEP 440 形式;打包阶段再统一。
  • “工具”同时指 agent 的 read/bash/write/edittools/builtin_tools/ 实用工具和 ui/views/system_tools/ 桌面集成。任务与文档必须使用完整路径或明确类别,不能只写“tool”。

已确认的结构与行为缺陷

配置和测试隔离

  • 已解决(P0-01):所有运行时配置读取统一经 core/config_pathsHAOCODE_CONFIG_FILE 优先);tests/test_config_isolation.py 用打开路径拦截器证明真实配置从未被打开。
  • 新测试必须在导入 MainWindow 及相关模块前同时重定向数据库和配置(统一用 tests/_test_env.pyisolate()),并检查被测模块是否缓存了路径常量。
  • 少数 GUI 测试(smoke_offscreen.pysmoke_mode.pysmoke_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.pyui/views/wv2_view.py 和相关进程处理是 Windows 专用路径;Linux 只能选择 QtWebEngine。
  • ui/views/system_tools/global_hotkey.py 使用 Windows 原生 API,Linux 导入和运行路径尚未隔离。
  • agent 的 bash 工具使用隐式 shell 选择:Windows 通常落到 cmd.exeLinux 通常落到 /bin/sh,不满足既定的 /bin/bash -lc 契约。
  • Windows 使用进程树终止手段;POSIX 侧尚无对完整进程组的等价取消/超时保证。
  • 项目中的 Windows 路径、动态库和 WebView2 探测不能在 Linux 启动阶段被无条件访问。

文档和仓库状态

  • ARCHITECTURE.md 仍含旧产品名和失效目录;误拼接的外部修复文档已经移除,文件顶部已明确标记为历史资料。
  • 第三方修复要求提到的 haocode.specpyi_rth_trace.pytests/diag_render_scale.pytests/diag_panel_scrollbar.pytests/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.mdREPAIR_BACKLOG.mdVERIFICATION.md 为准。

本阶段明确延后

  • 拆分 main_window.pyapp.js 或迁移现有模块。
  • 批量重命名文件、类或公开跨语言接口。
  • PyInstaller/其他打包配置、安装器、AppData/XDG 数据目录迁移。
  • WebKitGTK 或其 Qt 封装。
  • 通用键盘钩子框架;Linux 只实现现有截图快捷键需要的能力。
  • agent shell 沙盒、命令审批、路径权限边界。
  • 新工具注册系统、参考其他 harness 增加功能或改变 pi 对齐目标。
  • Ubuntu 以外 Linux 发行版的支持承诺。

结构或命名任务只有在“发现的问题已逐项归类为确定缺陷、已接受技术债或明确延后,并且没有借机移动/拆分模块”时才算审计完成。