首页
/ Gogs 仓库的 AGENTS.md 工程协作规范全解读:从编码到提交的完整开发约定

Gogs 仓库的 AGENTS.md 工程协作规范全解读:从编码到提交的完整开发约定

2026-09-07 16:36:25作者:魏献源Searcher

说明:本文将基于 AGENTS.md 这份仓库级开发协作手册,结合 Gogs(自托管 Git 服务)当前仓库的实际源码、构建配置与测试代码,逐条解读其对 AI 开发助手与人类开发者提出的工作准则,包括核心协作原则、Go 与前端编码规范、本地化流程、可访问性要求、构建与代码提交纪律。读者读完可以掌握在该仓库中高效协作的正确姿势,以及每条规范背后的仓库实现依据。

一、AGENTS.md 是什么:给代码协作者的“行动总纲”

在 Gogs 仓库根目录中,AGENTS.md 是一份面向代码编写者(尤其是 AI Agent)的工程协作手册。它与普通的贡献指南不同:内容高度浓缩,条条都是可执行的硬性约束,覆盖了从“接到任务后如何推进”到“写错代码时如何自纠”,再到“文案、国际化、UI、提交”的全链路约定。

该文件与仓库中其他文档(如 web/DESIGN.md)形成“总纲 + 细则”的关系:AGENTS.md 负责定义适用于全仓库的通用规则,并引用专门的模块文档作为补充约束。理解它,等同于理解这个仓库当前"被期望如何被维护"。

二、核心协作原则:一次做对,尊重现状

文档开篇即强调两条贯穿始终的核心原则:

  1. 停止无意义的附和,一次做对:不要用“你说得对”这类空话回应,而要在第一次尝试时就做正确,并在改动后进行事实核查与自我复查;如果不确定,就主动求助。
  2. 以当前版本为新的起点:当发现超出自己知识范围的既有改动时,不要盲目覆盖,而是把它当作新起点,尊重周边上下文中已经形成的模式。

这两条原则的实际价值在于:Gogs 是一个长期演进的成熟代码库(覆盖 cmd/internal/ 下的 app、auth、context、database、route、repo 等大量子包,以及 web/ 前端工程),任何机械化的“重写式”改动都极易破坏既有约定。文档明确要求 Agent 在改动前先以现有代码为锚点,改动后先自查再交付,这与仓库中大量配套测试(例如 internal/database 下几乎每个模块都有同名 _test.go)的工程质量要求是一致的。

三、Style and mechanics:全仓库通用文案规则

