AionUi 开发规范与 AI 协作指南:CLAUDE.md / AGENTS.md 架构、进程边界与质量门禁全解
【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20+ more CLI Agent | Customize your assistants | Team them up|Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi
AionUi 是一个将命令行 AI Agent(OpenClaw、Hermes、Claude Code、Codex、OpenCode 等 20+ CLI Agent)转化为现代 AI 聊天界面的开源项目,采用 Electron 多进程架构。本文以仓库根目录的CLAUDE.md(其内容仅一行@AGENTS.md,指向仓库统一的 AI 协作指南AGENTS.md)为骨架,逐节解读这份面向人类与 AI 贡献者的项目开发规范,并结合 justfile、package.json、vitest.config.ts、uno.config.ts 以及.claude/skills/下的四个 Skill 文件,给出可直接落地的编码、架构、测试与提交流程。读完本文,你将掌握 AionUi 的进程边界规则、目录/命名约定、质量门禁命令链,以及如何让 AI Agent 在本仓库中产出符合规范的代码。
一、CLAUDE.md 与 AGENTS.md:AI 协作文档的引用机制
仓库根目录的 CLAUDE.md 全文只有一行:
@AGENTS.md这是 Claude Code 生态中标准的文档引用语法:@文件名表示将目标文件内容嵌入当前上下文。因此CLAUDE.md的实际承载内容即根目录的 AGENTS.md——一份 155 行的 "AionUi Project Guide",面向所有贡献者(人类与 AI 一视同仁)定义代码规范、架构约束、测试标准与协作工作流。其开篇即要求:所有贡献者在提交 PR 之前必须阅读 CONTRIBUTING.md(中文版见 CONTRIBUTING.zh.md)。
这一设计在 AI 协作场景下意义重大:将完整规范收敛到一个入口文件,再通过@引用注入到 AI 的上下文窗口,避免 AI 遗漏散落在各处的规则;同时规范的完整细节下沉到docs/与.claude/skills/的专项文档中,由 AGENTS.md 统一索引。仓库的完整规范体系为:
- 文件结构总则:docs/contributing/file-structure.md
- 架构明细:AGENTS.md 中标注为
docs/architecture/overview.md(注意:该路径在当前仓库快照中尚不存在,属于文档规划中的目标位置,实际架构约束请以 AGENTS.md 与架构 Skill 为准) - 专项 Skill:
.claude/skills/architecture/SKILL.md、.claude/skills/i18n/SKILL.md、.claude/skills/testing/SKILL.md、.claude/skills/bump-version/SKILL.md
二、代码规范(Code Conventions)
2.1 目录与文件结构
AGENTS.md 给出第一优先级规则:每个目录的直接子项(文件 + 子目录)不超过 10 个,新建或大规模重组目录必须满足此限制。完整规则见 docs/contributing/file-structure.md,其中进一步明确了根目录纪律:README 翻译版归属docs/readme/、指南文档归属docs/guides/、贡献者文档归属docs/contributing/、架构文档归属docs/architecture/、PRD 归属docs/prds/,配置文件(tsconfig.json、package.json等)留在根目录。
关于目录命名,AionUi 横跨 React 与 Node.js 两个生态,采用双轨制:
| 作用域 | 目录命名 | 理由 |
|---|---|---|
Renderer(src/renderer/)组件/模块目录 | PascalCase | React 惯例——目录名即组件名 |
| 其余所有目录 | lowercase | Node.js 惯例 |
| 分类目录(所有位置) | lowercase | components/、hooks/、utils/、services/是类别而非实体 |
| 平台目录(Renderer 页面内) | lowercase | 与src/process/agent/<platform>/跨进程命名一致 |
快速判断口诀:目录在src/renderer/内且代表具体组件/功能模块(而非类别)→ PascalCase,否则一律小写。唯一例外是平台目录(如acp/、codex/、gemini/、nanobot/、openclaw/),即使在 renderer 内也用小写,以对齐主进程的agent/目录。
文件命名规则全局统一:组件 PascalCase(Button.tsx、Modal.tsx);工具函数 camelCase(formatDate.ts);Hooks 为use前缀的 camelCase(useTheme.ts);常量文件 camelCase(constants.ts),内部值用 UPPER_SNAKE_CASE;类型文件 camelCase(types.ts);样式文件 kebab-case 或ComponentName.module.css;未使用的参数以_前缀开头。
2.2 UI 组件库与图标
- 组件库:
@arco-design/web-react,新 UI 一律优先使用 Arco 组件,禁止使用原生交互式 HTML(<button>、<input>、<select>等),对应使用Button、Input、Select、Modal等 Arco 组件。纯布局标签(<div>、<span>、<section>、<nav>、<main>)不受限。 - 图标库:
@icon-park/react,所有图标必须来自该库。这两项依赖均在根 package.json 中声明(@arco-design/web-react ^2.66.1、@icon-park/react ^1.4.2)。
2.3 CSS 规范
- 优先使用UnoCSS 工具类(如
flex items-center gap-8px);复杂/可复用样式必须用CSS Modules(ComponentName.module.css),不允许普通.css文件承载组件样式。 - 颜色只能使用语义化 token:来自 uno.config.ts 的语义色(如
text-t-primary、bg-base、border-b-base)或 CSS 变量,禁止硬编码颜色值(如#86909C)。唯一例外是src/renderer/pages/settings/CssThemeSettings/presets/下的主题预设文件——它们本身就是在定义主题 token。 - Arco 主题覆写集中在
packages/desktop/src/renderer/styles/arco-override.css;组件级 Arco 覆写使用 CSS Module 搭配:global()。全局样式只能放在packages/desktop/src/renderer/styles/。
从 uno.config.ts 源码可以看到语义 token 的具体设计:textColors定义了t-primary/t-secondary/t-tertiary/t-disabled,backgroundColors定义了base/1~10/hover/active等(同时支撑bg-*与border-*),另有borderColors、brandColors、aouColors(AOU 品牌 1-10 阶色)以及message-user、workspace-btn等组件专用色。这些工具类全部映射到 CSS 变量(如var(--text-primary)、var(--bg-base)),因此换主题时无需改动组件代码。
格式规则(Oxfmt,与 Prettier 兼容):单元素数组一行内联([{ id: 'a', value: 'b' }]);多行数组/对象必须带尾逗号;字符串使用单引号。
2.4 TypeScript 规范
- 严格模式:禁止
any,禁止隐式返回。 - 路径别名:
@/*、@process/*、@renderer/*。实际配置见 vitest.config.ts 中的resolve.alias:@/→packages/desktop/src、@process/→packages/desktop/src/process、@renderer/→packages/desktop/src/renderer、@worker/→packages/desktop/src/process/worker等。 - 优先使用
type而非interface(遵循 Oxlint 配置)。 - 代码注释用英文;公共函数写 JSDoc。
2.5 国际化(i18n)
新增或修改的用户可见文本必须使用 i18n key,禁止硬编码字符串。语言与模块定义在packages/desktop/src/common/config/i18n-config.json(单一事实来源)。完整工作流见.claude/skills/i18n/SKILL.md,其要点包括:
- key 使用命名空间点号记法:
t('module.key')或t('module.nested.key'); - 新 key 必须添加到每一个受支持语言目录,缺失任何一个都会导致
node scripts/check-i18n.js在 CI 中失败; - 提交前必须依次执行
bun run i18n:types(依据参考语言en-US重新生成i18n-keys.d.ts)与node scripts/check-i18n.js(校验结构、key 与类型同步),顺序不可颠倒; - 含 HTML 的翻译使用 react-i18next 的
Trans组件;变量插值使用{{var}}语法。
三、架构:双进程边界与 IPC 桥
AionUi 是 Electron 多进程应用,AGENTS.md 用一张表明确了两类进程及其 API 使用红线:
| 进程 | 路径 | 限制 |
|---|---|---|
| 主进程(Main) | packages/desktop/src/process/ | 禁止 DOM API |
| 渲染进程(Renderer) | packages/desktop/src/renderer/ | 禁止 Node.js API |
架构 Skill(.claude/skills/architecture/SKILL.md)对边界定义更细:主进程可用 Node.js、Electron main API、fs、path、child_process,禁用document/window/React;渲染进程可用 DOM、React、浏览器 API,禁用fs/path等 Node API;Worker 进程(packages/desktop/src/process/worker/)仅 Node API;Preload(packages/desktop/src/preload/)仅contextBridge与ipcRenderer。违反边界会导致运行时崩溃——例如在 renderer 里直接import { something } from '@process/services/foo'会直接崩掉,正确做法是通过 preload 暴露的window.api.someMethod()走 IPC。
跨进程通信的唯一合法通道:
- 主进程 ↔ 渲染进程:通过
packages/desktop/src/preload/+packages/desktop/src/process/bridge/*.ts的 IPC 桥; - 主进程 ↔ Worker:通过
packages/desktop/src/process/worker/WorkerProtocol.ts的 fork 协议。
代码放哪?架构 Skill 给出了决策树:UI(React 组件/Hooks/页面)→renderer/;IPC handler →process/bridge/;主进程业务逻辑 →process/services/;AI 平台连接 →process/agent/<platform>/;后台 worker 任务 →process/worker/;主进程与渲染进程共用 →common/;HTTP/WebSocket 端点 →process/webserver/;插件加载器 →process/extensions/;消息渠道(飞书、钉钉、Telegram)→process/channels/。这与 docs/contributing/file-structure.md 中的目标结构与主进程命名模式(<domain>Bridge.ts、<Name>Service.ts、I<Name>Service.ts、<Name>Repository.ts)相互印证。
服务层可测试性同样有硬性要求:纯逻辑与 IO 分离——纯逻辑写成独立函数(不引入fs/db/net);IO 操作用薄包装;服务方法应通过参数接收 IO 结果而非内部直接调用 IO。依赖注入优于模块级 mock:
// ❌ 难以测试——必须 mock 整个模块 import { db } from '@process/database'; function getConversation(id: string) { return db.query('SELECT * FROM conversations WHERE id = ?', id); } // ✅ 易于测试——注入依赖 function getConversation(repo: IConversationRepository, id: string) { return repo.findById(id); }既有代码可用vi.mock(),新代码优先参数注入。
四、测试体系:Vitest 4 双环境与 80% 覆盖率目标
框架:Vitest 4(vitest.config.ts),项目覆盖率目标 ≥ 80%,常规变更必须为变更行为补充聚焦测试。
bun run test # 运行全部测试 bun run test:coverage # 生成覆盖率报告vitest.config.ts 揭示了测试架构的两个关键设计:
双测试环境(Vitest 4 projects):
node环境:主进程逻辑、工具函数、服务层,匹配*.test.ts;jsdom环境:React 组件/Hooks 的 DOM 测试,匹配*.dom.test.ts/*.dom.test.tsx。 CI 下超时放宽到 30s(本地 10s),以应对 windows-2022 上重型组件渲染的慢速问题。
覆盖率默认全量收集:
coverage.include覆盖packages/desktop/src/**/*.{ts,tsx}与所有 packages 源码,新文件自动纳入统计,仅排除入口文件(index.ts、preload.ts)、类型声明、shims、静态资源等不可单测项。因此测试 Skill 特别提醒:新源码若被coverage.exclude误排除,应主动移除排除规则。
测试文件与源码一一镜像(见 docs/contributing/file-structure.md 的映射表):CronService.ts→tests/unit/cronService.test.ts、useAutoScroll.ts→tests/unit/useAutoScroll.dom.test.ts等;当tests/unit/直接子项超过 10 个时按源码结构分目录。
测试 Skill(.claude/skills/testing/SKILL.md)的写作质量守则值得一提:
- 描述行为而非实现:写
should return cached task without hitting repo on second call,而不是should call repo.getConversation; - 每个
describe块至少覆盖一条失败路径(依赖返回undefined/抛错、空列表、边界值); - 每个
it()只测一个行为,超过 3 个expect()说明测得太杂; - 自检法:把被测核心逻辑删掉,若测试仍通过,说明它没在守护任何东西;
- 从风险出发而非从覆盖率缺口出发:先列最容易出 bug 的场景,覆盖是结果而非起点。
E2E 测试则使用 Playwright(playwright.config.ts),just e2e-test会先执行bun run package构建出新鲜的out/产物再启动应用(见 justfile)。
五、开发工作流与质量门禁
5.1 范围与执行(Scope & Enforcement)
- 硬性阻断项(Hard blockers):进程边界违规、TypeScript 报错、测试失败、不安全的 IPC 用法、新增/变更用户可见文本缺少 i18n、新 UI 中出现原生交互式 HTML。
- 当前变更要求:命名、CSS、文件放置、测试、文档、目录大小、单文件目录等规则,只约束本次创建或实质修改的文件。
- 棘轮规则(Ratchet):既有的目录过大或单文件目录问题,在普通功能开发或 bugfix 中不需要清理,但本次变更不得让其更糟。
- 禁止扩大范围:实现计划与评审不得私自追加清理类任务、阶段或验收标准(除非用户明确要求)。
- 忽略的工作文档:
docs/superpowers/是刻意 gitignore 的本地 Superpowers 规范与计划目录,禁止 force-add 或提交其中的文件。
5.2 开发中的自动修复
bun run lint:fix # 自动修复 lint 问题(oxlint) bun run format # 自动格式化所有文件(oxfmt) bunx tsc --noEmit # 校验无类型错误若改动触及packages/desktop/src/renderer/、locales/或packages/desktop/src/common/config/i18n,还需追加:
bun run i18n:types node scripts/check-i18n.js从 package.json 可见完整工具链:lint 用oxlint(^1.56.0)、格式化用oxfmt(^0.41.0)、测试用vitest(^4.0.18),另有lint-staged在 pre-commit 时对*.{ts,tsx,js,jsx}执行oxlint --fix+oxfmt。仓库采用 bun 作为包管理器与脚本运行器(engines要求 Node>=22 <25)。
5.3 推送前:用just push,不要裸用git push
AI Agent 未经明确要求不得 push。需要推送时统一使用just push:
just push # lint → format-check → typecheck → test → git push just push -u origin feat/branch # 相同检查,附带额外 git push 参数任何一步失败都会中止推送,修复并提交后重试。justfile 中对应配方定义如下:
push *ARGS: lint-strict fmt-check typecheck i18n-check test git push {{ ARGS }} lint-strict: bun run lint -- --quiet也就是说 push 门禁实际是五连检查:lint-strict(仅报错误)→format:check→tsc --noEmit→ i18n 类型生成与校验 → 全部测试。给 AI Agent 的提示很关键:just push对 lint 使用--quiet,只有错误才会导致失败;仓库存在大量历史 lint warning,不代表失败,判断成功与否看退出码而非输出量。
5.4 PR 前的更严格检查:prek
prek精确复刻 CI 流水线(包括所有文件类型的文件尾、行尾空白检查):
# 一次性安装 npm install -g @j178/prek # 运行 prek run --from-ref origin/main --to-ref HEADprek是只读的——只报告不修复。若报告问题,先跑上面的自动修复命令、提交,再重跑。
5.5 Commit 与 PR 格式
Commit 与 PR 标题必须遵循 CONTRIBUTING.md 中定义的 Conventional Commit 格式:
<type>(<scope>): <subject>允许的 type:feat、fix、perf、refactor、docs、style、chore、test、ci、build。
开 PR 时按 PR 模板(AGENTS.md 标注为.github/pull_request_template.md,当前仓库快照中尚不存在)填写正文,并诚实勾选清单(只勾实际运行/验证过的项)。严禁添加 AI 签名(Co-Authored-By、Generated with等一律禁止)。
六、Skills 索引:面向 Agent 的专项规范
AGENTS.md 将规范按主题沉淀为四个 Claude Skill,位于.claude/skills/,适用于所有 Agent 与贡献者:
| Skill | 用途 | 触发时机 |
|---|---|---|
| architecture | 各进程类型的文件与目录结构约定 | 创建文件、新增模块、架构决策 |
| i18n | 国际化工作流与标准 | 新增/修改用户可见文本、改动locales/或packages/desktop/src/common/config/i18n |
| testing | 测试工作流与质量标准 | 写测试、改运行时行为、修 bug、声称行为已验证 |
| bump-version | 版本升级工作流:改 package.json、检查、分支、PR、打 tag | 升级版本、/bump-version |
以bump-versionSkill 为例,它定义了完整的/bump-version [version] [flags]命令:支持--core <version>显式指定 AionCore 版本、--skip-core纯前端发布;流程包含 13 步——从"必须处于干净的 main 分支"的前置检查、查询 AionCore 最新 release 并核对 7 个平台产物(6 个 tar.gz/zip + checksums.txt)、更新package.json的version与aioncoreVersion、按 Conventional Commit 分组生成 CHANGELOG 条目、依次通过 lint/format/tsc/vitest、开分支提交、gh pr create并启用 squash 自动合并、每 5 分钟轮询(最长 30 分钟)、合并后清理分支并git tag推送触发 release 构建。仓库当前package.json中的aioncoreVersion: "v0.2.1"与version: 2.2.1正是这套流程的产物。
七、速查清单
对任何即将在 AionUi 仓库提交代码的贡献者(人类或 AI),AGENTS.md 实质上要求同时满足:
- 架构:代码位于正确的进程目录,无跨进程 import;新 IPC 通道必须经 preload 桥接;目录 ≤ 10 直接子项;无单文件目录;平台目录统一小写。
- UI/CSS:一律 Arco 组件 + icon-park 图标,无原生交互 HTML;UnoCSS 优先、复杂样式走 CSS Module;颜色只用语义 token,禁止硬编码。
- 类型与 i18n:TS 严格模式、路径别名、
type优先;所有用户可见文本走 i18n 且同步全部语言目录,i18n:types先于check-i18n.js。 - 测试:新功能必须带测试,
bun run test全绿,覆盖率 ≥ 80%;测试描述行为、覆盖失败路径。 - 流程:
just push五连门禁通过后推送;不擅自 push;不加 AI 签名;commit 遵循 Conventional Commit 格式。
这套规范的精髓在于"用工具链强制纪律":目录大小、命名、边界、i18n、测试目标都被显式写成可检查的规则,配合 lint/format/typecheck/test/i18n 五重门禁与prek的 CI 复刻,让人类与 AI 在同一个质量平面上协作。对希望引入 AI Agent 参与开发的团队而言,AionUi 的 AGENTS.md + Skills 模式是一个值得直接参考的范本。
【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20+ more CLI Agent | Customize your assistants | Team them up|Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考