首页
/ Motrix 工程规范全解:基于 CLAUDE.md 的双宿主架构边界、核心命令与 AI Agent 协作规则

Motrix 工程规范全解:基于 CLAUDE.md 的双宿主架构边界、核心命令与 AI Agent 协作规则

2026-09-06 13:25:43作者:虞亚竹Luna

Motrix(Motrix Turbo)是一个同时运行在 Electron 桌面端与 Node/Web 服务端的完整下载管理器。本文以仓库根目录的 CLAUDE.md 为骨架,完整解读它定义的仓库定位、核心命令、架构边界与规则路由机制,并结合 package.jsonscripts/check-boundaries.mjssrc/shared/protocol/commands.ts 等源码证据,说明这些规范是如何被脚本和类型契约落地成可执行、可验证的工程约束的。读完本文,你将掌握 Motrix 的目录分层、双传输契约、提交质量门禁,以及 AI Agent 在该仓库协作时的规则加载顺序。

CLAUDE.md 在仓库中的定位

CLAUDE.md 是 Motrix 的 AI Agent 权威指引文件,开篇给出两条仓库级事实:

  1. 项目形态:Motrix Turbo 是 Electron + Node/Web 下载管理器。src/core/ 必须保持宿主中立(host-neutral),以便同一份产品核心既能被 Electron 壳复用,也能被 Node 服务端壳独立替换。
  2. 分支策略:开发在 main 分支进行;master 是冻结的遗留分支,对应旧版 Electron 22 / Vue 2 应用。所有分支创建与 PR 目标只能是 main,绝不能指向 master

