Skip to content

[Feat & Bug] Core Tool Enhancements, Audit & Session Stats Panel / 核心工具增强、审核与会话统计面板#49

Merged
SunYanbox merged 7 commits intomainfrom
develop
Apr 30, 2026
Merged

[Feat & Bug] Core Tool Enhancements, Audit & Session Stats Panel / 核心工具增强、审核与会话统计面板#49
SunYanbox merged 7 commits intomainfrom
develop

Conversation

@SunYanbox
Copy link
Copy Markdown
Owner

Overview / 概述

This PR implements the core feature enhancements for the second phase of ManualAid, including the safe editing toolchain (two-phase commit audit mechanism), Git whitelist command encapsulation, audit tab UI, session statistics panel, as well as multiple stability fixes and UI optimizations. / 本 PR 实现了 ManualAid 第二阶段的核心功能增强,包括安全编辑工具链(两阶段提交审核机制)、Git 白名单命令封装、审计标签页 UI、会话统计面板,以及多项稳定性修复和 UI 优化

Contains 7 commits spanning from 2026-04-29 to 2026-04-30. / 包含 7 个提交,时间跨度 2026-04-29 ~ 2026-04-30


New Features / 新增功能

1. Core Tool Enhancements — Safe Editing & Two-Phase Commit / 核心工具增强 — 安全编辑与两阶段提交

  • EditTool: Safe string replacement editing with context_before/context_after context validation and max_replacements limit / EditTool:安全字符串替换编辑,支持 context_before/context_after 上下文校验和 max_replacements 限制
  • GitTool: Whitelist-based safe encapsulation with three-level classification / GitTool:白名单安全封装,三级分类
    • Safe commands (e.g., status, log) execute directly without audit / 安全命令(如 status、log)免审直接执行
    • Modification commands (e.g., add, commit) require audit / 修改命令(如 add、commit)标记需审核
    • Dangerous commands are blocked directly / 禁止命令直接拦截
  • WriteTool: Changed to preview mode, no longer writes to disk directly, creates PENDING_AUDIT snapshot / WriteTool:改为预览模式,不再直接写盘,发布 PENDING_AUDIT 快照
  • AuditCommitter: Post-audit write module, new files go through create_file_with_parents, existing files verify mtime to prevent conflicts / AuditCommitter:审核后写盘模块,新文件走 create_file_with_parents,已有文件校验 mtime 防冲突

2. Audit Tab / 审计标签页

  • Textual third tab displaying all PENDING_AUDIT snapshots / Textual 第三标签页,展示所有 PENDING_AUDIT 快照
  • Supports approve/reject operations / 支持批准 / 拒绝操作
  • Asynchronous DOM mounting without blocking UI thread / 异步 DOM 挂载,不阻塞 UI 线程
  • Differentiated styling with long list scrolling support / 差异化样式展示,支持长列表滚动

3. Session Statistics Panel / 会话统计面板

  • New StatsTab component for global and per-session tool usage ranking / 新增 StatsTab 组件,全局与单会话维度工具调用排名
  • DatabaseManager extensions: get_session_summary, get_all_sessions, rename_session, delete_session, get_tool_usage_ranking / DatabaseManager 扩展:get_session_summary、get_all_sessions、rename_session、delete_session、get_tool_usage_ranking
  • Real-time session duration display (updates every second) / 实时会话时长显示(每秒更新)
  • Session rename/delete interactive dialogs / 会话重命名 / 删除交互对话框

Fixed Issues / 修复问题

Category / 类别 Description / 描述
Windows Compatibility / Windows 兼容性 NTFS timestamp precision issue causing mtime detection failure, added extra write fallback logic / NTFS 时间戳精度问题导致 mtime 检测失败,增加额外写入兜底逻辑
UI Rendering / UI 渲染 Audit diff content height overflow, added max-height and overflow-y: auto / 审计差异内容高度溢出,添加 max-height 和 overflow-y: auto
UI Components / UI 组件 Fixed #tools-result-collapsibles#tools-result-collapsible ID mismatch / 修正 #tools-result-collapsibles → #tools-result-collapsible ID 不匹配
Async Interaction / 异步交互 Changed AuditTab._refresh and on_button_pressed to async to prevent UI blocking / 修正 AuditTab._refresh 和 on_button_pressed 改为 async,避免 UI 阻塞
Race Conditions / 竞态条件 Replaced direct call with set_timer for set_committer refresh logic / set_committer 刷新逻辑改用 set_timer 代替直接调用
Git Robustness / Git 健壮性 Force GIT_PAGER=cat / GIT_TERMINAL_PROMPT=0 in subprocess.run to disable interaction; add null protection for stdout/stderr / subprocess.run 强制 GIT_PAGER=cat / GIT_TERMINAL_PROMPT=0 禁用交互;stdout/stderr 空值防护

