v0.9.7 - Python 引擎、Gitignore 锚定修复、引擎生命周期与安全加固

核心亮点

docmd v0.9.7 引入了全新的 Python 引擎,修复了 v0.9.6 引入的 gitignore 回归问题,统一了引擎生命周期管理,并对 CLI 和开发服务器进行了一系列安全加固。

  • Python 引擎 (@docmd/engine-python):全新引擎适配器,利用 Python 3 (>= 3.8) 通过高性能 stdio 工作池加速文件发现、Git 历史解析及搜索索引。
  • 统一引擎生命周期 (@docmd/api, @docmd/core):在所有引擎(js、rust、python)中实现标准化的 shutdown() 和 destroy() 方法,具备工作池空闲自动清理与进程安全退出。
  • docmd-search 0.1.6 集成:更新搜索集成与插件 peerDependencies,要求支持 Python 引擎的 docmd-search >=0.1.6。
  • Gitignore 锚定模式修复 (#244):锚定模式(如 /airo)现在相对于项目根目录进行匹配,而非绝对文件系统路径。此前,若模式恰好与绝对路径中任意祖先文件夹的名称相符,所有页面都会被静默排除,构建将报告 Generated 0 pages。
  • MCP config.exclude 执行 (#245):search_docs、list_docs 与 validate_docs 现在遵守 config.exclude。此前,被排除的文件(例如草稿或归档页面)仍会通过 MCP 工具暴露给 AI 智能体。
  • Shell 注入防护:在 doctor 命令和搜索索引子进程中,将 execSync shell 模板字符串替换为 spawnSync 显式参数数组。
  • 开发服务器 XSS 与路径穿越加固:404/500 错误页面中反射的 URL 现已进行 HTML 转义,重定向目标经过严格验证。
  • 资产路径规范化:Live 服务器资产解析现在通过 canonicalSafePath 强制执行安全路径边界。

Python 引擎 (@docmd/engine-python)

v0.9.7 将 Python 引入到 docmd 与 JavaScript、Rust 并列的多引擎架构中:

  • 自动探测与零配置:若系统 PATH 中安装有 Python 3,在 docmd.config.json 中配置 "engine": "python" 即可自动启用。若未检测到,docmd 会平滑降级至 JS 引擎。
  • 持久化工作池:通过优化的 stdio JSON-RPC 工作池运行,支持空闲自动回收,消除跨任务的子进程启动开销。
  • 插件深度集成:直接驱动 Git 日志提取、搜索索引及批量文件扫描。

引擎生命周期与资源管理 (@docmd/api, @docmd/core)

  • 标准化关停机制:在所有引擎实现(@docmd/engine-js、@docmd/engine-rust、@docmd/engine-python)的 Engine 接口中统一提供 shutdown() 与 destroy() 钩子。
  • 资源彻底释放:构建与开发管线在完成时自动调用 shutdownEngines(),彻底释放子进程管道、内存和原生绑定。
  • 空闲工作池回收:Python 引擎在无任务空闲时自动关停工作进程,杜绝后台僵尸监听进程。

Gitignore 锚定模式回归 (@docmd/core)

已修复的 Bug (#244): 自 v0.9.6 引入 .gitignore 感知的页面发现功能以来,带前导 / 的锚定模式会被去掉该斜杠,然后与每个文件的完整绝对路径进行匹配。这意味着 /airo(用于忽略仓库根目录的编译产物)也会匹配 /Users/someone/github/airo/docs/ 下的所有文件。

根本原因:isExcludedPath 去掉前导 / 后,对完整绝对路径执行 normalizedPath.includes('/airo/'),而非相对路径。

修复方案: 锚定模式现在仅与相对于顶级源目录的路径进行匹配。非锚定模式(无前导 /)保留原有的任意路径段匹配行为。findFilesRecursive 现在跟踪并在所有递归调用中传递原始项目根目录。

安全加固 (@docmd/core、@docmd/plugins-search、@docmd/live)

  • doctor 命令:将 execSync 替换为 spawnSync(['npm', 'doctor']),使用 shell: false。
  • 搜索索引子进程:以相同方式进行加固。
  • 开发服务器 (docmd dev):404 和 500 错误中反射的 req.url 现在经过 HTML 转义;重定向目标经过白名单验证后才作为 Location 响应头发送。
  • Live 服务器资产解析:所有资产路径通过 canonicalSafePath 解析,确保请求不能穿越到输出目录之外。

MCP config.exclude 执行 (@docmd/core)

已修复的 Bug (#245): MCP 服务端中的 search_docs、list_docs 和 validate_docs 此前忽略了 config.exclude。内部的 findMarkdownFiles() 函数仅跳过 node_modules 和点前缀目录,从未读取过 v0.9.6 中引入的排除模式。这意味着查询 MCP 服务的 AI 智能体可以发现并读取特意从公开发布站点中排除的文档(如归档规范、内部草稿)。

修复方案: search_docs 和 list_docs 现在使用 findFilesRecursive()(即构建管线所使用的相同文件遍历器),它已应用 config.exclude、.gitignore 及所有标准跳过规则。validate_docs 将 config.exclude 传递给链接校验器的文件遍历逻辑。构建输出与 MCP 工具结果现在对“哪些属于已发布文档”保持完全一致。

0.9.8 展望

  • Pre-flight 批量安装后的包完整性检查,以检测半解压的包被误标记为已解析的情况。
  • Gitignore 匹配引擎的进一步改进(否定模式 !、子目录级 .gitignore 文件)。