该规范适用于所有面向用户的文本,包括但不限于 UI 文案、文档与代码注释。核心规则包括:

  • 采用 sentence case(句首大写、其余小写),但品牌名保留原始大小写;
  • 完整句子必须以句号结尾
  • 正文中禁止使用 em dash()与 en dash(,应改写为逗号、句号、冒号或括号;唯一的例外是作为 UI 设计中的视觉分隔符(例如标题与描述之间);
  • 不要过度使用分号,两个短句通常比一个用分号连接的长句更清晰;仅当两个子句耦合极强、拆分会丢失含义时才使用分号;
  • 注释应解释代码无法直接表达的意图,而不是复述代码行为;优先使用更具描述性的命名。此规则优先于“跟随既有模式”;
  • CHANGELOG 条目只描述用户视角的可见影响,不写入实现细节(可对照仓库根目录的 CHANGELOG.md 的写作风格);
  • 使用 e.g.,i.e., 时必须带尾随逗号

这些细节对中文社区团队同样有借鉴意义:在提交信息、Release 说明与界面文案上保持一致的句式风格,能显著降低多语言维护与后续机器翻译的成本。

四、Coding guidelines:Go 侧的三条硬规范

4.1 错误处理统一使用 cockroachdb/errors

文档规定所有 Go 代码的错误处理统一使用 github.com/cockroachdb/errors。该要求与当前仓库的依赖声明完全一致:go.mod 第 9 行声明了 github.com/cockroachdb/errors v1.13.0

从源码看,这一约定已被大面积落实。例如在 internal/databaseactions.goattachment.gocomment.godatabase.goissue.go 等实现中均大量使用 errors.Newerrors.Wrap 系列调用,为错误链保留原始上下文。选用该库的价值在于其丰富的堆栈信息保留能力,便于在 Gogs 这类需要精确追踪数据库与 Git 操作失败原因的服务端代码中快速定位根因。

4.2 测试断言统一使用 stretchr/testify

测试必须使用 github.com/stretchr/testify 进行断言,同时要审慎选择 requireassert当断言失败后测试无法继续有意义地执行时,应当使用 require(立即终止),反之才使用 assert(继续执行)。

该约定同样有仓库证据支撑:go.mod 第 45 行声明 github.com/stretchr/testify v1.11.1;典型示例如 internal/database/access_tokens_test.go,其中大量使用 assert.Equalassert.Trueassert.False 组合校验 token 的时间戳与使用状态字段。选择 assert 而非 require 的场景通常是同一实体多个字段的独立校验,单点失败不影响其他断言继续执行;反之,若后续断言依赖前一步结果,则应使用 require 尽早暴露问题。

4.3 5xx 错误必须在 handler 内直接记录日志

文档规定:每一个 5xx 响应都必须在 handler 内部直接记录错误日志,不要在共享 helper 中统一打日志。从源码结构看,这正对应 internal/context/context.go 提供的 ErrorNotFoundOrError 等上下文方法:路由层在调用它们时同时传入人类可读的描述(例如 internal/route/home.go 中的 c.Error(err, "search repository by name")),从而让错误日志携带具体的业务语义,而不是在底层共享封装里打出一堆无法区分场景的堆栈。这种“语义化日志下沉到调用点”的模式,直接服务于 Gogs 生产环境下的问题定位效率。

五、Localization:本地化文件的“编辑主权”边界

本地化是 Gogs 这类国际化项目的高频改动点,文档给出了明确的权限边界:

  • 只能编辑 conf/locale/locale_en-US.ini(英文基准语言文件);
  • 其他 locale_*.ini 由社区维护,严禁增删或改写其中的键,即使是删除 Go/模板侧已经失效的死键也不允许。

仓库现状与该约定吻合:conf/locale/ 目录下共存有 32 个语言文件(含 locale_zh-CN.inilocale_ja-JP.inilocale_ko-KR.ini 等),其中 locale_en-US.ini 是唯一由主仓库维护者直接掌管的基准源。这条规则的工程意义在于:避免主分支与社区翻译仓库之间因键名不一致产生合并冲突,保证自动化提取与回填流程(可参考 web/scripts/extract-locales.mjs 这类脚本的同步基础)永远以 en-US 为准。

六、UI guidelines:移动优先与无障碍底线

前端工作必须遵守三条相辅相成的约束:

  1. 移动优先设计:每个 UI 都必须在窄视口下先做好做对,再通过响应式断点增加桌面端精化;在约 375px 宽度下验证通过,才能视为完成。
  2. 至少满足 WCAG 2.2 AA,具体量化要求包括:
    • 每个交互控件都有可辨识的可访问名称(可见 label 或 aria-label);
    • 颜色不能作为信息的唯一载体(必须配文字、图标或形状);
    • 正文与有意义图标相对背景满足 4.5:1 对比度(大号文字与 UI 组件为 3:1);
    • 焦点始终可见且不会被困住;
    • 触摸目标至少 24×24 CSS px(优先 40×40)。
    • 拿不准时,宁可选择更高对比度、更大目标与更明确的标签。
  3. web/ 下的工作必须遵循 web/DESIGN.md 中记录的排版、颜色层级、表面装饰、文件命名与无障碍细则;当一个模式在两处被使用时,就应当回写更新该文档。

6.1 服务端数据的获取位置:route loader 而非 useEffect

文档对数据获取给出了一条非常具体的前端架构约束:当页面需要服务端数据渲染时,必须在 TanStack Router 路由的 loader 中获取,让页面只在响应返回后才挂载;严禁在页面组件内部用 useEffect 触发该请求,否则会造成数据到达前先闪烁出空 UI。

该约束在仓库中有清晰的实现对应:web/src/router.tsx 基于 TanStack Router 构造路由树(createRootRouteWithContextcreateRoute),并为根路由配置 defaultErrorComponent: ServerError;而 web/src/routes/repo.tsx 就是典型实践:其路由节点定义了 loaderDeps 与异步 loader,在 loader 内完成请求并发起错误响应,例如返回 404 而不浪费一次拉取。仓库中 web/src/pages/NotFound.tsxweb/src/pages/ServerError.tsx 等组件则承担路由错误渲染。

七、Build instructions:用 moon 统一构建与质量门禁

当前仓库的前后端构建统一通过 moonrepo 的任务编排完成,仓库根目录 moon.yml(Go 后端,项目 id 为 gogs)与 web/moon.yml(TypeScript 前端,项目 id 为 web)定义了全套任务。文档要求:

  • 尽量使用 moon run <project>:<task> 而不是裸的 go / pnpm 命令,例如 moon run gogs:buildmoon run web:dev
  • 需要绕过缓存时传入 --force
  • 改完 Go 代码后必须运行 moon run gogs:lint,改完前端代码后运行 moon run web:lint,并修复全部 linter 错误

两个 moon 配置文件中的关键任务对应关系整理如下:

任务 后端(moon.yml 前端(web/moon.yml
安装依赖 installgo mod tidy + go generate ./... installpnpm install(在工作区根执行)
格式化 formatgolangci-lint fmt formatpnpm run format
Lint lintgolangci-lint run lintpnpm run lint
测试 testgo test -cover -race ./...
构建 buildgo build -v -trimpath 并注入 BuildTime/BuildCommit.bin/gogs buildpnpm run build 输出到 /public/dist
开发运行 servercd .bin && ./gogs web devpnpm run dev
全量产物 build-prod:以 -tags prod 构建,依赖 web:build 被后端 build-prod 依赖

值得注意的实现细节:build 任务通过 -ldflags "-X 'gogs.io/gogs/internal/conf.BuildTime=...' -X '...BuildCommit=...'" 把编译时间与当前 commit 注入 internal/conf 包,这意味着每次构建产物的版本信息都可在运行时追溯;而 build-prod 会额外携带 -tags prod 并串联前端 web:build,构成前后端一致的生产构建链路。此外根 moon.yml 还提供了 portlessdevprod 等组合任务,用于把本地服务暴露到 gogs.localhost 开发域名。

八、Tool-use guidance 与 Source code control:工具纪律与提交纪律

8.1 工具使用

  • 访问 GitHub 上非公开的信息时使用 gh CLI;
  • Chrome DevTools MCP 必须以 headless 模式运行,避免抢走用户前台浏览器焦点;任务结束后用 pkill -f chrome-devtools-mcp 清理所有残留进程。

8.2 源码控制纪律

  • 从 fork 推送 PR 变更时使用 SSH 地址,且不要添加 remote
  • 除非被明确要求,绝不直接提交到 main 分支;一次“允许”只对应 main 分支上的一次提交动作;
  • 绝不擅自 amend 提交,除非被明确要求;
  • 创建 git worktree 时,worktree 目录名必须与其分支名一致,不得使用随机或生成的后缀。

最后一条对多分支并行开发极具实操价值:目录名 = 分支名的约定让本地多个 worktree 之间可以靠路径名直接辨别分支归属,避免 gogs-fix-a1k2 这类无法识别的随机目录堆积。结合“不直推 main”“不 amend”两条纪律,可以推断该仓库期望的协作流是:功能分支或 fork 分支 → 提交 → PR 审查合并,历史保持线性与可追溯。

九、小结:把规范变成可执行的协作清单

AGENTS.md 的要点压缩为 AI 助手与贡献者的每日行动清单:

  1. 改动前先读周边代码,以当前实现为起点;改动后自查并验证,不空口附和;
  2. 文案一律 sentence case、句末带句号、正文不用 em/en dash、少用分号;注释写意图而非复述代码;
  3. Go 错误处理一律走 cockroachdb/errors,测试断言用 testifyrequire 只在无法继续执行时使用;5xx 的错误日志留在 handler 内记录;
  4. 本地化只改 locale_en-US.ini
  5. 前端先做移动端再上桌面端,任何 UI 都须达到 WCAG 2.2 AA;需要服务端数据的页面一律在路由 loader 中取数;前端模式遵循 web/DESIGN.md
  6. 优先用 moon run gogs:buildmoon run web:dev 等任务;改完代码先跑对应 lint 并清零告警;
  7. 提交遵循 SSH + 不直推 main + 不 amend + worktree 目录名与分支名一致。

这份文档的价值在于:它把 Gogs 仓库多年沉淀的工程品味,显式化为机器可读、可判罚的规则。无论你是人类贡献者还是 AI 编码助手,遵循 AGENTS.md 都是在以仓库维护者认可的姿势推进改动,从而让每一次提交都更接近一次通过。

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389