Architecture Changes / 架构变更

  • Database / 数据库: Added pending_content column and related query methods to file_snapshots table / file_snapshots 表新增 pending_content 列及相关查询方法
  • ToolRegistry / 工具注册表: Three-level classification query / edit / dangerous, Git determines audit status by subcommand / 工具三级分类 query / edit / dangerous,Git 按子命令判定审核状态
  • Two-Phase Commit / 两阶段提交: Writes/edits only record snapshots → user audits in AuditTab → actual write after approval / 写入/编辑仅记录快照 → 用户在 AuditTab 审核 → 批准后实际写盘

Code Quality / 代码质量

  • Improved unit tests: TestSessionSummary, TestAllSessions, TestRenameSession, etc. / 完善 TestSessionSummary、TestAllSessions、TestRenameSession 等单元测试
  • Type annotation fix: _log_tool_call return type from None to str | None / 类型注解修正:_log_tool_call 返回类型 None → str | None

新增功能: 引入 `.ManualAid/` 数据库目录和文件修改时间校验机制
- 新增 `DatabaseManager` 线程安全单例类
  * 按 workspace 路径区分实例(支持多工作区并发)
  * WAL 模式支持并发读写并保持 ACID
  * 统一封装 `execute/fetchone/fetchall` 查询接口
  * 自动创建 `.ManualAid/manualaid.db` 数据库文件
  * 预定义 sessions, tool_calls, file_read_records, file_snapshots 表
  * 支持线程安全:`threading.local()` 连接 + `threading.Lock` 写保护

- 新增 `FileTracker` 文件元数据工具类
  * 使用 BLAKE2b 哈希(SHA256 替代,更快速)
  * 统一处理 mtime/size/checksum 计算

- 工具调用流程增强
  * ToolRegistry.execute() 自动记录调用到 `tool_calls` 表(含 duration_ms, status, args_hash)
  * console 启动时自动创建 session,atexit 时关闭并记录运行时长

- 文件读取操作 (`read`, `read_lines`) mtime 追踪
  * 成功读取后自动记录 `(file_path, mtime, size, checksum)` 到 `file_read_records` 表
  * UPSERT 语义:新记录插入,已有记录更新 mtime 并增加 read_count
  * 错误静默处理,不影响正常读取功能

- 文件写入操作 (`write`) 外部修改保护
  * 写入前执行 mtime 验证:检查文件是否在读取后被外部修改
  * 容差 0.001 秒,适应不同文件系统精度差异
  * 文件从未读取时,允许直接写入(无保护)
  * 检测到外部修改时返回 AI 友好的错误消息:
    "ERROR: FILE_MODIFIED_EXTERNALLY - The file was modified externally since last read. Please re-read the file with the "read" tool before writing to it."
  * 安全写入后记录 diff 到 `file_snapshots` 表(audit_status='PENDING_AUDIT')

- 测试覆盖:新增 49 个测试,共 80/80 通过(1跳过的)
  * `DatabaseManager`: 单例、线程安全、WAL、CRUD、边界条件
  * `FileTracker`: BLAKE2b、文件元数据计算
  * `ReadTool`: mtime/checksum 记录、read_count 更新
  * `WriteTool`: mtime 验证、外部修改阻止、diff 生成、快照记录

📝 Phase 1 完全实现了 TODO_数据库持久化.md 中的 P0 核心架构
✅ 提供原子性文件写入、外部修改保护、AI 友好错误消息
🏗️ Phase 2 (P1) 准备就绪:编辑工具重构、Git 工具统一封装、审计仪表板
- 问题: Windows NTFS 时间戳精度为 100ns,但某些情况下 0.01 秒延迟仍不足以保证 mtime 变化
- 修复: 在检测到时间戳未变化时(stored_mtime == current_mtime)增加额外写入操作
- 优化: 增加时间戳验证逻辑,确保测试的健壮性
- 测试: 外部修改检测现在可靠通过,所有 80 个测试依然保持通过

✅ windows/ntfs 兼容性确保,Phase 1 数据库持久化测试完全稳定
新增功能:
- EditTool: 安全字符串替换编辑,支持上下文校验和 max_replacements 限制
- GitTool: 白名单安全封装,安全命令免审/修改命令标记/禁止命令拦截
- AuditTab: Textual 第三标签页,展示 PENDING_AUDIT 快照,支持批准/拒绝
- AuditCommitter: 审核后写盘模块,新文件走 create_file_with_parents,已有文件校验 mtime
- WriteTool: 改为预览模式,不再直接写盘,发布 PENDING_AUDIT 快照

