Motrix 工程规范全解:基于 CLAUDE.md 的双宿主架构边界、核心命令与 AI Agent 协作规则
【免费下载链接】MotrixA full-featured download manager.项目地址: https://gitcode.com/GitHub_Trending/mo/Motrix
Motrix(Motrix Turbo)是一个同时运行在 Electron 桌面端与 Node/Web 服务端的完整下载管理器。本文以仓库根目录的 CLAUDE.md 为骨架,完整解读它定义的仓库定位、核心命令、架构边界与规则路由机制,并结合 package.json、scripts/check-boundaries.mjs 与 src/shared/protocol/commands.ts 等源码证据,说明这些规范是如何被脚本和类型契约落地成可执行、可验证的工程约束的。读完本文,你将掌握 Motrix 的目录分层、双传输契约、提交质量门禁,以及 AI Agent 在该仓库协作时的规则加载顺序。
CLAUDE.md 在仓库中的定位
CLAUDE.md 是 Motrix 的 AI Agent 权威指引文件,开篇给出两条仓库级事实:
- 项目形态:Motrix Turbo 是 Electron + Node/Web 下载管理器。
src/core/必须保持宿主中立(host-neutral),以便同一份产品核心既能被 Electron 壳复用,也能被 Node 服务端壳独立替换。 - 分支策略:开发在
main分支进行;master是冻结的遗留分支,对应旧版 Electron 22 / Vue 2 应用。所有分支创建与 PR 目标只能是main,绝不能指向master。
仓库中的 AGENTS.md 进一步说明:Claude Code 规则是唯一的规范来源,Codex 等其他 Agent 直接继承而不再维护第二份副本。它规定了 Agent 在检查或修改文件前必须依次读取:
CLAUDE.md;- 所有不带
pathsfrontmatter 的全局.claude/rules/*.md规则; - 所有
paths模式与待检查/修改文件相匹配的规则。
冲突解决顺序为:当前用户指令 >AGENTS.md>CLAUDE.md> 匹配的.claude/rules/*.md> Agent 默认行为,并要求"更新 Claude 规范规则而不是重复维护指引"。这种"单一事实源 + 按路径按需加载"的设计,是本文后面"规则路由"一节的核心。
核心命令一览
CLAUDE.md 给出的命令表是仓库日常开发的入口,这里完整继承并结合 package.json 的scripts字段补充实际执行内容:
| 命令 | 用途 | 实际执行内容(来自 package.json) |
|---|---|---|
pnpm start | Electron 开发运行器 | node scripts/dev.mjs,且prestart会先执行ensure:electron-runtime与ensure-native-abi.mjs electron |
pnpm start:server | 已构建的 Node/Web 服务端 | MOTRIX_SKIP_ELECTRON_REBUILD=1 node dist/server/index.mjs |
pnpm test | 全量 Vitest 套件 | vitest run(pretest先跑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:builtin、build:native-host、build: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 test(pretest: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" 一节是整个文档最核心的部分,逐条列出四条不可违反的依赖方向:
src/core/绝不导入electron或src/main/;src/renderer/绝不导入src/core/、src/main/或src/server/;渲染层与后端通信必须经由@renderer/lib/transport,并使用共享协议常量;src/shared/只包含纯跨层契约与描述性运行时数据:不允许 IO、定时器、网络、Electron API 或任何 Node 特有 API;- 一律使用
src/shared/protocol/导出的Commands、Queries、Events及其Bridge*对应物,禁止使用裸传输通道字符串。
自动化边界检查:check-boundaries.mjs
这些约束并非仅靠自觉。scripts/check-boundaries.mjs 用一组grep -rnE规则做机器化兜底,例如:
core must not import electron:在src/core/下禁止from 'electron';core must not import fastify:src/core/也不允许直接依赖服务端框架fastify,保证核心不感知任何宿主;shared must not use Node-specific APIs or globals:src/shared/下禁止node:前缀导入、动态import('node:...'),以及process.、NodeJS.全局引用;renderer must not import core or main:src/renderer/下禁止出现(core|main)/路径导入;server must not import electron与server must not import src/main:服务端壳与 Electron 主进程彻底隔离;- 还有一条 UI 级规则:
src/renderer/components/add-task/组件不得直接导入@renderer/lib/transport或@shared/protocol/commands,仅放行三个 IPC 感知文件(use-external-hydration.ts、drop-zone.tsx、add-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.ts 与 src/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.ts、events.ts、bridge.ts(Bridge*通道)以及带测试的errors.ts、forwardable-events.ts、handler-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 --check、cargo clippy -D warnings、cargo test --locked三件套; - 打包/发布代码:跑
tests/scripts/下对应聚焦测试与验证脚本。
只有针对已审查过的、可自动修复的问题才允许使用pnpm exec biome check --write .,且之后必须重跑完整门禁。
分支、提交与发布纪律
CLAUDE.md 只给出"开发在main、master已冻结"的原则;.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.mjs、dist/server/motrix-admin.mjs |
| 浏览器 renderer | dist/renderer-web/ |
由于package.json声明了"type": "module",main、preload、worker 产物必须保持.cjs,服务端产物保持.mjs;main字段(当前为dist/main/index.cjs)必须与 main 产物一致。此外该规则还约定:pnpm 配置集中在pnpm-workspace.yaml(保持nodeLinker: hoisted);Electron 43 不依赖pnpm install自动拉取二进制,本地流程必须先跑pnpm run ensure:electron-runtime;better-sqlite3这类原生模块必须匹配活动 ABI——测试用 Node ABI,Electron 与 E2E 用 Electron ABI,由scripts/ensure-native-abi.mjs的prestart/pretest/pretest:e2e钩子保障;服务端 Docker 镜像刻意不含 pnpm 与构建工具链,禁止运行时本地重编原生模块。
规则路由:按需加载的 .claude/rules 体系
CLAUDE.md 末尾的 "Rule Routing" 一节定义了规则加载机制:没有pathsfrontmatter 的规则是全局规则;带路径作用的规则只在其模式匹配到正在检查或修改的文件时才加载。路由表如下:
| 规则文件 | 作用范围 |
|---|---|
| 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.md与electron-vite.md都带有paths列表(如["src/**/*.ts", "src/**/*.tsx", "scripts/check-boundaries.mjs"]),而commit-and-quality.md、git-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 协作的前提。
【免费下载链接】MotrixA full-featured download manager.项目地址: https://gitcode.com/GitHub_Trending/mo/Motrix
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考