# 当前代码状态与结构审计 > 用途:处理结构、命名、模块边界或技术债任务前读取。本文只记录已经由源码确认的现状;精确实现仍以当前源码为准。修复顺序和验收要求见 [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 发行版的支持承诺。 结构或命名任务只有在“发现的问题已逐项归类为确定缺陷、已接受技术债或明确延后,并且没有借机移动/拆分模块”时才算审计完成。