架构变更:
- 数据库: file_snapshots 表新增 pending_content 列 + 查询方法
- ToolRegistry: 工具三级分类 (query/edit/dangerous),git 按子命令判定审核状态
- 两阶段提交: 写入/编辑仅记录快照,审核批准后实际写盘
- 新增功能: 实现完整的会话统计面板与数据库支持
  * 新增 `src/console/ui/widgets/stats_tab.py` 模块,包含 `StatsTab`、`RenameDialog` 和 `QuestionDialog` 组件
  * 在 `tui_console.py` 中集成新的 "Statistics" 标签页,支持切换时自动刷新数据
  * 扩展 `DatabaseManager` 新增 `get_session_summary`、`get_all_sessions`、`rename_session`、`delete_session` 及 `get_tool_usage_ranking` 等统计相关 API
  * 实现全局与单会话维度的工具调用排名计算逻辑,支持按次数降序排列并展示平均耗时
- 修复问题: 优化审核标签页的异步交互体验
  * 将 `AuditTab._refresh` 和 `on_button_pressed` 改为 `async` 方法,确保 UI 线程不阻塞
  * 修正 `set_committer` 中的刷新逻辑,改用 `set_timer` 避免挂载前的竞态条件
  * 调整 `AuditTab` CSS 移除硬编码的 `font-family` 以适配主题
- 重构优化: 统一代码风格与文档注释格式
  * 将 `git_tool.py`、`edit_tool.py`、`audit_committer.py` 等文件中的中文逗号 `,` 统一替换为英文逗号 `,`
  * 更新 `tool_registry.py` 和测试文件中的注释标点符号规范
  * 完善 `TestSessionSummary`、`TestAllSessions`、`TestRenameSession` 等单元测试用例
- 新增功能: 实时展示当前会话持续时间
  * 在 `stats_tab.py` 的 `on_mount` 中引入 `set_interval(1.0, self._update_live_duration)` 定时器
  * 新增 `_update_live_duration` 方法,通过查询 `sessions` 表的 `created_at` 字段计算并更新 `#stats-current-session` 表格单元格
  * 复用 `_format_duration` 方法将秒数转换为人类可读格式
- 修复问题: 修正 UI 组件 ID 不匹配导致的渲染错误
  * 在 `tools_result_widget.py` 中将查询 ID 从 `#tools-result-collapsibles` 修正为 `#tools-result-collapsible`
- 重构优化: 异步化 DOM 挂载操作以支持并发渲染
  * 在 `audit_tab.py` 中将 `self.mount()` 和 `log.mount()` 调用替换为 `await self.mount()` 和 `await log.mount()`
  * 在 `audit_tab.py` 的 CSS 样式中添加 `overflow-y: auto` 以支持长列表滚动
- 类型修正: 统一工具调用日志函数的返回类型
  * 将 `tool_registry.py` 中 `_log_tool_call` 方法的返回类型注解由 `None` 更改为 `str | None`
  * 调整 `session_id` 为空时的返回值逻辑以匹配新的类型定义
- 修复问题: 修正审计差异内容高度溢出及显示异常
  * 为 `.audit-diff` CSS 类添加 `max-height: 15` 限制
  * 启用 `.audit-diff` 的 `overflow-y: auto` 滚动属性
- 重构优化: 调整差异内容容器的层级结构
  * 将 `Static` 组件从直接追加改为包裹在 `Vertical` 容器内
  * 更新变量命名以区分 `diff_static` 与 `diff_container`
- 修复问题:增强子进程输出的空值兼容性
  * result.stderr 增加空值防护 (result.stderr or "")
  * result.stdout 为 None 时回退至 explicit PIPE 模式捕获字节流并解码
- 修复问题:强制禁用 Git 命令行交互与分页
  * subprocess.run env 添加 GIT_PAGER=cat 及 GIT_TERMINAL_PROMPT=0
  * 忽略 Ruff UP022 规则关于 capture_output 的警告,保留 bytes 回退逻辑
@SunYanbox SunYanbox self-assigned this Apr 30, 2026
@SunYanbox SunYanbox added bug Something isn't working enhancement New feature or request labels Apr 30, 2026
@SunYanbox SunYanbox merged commit e733cb3 into main Apr 30, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant