跳至内容

贡献指南

本页是 AICodeReviewer 的公开贡献者指南,覆盖仓库布局、本地开发环境搭建、测试与验证矩阵,以及常见贡献工作流。仓库根目录的 AGENTS.md 持有常驻规则、护栏、环境说明,以及需要避免重新引入的已知代码陷阱列表——较大改动前请先阅读。

路径 用途
packages/* 运行时 TypeScript 包(CLI、core、server、agents、sandbox、outputs、mcp-output、llm、vcs、store、eval)。用 pnpm workspace 和 TypeScript project references 管理。
docs/site 本文档站点(Astro Starlight,English + 简体中文)。独立的 workspace 包,不属于运行时。
docs/(其他) 专题参考模块(如输出通道),编写本站页面时参考。
example/ 部署样例:config.yaml、.env.sample、Compose 栈、trigger 脚本。
deploy/ Dockerfile、deploy.sh 及相关部署资产。
eval/ 永久 eval CLI 测试 fixture。
AGENTS.md 常驻贡献者指引、护栏和已知代码陷阱。
.agents/skills/ 可复用的工作流技能(审计、部署、维护等)。

要求:

  • AICR runtime 使用 Node.js >= 22(better-sqlite3 13 的硬性要求;部署镜像 使用 Node 24 LTS userspace)。
  • docs:build / docs:check 使用 Node.js >= 23.6;源码配置校验器依赖 Node 原生 TypeScript stripping。文档 CI job 使用 Node 24。
  • pnpm。
终端窗口
# 在仓库根目录
pnpm install
pnpm build

最后一次修改后、提交变更前运行全部适用门禁,并确认工具实际发现了预期文件或测试。Linux/CI 的最终 runtime 门禁是 pnpm run ci;Windows PowerShell 直接调用 Node 二进制。

步骤 Linux/CI Windows PowerShell
ESLint pnpm lint node node_modules/eslint/bin/eslint.js . --max-warnings=0
类型检查 pnpm typecheck node node_modules/typescript/bin/tsc -b tsconfig.json --pretty false
单元测试 pnpm test node node_modules/vitest/vitest.mjs run --coverage
Markdown lint pnpm markdownlint node node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs
构建 pnpm build cmd /c "pnpm build"
Eval fixture 校验 pnpm eval:validate(构建后) node packages/cli/dist/index.js eval --validate-only
文档构建 pnpm docs:build pnpm docs:build

pnpm eval:validate 运行 aicr eval --validate-only,只校验 eval/*.json 的结构和预期 problem 约定——不需要 LLM,不需要 config 密钥。完整 aicr eval 会加载 config 并调用 LLM,应作为单独的、按环境配置的 benchmark 任务。

影响配置 shape、agent 适配器、MCP 工具接口约定、输出渲染、部署行为或公开工作流的变更,必须在同一次变更中更新对应文档、example/config.yaml 和 example/README.md。

以下测试可使用本机临时服务,无需生产凭据:

变量 要求与覆盖范围
AICR_SVN_TEST_EXECUTABLE svn 的绝对路径,同目录提供 svnadmin 和 svnserve。启用真实仓库元数据测试,以及 post-commit hook → 带认证 HTTP → SQLite 调度测试。
AICR_REDIS_TEST_URL 本机测试 Redis 的 URL。启用自动提交存储和模型目录持久化测试;目录测试使用独立随机键前缀。
AICR_GITEA_TEST_URL / AICR_GITEA_TEST_TOKEN 一次性回环 HTTP Gitea 及临时管理员 token。测试创建私有仓库和用户、发布 issue,再读取持久化的 assignees。两者都未设置才跳过,配置不完整则失败。

运行上面的测试命令前设置变量;未设置时,对应集成测试会跳过。SVN fixture 位于 build/tmp/,hook 测试会停止自己启动的服务。这些测试不调用 LLM,也不向远端系统发布 review;部署专属的认证和网络仍需单独验收。

Gitea 验收在 Linux 或 WSL Debian 的仓库根目录运行,需有 rootless Podman、curl、node 和 timeout:

终端窗口
bash tests/services/with-gitea.sh \
pnpm exec vitest run packages/outputs/test/gitea-assignment-live.test.ts --maxWorkers=1

脚本固定 Gitea 1.25.4 与 SQLite,限制 1 CPU / 512 MiB,绑定随机回环端口。 它在 ~/workspace/github/atframework 下创建独立目录(可用 AICR_ACCEPTANCE_ROOT 覆盖),提供两个 fixture 变量,退出时移除自己的容器、数据及本轮下载的镜像。 服务另设 900 秒运行上限。日志保留在 build/logs/gitea-*。 中断后仍须检查自有资源已清理;SIGKILL 无法执行目录清理。这些结果只覆盖固定 Gitea 版本。

packages/core/test/config-examples.test.ts 始终校验部署配置及仓库文档的配置 YAML 片段,包含两种语言;畸形配置片段明确失败,不会被跳过。

SVN 脚本使用固定 Debian 镜像和 Subversion 1.14.5-3,限额 1 CPU / 256 MiB, 回环随机端口,采用同样的 900 秒生命周期和清理规则。脚本提供 AICR_SVN_TEST_URL; 测试进程的 PATH 需有 svn。用例核验辅助仓库内容、diff 与失败清理, 并通过 orchestrator 和确定性模型 fixture 执行分析与发布。

终端窗口
bash tests/services/with-svn.sh \
pnpm exec vitest run packages/vcs/test/svn-context-live.test.ts \
packages/server/test/svn-analysis-live.test.ts --maxWorkers=1

PostgreSQL SCRAM/TLS/角色、Redis TLS/ACL/AOF 与 SVN HTTPS/authz/hook 使用部署 fixture。 它在容器重启后核验持久化数据,使用随机回环端口,服务共享 1 CPU / 512 MiB。 退出时删除自有容器、数据卷和临时目录,Debian 包版本记录在 build/logs/deployment-versions.log。

终端窗口
bash tests/services/with-deployment-services.sh

可选子命令接收 AICR_PG_TEST_URL、AICR_REDIS_TEST_URL、 AICR_REDIS_OOM_TEST_URL 和 NODE_EXTRA_CA_CERTS。证书验证保持开启, OOM 注入使用独立 Redis 进程;共享 PG 的测试串行执行:

终端窗口
bash tests/services/with-deployment-services.sh \
pnpm exec vitest run --coverage --maxWorkers=1

真实账户测试在整组环境变量缺省时跳过,配置不完整时失败,不会自动读取凭据文件。 请使用测试群和测试账户。

必需变量 用例与可选设置
AICR_FEISHU_TEST_APP_ID、AICR_FEISHU_TEST_APP_SECRET、AICR_FEISHU_TEST_RECEIVE_ID packages/outputs/test/feishu-app-live.test.ts:读取成员/资料,发送一张卡片并撤回。AICR_FEISHU_TEST_DIRECTORY_CHAT_ID 选择另一来源群;AICR_FEISHU_TEST_MENTION_OPEN_ID 启用对一个获准成员的通知。
AICR_ZHIPU_TEST_BASE_URL、AICR_ZHIPU_TEST_API_KEY packages/llm/test/providers-live.test.ts:glm-5.3-flash;AICR_ZHIPU_TEST_KIND 选择 openai_compatible(默认)或 anthropic。
AICR_KIMI_TEST_BASE_URL、AICR_KIMI_TEST_API_KEY 同一用例,kimi-for-coding;AICR_KIMI_TEST_KIND 选择协议。

anthropic 的 base URL 填写协议根地址,不带 /v1。 LLM 每个已启用供应商调用一次,60 秒截止、256 输出 token、关闭 thinking、无自动重试。 测试核验回答与 usage,不衡量评审质量或计费。日志只记录数量和 usage, 不记录凭据、成员资料或供应商原始错误。飞书撤回失败则测试失败;强制中断后需核对测试群 是否仍有测试卡片。

维护了 development/secret/secret.yaml 时,可显式调用本地 helper,需 yq v4; 它只将选定字段读入测试子进程环境:

终端窗口
node tests/services/with-local-secrets.mjs feishu
node tests/services/with-local-secrets.mjs zhipu
node tests/services/with-local-secrets.mjs kimi
node tests/services/with-local-secrets.mjs zhipu anthropic
node tests/services/with-local-secrets.mjs kimi anthropic

字段组为 .channel.feishu_app.{app_id,app_secret,receive_id}、 .llm.provider.zhipu.{baseURL,token} 与 .llm.provider.kimi_coding_backup.{baseURL,token}。CI 直接提供环境变量。 这些真实调用与普通覆盖率测试分开执行。

  1. 在 packages/<name>/ 下创建包目录,包含自己的 package.json、tsconfig.json、src/ 和 test/。
  2. 把包加入 pnpm-workspace.yaml(workspace 已 glob packages/*,通常自动包含)。
  3. 从根 tsconfig.json 和任何消费它的包加 TypeScript project reference;并从新包的 tsconfig.json 反向引用其依赖。
  4. 至少加一个 test/index.test.ts,让包有测试面,即使只导出一个常量。
  5. 如果包引入了原生模块,把新的 onlyBuiltDependencies 条目加入 pnpm-workspace.yaml(pnpm 10 用 onlyBuiltDependencies 门控原生构建)。

packages/core/src/config.ts 中的 Zod schema 是真源。

  1. 更新 schema(以及任何 superRefine 跨字段校验)。
  2. 在 packages/core/test/config.test.ts 加或更新测试。
  3. 在 example/config.yaml 加带注释的示例。
  4. 更新 docs/site/src/content/docs/.../configuration/ 下相关叙述页,以及配置字段参考中的字段表——两个 locale 都要改。字段表漏掉 schema 字段、写了不存在的字段、或中英两表漂移时,pnpm docs:build 会直接失败并指出缺什么。
  5. 如果字段改变运行时行为,更新 example/README.md 和对应专题文档。

workspace 配置文件不能写系统级字段;遵守 cache / defaults / instances 三段式 shape 和 global → workspace-default → workspace-instance 的覆盖顺序。

  1. 在 packages/outputs/src/ 实现 dispatcher,并在输出注册表中注册。channel kind 是受注册表约束的自由字符串(不是封闭枚举)。
  2. 在模板引擎下为 problem 和 summary 变体加内置 Handlebars 模板。
  3. 加测试;如果 channel 是 IM bot,还要加 IM-markdown 转换器测试(表格正则不能在 .test() 上用 g flag)。
  4. 在输出通道文档化该 channel,并把字段加进配置字段参考。
  5. 在 example/config.yaml 加带注释的示例。

每个 channel 必须遵守的 problem schema、summary schema、channel 映射和 no-problems 策略,参见输出通道。

文档站点是双语的(English 在 .../en/,简体中文 在 .../zh-cn/)。每个面向用户的页面都同时存在于两个 locale;请保持配置键、命令、路径、字段名和枚举值在不同 locale 间完全一致。

  • 用 pnpm docs:build 本地构建并校验。构建会依次运行六道校验:公开/内部边界(src/content/docs/ 下的页面不得引用内部 AI/路线图文档树,也不得保留仅供维护者参考的迁移占记)、配置字段表对 Zod schema 的覆盖、CLI 命令/flag 与 packages/cli 实现的一致性、内部链接/锚点解析(含 sidebar 覆盖)、SEO 元数据(每个页面都需要非空且长度合规的 title/description,以及已提交的 robots.txt 和 1200x630 og-image.png)、双语一致性(两个 locale 页面集合相同、代码块数量与机器 token——配置键、环境变量、flag、路径——一致,且不出现禁用填充词)。
  • sidebar slug 省略 index 段(如 troubleshooting/index.md 的 slug 是 troubleshooting)。frontmatter template 只接受 doc 或 splash;Starlight social 是链接项数组。
  • 内容页用 .md。两个首页(en/index.mdx、zh-cn/index.mdx)用 .mdx,以便渲染 Starlight 组件(hero frontmatter 加 Card、CardGrid、LinkCard、Steps、Aside)。MDX 由 Starlight 内置提供,无需额外集成;组件在纯 .md 中不会渲染。公开内容校验器同时扫描 .md 和 .mdx。
  • 交叉链接使用带 locale 前缀的路径(/en/...、/zh-cn/...)。

当你改变配置 shape、输出渠道规范或运行时行为时,请在同一次变更中更新两个 locale 的相关页面。

  • 保持编辑最小且外科手术式;不要为了通过而削弱 lint、类型检查、测试或 markdown 门控。
  • 所有临时任务产物(草稿脚本、调试日志、一次性报告、benchmark 输出)都放在 build/ 下,绝不放在仓库根目录、eval/ 或任何包目录。
  • 公共/共享模块(packages/cli/src、ReviewEvent、模板上下文)必须保持平台中立——从 @aicr/core 导入规范 schema/常量,把 provider/channel 专属名称限制在配置约定、文档、测试和平台专属适配器内。

完整、常驻的贡献者规则——包括需要避免重新引入的已知代码陷阱编号列表——请阅读仓库根目录的 AGENTS.md。