{"id":"a47e82c4-7b51-4c81-b027-f2b3cacedc05","slug":"iftree-editor","kind":"mcp","name":"iftree-editor","summary":"本地优先的文档数据管理工具：把大规模语料整理成带稳定地址的条件树，精确定位片段且可回溯出处；关键词 + bge-m3 语义检索，经 MCP 开放给外部 AI agent。","owner":"Meari-Prototype","repoUrl":"https://github.com/Meari-Prototype/iftree-editor","license":"Apache-2.0","licenseTier":"permissive","trust":"community","stars":6,"match":null,"fewStars":false,"format":"mcp","createdAt":"2026-06-05T13:08:13.000Z","addedAt":"2026-10-21T06:12:03.030Z","logoUrl":"https://avatars.githubusercontent.com/u/275577454?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["search","memory-knowledge","databases"],"tags":["ai-agents","document-management","electron","knowledge-base","lancedb","llm","local-first","rag"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T02:53:18.689Z","sample":false,"url":"https://conduits.dev/tools/iftree-editor","language":"TypeScript","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# IF-Tree Editor · 条件树编辑器\n\n**简体中文** · [English](README.en.md)\n\n> 本地优先的文档数据管理工具：把多文档语料整理成带稳定地址的 if-tree 条件树，便于在大规模原文（设计目标为百亿字级）中精确定位所需片段。检索结果可回溯到具体出处，也可通过 MCP 交由外部 agent 框架协作处理。\n\n![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)\n![Electron](https://img.shields.io/badge/Electron-39-47848F?logo=electron&logoColor=white)\n![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=black)\n![Vite](https://img.shields.io/badge/Vite-7-646CFF?logo=vite&logoColor=white)\n![platform](https://img.shields.io/badge/platform-Windows-lightgrey)\n![status](https://img.shields.io/badge/status-0.6.7%20alpha-orange)\n\n> **项目状态：0.6.7，早期开发阶段。** 项目仍在活跃开发中，请按早期版本对待：\n>\n> - **前端**：仍有较多已知 bug 未修复。\n> - **后端写入路径**：缺少长期使用的实测——项目开发时间尚短，客观上还没有积累足够的长时运行数据。\n> - **已就绪可用**：核心的 **MCP 只读查询服务**与 **db 命令契约**已经稳定可用，只读检索是当前最可依赖的部分。\n>\n> 版本变更见 [CHANGELOG](CHANGELOG.md)。\n\n---\n\n## 目录\n\n- [简介](#简介)\n- [文档](#文档)\n- [功能特性](#功能特性)\n- [界面预览](#界面预览)\n- [技术栈](#技术栈)\n- [环境要求](#环境要求)\n- [快速开始](#快速开始)\n- [配置](#配置)\n- [数据存储](#数据存储)\n- [语义向量](#语义向量)\n- [导入与导出](#导入与导出)\n- [MCP 与外部 agent](#mcp-与外部-agent)\n- [项目结构](#项目结构)\n- [开发与测试](#开发与测试)\n- [许可证](#许可证)\n- [致谢](#致谢)\n\n---\n\n## 简介\n\nIF-Tree Editor 是一个本地优先的文档数据管理工具，面向规模较大的多文档语料（设计目标为百亿字级）。它要解决的问题是：在大量原文中准确找到需要的片段，并保证结果可核对、不被模型臆测替代。为此，它把原文整理成带稳定地址的条件树：\n\n- 每个节点有形如 `1`、`1-3`、`1-3-2` 的地址：`1` 为根节点，`1-3` 是 `1` 的第 3 个子节点，地址前缀表示父子关系。地址由 `parent_id + sort_order` 动态重算，增删、拖拽、重挂之后保持一致，使每个句子都有可引用的固定坐标。\n- 关键词检索与基于 `bge-m3` 的本地语义检索配合句子级 offset 映射，可将命中定位到具体句子，而非整篇文档。\n- 数据存于本地（SQLite + LanceDB），不依赖云服务。内置 Agent 回答事实问题时需先读取正文证据并给出证据节点地址，不以模型常识作答，便于核对。\n- 通过 MCP 将文档库以分级权限（问答 / 协作 / 完全）开放给外部 agent 框架，用于检索与协同处理。\n\n同一份内容可在两种阅读密度之间切换：折叠时呈现为 Markdown 文档，展开时呈现为条件树；导入时保留句子到原文的 offset 映射，使两种视图对应同一份原文。\n\n## 文档\n\n- [上手教程](docs/getting-started.md)——从安装到第一次检索，15 分钟走通核心流程。\n- [操作指南](docs/how-to.md)——配置 LLM、构建向量、各格式导入、智能导入、接入外部 agent、记忆卷、流式写入、备份。\n- [参考手册](docs/reference.md)——MCP 工具、db 命令、import-json 契约、配置与环境变量的查表清单。\n- [概念与设计](docs/concepts.md)——地址、信任分级、三方合并、记忆三层、共享后端的设计与取舍。\n- [更新日志](CHANGELOG.md)\n\n## 功能特性\n\n- **精确检索**：关键词检索 + 基于 `bge-m3` 的本地语义检索，配合句子级 offset 映射，把命中定位到具体几句；默认 GPU（DirectML）/fp16 推理，可切换 CPU。\n- **基于证据的回答**：内置 Agent 回答事实问题时需读取正文证据并给出证据节点地址，不以模型常识或题目措辞作答，结果可核对。\n- **本地优先存储**：文档、节点、事实前提、ERROR、引用关系与历史存于 SQLite，节点级语义向量存于 LanceDB，无需任何云服务即可使用。\n- **Agent 协作与 MCP**：内置 Agent 与 MCP 服务共用一套权限分级（问答 / 协作 / 完全）；外部 agent 框架可检索读证据，协作档起的写入一律先进编辑分支待人审。LLM 支持 OpenAI 兼容与 Anthropic 兼容接口。\n- **稳定地址的条件树**：节点地址形如 `1-3-2`，由 `parent_id + sort_order` 动态重算，增删、重挂之后保持一致，使每个句子可被精确引用。\n- **双密度阅读**：折叠呈现为 Markdown 文档，展开呈现为可操作条件树；树视图默认展开到真实最大深度，可逐层展开 / 收起 / 全部展开 / 全部折叠。\n- **多视图**：树视图、关系图谱、IDE 视图、富文本、关键词搜索、语义搜索；关系图谱按 if-tree 阅读顺序生成有向边，并叠加显式引用边。\n- **结构编辑**：只读 / 编辑锁；新增空节点、单选或 `Ctrl` 多选拖拽重挂，拖到节点上可选择合并 / 并列 / 挂载；内置撤销 / 重做（`Ctrl+Z`、`Ctrl+Y`、`Ctrl+Shift+Z`）。\n- **编辑分支与三方合并**：agent 的结构性修改写入影子分支待审；合入主干按稳定节点 id 做 merkle 三方调和——快进直写、结构性失配整体受阻、字段级冲突由人逐条裁决。\n- **流式写入**：聊天记录、日志类数据流按「增量编辑」模式直接追加节点（不走分支），关键词与语义索引随写增量维护；海量导入有 bulk 加速会话。\n- **事件记忆卷**：外部 agent 会话收尾把自述日志投递成记忆卷，按 24 小时节律自动封卷、进入可提炼；提炼经 `memory-distill` skill 产出长期核心记忆的 diff 提议，由 `human` 档人审落地。\n- **共享后端**：一库一后端进程，应用、MCP、命令行通过命名管道共用，同时在线互不冲突。\n- **多格式导入导出**：导入 CHM、TXT、Markdown、PDF、DOCX、EPUB；结构不规则的源文走智能导入（LLM 产 JSON 经逐字节校验入库）；Excel / CSV 明确作为数据库导出的中继格式，不作为普通文档导入；导出 JSON 结构（Markdown 导出重新设计中、临时停用）。\n- **AI 摘要备注**：调用 OpenAI / Anthropic 兼容接口，为单个节点、子树、当前层级或全文生成摘要备注。\n- **丰富的节点元数据**：节点类型、信任级别、人工标签、事实前提、ERROR、引用关系与保存历史。\n\n## 界面预览\n\n| | |\n| --- | --- |\n| **树视图与双密度阅读**<br>![树视图主界面](docs/images/editor-tree.png) | **关键词检索**<br>![关键词搜索](docs/images/keyword-search.png) |\n| **IDE 视图与 Agent 协作**<br>![IDE 视图与 Agent 对话](docs/images/ide-agent.png) | **启动器**<br>![启动器](docs/images/launcher.png) |\n\n## 技术栈\n\n| 领域 | 选型 |\n| --- | --- |\n| 桌面框架 | Electron 39 |\n| 界面 | React 19 + Vite 7 |\n| 本地数据库 | better-sqlite3 |\n| 向量数据库 | LanceDB |\n| 语义向量 | @huggingface/transformers（`bge-m3`，ONNX Runtime，GPU 走 DirectML） |\n| Agent / 工具协议 | @modelcontextprotocol/sdk（MCP） |\n| 其它 | pdfjs-dist、fflate、lucide-react、@radix-ui |\n\n## 环境要求\n\n- **操作系统**：Windows 10 / 11（开发与验证均在 Windows 上进行；脚本以 PowerShell 为主）。\n- **Node.js**：建议 20 LTS 或更高（验证在 Node 24 上进行）。原生模块（better-sqlite3）按 node ABI 预编译（`prebuild-install` 下载，无需编译工具链）；测试、CLI、MCP、后端服务均纯 node 运行（ABI 说明见[开发与测试](#开发与测试)）。\n- **包管理器**：npm。\n- **GPU（可选）**：支持 DirectX 12 的显卡可经 DirectML 加速语义向量；没有可用 GPU 时在设置页切换到 CPU。\n\n## 快速开始\n\n首次安装依赖：\n\n```powershell\nnpm install\n```\n\n构建前端并启动应用：\n\n```powershell\nnpm run build\nnpm run app\n```\n\n> `npm run app` 会先构建、再把 better-sqlite3 按 node ABI 预编译。桌面端是 Electron 外壳，但前端不再 in-process 用原生模块，由主进程拉起独立的 node 后端进程。修改主进程或 preload 后，需要重启 Electron 窗口。\n\n开发模式（先起 Vite dev server，再让 Electron 加载它）：\n\n```powershell\nnpm run dev\n$env:ELECTRON_START_URL = 'http://127.0.0.1:5173'\nnpm run app\n```\n\nWindows 上也可以直接双击 `start.bat`，它会自动完成\"安装依赖 → 构建 → 启动\"。\n\n## 配置\n\n### LLM 接口（`.env`）\n\n复制 `.env.example` 为 `.env` 并填入你的 Key。LLM 摘要与内置 Agent 支持两种接口协议，可在设置页按供应商选择：\n\n- **OpenAI 兼容**：请求 `{baseUrl}/chat/completions`。\n- **Anthropic 兼容**：请求 `{baseUrl}/v1/messages`，使用 `x-api-key` 与 `anthropic-version` 请求头，需要在 API 配置中填写最大输出 token。\n\nOllama 本地模型与 DeepSeek 等服务都可通过上述协议接入（DeepSeek 的 Anthropic 兼容端点默认为 `https://api.deepseek.com/anthropic`）。下面是 OpenAI 兼容方式的常用环境变量：\n\n```dotenv\nOPENAI_API_KEY=your-api-key\nOPENAI_BASE_URL=https://api.deepseek.com\nOPENAI_MODEL=deepseek-v4-pro\n```\n\n设置页中维护的多供应商配置会写回 `.env`，详见文件内注释。`.env` 已在 `.gitignore` 中，不会被提交。\n\n### 应用配置（`iftree.config.json`）\n\n控制摘要策略、Agent 工具参数与渲染模式，例如摘要的字数上下限、压缩比例、搜索结果条数、是否强制硬件加速等。渲染模式、硬件加速与 debug 日志对应启动器里的开关；早期版本默认开启 debug 日志（运行日志写入 `.iftree-debug/`），便于反馈问题。字段说明见[参考手册](docs/reference.md#配置与环境变量)。\n\n### 数据目录（`IFTREE_HOME`）\n\n设置环境变量 `IFTREE_HOME` 可覆盖默认数据目录，便于测试或隔离不同数据集。\n\n## 数据存储\n\n应用涉及三类本地数据：你管理的**文档库**、由它解析出的**主数据库**，以及可重建的**派生数据**（向量与附件）。\n\n### 文档库（`library/`）\n\n`library/` 位于项目根目录，是存放并组织全部源文档（`.chm` / `.txt` / `.md` / `.pdf` / `.docx`）的工作区，可按文件夹分层。它是这个工具最核心的数据：应用内以文件夹树浏览、组织文档库，内置 Agent 也只能在 `library/` 内按权限以相对路径读写，不暴露绝对路径。\n\n`library/` 已在 `.gitignore` 中——它是你的数据，不随仓库分发。它与 `docs/` 完全是两回事：前者是被管理的文档语料，后者只是项目文档，不要把 `library/` 并入 `docs/`。\n\n### 主数据库（`database/store.sqlite`）\n\n导入后解析出的结构化数据——文档、节点、前提、ERROR、引用、历史、记忆卷——存于项目根的 `database/store.sqlite`（已在 `.gitignore`），可用环境变量 `IFTREE_DB` 指定其他路径。\n\n### 派生数据（默认 `database\\`，可用 `IFTREE_HOME` 覆盖）\n\n向量与附件默认写入主库同目录 `database\\`（0.5.0 起锚工作区，避免与 SQLite 分家；早期默认为 `%USERPROFILE%\\.iftree`，仍可用 `IFTREE_HOME` 覆盖）：\n\n```text\ndatabase\\               # 与主库 store.sqlite 同目录（IFTREE_HOME 默认）\n  vectors\\nodes.lance\\  # 节点级语义向量\n  assets\\doc-<id>\\      # 文档附件（图片等）\n```\n\n原始 Markdown 阅读源保存在 SQLite 的 `source_documents` / `source_spans`，句子切分只保存 offset 映射，不重组正文结构；树节点可聚合显示 `23-25;27-28;32` 这类句子编号范围。\n\n## 语义向量\n\n- 默认模型为 `Xenova/bge-m3`（`BAAI/bge-m3` 的 Transformers.js ONNX 权重），数据库维度由当前模型推导并精确校验。\n- 本地推理在后端 node 进程中用 Transformers.js 执行：GPU 配置使用 `device: 'dml'`（DirectML），CPU 配置使用 `device: 'cpu'`；每批 16 条文本，单篇文档内默认 4 个子批并发（设置页的 worker 数）。\n- 设置页可切换模型、计算目标（GPU/CPU）、worker 数、batch size 与本地 ONNX 模型路径，并提供当前模型的手动下载按钮。\n- 本地模型路径直接作为 Transformers.js 的本地模型根目录使用；填了本地路径就不再从远端拉取模型。\n- 在设置页保存新的模型、维度或本地模型路径时会丢弃旧的 LanceDB 表，向量不会自动重建，需要对要做语义检索的文档重新补建。经 `IFTREE_EMBED_*` 环境变量换模型不会丢表，同维度新旧向量会混在一张表里，须自己重建，见[操作指南](docs/how-to.md#构建语义向量)。\n\n## 导入与导出\n\n**导入**\n\n| 格式 | 说明 |\n| --- | --- |\n| CHM `.chm` | 以 `.hhc` 目录和 HTML 正文生成结构树 |\n| 文本 `.txt` | 按标题行、段落和句子生成层级结构 |\n| Markdown `.md` | 按 heading、段落和句子生成层级结构 |\n| PDF `.pdf` | 带文本层映射的 PDF 导入 |\n| DOCX `.docx` | 按 OOXML 段落样式 `<w:pStyle>` 识别标题层级 |\n| EPUB `.epub` | 解析章节结构与正文，句子可定位回原文 |\n\nExcel `.xlsx` 与 CSV `.csv` 是数据库导出的中继格式，不作为普通文档导入。\n\n结构不规则、规则解析不出来的源文可走**智能导入**：LLM 观察源文写一次性切割脚本产出 JSON，经 `db import-json` 逐字节校验入库，正文只能是源文切片、不允许改写（详见[操作指南](docs/how-to.md#用智能导入处理无规则结构的源文)）。\n\n**导出**：JSON 结构。（Markdown 文档导出正在重新设计，本版临时停用。）\n\n## MCP 与外部 agent\n\nMCP server 把文档库开放给 Claude Code、Codex 等外部 agent 框架，stdio 传输，权限档在启动时由环境变量 `IFTREE_MCP_TIER` 锁定：`read`（检索与读取，默认）、`edit`（+ 编辑分支写入、流式写入、记忆投递）、`full`（+ 合并回滚等管理动作，身份仍 llm）、`human`（别名 `yolo`，写入者身份为 human：批准 llm 待审、标受控）。\n\n客户端配置示例（以项目根为工作目录）：\n\n```json\n{\n  \"mcpServers\": {\n    \"iftree-library\": {\n      \"command\": \"npm\",\n      \"args\": [\"run\", \"--silent\", \"mcp:node\"],\n      \"env\": { \"IFTREE_MCP_TIER\": \"read\" }\n    }\n  }\n}\n```\n\n应用、MCP、命令行共享同一个后端进程（一库一后端），可同时在线。工具清单与 `db` 命令契约见[参考手册](docs/reference.md)；外部 agent 的智能导入与记忆投递契约随仓库分发在 [`.iftree-llm-workspace/skills/`](.iftree-llm-workspace/skills/)。\n\n## 项目结构\n\n```text\n.\n├── electron/\n│   ├── main.ts           # 主进程装配根：窗口、IPC 与 preload 装配，拉起共享 node 后端并转发读写（不再 in-process 访问数据库）\n│   ├── launcher.ts       # 启动器窗口（文档列表 / 渲染模式）+ 主服务拉起 + 启动超时与运行期心跳看门狗\n│   ├── settings-io.ts    # .env / iftree.config.json / settings.json 的读写\n│   ├── e2e-capture.ts    # 端到端窗口截屏与视口分析\n│   ├── ipc-channels.ts   # IPC 通道常量\n│   └── preload.ts        # 安全桥接，向渲染进程暴露 window.iftree API\n├── index.html            # 渲染进程入口 HTML\n├── src/\n│   ├── renderer/\n│   │   └── main.tsx      # React 挂载入口\n│   ├── frontend/         # 界面层\n│   │   ├── App.tsx       # 装配根：hook / 命令装配与 context 组装\n│   │   ├── screens/      # 整屏拆分：编辑器 / 设置 / 左侧栏 / 工作区 / 弹窗宿主\n│   │   ├── commands/     # 命令层：editor / document / agent / treeView / axiom 业务动词\n│   │   ├── stores/       # 轻量 store 与编辑生命周期状态机\n│   │   ├── session/      # 文档会话：窗口化加载与驱逐、撤销栈与快照令牌\n│   │   ├── components/   # 视图与面板（树视图、关系图谱、富文本、设置等）\n│   │   ├── hooks/        # 文档状态、布局、选择、设置等 React hooks\n│   │   ├── data/         # 调用 window.iftree 的仓储 / 服务封装\n│   │   ├── features/     # 实体、库、设置等功能动作\n│   │   ├── lib/          # 前端工具函数\n│   │   └── styles.css\n│   ├── backend/          # 后端业务逻辑（跑在独立 node 后端进程）\n│   │   ├── store/        # 存储底座 / 历史 / 编辑分支子系统（SQLite schema 与文档/节点写操作）\n│   │   ├── db/           # schema、id、归一化、快照历史、内容寻址对象库\n│   │   ├── memory/       # 记忆卷：多租户隔离、锚布局、读写与维护\n│   │   ├── entities/     # 实体读写与投影\n│   │   ├── editor-session/ # 编辑器会话与快照令牌\n│   │   ├── diff/         # ref / view 差异计算\n│   │   ├── derived-index/ # 衍生索引（keyword / semantic-status）与自对账\n│   │   ├── projection/   # 编辑分支投影缓存\n│   │   ├── source/       # 源文档地址映射\n│   │   ├── text/         # 文本预算 / 合并\n│   │   ├── import/       # 导入编排与 JSON 落库\n│   │   ├── library/      # 库文件系统与虚拟文档\n│   │   ├── handlers/     # 读 / 写命令处理器\n│   │   └── llm/          # Agent 运行时、共享后端 SDK（命名管道）、headless agent、LLM 设置\n│   ├── mcp/              # MCP server 入口（`src/mcp/mcp-server.ts`，产物 `dist/src/mcp/mcp-server.js`）\n│   ├── core/             # 纯逻辑（无 Electron 依赖）\n│   │   ├── tree.ts       # 树构建、动态地址、扁平化 / 遍历\n│   │   ├── mindmap.ts    # 树视图投影、深度控制、布局\n│   │   ├── merkle.ts / merkle-diff.ts / merkle-merge.ts # 树哈希、差异与三方合并\n│   │   ├── source-text.ts / source-pdf.ts / source-docx.ts / source-chm.ts / source-epub.ts # 配合 import-formats/ 解析 txt/md/pdf/docx/chm/epub\n│   │   ├── source-markdown.ts # 原文解析与句子 offset 映射\n│   │   └── ...           # viewport、markdown、tree-cursor、tree-ui、flat-tree 等\n│   ├── vector/           # 语义向量：embeddings、vector-store、worker、模型下载\n│   └── agent/            # Agent 配置与会话存储\n├── scripts/              # CLI 工具：db 命令、native 重编、验证脚本、导入/导出/迁移；`scripts/mcp-server.ts` 是旧位置的兼容垫片\n├── tests/                # node:test 单元测试\n├── docs/                 # 项目文档：教程 / 操作指南 / 参考 / 概念\n├── .iftree-llm-workspace/\n│   └── skills/           # 面向 LLM 的导入与记忆投递契约（随仓库分发）\n├── library/              # 文档库工作区：你管理的源文档（运行时生成，已在 .gitignore）\n├── database/             # 主数据库 store.sqlite（运行时生成，已在 .gitignore）\n├── iftree.config.json    # 摘要策略 / Agent 工具 / 渲染模式配置\n└── .env.example          # 环境变量模板（LLM 接口）\n```\n\n## 开发与测试\n\n```powershell\nnpm run lint          # ESLint 静态检查（src / electron / scripts / tests）\nnpm run check:types   # TypeScript 类型检查（core 已类型化，其余模块逐步迁移）\nnpm run build         # 生产构建（esbuild 把运行时 .ts 编译到 dist/）\nnpm run check:native  # 校验 native module 与 node ABI 匹配\nnpm test              # node --test 运行单元测试\nnpm run test:verbs    # node --test 运行 db 动词契约套件\n```\n\n> 部分端到端 / 样例验证脚本（如 `verify:samples`、`verify:chm`）依赖本地样例数据，需自行准备对应文件后再运行。\n\n> **原生模块 ABI**：原生模块（better-sqlite3、LanceDB）是按运行时 ABI 编译的二进制。自 0.6.2 起统一到 **node ABI**——better-sqlite3 走 `prebuild-install` 下载 node 预编译包（无需编译工具链），`@lancedb/lancedb` 是 N-API 预编译、node 与 Electron 通用。测试、CLI、MCP、后端服务都用系统 `node` 运行（`npm test` / `node dist/scripts/<脚本>.js` / `npm run mcp:node`）。桌面 `npm run app` 仍是 Electron 外壳，但前端不再 in-process 用原生模块、由主进程拉起独立 node 后端，Electron 自身零原生重编；`npm run check:native` 校验 better-sqlite3 与 node ABI 匹配。\n\n## 许可证\n\n本项目基于 [Apache License 2.0](LICENSE) 发布，版权归 Meari 所有（见 [NOTICE](NOTICE)）。\n\n## 致谢\n\n- 界面内置 [Noto Sans CJK](src/frontend/assets/fonts/NOTICE.md) 字体（SIL Open Font License）。\n- 语义向量基于 [BAAI/bge-m3](https://huggingface.co/BAAI/bge-m3) 模型。\n- 以及 Electron、React、Vite、LanceDB、Transformers.js 等开源项目。\n- 开发过程中借助 ChatGPT 6 astra、ChatGPT 5.6 sol、ChatGPT 5.5、Claude Opus 5、Claude Fable 5.1、Claude Opus 4.8、Claude Opus 4.7、Claude Sonnet 5、Claude Fable 5、Kimi K3、GLM 5.3、GLM 5.3 Flash、GLM 5.2 与 DeepSeek V4 辅助。\n"}