feat: v0.5.0 审计修复版 — 类型基线重建 + 会话隔离 + SubAgent 可观测性 + 三项功能补全
CI / 类型检查 + Lint + 单元测试 (push) Failing after 5m38s
CI / 产物编译验证 (push) Successful in 10m15s
CI / 全量测试 (Electron ABI) (push) Failing after 5m27s

P0 安全与工程基线(止血):
- .npmrc 移除硬编码 Gitea npm 凭据,改为 GITEA_NPM_AUTH 环境变量注入(已验证未设变量时 401)
- 修复 typecheck 空操作缺陷:solution-style 根 tsconfig 改为双工程真检查(node + web),
  pre-commit 与 CI 门禁恢复拦截能力
- 修复 4 处 v0.4.1 遗留类型错误:confirmation-hook.test 枚举名 FILE_SYSTEM→FILESYSTEM、
  agent.ts VALIDATION 事件 severity 类型谓词收窄、ContextMenu.tsx 导出 attachments 类型
- 补装 v0.4.1 声明但未安装的 node-html-parser 依赖

P1 逻辑缺陷修复(跨模块边界):
- ConfirmationHook 会话隔离:rememberedDecisions 与 pendingConfirmations 按 sessionId 隔离,
  abortSession 只清本会话 pending(修复 A 会话中断误杀 B 会话确认、拒绝记忆跨会话污染)
- SubAgent 可观测性:orchestrator 六个事件此前全项目零消费者,现接入
  ① subagent:event 生命周期广播(AgentMonitor 新增 SubAgent 状态区)
  ② SubEngine 流事件独立 TRACE 录制(sessionId=taskId 的 JSONL 文件)
- main.ts 启动链路异常兜底:初始化失败时记录日志 + 系统错误对话框 + 退出(原为白屏挂起)

P2 工程强化:
- CI:typecheck 双工程真检查;electron-test 从 experimental(continue-on-error)转正为阻塞门禁;
  GITEA_NPM_AUTH secret 注入说明
- 渲染 bundle 代码分割:单 2630KB chunk 拆为 main 557KB + vendor-react/mui/markdown/icons
  (业务代码变更不再使 vendor 缓存失效)
- database 建表 mcp_servers CHECK 直接含 streamable-http(新库不再依赖迁移 6 立即重建)

P3 功能补全:
- DeepSeek 余额显示:新增 llm:getBalance IPC + LLMSettings 余额卡片(复用适配器原死代码 getBalance)
- FTS5 会话内容搜索:messages_fts 虚表 + INSERT/UPDATE/DELETE 触发器实时同步 +
  存量库 rebuild 迁移 + sessions:searchContent IPC + Sidebar 搜索框标题∪内容联合搜索
  (短语转义防 FTS 运算符注入,按会话聚合展示 snippet)
- 审计日志导出:audit:export IPC(JSONL / CSV RFC 4180 转义)+ LogsSettings 导出按钮

文档一致性大扫除:
- README:工具数统一为 28(原 26/27/30 三口径)、handlers.ts→ipc/、录制事件名更正、
  删除虚构的审计导出/归档宣称与 Schema 虚构字段、MCP 三种传输、配置 key 更正、
  项目结构树对齐实际(settings 10 文件/lib 6 文件/react-virtuoso)、clone 地址改为 Gitea、
  新增 GITEA_NPM_AUTH 配置说明、测试数 207