仓库中的 AGENTS.md 进一步说明:Claude Code 规则是唯一的规范来源,Codex 等其他 Agent 直接继承而不再维护第二份副本。它规定了 Agent 在检查或修改文件前必须依次读取:

  1. CLAUDE.md
  2. 所有不带 paths frontmatter 的全局 .claude/rules/*.md 规则;
  3. 所有 paths 模式与待检查/修改文件相匹配的规则。

冲突解决顺序为:当前用户指令 > AGENTS.md > CLAUDE.md > 匹配的 .claude/rules/*.md > Agent 默认行为,并要求"更新 Claude 规范规则而不是重复维护指引"。这种"单一事实源 + 按路径按需加载"的设计,是本文后面"规则路由"一节的核心。

核心命令一览

CLAUDE.md 给出的命令表是仓库日常开发的入口,这里完整继承并结合 package.jsonscripts 字段补充实际执行内容:

命令 用途 实际执行内容(来自 package.json)
pnpm start Electron 开发运行器 node scripts/dev.mjs,且 prestart 会先执行 ensure:electron-runtimeensure-native-abi.mjs electron
pnpm start:server 已构建的 Node/Web 服务端 MOTRIX_SKIP_ELECTRON_REBUILD=1 node dist/server/index.mjs
pnpm test 全量 Vitest 套件 vitest runpretest 先跑 ensure-native-abi.mjs node
pnpm exec vitest run <test-path> 单测聚焦运行 针对单个测试路径
pnpm run lint Biome 全仓检查 biome check .(由 biome.json 限定范围)
pnpm exec tsc --noEmit 类型检查 TypeScript 编译期检查,不产出文件
pnpm build 桌面端生产构建 依次执行 build:builtinbuild:native-hostbuild:electron(后者含 main/preload/worker/renderer 四个 vite 构建)
pnpm build:server Node/Web 生产构建 build:builtin + build:legal + server/worker/renderer-web 三个 vite 构建
pnpm test:e2e Playwright 端到端套件 playwright testpretest:e2e 先确保 Electron 运行时与 Electron ABI)

CLAUDE.md 还强调两条执行纪律:

  • 使用 pnpm exec 而不是 npx。仓库锁定 packageManager: pnpm@11.22.0,用 pnpm 调用可保证依赖解析与锁文件一致。
  • 权威提交门禁是 .claude/rules/commit-and-quality.md,它规定了每次提交前必须通过的三项检查(见下文"提交质量门禁")。

package.json 的依赖表可以看到这套命令背后的技术栈规模:Electron 43、React 19、Vite 8、Vitest 4、Playwright、Fastify、better-sqlite3、quickjs-emscripten(插件沙箱)、zod(契约校验)等,pnpm build / pnpm build:server 分别对应桌面与 Web 两条交付链路。

架构边界:四条硬性约束

CLAUDE.md 的 "Architecture Boundaries" 一节是整个文档最核心的部分,逐条列出四条不可违反的依赖方向:

  1. src/core/ 绝不导入 electronsrc/main/
  2. src/renderer/ 绝不导入 src/core/src/main/src/server/;渲染层与后端通信必须经由 @renderer/lib/transport,并使用共享协议常量;
  3. src/shared/ 只包含纯跨层契约与描述性运行时数据:不允许 IO、定时器、网络、Electron API 或任何 Node 特有 API;
  4. 一律使用 src/shared/protocol/ 导出的 CommandsQueriesEvents 及其 Bridge* 对应物,禁止使用裸传输通道字符串

自动化边界检查:check-boundaries.mjs

这些约束并非仅靠自觉。scripts/check-boundaries.mjs 用一组 grep -rnE 规则做机器化兜底,例如:

  • core must not import electron:在 src/core/ 下禁止 from 'electron'
  • core must not import fastifysrc/core/ 也不允许直接依赖服务端框架 fastify,保证核心不感知任何宿主;
  • shared must not use Node-specific APIs or globalssrc/shared/ 下禁止 node: 前缀导入、动态 import('node:...'),以及 process.NodeJS. 全局引用;
  • renderer must not import core or mainsrc/renderer/ 下禁止出现 (core|main)/ 路径导入;
  • server must not import electronserver must not import src/main:服务端壳与 Electron 主进程彻底隔离;
  • 还有一条 UI 级规则:src/renderer/components/add-task/ 组件不得直接导入 @renderer/lib/transport@shared/protocol/commands,仅放行三个 IPC 感知文件(use-external-hydration.tsdrop-zone.tsxadd-task-form.tsx),把"谁有权发起 IPC"收敛到极少数入口。

脚本对每条规则输出 [PASS]/[FAIL],任一失败即以非零码退出。需要留意的是,.claude/rules/architecture.md 明确指出该脚本只是"自动化基线",并非完整的架构证明——部分例外不是机器强制的,改动导入时仍需对照规则矩阵人工审查。

完整分层矩阵与双传输契约

.claude/rules/architecture.md 在 CLAUDE.md 四条边界的基础上给出了更完整的分层矩阵:

目录 角色 允许的依赖
src/renderer/ Electron/浏览器前端 @shared/、渲染层本地模块
src/core/ 宿主中立的产品核心 @shared/、宿主中立的 Node/外部库
src/main/ Electron 壳与 IPC @core/@shared/、Electron
src/preload/ Electron 桥 @shared/ 协议值/类型、Electron
src/server/ Node/Docker 壳 @core/@shared/、服务端库
src/shared/ 跨层契约 仅纯 schema、常量、数据与工具函数

该规则文件还解释了"同构前端 + 双宿主"的关键机制——双传输契约

Electron: renderer -> ElectronTransport -> preload -> main IPC -> core
Browser:  renderer -> HttpWsTransport -> server RPC/events -> core

在源码中可以逐一印证:渲染层的 src/renderer/lib/transport/electron.tssrc/renderer/lib/transport/http-ws.ts 正是两条传输实现的落点,src/server/ 下则有配套的 HTTP/WS 桥接模块。规则强调:window.motrix 的直接访问仅限于 Electron 传输实现与窄范围的平台适配器,特性代码必须留在抽象之后;事件通过所选择的壳与传输返回,因此渲染层状态不能依赖任何宿主特定通道。

协议常量:禁止裸通道字符串

第四条边界在 src/shared/protocol/commands.ts 中有直接体现——所有命令通道名集中定义为常量对象,例如:

export const Commands = {
  CreateDownload: 'command:createDownload',
  PauseTask: 'command:pauseTask',
  ResumeTask: 'command:resumeTask',
  RemoveTasks: 'command:removeTasks',
  UpdateSettings: 'command:updateSettings',
  RestartEngine: 'command:restartEngine',
  // ...
}

src/shared/protocol/ 目录下还有配套的 queries.tsevents.tsbridge.tsBridge* 通道)以及带测试的 errors.tsforwardable-events.tshandler-types.ts。这种集中式通道表让 IPC 两端(Electron 主进程与 HTTP/WS 服务端)共享同一份"词汇表",任何新增命令都必须先进入契约层,再被两个壳分别注册处理器。

引擎适配器边界

同一条架构规则还规定了产品层与下载引擎之间的隔离:产品级代码一律面向 src/core/engine/engine-adapter.ts 中的 EngineAdapter 接口,而不是直接依赖 aria2 RPC 类型;具体引擎在适配器边界处做翻译。EngineSupervisor(位于 src/core/engine/)是引擎启动、停止、重启生命周期的唯一持有者。这正是 CLAUDE.md 开头"核心必须宿主中立、可被未来引擎独立替换"这一设计意图在引擎层的延伸。

提交质量门禁

.claude/rules/commit-and-quality.md 是 CLAUDE.md 指定的"权威提交门禁",分为两部分。

每次提交必跑三项检查(失败必须修复后才能提交):

pnpm run check:boundaries
pnpm run lint
pnpm exec tsc --noEmit

其中 pnpm run lint(即 biome check .,范围由 biome.json 约束)与 CI 运行的是同一条命令——规则明确要求不要换成更窄的路径列表,也不允许用管道等方式丢弃其退出码。暂存文件后还需检查 git diff --staged 并运行 git diff --cached --check,不得因 CI 任务非阻塞而掩盖失败。

按变更类型附加的检查

  • 行为/逻辑变更:pnpm exec vitest run <test-path> 聚焦测试;跨切面改动用 pnpm test
  • 浏览器/Electron 用户流:受影响流程有 E2E 覆盖时跑 pnpm test:e2e
  • 国际化资源或 i18n 行为:pnpm run check:i18n
  • 新增或重命名文件:pnpm run check:file-names
  • 插件 manifest 契约:pnpm run check:schema-parity
  • 依赖、打包资源或许可证元数据:pnpm run check:third-party-notices
  • 原生宿主 Rust(packages/native-host):cargo fmt --checkcargo clippy -D warningscargo test --locked 三件套;
  • 打包/发布代码:跑 tests/scripts/ 下对应聚焦测试与验证脚本。

只有针对已审查过的、可自动修复的问题才允许使用 pnpm exec biome check --write .,且之后必须重跑完整门禁。

分支、提交与发布纪律

CLAUDE.md 只给出"开发在 mainmaster 已冻结"的原则;.claude/rules/git-workflow.md 把它展开为完整规范:

  • 提交信息:英文 Conventional Commits,格式 <type>(<optional-scope>): <imperative summary>,允许类型 feat/fix/refactor/perf/test/docs/chore/ci/style;摘要小写、无句号、小于 72 字符;必要时加 body 与 BREAKING CHANGE: 脚注;不得自动添加 AI 署名或 co-author trailer。
  • 分支:从当前 main 拉出,命名 <type>/<snake_case_topic>_<YYYYMMDD>(可含 issue 号);禁止直接推送或强推 main;rebase 前只 rebase 私有特性分支到 main,rebase 后用 git push --force-with-lease 更新自己的分支。
  • PR:保持聚焦,标题遵循 Conventional Commits,描述说明改了什么、为什么、如何验证;默认 squash 合并,仅当发布、热修或需要保留提交级历史时才用普通合并;合并后删除分支。
  • 发布安全:以仓库内 workflow 与脚本为发布权威——package.json 使用严格 SemVer,创建受保护的 v<package-version> 标签(标签与包版本必须一致,支持 stable 与 beta 两个渠道);标签推送触发发布 workflow,只有平台构建、隔离签名/收尾任务、签名检查、包验证、制品装配与更新产物校验全部通过后才能发布;macOS 要求签名与公证,Windows 在缺少 Authenticode 密钥时可显式以无签名收尾并在发布说明中披露。

构建产物与原生 ABI 约束

.claude/rules/electron-vite.md 补充了 CLAUDE.md 中 pnpm build / pnpm build:server 背后的硬性产物契约:

目标 输出
Electron main dist/main/index.cjs
preload dist/preload/preload.cjs
QuickJS worker dist/core/plugin/host/quick-js-worker.cjs
Electron renderer dist/renderer/
Node server 与 CLI dist/server/index.mjsdist/server/motrix-admin.mjs
浏览器 renderer dist/renderer-web/

由于 package.json 声明了 "type": "module",main、preload、worker 产物必须保持 .cjs,服务端产物保持 .mjsmain 字段(当前为 dist/main/index.cjs)必须与 main 产物一致。此外该规则还约定:pnpm 配置集中在 pnpm-workspace.yaml(保持 nodeLinker: hoisted);Electron 43 不依赖 pnpm install 自动拉取二进制,本地流程必须先跑 pnpm run ensure:electron-runtimebetter-sqlite3 这类原生模块必须匹配活动 ABI——测试用 Node ABI,Electron 与 E2E 用 Electron ABI,由 scripts/ensure-native-abi.mjsprestart/pretest/pretest:e2e 钩子保障;服务端 Docker 镜像刻意不含 pnpm 与构建工具链,禁止运行时本地重编原生模块。

规则路由:按需加载的 .claude/rules 体系

CLAUDE.md 末尾的 "Rule Routing" 一节定义了规则加载机制:没有 paths frontmatter 的规则是全局规则;带路径作用的规则只在其模式匹配到正在检查或修改的文件时才加载。路由表如下:

规则文件 作用范围
commit-and-quality.md 必查项与按变更类型的验证
git-workflow.md 提交、分支、PR 与发布
language-and-docs.md 语言与公开/私有文档
architecture.md 分层边界与传输流
electron-vite.md 构建、打包、原生 ABI 与 pnpm
code-style.md TypeScript、React、CSS 与文件命名
renderer.md 渲染层状态、组件、表单与传输
panel-layout.md 视口高度与滚动布局
i18n.md 语言目录与用户可见文案
domain-model.md 共享领域类型、校验与错误
plugins.md 插件沙箱、能力与内置插件
plugin-registry.md 注册表兼容性与安装完整性
bridge.md MDXP 配对、分发与传输

从 frontmatter 结构看,这条路由机制是可直接观察的:architecture.mdelectron-vite.md 都带有 paths 列表(如 ["src/**/*.ts", "src/**/*.tsx", "scripts/check-boundaries.mjs"]),而 commit-and-quality.mdgit-workflow.md 没有 paths 字段,属于全局规则。AGENTS.md 补充了运行时语义:作用域扩大时要加载新匹配的规则,但不要默认加载不相关的路径作用规则——这既控制 Agent 的上下文成本,也避免无关规则干扰当前变更。

小结

CLAUDE.md 虽短,却是 Motrix 仓库工程体系的总纲:它用 9 条 pnpm 命令定义了开发入口,用 4 条架构边界锁定了 shared/core/renderer/main/server/preload 六层目录的依赖方向,并用规则路由表把 13 份细则按文件作用域分发。这些纸面约束在仓库中都有可执行的对应物——scripts/check-boundaries.mjs 把导入方向变成 grep 规则,src/shared/protocol/commands.ts 把通道字符串收敛为共享常量,prestart/pretest 钩子把 ABI 匹配变成脚本前置条件,commit-and-quality.md 把三项检查变成提交前置门禁。理解并遵循这套"文档—脚本—契约"三位一体的规范,是向 Motrix 贡献代码或驱动 AI Agent 协作的前提。

登录后查看全文
热门项目推荐
相关项目推荐