🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇧🇦 bs · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇹🇼 zh-TW
使用本指南为拉取请求选择最小且可靠的开发循环。它不能取代下方链接的特定领域架构和安全文档;它将每种常见变更类型与其契约、针对性检查和 CI 覆盖范围关联起来。
- 编辑前选择基础分支。 找到最高版本且仍处于活跃状态的
release/v*分支,并从其最新提交创建分支。以该分支而非main为目标。如果当前处于发布冻结期,请勿以已冻结的分支为目标;请使用 分支与发布模型中所述的下一个活跃周期。 - 明确契约。 识别变更影响的每个目录、架构、生成产物、公共 API 或用户界面。下表给出了最低起始集合。
- 编写或更新针对性测试。 对
src/、open-sse/、electron/或bin/中的生产代码所做的变更,必须在同一 PR 中包含自动化测试。先运行能够证明相关行为的最小测试文件集合,然后运行列出的针对性门禁检查。 - 让 CI 运行广泛的测试矩阵。 完整的单元测试分片、Vitest、覆盖率渐进门槛以及生产构建都会在 PR 上运行。仅当针对性测试失败表明存在更广泛的影响,或变更横跨多个子系统时,才在本地运行广泛的测试套件。
- 评审前完成同步。 获取活跃基础分支,检查其中的新提交以及你的分支相对于它的差异,然后根据贡献者工作流对基础分支执行 rebase 或 merge。应从源文件解决生成文件和目录冲突,重新生成这些文件,再次运行针对性循环,并确认 PR 仍以活跃的发布分支为目标。
- 记录证据。 在 PR 模板中列出已运行的命令、所有新增或修改的测试文件、迁移或功能标志,以及仍待 CI 验证的所有项目。
以下命令是最低限度的针对性检查,并不意味着可以跳过直接覆盖你所变更行为的测试。
契约
src/shared/constants/providers/中的提供者定义及其在src/shared/constants/providers.ts中的组合。open-sse/config/providerRegistry.ts或其拆分出的注册表文件中的模型和功能。- 执行器/转换器选择、OAuth 或 API 密钥配置、仪表板资源,以及适用时生成的提供者参考文档。
- 公共凭据必须使用
resolvePublicCred();错误响应必须使用共享的错误净化辅助函数。请参阅docs/security/PUBLIC_CREDS.md(位于 git 中;不会编译到/docs)和 错误净化。
针对性循环
npm run check:provider-consistency
npm run check:provider-assets
node --import tsx/esm --test tests/unit/provider-translate-path-golden.test.ts
node --import tsx/esm --test tests/unit/<provider-or-executor>.test.ts
npm run gen:provider-reference # 当目录发生变化时;提交生成的差异
npm run lint还要测试所有受影响的请求系列:聊天、Responses、图像、嵌入、音频或视频。将生成的目录和黄金文件差异作为契约变更进行审查;不要盲目接受。
契约
src/shared/constants/routingStrategies.ts中的公共策略值和 UI 元数据。open-sse/services/combo.ts和open-sse/services/combo/下的分派与排序。- Combo 架构、持久化、韧性状态、模型功能以及 API/UI 控件。
- 行为发生变化时,请参阅 Auto-Combo 引擎和韧性文档。
针对性循环
node --import tsx/esm --test tests/unit/combo-<behavior>.test.ts
npm run test:combo:matrix # 策略或分派变更
npm run check:known-symbols # 策略注册变更
npm run lint在本地使用确定性的模拟上游测试。实时 Combo 冒烟测试需要凭据,并且必须手动执行,不能替代 CI。
契约
src/app/和src/shared/components/下的 Next.js 路由/页面及共享组件边界。- API 响应结构、加载/空白/错误状态、键盘和屏幕阅读器行为、响应式布局、主题以及区域设置扩展。
src/i18n/messages/en.json中的英文 UI 源字符串;不要硬编码新的面向用户的文案。
针对性循环
node --import tsx --test tests/unit/dashboard/<feature>.test.ts
npx vitest run --config vitest.config.ts tests/unit/ui/<component>.test.tsx
npm run check:dashboard-typecheck
npm run lint对于交互或视觉变更,请运行应用并检查窄视口和宽视口。CI 会运行生产构建和更广泛的测试套件;视觉行为仍需要根据变更选择适当的针对性组件测试、Playwright 测试或有记录的手动检查。
契约
src/i18n/messages/en.json是 UI 源;config/i18n.json是区域设置源。- CLI 目录单独位于
bin/cli/locales/下。 - 必须原样保留 ICU 占位符和标签。不要翻译产品/提供者/模型名称、协议和标头名称、命令、代码/JSON 标识符、URL、环境变量,或
OmniRoute、OAuth、MCP和A2A等受保护术语。当前源列表为scripts/i18n/glossary/protected-terms.json。
针对性循环
npm run i18n:sync-ui:dry
npm run i18n:check-ui-coverage
npm run i18n:check-value-drift
npm run i18n:check-glossary
npm run check:cli-i18n # 当 CLI 字符串/目录发生变化时
npm run lint这是针对现有系统的指导,并非扩展其工具或键模型的许可。在替代系统的设计过程中,请保持 i18n 补丁精确且范围有限。除非任务明确要求生成翻译,并且你已审查生成的差异,否则不要运行会调用外部服务的翻译命令。
契约
bin/cli/中的公共命令和标志、生成的 API 命令、退出码、stdout/stderr 和 JSON 输出结构、配置/环境行为以及打包文件。- CLI 面向用户的字符串必须使用 CLI i18n 层,并保持
en/pt-BR目录同步。 - 保持 Node 作为受支持的运行时,并维持已发布的二进制契约。
聚焦循环
node --import tsx/esm --test tests/unit/cli/<command>.test.ts
npm run check:cli-i18n
npm run build:cli # 生成的/捆绑的 CLI 变更
npm run check:pack-policy # 包对外接口变更
npm run lint当行为取决于解析、文件或退出状态时,请在临时数据目录中使用确切命令。CI 会执行更广泛的包构件和生态系统检查。
契约
src/lib/db/下的领域模块;直接导入特定模块(旧的localDb.ts重新导出层已移除)。src/lib/db/migrations/下带编号且幂等的 SQL 迁移、事务安全性、升级 行为、索引,以及受该架构影响的每个调用方。- 路由和处理程序绝不直接执行原始 SQL。
聚焦循环
npm run check:migration-numbering
npm run check:db-rules
node --import tsx/esm --test tests/unit/db/<domain>.test.ts
node --import tsx/esm --test tests/unit/db/migration-<number>.test.ts
npm run lint添加迁移时,请同时测试全新数据库以及从上一版架构升级。数据库测试
必须关闭句柄,并在清理期间调用 resetDbInstance()。仅当尽力支持的 Bun 适配器路径发生变化时才运行 npm run test:bun:db;Node 仍是权威运行时。
契约
- 根目录和工作区清单/锁文件、
scripts/build/、Next.js 独立构建组装、dist/包内容、Electron 平台元数据、CI 工作流以及部署哨兵。 - 必须保持受支持的 Node 版本范围,以及
CLAUDE.md中列入允许列表的 Bun 用法不变。 - 构建产物保持不被跟踪;依赖项、许可证、工作流和包策略均适用。
聚焦循环
node --import tsx/esm --test tests/unit/build/<behavior>.test.ts
npm run check:build-scope
npm run check:lockfile # 依赖项或锁文件变更
npm run check:pack-policy # 已发布包的对外接口变更
npm run lint仅当变更影响编译、独立构建组装、资源或运行时捆绑时,才在本地使用 npm run build。仅将 npm run build:release 用于发布/部署验证。CI 的构建是最终的跨平台信号;特定于平台的 Electron 变更需要相应的聚焦构建或冒烟测试证据。
两个 scripts/dev/ 辅助脚本为其他会话仍在运行的 devbox 编码了本地开发循环:
scripts/dev/typecheck-touched.sh --base release/vX.Y.Z # merge-base(HEAD, base)..HEAD 中的文件
scripts/dev/typecheck-touched.sh src/a.ts tests/unit/b.test.ts # 仅检查这些文件
scripts/dev/new-worktree.sh fix/1234-slug release/vX.Y.Z # 隔离的 worktree,可安全并行运行typecheck-touched.sh仅通过临时tsconfig.touched.tmp.json(extends ./tsconfig.json、types: ["node"]、noEmit、incremental: false)对改动过的.ts/.tsx文件执行类型检查,并使用 6 GB 堆内存,因此它取代了会在高负载机器上因 OOM 而失败的项目级tsc -p tsconfig.json。它会输出改动文件中的错误以及一行摘要;当改动文件中存在错误时退出码为1,当错误仅存在于导入的文件中,或 tsc 在没有诊断信息的情况下终止时退出码为2(请读取其指定的_artifacts/typecheck-touched/下的日志),没有错误时退出码为0。临时 tsconfig 始终会被删除;切勿提交它。new-worktree.sh会通过<git-common-dir>/omniroute-new-worktree.lock串行化并发运行(默认最多等待 600 秒,并显示提示消息;脚本头部记录了覆盖此设置的方法);如果git worktree add在 worktree 存在之前失败,它还会回滚所创建的分支,因此重试时无需手动执行git branch -D。硬链接的node_modules和.husky/_副本保持不变。
源代码测试无法证明打包后的构件可以启动:打包清单、裁剪后的依赖项和原生二进制文件方面的问题,只有在 tarball
被安装并启动后才会暴露。npm run dev:candidate(scripts/dev/candidate.mjs)是 RFC #8084
中“构建一次 / 验证 / 提升”流程的本地实现:它构建一个候选版本、验证该确切构件、通过目录重命名提升它,并在提升后的槽位未通过健康检查时将其回滚。
npm run dev:candidate -- run --dry-run --json # 输出计划,不进行任何更改
npm run dev:candidate -- run # 构建 + 验证 + 提升,自动回滚
npm run dev:candidate -- build # npm pack + 安装到 _artifacts/candidate/<id>/
npm run dev:candidate -- validate --id <id> # 在空闲端口上启动,检查 /api/health + /v1/models
npm run dev:candidate -- promote --id <id> # <id> → current,current → previous
npm run dev:candidate -- rollback # 交换 current 和 previous
npm run dev:candidate -- run --from-tarball <file.tgz> # 重用在其他位置(CI)构建的 tarball- 只构建一次。
build会打包当前工作树(它需要dist/server.js,因此请先运行npm run build:release)或复制--from-tarball,然后将 tarball 安装到隔离的 npm prefix 中,因为 tarball 不包含node_modules。id 是简短的HEADsha(工作树存在本地更改时附加-dirty),对于 tarball 则为tgz-<sha256>。如果一个干净的 id 已完成构建,则会直接重用而不是重新构建;传入--force可强制重新构建。 - 验证软件包,而不是源代码。
validate会使用全新的DATA_DIR=<candidate>/data、伪造的密钥,并从环境中移除操作者的OMNIROUTE_API_KEY、STORAGE_ENCRYPTION_KEY和INITIAL_PASSWORD,然后启动已安装的 CLI (serve --port <free port>),从而检查全新安装在无密钥情况下的回环接口安全状态。它会等待GET /api/health返回 200,要求GET /v1/models返回 200,停止进程组,并将判定结果连同 tarball 哈希一起记录在validation.json中。 - 提升同一个构件。 如果候选版本没有针对其当前 tarball 哈希的通过验证记录,
promote会拒绝提升。默认活动槽位是_artifacts/candidate/current;--target <dir>可选择同一文件系统中的其他目录,其上一版本槽位为<dir>.previous。每次重命名都是原子的;如果流程中途失败,则会撤销已执行的重命名。 - 回滚。
run会再次验证提升后的槽位,如果检查失败,则交换current和previous以执行回滚。首次验证失败的候选版本绝不会被提升。
所有内容都会写入已被 git 忽略的 _artifacts/candidate/;现有的 OmniRoute
安装及其数据目录绝不会被修改。提升后的 CLI 位于
_artifacts/candidate/current/prefix/bin/omniroute;使用时请通过你自己的 DATA_DIR
启动它。退出码:0 表示成功,1 表示验证或提升失败,2 表示用法错误或缺少构建。
| 每个补丁均在本地运行 | CI 提供广泛的验证信号 |
|---|---|
| 上述直接行为测试和类别门禁 | 分片的完整单元测试套件和串行测试 |
npm run lint |
Vitest 测试套件以及覆盖率/质量递进门槛 |
| 仅当受影响的契约需要时才进行类型检查或构建 | 生产构建、安全、文档、依赖项和 PR 策略门禁 |
| 仅当自动化无法验证行为时才进行手动交互/实时检查 | 工作流配置的跨作业集成和平台检查 |
聚焦的本地循环通过,只能证明变更的契约符合预期,并不能证明不相关的 CI 检查也会通过。 反过来,也不要让每次本地编辑都等待完整的仓库测试矩阵。
请求审查之前:
- 确认 PR 的基础分支仍是最新的活跃
release/v*分支。 - 获取该基础分支,并审查自创建当前分支以来合入的提交。
- 检查
git diff <active-base>...HEAD,确认没有意外变更或生成内容导致的无效变更。 - 通过更新源文件并重新生成输出来解决目录和生成文档的冲突。
- 完成协调后,重新运行 PR 描述中列出的每项聚焦测试/门禁。
- 切勿仅为适配已变动的基础分支而削弱断言或删除必需的测试。