- 架构/构建指南/UI UX/IR 标准 4 份 HTML 设计文档同步修正(工具数、表数 10、
  磁盘文件 2 个现状注记、ipc/*.ts 路径)
- eslint.config.js 与开发规范.md 注释对齐零容忍基线与 better-sqlite3 选型

测试: 199→207 用例(新增 ConfirmationHook 跨会话隔离 5 用例 + FTS5 搜索/审计导出 8 用例)
验证: lint 0 problems / typecheck 双工程 0 errors / test:electron 207 全过 / build 成功
This commit is contained in:
2026-08-21 21:07:01 +08:00
parent 49c9b25538
commit 7e8b4882a0
32 changed files with 3031 additions and 579 deletions
+91 -67
View File
@@ -10,7 +10,7 @@
</p>
<p align="center">
<img src="https://img.shields.io/badge/version-0.4.1-blue?style=flat-square" alt="Version" />
<img src="https://img.shields.io/badge/version-0.5.0-blue?style=flat-square" alt="Version" />
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License" />
<img src="https://img.shields.io/badge/Electron-35-47848F?style=flat-square&logo=electron" alt="Electron" />
<img src="https://img.shields.io/badge/React-19-61DAFB?style=flat-square&logo=react" alt="React" />
@@ -29,7 +29,7 @@
---
<p align="center">
Metona 是一款<strong>基于 Electron 的本地优先 AI Agent 桌面应用</strong>,内置<strong> ReAct 状态机驱动</strong>的智能体循环引擎、<strong>26 个内置工具</strong>、<strong>三层记忆系统</strong>、<strong>四层纵深安全防线</strong>与<strong>完整可观测性链路</strong>。支持六种 LLM ProviderDeepSeek / Agnes / MiMo / Ollama / OpenAI / Anthropic),兼容 <strong>MCP 协议</strong>扩展,为开发者提供开箱即用的 AI 编程伙伴。
Metona 是一款<strong>基于 Electron 的本地优先 AI Agent 桌面应用</strong>,内置<strong> ReAct 状态机驱动</strong>的智能体循环引擎、<strong>28 个内置工具</strong>、<strong>三层记忆系统</strong>、<strong>四层纵深安全防线</strong>与<strong>完整可观测性链路</strong>。支持六种 LLM ProviderDeepSeek / Agnes / MiMo / Ollama / OpenAI / Anthropic),兼容 <strong>MCP 协议</strong>扩展stdio / SSE / Streamable HTTP,为开发者提供开箱即用的 AI 编程伙伴。
</p>
---
@@ -63,7 +63,7 @@
<p>ReAct 八状态闭环、流式对话 (SSE/NDJSON)、Thinking 推理模式、死循环检测、上下文自动压缩、指数退避重试</p>
</td>
<td width="50%">
<h3>🔧 26 个内置工具</h3>
<h3>🔧 28 个内置工具</h3>
<p>文件系统 · 代码搜索 · 网络搜索 · 浏览器自动化 · Git · Shell 命令 · HTTP 请求 · 记忆存储 · 任务管理</p>
</td>
</tr>
@@ -84,7 +84,7 @@
</td>
<td>
<h3>📡 MCP 协议兼容</h3>
<p>支持 stdio / SSE 种传输方式的 MCP Server,动态发现工具,无需重启应用</p>
<p>支持 stdio / SSE / Streamable HTTP 三种传输方式的 MCP Server,动态发现工具,无需重启应用</p>
</td>
</tr>
<tr>
@@ -115,6 +115,7 @@
| 🛰 MCP | **@modelcontextprotocol/sdk** | 1.12 | 外部工具协议集成 |
| 🎨 样式 | **Tailwind CSS** | 4 | 辅助原子化样式 |
| 📝 Markdown | **react-markdown + remark-gfm** | 10 / 4 | 富文本渲染 |
| 🌐 HTML 解析 | **node-html-parser** | 6 | 搜索引擎结果结构化解析 |
| 🔢 UUID | **nanoid** | 5 | 唯一 ID 生成 |
| ✅ 校验 | **Zod** | 3 | 运行时类型校验 |
| 💾 缓存 | **lru-cache** | 11 | 内存缓存 |
@@ -135,20 +136,25 @@
```bash
# 1. 克隆仓库
git clone https://github.com/your-org/metona-ai-desktop.git
git clone https://git.metona.cn/MetonaTeam/metona-ai-desktop.git
cd metona-ai-desktop
# 2. 安装依赖
# 2. 配置私有 npm 仓库凭据(@metona-team/metona-toast 需要)
# 值为 base64("用户名:密码"),向仓库管理员申请
$env:GITEA_NPM_AUTH = "<你的 base64 凭据>" # PowerShell
# export GITEA_NPM_AUTH="<你的 base64 凭据>" # bash
# 3. 安装依赖
npm install
# 3. 配置 API Key(可选——推荐启动后在应用内「设置 → LLM 配置」可视化配置)
# 4. 配置 API Key(可选——推荐启动后在应用内「设置 → LLM 配置」可视化配置)
cp .env.example .env
# 编辑 .env 预置密钥(应用内未配置时自动回退读取,见下方「环境变量」说明)
# 4. 启动开发模式
# 5. 启动开发模式
npm run dev
# 5. 构建生产包
# 6. 构建生产包
npm run build
```
@@ -234,7 +240,7 @@ Metona 的核心是一个 **ReAct (Reasoning + Acting)** 状态机驱动引擎
| 🔄 **流式对话** | SSE (DeepSeek/Agnes/MiMo) + NDJSON (Ollama) 双协议流式响应 |
| 💭 **Thinking 模式** | 支持 deepseek-v4-pro / agnes-2.0-flash / qwen3 等推理模型的思维链展示 |
| 🔁 **死循环检测** | 连续 3 轮相同工具调用签名自动终止 |
| 📦 **上下文压缩** | 80% 阈值触发 LLM 摘要压缩,保留最近 10 条消息 |
| 📦 **上下文压缩** | 80% 阈值触发 LLM 摘要压缩,按 token 预算动态保留近期消息(超长 tool_result 二次截断) |
| 🔄 **错误重试** | 指数退避 (1s/2s/4s) + ±20% jitter,上限 30s |
| ⏱️ **可配置迭代** | 最大迭代次数 (默认 20)、总超时 (默认 600s)、工具执行超时 (默认 120s) |
| 🧵 **子任务委派** | TaskOrchestrator 支持最大 3 层深度的 SubAgent 编排 |
@@ -245,26 +251,29 @@ Metona 的核心是一个 **ReAct (Reasoning + Acting)** 状态机驱动引擎
### 工具分类总览
Metona 内置 **26 个工具**,按安全风险分为五个等级:
Metona 内置 **28 个工具**,按安全风险分为五个等级:
```
SAFE (无需确认) LOW (无需确认) MEDIUM (可配自动) HIGH (强制确认) CRITICAL (双人复核)
SAFE (14 个) LOW (5 个) MEDIUM (6 个) HIGH (3 个) CRITICAL (预留)
│ │ │ │ │
├─ read_file ├─ web_search ├─ write_file ├─ delete_file ├─ (预留)
├─ list_directory ├─ web_fetch ├─ file_editor ├─ run_command
├─ search_files ├─ http_request ├─ memory_store ─ web_browser
├─ code_search ├─ run_tests ├─ delegate_task ├─ git_commit
├─ diff_viewer ─ task_manager ├─ file_move └─ browser actions
├─ git_status └─ think (open/navigate)
├─ read_file ├─ web_search ├─ write_file* ├─ delete_file ├─ (预留)
├─ list_directory ├─ web_fetch ├─ file_editor* ├─ run_command
├─ search_files ├─ http_request ├─ file_move* ─ web_browser
├─ code_search ├─ run_tests ├─ git_commit*
├─ diff_viewer ─ task_manager ├─ memory_store
├─ git_status └─ delegate_task
├─ git_diff
├─ git_log
├─ lint_code
├─ project_info
├─ memory_search
├─ view_image
─ file_info
─ file_info
└─ think
```
> `*` 标记的 MEDIUM 工具设置了 `requiresPermission: true`(执行前需用户确认);未标记的 MEDIUM 工具(memory_store / delegate_task)无需确认。
### 详细工具列表
#### 📂 文件系统 (7 tools)
@@ -319,7 +328,7 @@ SAFE (无需确认) LOW (无需确认) MEDIUM (可配自动)
|:---|:---|:---|:---|
| `git_status` | SAFE | 否 | 工作树状态,porcelain v1 格式解析 |
| `git_diff` | SAFE | 否 | 差异输出,50KB 截断,5MB maxBuffer |
| `git_log` | SAFE | 否 | 提交历史,支持 --oneline / --stat 等格式 |
| `git_log` | SAFE | 否 | 提交历史,--oneline 紧凑格式或 NULL 分隔的完整字段格式 |
| `git_commit` | MEDIUM | 是 | 暂存 + 提交,校验文件在工作空间内 |
#### 📋 任务与辅助 (4 tools)
@@ -343,6 +352,8 @@ Metona 通过统一的 `IMetonaProviderAdapter` 接口抽象了所有 LLM Provid
| **AgnesAdapter** | `agnes` | agnes-2.0-flash | 1M tokens | SSE | `chat_template_kwargs` / Anthropic 兼容 | 是 (URL + Base64) |
| **MimoAdapter** | `mimo` | mimo-v2.5-pro / mimo-v2.5 | 1M tokens | SSE | `thinking.type: enabled` | 是 (URL + Base64) |
| **OllamaAdapter** | `ollama` | qwen3 / gemma3 / deepseek-r1 等 | 可配 (num_ctx) | NDJSON | `think` 参数 | 是 (Base64) |
| **OpenAIAdapter** | `openai` | gpt-4o / gpt-4.1 / o3-mini | 128K~1M tokens | SSE | `reasoning_effort`(o 系列) | 是(o 系列除外) |
| **AnthropicAdapter** | `anthropic` | claude-sonnet-4-5 / claude-opus-4-1 / claude-haiku-4-5 | 200K tokens | SSE(原生事件) | `thinking.budget_tokens` | 是 (Base64) |
### 适配器核心能力
@@ -484,14 +495,14 @@ Metona 的 Agent 引擎采用分层架构,每层职责清晰:
| 进程 | 运行时 | 职责 |
|:---|:---|:---|
| **Main Process** | Node.js | Agent 引擎、工具调度、SQLite 数据库、MCP 管理、配置服务 |
| **Preload Script** | 沙箱 | `contextBridge` 安全暴露 `window.metona` (15 个 API 命名空间) |
| **Preload Script** | 沙箱 | `contextBridge` 安全暴露 `window.metona` (15 个 API 命名空间v0.5.0 新增 llm) |
| **Renderer** | Chromium | React 19 + MUI 9 界面渲染,Zustand 状态管理 |
### 核心数据流
```
用户输入 → ChatInput → agent-store.sendMessage
→ IPC: agent:sendMessage → handlers.ts
→ IPC: agent:sendMessage → ipc/agent.ts
→ reloadAdapter (配置签名比对,热重载)
→ 保存用户消息到 SQLite messages 表
→ 加载历史消息 + 注入相关记忆 (MemoryManager.search)
@@ -519,29 +530,31 @@ Metona 的 Agent 引擎采用分层架构,每层职责清晰:
- **TraceViewer**:按 `runId` 分组可视化展示每轮 ReAct 迭代,包括思考过程、工具调用参数/结果/耗时、状态转换链
- **Token 用量面板**:输入/输出 Token、当前上下文占用百分比 (按 60%/80% 阈值变色)、压缩节省的 Token
- **SubAgent 状态区**v0.5.0):AgentMonitor 实时展示 delegate_task 委派的子任务生命周期(委派/运行/完成/失败、层级深度、耗时、迭代轮数)
### 会话录制
- **9 种事件类型**session_start, user_message, assistant_message, tool_call, tool_result, state_change, context_compressed, error, session_end
- 录制到 JSONL 文件,支持回放重放
- 录制格式:每行一条结构化 JSON 事件
- **9 种事件类型**session_start, context_built, iteration_start, llm_request, llm_response, tool_call, tool_result, iteration_end, session_end
- 录制到 JSONL 文件`{workspace}/logs/session_*.jsonl`),支持事后回放分析
- v0.5.0: SubAgentdelegate_task)的执行轨迹录制到独立 JSONL 文件(taskId 作为会话标识)
### 审计日志
- **链式哈希防篡改**:每条记录哈希 = SHA-256(prev_hash + 记录内容)INSERT-ONLY 触发器
- **完整性校验**`verifyChain()` 逐条验证哈希链
- **导出**:支持只读 JSONL (chmod 0o444)、CSV、归档 (90 天保留)
- **导出**:支持 JSONL / CSV 两种格式导出(设置 → 日志与数据)
### SLO 监控
| 指标 | 目标 |
SLOMonitor 在 5 分钟滑动窗口内实时统计 Agent 请求质量,燃烧速率超预算时记录告警日志:
| 监控项 | 说明 |
|:---|:---|
| Agent Loop 成功率 | 95% |
| P99 延迟 | < 60s (95%) |
| 工具调用成功率 | 98% |
| 死循环发生率 | < 0.1% (99.9%) |
| MCP Server 可用性 | 99% |
| 应用崩溃率 | < 0.1% (99.9%) |
| 请求成功率 | 按 complete 事件的 terminationReason 统计错误率 |
| 延迟分布 | P50 / P95 / P99 分位数 + 平均延迟 |
| 吞吐量 | 每秒请求数 |
| 燃烧速率 | 实际错误率 / 错误预算(目标 99.9%),>1 时告警 |
| 健康检查 | 每 60s 检查数据库连通性、系统可用内存、主进程堆内存 |
---
@@ -553,7 +566,7 @@ Metona 的 Agent 引擎采用分层架构,每层职责清晰:
┌──────────┬──────────────────────────────┬──────────────┐
│ │ Header 顶部栏 │ │
│ Sidebar │ Provider · Model · 面板切换 │ DetailPanel │
260px ├──────────────────────────────┤ 360px │
300px ├──────────────────────────────┤ 360px │
│ │ │ │
│ 会话列表 │ ChatPanel 聊天区域 │ Trace View │
│ 搜索 │ │ Memory │
@@ -627,18 +640,20 @@ OLLAMA_BASE_URL=http://localhost:11434
| 配置项 | 默认值 | 说明 |
|:---|:---|:---|
| `llm.provider` | `deepseek` | LLM Provider ID |
| `llm.model` | `deepseek-v4-pro` | 模型标识符 |
| `llm.provider` | (空) | LLM Provider ID(未配置时回退 .env |
| `llm.model` | (空) | 模型标识符 |
| `agent.maxIterations` | `20` | ReAct 最大迭代轮次 |
| `agent.totalTimeoutMs` | `600000` | Agent 总超时 (ms) |
| `agent.toolTimeoutMs` | `120000` | 单个工具执行超时 (ms) |
| `agent.toolExecutionTimeoutMs` | `120000` | 单个工具执行超时 (ms) |
| `agent.thinkingEnabled` | `true` | 启用 Thinking 推理模式 |
| `agent.thinkingEffort` | `high` | 推理强度 (high / max) |
| `agent.thinkingEffort` | `high` | 推理强度 (low / medium / high / max) |
| `agent.confirmationTimeoutMs` | `120000` | 确认弹窗超时 (30s ~ 600s) |
| `deepseek.contextWindow` | `1000000` | DeepSeek 上下文窗口 |
| `agnes.contextWindow` | `1000000` | Agnes 上下文窗口 |
| `mimo.contextWindow` | `1000000` | MiMo 上下文窗口 |
| `ollama.numCtx` | `4096` | Ollama num_ctx 参数 |
| `openai.contextWindow` | `128000` | OpenAI 上下文窗口 |
| `anthropic.contextWindow` | `200000` | Anthropic 上下文窗口 |
| `ollama.numCtx` | (空) | Ollama num_ctx 参数(空 = 由模型决定) |
### SearXNG 元搜索引擎 (可选)
@@ -658,11 +673,13 @@ MetonaAI-Desktop/
│ ├── 📄 main.ts # 应用入口
│ ├── 📄 preload.ts # contextBridge 安全桥接 (15 个 API)
│ ├── 📂 ipc/ # IPC 域模块 (P2 拆分, 50+ 通道)
│ │ ├── 📄 index.ts # 统一注册入口
│ │ ├── 📄 agent.ts # Agent 消息/中断/常驻事件管道
│ │ ├── 📄 sessions.ts # 会话 CRUD
│ │ ├── 📄 config.ts # 配置读写 (共享副作用)
│ │ ├── 📄 tools.ts # 工具列表/确认
│ │ ├── 📄 index.ts # 统一注册入口(防重入)
│ │ ├── 📄 context.ts # 共享上下文 + broadcast 多窗口广播
│ │ ├── 📄 shared.ts # 配置写入共享副作用
│ │ ├── 📄 agent.ts # Agent 消息/中断/常驻事件管道/SubAgent 广播与录制
│ │ ├── 📄 sessions.ts # 会话 CRUD/消息截断/Trace 持久化
│ │ ├── 📄 config.ts # 配置读写 (get/set/setBatch)
│ │ ├── 📄 tools.ts # 工具列表/确认/自动执行
│ │ └── 📄 ... (mcp/memory/tasks/data/workspace/app)
│ ├── 📂 services/ # 业务服务层 (12 个 Service)
│ │ ├── 📄 agent-engine-manager.service.ts # 每会话独立引擎管理 (P2)
@@ -692,7 +709,7 @@ MetonaAI-Desktop/
│ │ │ └── 📂 shared/ # 共享: OpenAI 格式 · SSE 解析
│ │ ├── 📂 tools/ # 工具系统
│ │ │ ├── 📄 registry.ts # 工具注册 · PolicyEngine · 超时管理
│ │ │ └── 📂 built-in/ # 26 个内置工具实现
│ │ │ └── 📂 built-in/ # 28 个内置工具实现
│ │ │ ├── 📄 filesystem.ts # 文件系统 (7 tools)
│ │ │ ├── 📄 file-editor.ts # 精准编辑
│ │ │ ├── 📄 file-guard.ts # 路径安全共享工具
@@ -739,16 +756,16 @@ MetonaAI-Desktop/
│ │ └── 📄 token-estimator.ts # Token 估算 (CJK/ASCII)
│ └── 📂 utils/
│ └── 📄 slo.ts # 健康检查 · SLO 监控
├── 📂 src/ # React 渲染进程 (~42 文件)
├── 📂 src/ # React 渲染进程 (~50 文件)
│ ├── 📄 main.tsx # 渲染进程入口
│ ├── 📄 App.tsx # 根组件 (三栏布局 + Store 连接)
│ ├── 📂 components/
│ │ ├── 📂 chat/ # 聊天组件 (11 个)
│ │ │ ├── 📄 ChatPanel.tsx # 聊天主面板
│ │ │ ├── 📄 MessageList.tsx # 消息列表 (content-visibility 虚拟滚动)
│ │ │ ├── 📄 MessageList.tsx # 消息列表 (react-virtuoso 真虚拟滚动)
│ │ │ ├── 📄 MessageItem.tsx # 消息路由 (memo)
│ │ │ ├── 📄 AssistantMessage.tsx # Agent 回复 (Markdown + 代码高亮)
│ │ │ ├── 📄 UserMessage.tsx # 用户消息 (附件 + 双击编辑)
│ │ │ ├── 📄 UserMessage.tsx # 用户消息 (附件 + 双击编辑重发)
│ │ │ ├── 📄 SystemMessage.tsx # 系统通知
│ │ │ ├── 📄 ChatInput.tsx # 输入框 (附件 + / 命令)
│ │ │ ├── 📄 ThoughtBlock.tsx # 思考过程 (可折叠)
@@ -757,18 +774,20 @@ MetonaAI-Desktop/
│ │ │ └── 📄 StreamingIndicator.tsx # 流式加载指示器
│ │ ├── 📂 layout/ # 布局组件 (5 个)
│ │ │ ├── 📄 Header.tsx # 顶部栏 (Provider · 面板切换)
│ │ │ ├── 📄 Sidebar.tsx # 侧边栏 (会话列表 · 工具管理)
│ │ │ ├── 📄 Sidebar.tsx # 侧边栏 (会话列表 · 标题/内容搜索 · 工具管理)
│ │ │ ├── 📄 DetailPanel.tsx # 详情面板 (4 Tab)
│ │ │ ├── 📄 AgentMonitor.tsx # Agent 状态指示器
│ │ │ ├── 📄 AgentMonitor.tsx # Agent 状态指示器 + SubAgent 状态区
│ │ │ └── 📄 StatusBar.tsx # 底部状态栏
│ │ ├── 📂 settings/
│ │ │ ── 📄 SettingsModal.tsx # 设置弹窗 (8 标签页)
│ │ ├── 📂 settings/ # 设置弹窗 (v0.4.1 拆分, 10 文件)
│ │ │ ── 📄 SettingsModal.tsx # 主框架 + 垂直 Tab 导航
│ │ │ ├── 📄 useConfig.ts # 共享配置读写 Hook
│ │ │ └── 📄 ... (LLM/Agent/Tools/MCP/SearXNG/Appearance/Logs/Workspace 8 个 Tab)
│ │ ├── 📂 memory/
│ │ │ └── 📄 MemoryViewer.tsx # 记忆浏览器 (3 类型)
│ │ ├── 📂 tasks/
│ │ │ └── 📄 TaskList.tsx # 任务列表
│ │ ├── 📂 trace/ # 追踪组件 (3 个)
│ │ │ ├── 📄 TraceViewer.tsx # ReAct 迭代时间轴
│ │ │ ├── 📄 TraceViewer.tsx # ReAct 迭代时间轴 (按 runId 分组)
│ │ │ ├── 📄 TraceStep.tsx # 单步详情 (Thought + ToolCalls)
│ │ │ └── 📄 TokenUsage.tsx # Token 统计面板
│ │ ├── 📂 workspace/
@@ -776,23 +795,25 @@ MetonaAI-Desktop/
│ │ ├── 📂 onboarding/
│ │ │ └── 📄 OnboardingWizard.tsx # 5 步引导向导
│ │ ├── 📂 common/
│ │ │ └── 📄 ErrorBoundary.tsx # 错误边界
│ │ │ └── 📄 ErrorBoundary.tsx # 错误边界 (上报 error:report)
│ │ ├── 📄 CommandPalette.tsx # Cmd+K 命令面板
│ │ ├── 📄 ConfirmationDialog.tsx # 工具确认弹窗 (批量审批)
│ │ ├── 📄 ContextMenu.tsx # 右键菜单
│ │ ├── 📄 ConfirmationDialog.tsx # 工具确认弹窗 (批量审批 + 拒绝记忆恢复)
│ │ ├── 📄 ContextMenu.tsx # 右键菜单 (5 类对象)
│ │ └── 📄 ToastContainer.tsx # Toast 通知 (metona-toast v2)
│ ├── 📂 hooks/
│ │ ├── 📄 useAgentStream.ts # 流式事件监听 (rAF 批处理)
│ │ ├── 📄 useAgentStream.ts # 流式事件监听 (rAF 批处理 + runId 过滤)
│ │ ├── 📄 useKeyboardShortcuts.ts # 键盘快捷键 (16 个)
│ │ └── 📄 useTheme.ts # 主题管理
│ ├── 📂 stores/
│ │ ├── 📄 agent-store.ts # Agent 状态 (消息·流·Trace·Token)
│ │ ├── 📄 agent-store.ts # Agent 状态 (消息·流·Trace·Token·编辑重发)
│ │ ├── 📄 session-store.ts # 会话列表 (搜索·置顶·归档)
│ │ └── 📄 ui-store.ts # UI 状态 (主题·面板·专注模式)
│ ├── 📂 lib/
│ │ ├── 📄 constants.ts # 常量 (布局·颜色·快捷键)
│ │ ├── 📄 formatters.ts # 格式化 (时间·Token·文件大小)
│ │ ├── 📄 theme.ts # MUI 暗色/亮色主题
│ │ ├── 📄 export-markdown.ts # 会话 Markdown 导出
│ │ ├── 📄 tool-result-display.ts # 工具结果显示层裁剪 (剥离 base64)
│ │ └── 📄 cn.ts # className 合并
│ ├── 📂 styles/
│ │ └── 📄 globals.css # 全局样式 (Tailwind + 动画 + Markdown)
@@ -844,7 +865,7 @@ npm run format # Prettier 格式化
# ─── 测试 ─────────────────────────────────
npm test # 运行单元测试 (Vitest, 系统 Node — audit 套件因 better-sqlite3 ABI 自动跳过)
npm run test:electron # 运行全量单元测试 (Electron Node ABI, 194 用例全执行, 含 SQLite 审计链哈希)
npm run test:electron # 运行全量单元测试 (Electron Node ABI, 199 用例全执行, 含 SQLite 审计链哈希)
npm run test:watch # 测试监听模式
# ─── 构建 ─────────────────────────────────
@@ -856,17 +877,20 @@ npm run preview # 预览构建产物
### 数据库 Schema
共 10 张表(v0.4.0 新增 `session_summaries` 用于分层上下文):
| 表名 | 用途 | 关键特性 |
|:---|:---|:---|
| `sessions` | 会话管理 | title, created_at, updated_at, pinned, archived |
| `messages` | 消息持久化 | role, content, reasoning_content, tool_calls (JSON), token_usage |
| `app_config` | 应用配置 | 键值对5 大分类 (llm/agent/tools/security/logging) |
| `audit_logs` | 审计日志 | chain_hash (SHA-256), INSERT-ONLY 触发器 |
| `mcp_servers` | MCP Server 配置 | name, transport (stdio/sse), command, args, env, url |
| `episodic_memories` | 情节记忆 | content, importance, access_count, last_accessed, created_at |
| `semantic_memories` | 语义记忆 | content, embedding (JSON), importance, decay_factor |
| `working_memories` | 工作记忆 | key-value, session_id, expires_at |
| `tasks` | 持久化任务 | title, description, status, priority, parent_id, session_id |
| `messages` | 消息持久化 | role, content, reasoning_content, tool_calls (JSON), attachments (JSON), iteration |
| `app_config` | 应用配置 | 键值对llm / agent / tools / security / logging / searxng / ui |
| `audit_logs` | 审计日志 | prev_hash + current_hash 链式哈希 (SHA-256), INSERT-ONLY 触发器 |
| `mcp_servers` | MCP Server 配置 | name, transport (stdio/sse/streamable-http), command, args, url |
| `episodic_memories` | 情节记忆 | content, summary, source, importance, tf_cache (分词缓存) |
| `semantic_memories` | 语义记忆 | key-value (UNIQUE key), category, confidence, access_count, tf_cache |
| `working_memories` | 工作记忆 | key-value, session_id + task_id + key 唯一约束 |
| `tasks` | 持久化任务 | title, description, status, priority, parent_id (自引用), order_idx |
| `session_summaries` | 会话滚动摘要 | summary, summarized_until_rowid 游标(分层上下文加载) |
---