diff --git a/.vitepress/config.mts b/.vitepress/config.mts index a2a607d..fc681dd 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -26,7 +26,8 @@ export default defineConfig({ items: [ { text: 'Aspose AI 产品能力分析', link: '/research/aspose-ai' }, { text: 'OfficeCLI:为 AI Agent 而生的 Office 工具', link: '/research/officecli' }, - { text: 'Office AI 技术方案对比', link: '/research/office-ai-tech-comparison' }, + { text: 'OfficeCLI 技术方案分析', link: '/research/officecli-tech' }, + { text: 'Aspose MCP Server 技术方案分析', link: '/research/aspose-mcp-tech' }, ], }, ], diff --git a/research/aspose-mcp-tech.md b/research/aspose-mcp-tech.md new file mode 100644 index 0000000..576597c --- /dev/null +++ b/research/aspose-mcp-tech.md @@ -0,0 +1,313 @@ +# Aspose.Words MCP Server 技术方案分析 + +> 调研时间:2026 年 5 月 | 作者:沙洲工作室 +> +> 基于源码阅读(v26.4.0),非黑盒测评 + +## 基本信息 + +| 项目 | 信息 | +|------|------| +| 仓库 | [aspose-words/Aspose.Words-MCP-Server](https://github.com/aspose-words/Aspose.Words-MCP-Server) | +| 语言 | Python | +| 许可证 | MIT(Server 层),Aspose.Words SDK 为商业许可 | +| 代码量 | ~6,628 行 Python(含测试) | +| 外部依赖 | 2 个核心包(fastmcp + aspose-words) | +| 支持格式 | 仅 Word (.docx) | +| 版本号 | 与 Aspose.Words SDK 版本对齐(26.4.0) | + +--- + +## 一、整体架构 + +### 分层结构 + +``` +┌─────────────────────────────────────────────────┐ +│ AI Agent(Claude 等) │ +├─────────────────────────────────────────────────┤ +│ FastMCP 传输层 │ +│ stdio / streamable-http / SSE │ +├─────────────────────────────────────────────────┤ +│ mcp_server.py(1,758 行) │ +│ register_tools() — 90 个 @mcp.tool 注册 │ +│ ↓ │ +│ tool_xxx() 辅助函数 — 可脱离 MCP 独立调用 │ +├─────────────────────────────────────────────────┤ +│ core/ 模块(12 个) │ +│ ┌─────────┬─────────┬─────────┬──────────┐ │ +│ │ content │ tables │ layout │ export │ │ +│ │ 595行 │ 413行 │ 128行 │ 196行 │ │ +│ ├─────────┼─────────┼─────────┼──────────┤ │ +│ │ reading │ notes │ io │ styles │ │ +│ │ 178行 │ 254行 │ 102行 │ 42行 │ │ +│ ├─────────┼─────────┼─────────┼──────────┤ │ +│ │comments │watermarks│protection│ links │ │ +│ │ 45行 │ 47行 │ 43行 │ 36行 │ │ +│ ├─────────┴─────────┴─────────┴──────────┤ │ +│ │ store.py(67行)— 文档 ID ↔ 名称映射 │ │ +│ │ utils/docs_util.py — 路径/颜色/段落工具 │ │ +│ │ utils/license.py — 许可证处理 │ │ +│ └────────────────────────────────────────┘ │ +├─────────────────────────────────────────────────┤ +│ Aspose.Words Python SDK │ +│ (商业闭源,需许可证或评估模式) │ +└─────────────────────────────────────────────────┘ +``` + +### 模块关系 + +**"薄门面 + 厚核心"架构**,三层调用链清晰分离: + +1. **MCP 工具层**(`mcp_server.py`):90 个用 `@mcp.tool` 装饰器注册的函数,负责参数校验和 MCP 接口适配 +2. **tool_xxx() 辅助层**(同一文件):可脱离 MCP 框架独立调用的函数,方便测试 +3. **core/ 业务层**(12 个模块):实际调用 Aspose.Words SDK 的业务逻辑 + +这种分离意味着如果要把 MCP 换成 REST API 或 gRPC,只需要替换最外层。 + +### 文档存储模型 + +**DocumentStore**(`store.py`,67 行)是一个线程安全的内存字典: +- `threading.RLock` 保证并发安全 +- 存储 `doc_id → {name: str}` 的映射 +- 纯内存会话级存储,不持久化 + +文档实体以 UUID 命名的 `.docx` 文件存储在 `DOCS_DATA_DIR`(默认 `./data`)。重启后扫描 data 目录可恢复。 + +### 无状态操作模式 + +每次操作都遵循**加载 → 修改 → 保存**的无状态模式: + +``` +1. path = ensure_path(doc_id) # 获取 .docx 文件路径 +2. doc = aw.Document(str(path)) # 加载文档到内存 +3. builder = aw.DocumentBuilder(doc) # 创建构建器 +4. [执行操作] +5. doc.save(str(path)) # 保存回磁盘 +``` + +没有驻留进程,没有内存缓存。每次调用都重新加载文件。简单可靠,但连续大量操作时性能不如 OfficeCLI 的 Resident Mode。 + +--- + +## 二、API 抽象设计 + +### 90 个 MCP 工具分类 + +Aspose MCP Server 注册了 90 个扁平的 MCP 工具,没有 OfficeCLI 那样的三层分级——每个工具是一个独立的操作: + +#### 文档生命周期管理(~10 个) + +| 工具 | 功能 | +|------|------| +| create_document | 创建新文档 | +| delete_document | 删除文档 | +| copy_document | 复制文档 | +| list_documents | 列出所有文档 | +| merge_documents | 合并多份文档 | +| save_as_new | 另存为新文档 | +| get_info | 获取文档信息 | +| stats | 文档统计 | +| get_document_base64 | 获取文档的 Base64 编码 | + +#### 内容插入(~20 个) + +这是工具数量最多的类别。采用**三位置插入模式**——同一种内容类型提供三个变体: + +| 位置 | 示例工具 | +|------|---------| +| 文末(end) | `insert_text_end`、`add_page_break_end`、`insert_list_end`、`insert_html_end` | +| 文首(start) | `insert_text_start`、`add_page_break_start`、`insert_list_start`、`insert_html_start` | +| 指定段落(at_paragraph) | `insert_text_at_paragraph`、`add_page_break_at_paragraph`、`insert_list_at_paragraph` | + +此外还有按锚文本定位的变体:`insert_header_near_text`、`insert_line_or_paragraph_near_text`、`insert_numbered_list_near_text`。 + +支持的内容类型:纯文本、标题、段落、分页符、列表(有序/无序)、HTML、Markdown、Base64 图片。 + +#### 内容读取与搜索(~6 个) + +| 工具 | 功能 | +|------|------| +| read_paragraphs | 按索引范围读取段落 | +| get_text | 获取全文文本 | +| get_xml | 获取文档 XML | +| get_outline / get_outline_simple | 获取文档大纲 | +| find_text | 文本搜索 | + +#### 文本操作(~3 个) + +| 工具 | 功能 | 特点 | +|------|------|------| +| replace_text | 文本替换 | 支持正则(有安全验证)、大小写、全词匹配、join_runs | +| delete_paragraph | 删除指定段落 | 按索引 | +| format_text | 格式化文本范围 | 支持段落内 start_pos/end_pos 字符级定位 | + +#### 表格操作(~18 个) + +表格是工具最多的模块之一,操作粒度细到单元格级: + +| 工具 | 粒度 | +|------|------| +| add_table_end / start / at_paragraph | 表格创建(三位置) | +| format_table | 表格整体格式 | +| set_table_cell_shading | 单元格着色 | +| apply_table_alternating_rows | 交替行颜色 | +| highlight_table_header | 高亮表头 | +| merge_table_cells / horizontal / vertical | 单元格合并 | +| set_table_cell_alignment | 单元格对齐 | +| set_table_column_width / widths | 列宽 | +| set_table_width | 表格总宽 | +| auto_fit_table_columns | 自动列宽 | +| format_table_cell_text | 单元格内文本格式 | +| set_table_cell_padding | 单元格内边距 | + +#### 页面布局(~6 个) + +| 工具 | 功能 | +|------|------| +| add_header_text / add_footer_text | 页眉页脚 | +| add_page_numbering | 页码 | +| set_different_first_page_header_footer | 首页不同页眉页脚 | +| set_page_setup | 页面设置(边距/方向/纸张) | +| insert_section_break | 分节符 | + +#### 脚注/尾注(~12 个) + +脚注是功能最丰富的子模块: +- 添加/删除脚注和尾注 +- 按锚文本定位脚注 +- 验证脚注是否存在 +- 脚注和尾注互转 +- 脚注样式设置 +- 获取所有注释 + +#### 其他模块 + +| 模块 | 工具数 | 功能 | +|------|--------|------| +| 评论 | 3 | 获取所有评论、按作者/段落过滤 | +| 属性 | 2 | 读写文档属性(标题/作者/关键词) | +| 保护 | 3 | 加密保护、取消保护、限制编辑 | +| 水印 | 2 | 文字水印、图片水印(Base64) | +| 链接 | 2 | 书签、超链接 | +| 样式 | 1 | 创建自定义样式 | +| 导出 | 3 | 多格式导出、高级导出选项、页面渲染为图片 | + +### 操作粒度 + +| 粒度 | 说明 | 示例 | +|------|------|------| +| 段落级 | **核心寻址单位**,绝大多数操作以 `paragraph_index` 定位 | insert_text_at_paragraph(paragraph_index=3) | +| Run 级 | format_text 支持段落内字符范围 | format_text(paragraph_index=2, start_pos=5, end_pos=10) | +| 单元格级 | 表格操作精确到行列 | set_table_cell_shading(table_index=0, row=1, col=2) | +| 锚文本定位 | 通过文本内容查找位置 | insert_header_near_text(anchor_text="Introduction") | + +### 设计特点 + +**扁平化工具设计**:不同于 OfficeCLI 的三层架构(语义/DOM/XML),Aspose MCP Server 的 90 个工具是扁平排列的。每个工具做一件明确的事,参数自解释。这降低了 AI Agent 的认知负担——不需要理解"应该用哪一层",直接找到对应操作即可。 + +**三位置插入模式**:`end/start/at_paragraph` 三个变体虽然增加了工具数量,但让 AI 不需要学习复杂的定位语法。 + +**安全设计**:正则表达式替换有专门的安全验证器——禁止 lookaround、backreference、group 引用、堆叠量词,最大 256 字符,防止 ReDoS 攻击。 + +--- + +## 三、Office 文档引擎 + +### 核心依赖:Aspose.Words SDK + +Aspose MCP Server 的**全部文档处理能力来自 Aspose.Words 商业 SDK**。Server 层不做任何格式解析——它只是把 MCP 调用翻译成 Aspose.Words API 调用。 + +使用的核心 Aspose.Words API: + +| API | 用途 | +|-----|------| +| `aw.Document(path)` | 加载文档 | +| `aw.DocumentBuilder(doc)` | 内容构建器(插入文本/图片/表格等) | +| `doc.range.replace()` / `replace_regex()` | 文本替换 | +| `doc.get_child_nodes()` | 节点遍历(段落/表格/评论/脚注) | +| `builder.insert_*()` | 插入各种元素 | +| `aw.saving.*SaveOptions` | 各格式导出选项 | +| `doc.watermark` | 水印 API | +| `doc.protect()` / `unprotect()` | 文档保护 | +| `aw.JoinRunsOptions` | Run 合并(26.x 新特性) | + +### 格式转换能力 + +这是 Aspose 相比 OfficeCLI 的**核心优势**——Aspose.Words SDK 内置了完整的文档渲染引擎,可以高保真输出多种格式: + +**输出格式**: +- 文档:DOCX、RTF、ODT +- 排版:PDF(含 PDF/A 合规级别) +- 网页:HTML、MHTML、HTML Fixed、EPUB、Markdown +- 图片:PNG、JPEG、TIFF、SVG +- 其他:Docling (JSON) + +**输入格式**:通过 `import_from_file` 可导入 Aspose.Words 支持的所有格式。 + +OfficeCLI 不做格式转换和渲染,只在原生 OOXML 格式内操作。当需要"把 docx 转成 PDF"时,Aspose 是更成熟的选择。 + +### 兼容性 + +**优势**: +- Aspose.Words 是 20 年的商业产品,格式兼容性经过大量企业验证 +- 内置完整的文档渲染引擎,PDF 输出质量高 +- 支持旧格式(.doc)的导入 +- 不依赖 Microsoft Office + +**限制**: +- 无许可证时有评估限制(输出文档带水印、页数限制) +- 仅覆盖 Word 格式——Excel 需要 Aspose.Cells MCP Server(TypeScript 实现),PPT 需要 Aspose.Slides(尚无 MCP Server) +- SDK 为闭源商业产品,无法审计其内部行为 + +--- + +## 四、技术栈 + +| 组件 | 技术选择 | 说明 | +|------|---------|------| +| 语言 | Python 3.11 - 3.13 | | +| MCP 框架 | FastMCP | 第三方 MCP 协议库,处理传输和序列化 | +| 文档引擎 | aspose-words ≥ 26.4.0 | 商业 SDK,Python 绑定 | +| 传输协议 | stdio / streamable-http / SSE | 通过环境变量 MCP_TRANSPORT 配置 | +| 测试框架 | pytest | 14 个测试文件,分三层 | +| 代码规范 | Ruff | 格式化 + lint | +| 构建 | Python build | 标准 pyproject.toml | +| 安装 | pip install aspose-words-mcp | PyPI 分发 | + +### 配置方式 + +通过环境变量配置: + +| 变量 | 默认值 | 说明 | +|------|-------|------| +| MCP_TRANSPORT | stdio | 传输协议 | +| MCP_HOST | 0.0.0.0 | HTTP 模式主机 | +| MCP_PORT | 8080 | HTTP 模式端口 | +| MCP_PATH | / | HTTP 路径 | +| DOCS_DATA_DIR | ./data | 文档存储目录 | + +### 测试覆盖 + +14 个测试文件,分三层: + +| 层级 | 文件 | 覆盖 | +|------|------|------| +| 单元测试 | test_store.py | DocumentStore | +| 服务器集成 | test_client_integration.py, test_run_server_config.py | MCP 客户端交互、启动配置 | +| 功能测试 | 10 个文件 | 文档管理、内容创建、表格、页面设置、页眉页脚、水印链接、HTML/Markdown、保护/批注/脚注等 | + +有 `AGENTS.md` 规范 AI Agent 的编码行为:禁止 `getattr/hasattr` 动态访问、禁止 broad `try/except`、版本必须与 Aspose.Words 对齐。 + +### Aspose 的 MCP 生态 + +Aspose 在多个产品线复制了相同的 AI 集成模式: + +| 产品线 | MCP Server | 语言 | 仓库 | +|--------|-----------|------|------| +| Words | aspose-words-mcp | Python | [链接](https://github.com/aspose-words/Aspose.Words-MCP-Server) | +| Cells | aspose-cells-mcp | TypeScript | [链接](https://github.com/aspose-cells/Aspose.Cells-MCP) | +| Words | agentic-net-examples | C# | AI 验证的示例代码 | +| Cells | agentic-net-examples | C# | AI 验证的示例代码 | + +模式一致:MCP Server + Agentic 示例库,逐步覆盖整个 Office 格式家族。 diff --git a/research/index.md b/research/index.md index 6be4b85..9180b8c 100644 --- a/research/index.md +++ b/research/index.md @@ -6,4 +6,5 @@ - [Aspose AI 产品能力分析](./aspose-ai) — 老牌文档处理公司的 AI 转型之路 - [OfficeCLI:为 AI Agent 而生的 Office 工具](./officecli) — 开源命令行 Office 套件,AI-first 设计 -- [Office AI 技术方案对比](./office-ai-tech-comparison) — OfficeCLI vs Aspose 源码级技术分析 +- [OfficeCLI 技术方案分析](./officecli-tech) — 架构、三层 API 设计、自研文档引擎源码分析 +- [Aspose MCP Server 技术方案分析](./aspose-mcp-tech) — 架构、90 个 MCP 工具、商业 SDK 集成分析 diff --git a/research/office-ai-tech-comparison.md b/research/office-ai-tech-comparison.md deleted file mode 100644 index 5e557df..0000000 --- a/research/office-ai-tech-comparison.md +++ /dev/null @@ -1,370 +0,0 @@ -# Office AI 技术方案对比:OfficeCLI vs Aspose - -> 调研时间:2026 年 5 月 | 作者:沙洲工作室 -> -> 基于源码分析,非黑盒测评 - -## 概述 - -本文从源码层面对比两种"AI + Office"技术方案: - -| 项目 | OfficeCLI | Aspose.Words MCP Server | -|------|-----------|------------------------| -| 开源 | ✅ Apache 2.0 | ✅ MIT(Server 层),核心 SDK 闭源商业 | -| 语言 | C#(.NET 10) | Python | -| 代码量 | 137,827 行 | ~6,628 行 | -| 核心依赖 | OpenXML SDK(开源) | Aspose.Words SDK(商业) | -| AI 集成方式 | CLI 命令 + MCP Server | MCP Server | -| 覆盖格式 | Word + Excel + PPT | 仅 Word | - -两者代表了截然不同的技术路线:**OfficeCLI 自己实现文档引擎**,**Aspose MCP Server 包装商业 SDK**。 - ---- - -## OfficeCLI 技术分析 - -### 架构 - -``` -┌─────────────────────────────────────────────┐ -│ AI Agent / 终端用户 │ -├──────────┬──────────────┬───────────────────┤ -│ CLI 命令 │ MCP Server │ Resident 管道 │ -├──────────┴──────────────┴───────────────────┤ -│ CommandBuilder │ -│ (System.CommandLine 路由) │ -├─────────────────────────────────────────────┤ -│ IDocumentHandler │ -│ ┌──────────┬──────────┬──────────┐ │ -│ │ WordHandler│ExcelHandler│PPTHandler│ │ -│ └──────────┴──────────┴──────────┘ │ -├─────────────────────────────────────────────┤ -│ Core(公式引擎、图表渲染、样式系统、SVG) │ -├─────────────────────────────────────────────┤ -│ DocumentFormat.OpenXML SDK │ -│ (微软开源) │ -└─────────────────────────────────────────────┘ -``` - -### 核心设计决策 - -**1. 基于 OpenXML SDK 自研引擎** - -OfficeCLI 没有依赖任何商业文档处理库,而是直接基于微软开源的 OpenXML SDK 构建了完整的文档操作引擎。这意味着: - -- ✅ 完全开源,无许可费 -- ✅ 可以深度定制每一层行为 -- ⚠️ 需要自己处理 Office 格式的所有复杂性 -- ⚠️ 13.8 万行代码的维护压力 - -总共只有 3 个 NuGet 依赖: -- `DocumentFormat.OpenXml 3.4.1` — 微软 OpenXML SDK -- `OpenMcdf 3.1.3` — OLE 复合文档(处理旧格式 .doc/.xls) -- `System.CommandLine 3.0.0-preview` — CLI 框架 - -依赖极简,是一个非常刻意的设计选择。 - -**2. 三层抽象架构** - -| 层级 | 命令 | 适合场景 | -|------|------|---------| -| L1 语义层 | `view`(text/annotated/outline/stats/issues) | AI 快速理解文档 | -| L2 DOM 层 | `get/query/set/add/remove/move/swap` | 结构化编辑 | -| L3 XML 层 | `raw/raw-set/add-part/validate` | 处理冷门功能 | - -这个分层非常聪明——AI Agent 日常用 L1+L2 就够了,遇到 L2 覆盖不到的功能可以降级到 L3 直接操作 XML。相当于给了 AI 一个"逃生舱"。 - -**3. 驻留进程(Resident Mode)** - -通过**命名管道(Named Pipe)**实现常驻进程模式: - -- 文档只打开/解析一次,后续操作直接在内存中执行 -- 两种模式:自动启动(60 秒空闲退出)和显式 open/close(12 分钟空闲退出) -- 并发安全,支持多个 AI Agent 同时操作不同文档 - -这解决了 CLI 工具的固有性能问题——每次执行命令都要加载 .NET 运行时 + 解析文件,驻留模式把这个开销摊薄到近乎零。 - -**4. 单二进制分发** - -通过 .NET 的 `PublishSingleFile + SelfContained + PublishTrimmed` 编译为单文件二进制: -- 内嵌 .NET 运行时,无需用户安装任何依赖 -- Skills、Schemas、CSS/JS 资源全部作为 `EmbeddedResource` 打入二进制 -- 支持 8 个平台目标(macOS/Linux/Windows × ARM64/x64,Linux 还有 musl 版本) - -对 AI Agent 来说,`curl | sh` 一行安装,立即可用。 - -**5. AI 技能系统** - -`skills/` 目录包含 12 个技能包,每个包含 `SKILL.md` + 参考文件: - -| 技能 | 用途 | -|------|------| -| officecli-docx | Word 文档操作指南 | -| officecli-xlsx | Excel 操作指南 | -| officecli-pptx | PPT 操作指南 | -| morph-ppt | PPT Morph 动画 | -| morph-ppt-3d | 3D Morph 效果 | -| officecli-academic-paper | 学术论文模板 | -| officecli-data-dashboard | 数据仪表板 | -| officecli-financial-model | 财务模型 | -| officecli-pitch-deck | 商业路演 PPT | -| officecli-word-form | Word 表单 | - -`schemas/help/` 目录是 JSON Schema 驱动的帮助系统——运行时从内嵌资源加载,AI 可以查询任何命令的参数说明。 - -### 代码质量观察 - -**优点**: -- 架构层次分明,`IDocumentHandler` 接口统一了三种格式的操作 -- 代码注释包含设计决策理由(不只是"做了什么"还有"为什么这样做") -- 错误处理完善——`SafeRun` 包装、友好的 XML 异常信息、JSON 错误信封 -- 跨平台细节考虑周到(Windows 句柄继承、macOS 代码签名、UTF-8 输出) - -**风险**: -- **零测试覆盖**——13.8 万行代码没有自动化测试,这是最大技术债务 -- 使用 `System.CommandLine` 的 preview 版本 -- Excel 处理器复杂度极高,大量 partial class 散布在多个文件中 -- 单人开发,bus factor = 1 - ---- - -## Aspose.Words MCP Server 技术分析 - -### 架构 - -``` -┌─────────────────────────────────────────────┐ -│ AI Agent(Claude 等) │ -├─────────────────────────────────────────────┤ -│ FastMCP(MCP 协议框架) │ -├─────────────────────────────────────────────┤ -│ mcp_server.py(70+ 工具注册) │ -│ ↓ tool_xxx() 辅助函数 │ -├─────────────────────────────────────────────┤ -│ core/ 模块 │ -│ ┌────────┬────────┬────────┬────────┐ │ -│ │content │tables │layout │export │ │ -│ │reading │styles │links │notes │ │ -│ │io │comments│watermarks│protection│ │ -│ └────────┴────────┴────────┴────────┘ │ -├─────────────────────────────────────────────┤ -│ Aspose.Words SDK(商业) │ -│ (闭源,需许可证或评估模式) │ -└─────────────────────────────────────────────┘ -``` - -### 核心设计决策 - -**1. 薄包装层设计** - -整个 MCP Server 本质上是 Aspose.Words SDK 的一层薄包装。核心逻辑不到 7000 行 Python,因为重活全部交给了 Aspose.Words 商业库。 - -三层调用链: -- MCP 工具函数(`@mcp.tool` 装饰器注册) -- `tool_xxx()` 辅助函数(可脱离 MCP 独立调用,方便测试) -- `core/` 模块(实际调用 Aspose.Words API) - -这种分离设计意味着换掉 MCP 协议层(比如改成 REST API),只需要改最外层。 - -**2. 文档存储模型** - -使用文件系统 + 内存映射: -- 每个文档用 UUID 标识,保存为 `.docx` 文件在 `./data` 目录 -- `DocumentStore` 是线程安全的内存字典,维护 doc_id → name 映射 -- 支持多文档同时打开和操作 - -这是一个简单但实用的设计——不需要数据库,重启后扫描 data 目录即可恢复状态。 - -**3. 依赖商业 SDK** - -核心依赖 `aspose-words>=26.4.0`(商业库)。这决定了: -- ✅ 文档处理能力经过 20 年打磨,格式兼容性极强 -- ✅ 代码量小,维护负担低 -- ⚠️ 无许可证时有评估限制(水印、页数限制) -- ⚠️ 只覆盖 Word 格式(Excel 有独立的 Aspose.Cells MCP Server) - -**4. 安全考虑** - -- 正则表达式查找替换有安全验证,防止 ReDoS 攻击 -- 文档保护功能支持加密和编辑范围限制 -- 有 `AGENTS.md` 规范 AI Agent 的编码行为 - -### 70+ 工具清单 - -MCP Server 注册了约 70 个工具,覆盖 Word 文档的几乎所有操作: - -| 类别 | 工具数 | 能力 | -|------|--------|------| -| 文档管理 | ~8 | 创建、复制、删除、合并、列表、导入 | -| 内容编辑 | ~10 | 插入文本/标题/段落/HTML/Markdown、查找替换 | -| 表格 | ~8 | 创建、合并单元格、着色、对齐、列宽 | -| 页面布局 | ~8 | 边距、方向、纸张、分栏、分节符、页眉页脚 | -| 样式格式 | ~6 | 自定义样式、文本格式化、列表 | -| 链接注释 | ~8 | 书签、超链接、批注、脚注、尾注 | -| 水印保护 | ~5 | 文字/图片水印、文档保护 | -| 导出读取 | ~10 | 多格式导出、页面渲染、段落读取、统计 | -| 属性 | ~4 | 标题、作者、关键词等文档元数据 | - -### 代码质量观察 - -**优点**: -- 分层清晰,MCP 层 / 工具层 / 核心层职责分明 -- 有测试覆盖(10 个测试文件,含单元测试和功能测试) -- 使用 Ruff 进行代码格式化和 lint -- 版本号与 Aspose.Words SDK 对齐(26.4.0) - -**不足**: -- `mcp_server.py` 单文件 1758 行,70+ 个工具注册在同一个函数里,可读性差 -- 每个工具都是对 `tool_xxx()` 的简单包装,存在大量重复模式 -- 仅覆盖 Word——Excel 和 PPT 需要独立的 MCP Server - -### Aspose 的 AI 开源生态 - -| 仓库 | 说明 | -|------|------| -| aspose-words/Aspose.Words-MCP-Server | Word MCP Server(Python) | -| aspose-cells/Aspose.Cells-MCP | Excel MCP Server(TypeScript) | -| aspose-words/agentic-net-examples | AI 验证的 C# 示例 | -| aspose-cells/agentic-net-examples | AI 验证的 C# 示例 | -| aspose-words/Aspose.Words-for-MarkItDown | 文档转 Markdown 插件 | -| aspose-words/Aspose.Words-for-Docling | 文档转 DoclingDocument 插件 | - -模式很统一:每个产品线 = MCP Server + Agentic 示例 + 生态插件。 - ---- - -## 核心差异对比 - -### 技术栈对比 - -| 维度 | OfficeCLI | Aspose MCP Server | -|------|-----------|-------------------| -| 语言 | C# (.NET 10) | Python | -| 代码量 | 137,827 行 | ~6,628 行 | -| 文档引擎 | 自研(基于 OpenXML SDK) | 商业 SDK(Aspose.Words) | -| 外部依赖 | 3 个 NuGet 包 | 2 个 pip 包 | -| 分发方式 | 单二进制,零依赖 | pip install,需 Python 环境 | -| 测试 | 无 | 有(10 个测试文件) | -| 格式覆盖 | docx + xlsx + pptx | 仅 docx | -| AI 接口 | CLI + MCP | 仅 MCP | -| 许可证 | Apache 2.0(完全免费) | MIT(Server),商业(SDK) | - -### 架构哲学对比 - -| 维度 | OfficeCLI | Aspose MCP Server | -|------|-----------|-------------------| -| 引擎策略 | 自研 13.8 万行 | 包装商业 SDK | -| 设计目标 | AI Agent 的通用 Office 工具 | Aspose 生态的 AI 入口 | -| 性能优化 | 驻留进程 + 批处理 + 实时预览 | 文件级操作,无常驻优化 | -| 抽象层次 | 三层(语义/DOM/XML) | 单层(70+ 扁平工具) | -| 扩展性 | 通过 L3 XML 层"逃生" | 受限于 SDK 暴露的能力 | -| 生态集成 | SKILL.md 技能系统 | MCP 协议标准 | - -### 能力覆盖对比 - -| 能力 | OfficeCLI | Aspose MCP | -|------|-----------|------------| -| Word 基础编辑 | ✅ | ✅ | -| Word 高级功能(表单、内容控件、OLE) | ✅ | 部分 | -| Excel 操作 | ✅(150+ 函数、透视表、图表) | ❌ | -| PPT 操作 | ✅(Morph、3D、动画) | ❌ | -| 文档格式转换 | 有限(同格式内操作) | ✅(docx→pdf/png/html) | -| 内置 AI 能力 | ❌ | ❌(Server 层无,SDK 有) | -| i18n / RTL | ✅ | ✅(SDK 层) | -| 实时预览 | ✅(Watch Mode + HTTP 服务器) | ❌ | - ---- - -## 适用场景分析 - -### OfficeCLI 最适合的场景 - -1. **AI 编辑器集成**(Claude Code、Cursor、Windsurf) - - 原因:CLI 是最自然的集成方式,无需配置 MCP 客户端 - - SKILL.md 让 AI 零学习成本上手 - -2. **需要同时操作 Word + Excel + PPT** - - 原因:一个工具覆盖三种格式,Aspose 需要三个独立 Server - -3. **对成本敏感的团队** - - 原因:完全免费开源,Aspose SDK 起价 $1,199 - -4. **需要交互式文档编辑** - - 原因:Watch Mode 实时预览 + Resident Mode 高性能,适合"边做边看" - -5. **PPT 制作场景** - - 原因:PPT 是 OfficeCLI 的强项(Morph、3D、动画),Aspose MCP 不覆盖 - -### Aspose MCP Server 最适合的场景 - -1. **企业级 Word 文档自动化** - - 原因:Aspose.Words 20 年积累的格式兼容性远超 OpenXML SDK 直接操作 - -2. **需要格式转换**(docx → pdf / png / html) - - 原因:Aspose 的渲染引擎是核心优势,OfficeCLI 不覆盖 - -3. **已有 Aspose 许可证的团队** - - 原因:MCP Server 是免费的,只需要已有的 SDK 许可证 - -4. **对文档正确性要求极高** - - 原因:商业 SDK 经过大量企业验证,边缘情况覆盖更全 - -5. **需要内置 AI 能力**(摘要、翻译、语法检查) - - 原因:通过 Aspose.Words SDK 可直接调用 LLM 处理文档 - ---- - -## 风险评估 - -### OfficeCLI 的风险 - -| 风险 | 严重程度 | 说明 | -|------|---------|------| -| 零测试覆盖 | 🔴 高 | 13.8 万行代码无自动化测试,格式兼容性靠手动验证 | -| 单人开发 | 🔴 高 | 核心开发者 1 人,bus factor = 1 | -| Office 格式复杂性 | 🟡 中 | OpenXML 规范极其庞大,边缘情况无穷,小团队难以穷举 | -| .NET preview 依赖 | 🟡 中 | System.CommandLine 仍是预览版 | -| 商业模式缺失 | 🟡 中 | 纯开源无收入,长期可持续性存疑 | - -### Aspose MCP Server 的风险 - -| 风险 | 严重程度 | 说明 | -|------|---------|------| -| 商业 SDK 锁定 | 🟡 中 | 核心能力依赖闭源商业库,价格由 Aspose 决定 | -| 仅覆盖 Word | 🟡 中 | Excel/PPT 需要独立 Server,集成复杂度高 | -| 代码组织 | 🟢 低 | 1758 行单文件可读性差,但功能正确 | -| MCP 生态成熟度 | 🟡 中 | MCP 协议仍在早期,标准可能变化 | - ---- - -## 总结 - -### 两种路线的本质差异 - -``` -OfficeCLI 路线: - 自研引擎 → 掌控一切 → 代码量大 → 维护压力大 → 但完全自由 - -Aspose 路线: - 包装 SDK → 站在巨人肩上 → 代码量小 → 受制于人 → 但质量有保障 -``` - -这是一个经典的"自研 vs 集成"权衡: - -- OfficeCLI 选择了**自由但艰难**的路——13.8 万行代码、零测试、单人维护,但不依赖任何商业组件 -- Aspose 选择了**省力但受限**的路——6600 行代码、有测试、成熟 SDK,但被锁定在商业生态中 - -### 给技术选型的建议 - -- **如果你是 AI Agent 开发者,想快速给 Agent 加上 Office 能力** → OfficeCLI。一行安装、CLI 直接调用、免费开源 -- **如果你是企业,需要在生产环境中处理大量 Word 文档** → Aspose。格式兼容性、稳定性、技术支持都更可靠 -- **如果你需要做 PPT 或 Excel** → OfficeCLI 是目前唯一选择(Aspose Cells MCP Server 存在但较新) -- **如果你需要 docx → pdf 转换** → Aspose。OfficeCLI 不做渲染 - -### 行业趋势判断 - -OfficeCLI 代表的"CLI-first AI 工具"范式正在兴起——工具不再为人类设计 GUI,而是为 AI Agent 设计命令行接口。这个趋势如果持续,**未来每个生产力软件都需要一个"AI Agent 接口"**,无论是 CLI、MCP 还是其他协议。 - -Aspose 代表的"传统软件 + AI 层"范式则更稳健——不颠覆已有架构,在成熟产品上叠加 AI 能力。风险低但想象空间有限。 - -两条路线未必会合一。更可能的结局是:OfficeCLI 类工具成为 AI Agent 的"默认手"(轻量、快速、免费),Aspose 类产品在需要高保真渲染和企业级兼容性时被调用。 diff --git a/research/officecli-tech.md b/research/officecli-tech.md new file mode 100644 index 0000000..63d45d1 --- /dev/null +++ b/research/officecli-tech.md @@ -0,0 +1,277 @@ +# OfficeCLI 技术方案分析 + +> 调研时间:2026 年 5 月 | 作者:沙洲工作室 +> +> 基于源码阅读(v1.0.72),非黑盒测评 + +## 基本信息 + +| 项目 | 信息 | +|------|------| +| 仓库 | [iOfficeAI/OfficeCLI](https://github.com/iOfficeAI/OfficeCLI) | +| 语言 | C#(.NET 10) | +| 许可证 | Apache 2.0 | +| 代码量 | ~285 个源文件,约 137,800 行 C# | +| 外部依赖 | 仅 3 个 NuGet 包 | +| 支持格式 | Word (.docx)、Excel (.xlsx)、PowerPoint (.pptx) | + +--- + +## 一、整体架构 + +### 分层结构 + +``` +┌─────────────────────────────────────────────────────────┐ +│ AI Agent / 用户终端 │ +├────────────┬──────────────┬─────────────────────────────┤ +│ CLI 命令 │ MCP Server │ Resident 管道(Named Pipe) │ +│ (System. │ (JSON-RPC │ (常驻进程,内存持有文档, │ +│ CommandLine│ over stdio) │ 近零延迟响应) │ +│ 路由) │ │ │ +├────────────┴──────────────┴─────────────────────────────┤ +│ CommandBuilder │ +│ (partial class,按功能拆分十余个文件) │ +│ View / Set / Add / Get / Dump / Raw / Batch / │ +│ Watch / Mark / Help / Import / Refresh / Check │ +├─────────────────────────────────────────────────────────┤ +│ DocumentHandlerFactory │ +│ (按扩展名分发到对应 Handler) │ +├──────────┬───────────────┬──────────────────────────────┤ +│ WordHandler │ ExcelHandler │ PowerPointHandler │ +│ (~25 partial│ (~20 partial │ (~30 partial files) │ +│ files) │ files) │ │ +│ 持有 │ 持有 │ 持有 │ +│ Wordprocessing│Spreadsheet │ Presentation │ +│ Document │ Document │ Document │ +├──────────┴───────────────┴──────────────────────────────┤ +│ Core 模块 │ +│ ┌──────────┬──────────┬──────────┬──────────────────┐ │ +│ │ Formula/ │ Chart/ │ Watch/ │ PivotTableHelper │ │ +│ │ 公式解析 │ SVG渲染 │ 实时预览 │ 透视表引擎 │ │ +│ │ + 求值 │ + ChartEx│ + SSE │ │ │ +│ ├──────────┼──────────┼──────────┼──────────────────┤ │ +│ │ ThemeColor│ FontMetrics│ Units │ HtmlPreview │ │ +│ │ 主题色解析│ 字体度量 │ 单位转换│ HTML 预览 │ │ +│ └──────────┴──────────┴──────────┴──────────────────┘ │ +├─────────────────────────────────────────────────────────┤ +│ DocumentFormat.OpenXML SDK 3.4.1 │ +│ (微软开源 OpenXML SDK) │ +└─────────────────────────────────────────────────────────┘ +``` + +### 模块关系 + +**入口层**:`Program.cs` 是 top-level statements 入口。在进入 System.CommandLine 之前,先拦截处理一批"快捷命令"——`mcp`、`install`、`skills`、`load_skill`、`config` 等,这些不走标准 CLI 路由。 + +**命令路由层**:`CommandBuilder` 是一个 partial class,拆分到十几个文件(`CommandBuilder.View.cs`、`CommandBuilder.Set.cs`、`CommandBuilder.Add.cs` 等),通过 `BuildRootCommand()` 注册所有子命令。注册的命令包括:`open/close`、`view`、`get`、`query`、`set`、`add`、`remove`、`move`、`swap`、`raw`、`rawSet`、`addPart`、`validate`、`batch`、`dump`、`import`、`create`、`merge`、`watch/unwatch`、`mark/unmark`、`goto`、`help` 等。 + +**Handler 层**:`DocumentHandlerFactory.Open()` 根据文件扩展名分发到三个 Handler。每个 Handler 持有对应的 OpenXML Document 对象,用 partial class 按功能拆分为大量文件: + +| Handler | partial 文件数 | 覆盖功能 | +|---------|--------------|---------| +| WordHandler | ~25 | View/Set/Add/Query/Navigation/HtmlPreview/FormFields/StyleList/I18n/ImageHelpers/Selector | +| ExcelHandler | ~20 | View/Set/Add/Query/Import/Slicer/HtmlPreview/CheckOverflow,带行索引缓存 | +| PowerPointHandler | ~30 | View/Set/Add/Query/Fill/Effects/Animations/Background/Theme/Comments/Hyperlinks/SvgPreview/Model3D | + +**Core 层**:40+ 个辅助模块,包含多个自研引擎(公式、图表、透视表等),以及主题色解析、字体度量、单位转换、HTML 预览等基础能力。 + +**统一接口**:三个 Handler 都实现 `IDocumentHandler` 接口,这是整个项目的核心抽象。 + +--- + +## 二、API / CLI 抽象设计 + +### 三层操作架构 + +OfficeCLI 最核心的设计是将 Office 文档操作分为三个粒度层次: + +#### L1:语义视图层(只读,理解文档) + +| 命令 | 视图模式 | 用途 | +|------|---------|------| +| `view --mode text` | 纯文本 | 获取文档全部文字内容 | +| `view --mode annotated` | 带编号标注 | 每个元素标上 `[P1]` `[T2]` 等编号,AI 通过编号定位 | +| `view --mode outline` | 大纲 | 文档标题层级结构 | +| `view --mode stats` | 统计 | 字数、段落数、表格数等 | +| `view --mode issues` | 问题检测 | 格式问题、兼容性问题 | +| `view --mode html` | HTML 预览 | 可视化渲染 | + +所有视图模式都有 JSON 变体(如 `ViewAsStatsJson()`),支持 `--start/--end/--max-lines/--cols` 分页参数。 + +**`annotated` 视图是关键设计**——它为文档中的每个元素生成唯一编号,AI Agent 在后续的编辑操作中可以直接引用编号进行精确定位,不需要用模糊的自然语言描述位置。 + +#### L2:DOM 操作层(读写,结构化编辑) + +| 命令 | 功能 | 操作粒度 | +|------|------|---------| +| `get ` | 获取元素,返回 `DocumentNode` | 元素级,可指定深度 | +| `query ` | CSS-like 选择器查询 | 类型/属性筛选 | +| `set ` | 修改元素属性 | 属性级(字体、颜色、对齐等) | +| `add ` | 添加元素 | 支持 Index/After/Before 定位 | +| `remove ` | 删除元素 | 元素级 | +| `move ` | 移动元素 | 元素级 | +| `swap ` | 交换两个元素 | 元素级 | + +`DocumentNode` 是跨文档类型的**通用 DOM 节点抽象**,包含:path(DOM 路径)、type(元素类型)、text(文本内容)、preview(预览)、style、format(属性字典)、children(子节点)。 + +#### L3:Raw XML 层(底层逃生舱) + +| 命令 | 功能 | +|------|------| +| `raw ` | 直接读取 OpenXML part 的原始 XML | +| `rawSet ` | XPath 定位并修改 XML 节点 | +| `addPart` | 创建新的 XML part(图表、页眉页脚等) | +| `validate` | OpenXML schema 合规性验证 | + +这层的存在非常务实:Office 格式的 XML 规范极其庞大,L2 无法覆盖所有操作。当 AI Agent 遇到 L2 不支持的功能时,可以降级到 XML 层直接操作——相当于一个"逃生舱"。 + +### AI Agent 交互设计 + +**1. MCP Server** + +`McpServer.cs` 实现了 JSON-RPC 2.0 over stdio 的 MCP 协议。为了兼容 .NET 的 PublishTrimmed(会裁剪掉反射),手写 `Utf8JsonWriter` 序列化,不使用 JSON 反射。支持 `tools/list` 和 `tools/call`,内置后台升级检查。 + +`McpInstaller` 支持一键注册到主流 AI 编辑器的配置文件:Claude Code、Cursor、VS Code Copilot、LM Studio。 + +**2. SKILL.md 技能系统** + +内置 `SKILL.md` 文件嵌入到二进制中,AI Agent 读取后自动学会使用方式。策略分层指导 AI 先用 L1 理解文档,再用 L2 编辑,必要时降级 L3。 + +`skills/` 目录包含 12 个专项技能包: + +| 技能 | 场景 | +|------|------| +| officecli-docx / xlsx / pptx | 三种格式的通用操作指南 | +| morph-ppt / morph-ppt-3d | PPT Morph 动画和 3D 效果 | +| officecli-academic-paper | 学术论文模板 | +| officecli-data-dashboard | 数据仪表板 | +| officecli-financial-model | 财务模型 | +| officecli-pitch-deck | 商业路演 PPT | +| officecli-word-form | Word 表单 | + +通过 `officecli skills install` 安装到 Agent 环境。 + +**3. Schema 驱动的帮助系统** + +`schemas/help/` 目录按格式(docx/pptx/xlsx)存放 JSON Schema 文件,描述每种元素的属性、别名、示例。嵌入为 EmbeddedResource,运行时通过 `SchemaHelpLoader` 读取,`SchemaHelpRenderer` 渲染。支持按动词(add/set/get)过滤——AI 可以查询"我能给 slide 设置哪些属性"。 + +**4. JSON 输出** + +全局 `--json` 选项,`OutputFormatter.WrapEnvelopeText()` 统一 JSON 信封格式。所有命令的输出都可以结构化,方便 AI 解析。 + +--- + +## 三、Office 文档引擎 + +### 底层依赖:OpenXML SDK + +OfficeCLI 基于微软开源的 `DocumentFormat.OpenXml 3.4.1` 构建。这个 SDK 提供了 Office Open XML(OOXML)格式的底层读写能力——本质上是操作 .docx/.xlsx/.pptx 文件内部的 XML 结构。 + +OpenXML SDK 本身是**低层级**的——它只提供 XML 节点的创建和操作,不提供"添加一个格式化的表格"这样的高层 API。OfficeCLI 在此基础上自研了大量高层抽象。 + +### 自研引擎模块 + +**1. 公式引擎(Core/Formula/)** + +自研 Excel 公式解析和求值器: +- `FormulaParser.cs` — 将公式文本解析为 AST +- `FormulaEvaluator.cs` + `.Functions.cs` + `.Helpers.cs` — 150+ 内置函数的求值 +- 支持 Numeric/String/Boolean/Error/Array 类型 +- 15 位有效数字精度控制 +- `ModernFunctionQualifier` 处理新版函数名 + +这意味着 OfficeCLI 可以在不打开 Excel 的情况下**计算公式结果**。 + +**2. 图表引擎(Core/Chart/)** + +这是代码量最大的自研模块之一: +- `ChartSvgRenderer.cs`(2,897 行)— 完整的 SVG 图表渲染器 +- `ChartSvgRenderer.CxExtract.cs` — ChartEx 扩展图表支持(直方图、漏斗图、树状图、旭日图、箱线图) +- `ChartHelper.cs` + Builder/Reader/Setter/Axis/Advanced — 图表 DOM 操作 +- `ChartExBuilder.cs` — ChartEx 格式构建器 +- `ChartPresets.cs` / `ChartExResources.cs` — 预设样式和嵌入的 XML 模板 + +可以在不安装 Office 的情况下**渲染图表为 SVG**。 + +**3. 透视表引擎(Core/PivotTableHelper\*)** + +6 个 partial 文件覆盖完整的透视表处理链:Parse → Cache → Definition → Render → Set → Readback。自行实现了透视表的缓存计算。 + +**4. 主题色系统** + +- `ThemeColorResolver` — 解析 Office 主题色(accent1-6 + shade/tint 变体) +- `OfficeDefaultThemeColors` — 内置默认主题 +- 这是正确渲染 Office 文档颜色的关键——Office 的颜色系统不是简单的 hex,而是基于主题的相对值 + +**5. 其他自研模块** + +| 模块 | 功能 | +|------|------| +| FontMetricsReader / LocaleFontRegistry | 字体度量和区域字体映射 | +| WordTocBuilder | 目录自动构建 | +| WordNumFmtRenderer | Word 编号格式渲染 | +| ExcelStyleManager | Excel 样式管理 | +| HtmlPreviewHelper / HtmlScreenshot | HTML 预览和浏览器截图 | +| DrawingEffectsHelper | 绘图效果(阴影、发光等) | +| SvgImageHelper | SVG 图片处理 | +| EmuConverter / Units / SpacingConverter | EMU/pt/cm/inch 单位转换 | +| OleHelper + OpenMcdf | OLE 嵌入对象处理 | +| WordStrictAttributeSanitizer | Strict OpenXML 属性清理 | +| GenericXmlQuery | 通用 XML 查询 | +| TemplateMerger | 模板合并 | +| PathAliases | DOM 路径别名系统 | + +### 兼容性考量 + +**优势**: +- 基于 OpenXML SDK,直接操作标准 OOXML 格式,与 Microsoft Office 原生兼容 +- 支持 Strict OpenXML 和 Transitional OpenXML 两种变体 +- 完整的 i18n 和 RTL(从右到左文字)支持 +- `validate` 命令可验证文档是否符合 OpenXML schema + +**风险**: +- OpenXML SDK 只是"能读写 XML",正确性取决于上层实现——Office 格式有大量未文档化的行为和边缘情况 +- 不支持旧格式(.doc/.xls/.ppt),仅支持 OOXML 格式(.docx/.xlsx/.pptx) +- 图表渲染、公式求值等自研引擎可能与 Office 的实际行为有差异 +- **没有自动化测试**(13.8 万行代码零测试),格式兼容性靠人工验证 + +--- + +## 四、技术栈 + +| 组件 | 技术选择 | 说明 | +|------|---------|------| +| 运行时 | .NET 10.0 | 最新版,启用 nullable + implicit usings | +| CLI 框架 | System.CommandLine 3.0.0-preview | 微软官方 CLI 库(仍是预览版) | +| 文档引擎 | DocumentFormat.OpenXml 3.4.1 | 微软开源 OpenXML SDK | +| OLE 支持 | OpenMcdf 3.1.3 | 开源 OLE 复合文档库 | +| IPC | Named Pipe | 驻留模式进程间通信 | +| MCP | 手写 JSON-RPC 2.0 | 不依赖 MCP 框架库 | +| 序列化 | Utf8JsonWriter + Source Generator | 兼容 PublishTrimmed,避免反射 | +| 构建 | dotnet publish | PublishSingleFile + SelfContained + PublishTrimmed | +| 实时预览 | 内嵌 HTTP 服务器 + SSE | Watch Mode | +| CI/CD | GitHub Actions | 8 个平台目标交叉编译 | + +### 单二进制分发 + +通过 .NET 的三个发布选项组合实现: +- `PublishSingleFile` — 打包为单文件 +- `SelfContained` — 内嵌 .NET 运行时 +- `PublishTrimmed` — 裁剪未使用的代码 + +Skills、Schemas、CSS/JS 资源全部作为 `EmbeddedResource` 嵌入程序集。`build.sh` 支持 8 个平台目标:macOS (ARM64/x64)、Linux (x64/ARM64/musl)、Windows (x64/ARM64)。macOS 构建包含 ad-hoc 代码签名。 + +### 驻留模式(Resident Mode) + +**问题**:每次执行 CLI 命令都要启动 .NET 运行时 → 打开文件 → 解析 XML → 执行操作 → 保存文件。AI Agent 连续执行几十条命令时,这个开销不可接受。 + +**解法**:双管道架构的常驻进程: +- **主命令管道**:接收和执行命令 +- **Ping 管道**:独立的健康检查通道,用于验证进程是否存活 +- `SemaphoreSlim` 单命令锁,串行化请求 +- 两种生命周期:自动启动模式(60 秒空闲退出),显式 open/close 模式(12 分钟空闲退出) +- 支持 `__set-idle-timeout__` RPC 动态调整超时 +- 关键不变量:ping 响应 ⇔ handler 持有文件锁 + +**流程**:`open` → 启动子进程(`__resident-serve__`)→ 后续命令通过 pipe 转发 → `close` 发送关闭指令。Windows 上有特殊处理来避免 handle 继承泄漏。