86 lines
10 KiB
Markdown
86 lines
10 KiB
Markdown
# AGENTS.md - Agent 接入手册
|
||
|
||
面向 AI Agent(以及新加入的人类协作者)的组件库使用规范。本文件同时是项目入口文档。
|
||
|
||
## 环境准备(新 Agent 必读,先跑通再干活)
|
||
|
||
1. **包管理器必须用 pnpm**:包间依赖用 `workspace:*` 协议,npm 不支持。安装依赖:`pnpm install`。
|
||
2. **构建工具**:TypeScript 5(`tsc`)。若环境未全局安装,可使用托管工作区的副本:`C:/Users/shawn/.workbuddy/binaries/node/workspace/node_modules/typescript`(本仓库历史即如此构建)。
|
||
3. **Node**:>= 18,ESM(`"type": "module"`)。
|
||
4. **环境自检 + 验证基线**:先跑 `node packages/tools/cli/bin/ua.js doctor`(秒级检查 node 版本 / 依赖安装 / git 钩子 / .ua 元数据可解析,任一失败退出码 1),通过后再跑 `npm run check`(build → demo → style → typecheck → smoke → index → verify → lint-iterations → audit:visual)确认基线全绿,再开始改代码。
|
||
|
||
## 编码规范(强制)
|
||
|
||
所有 TS / JS 代码遵循 `CODING.md`:注释一律中文(函数级 `/*** 作用 ***/`、行尾 `// 短注释`),代码紧凑 + 行工整、卫语句单行,高可扩展、低抽象、可读性优先。
|
||
|
||
**注释强制门禁**:`npm run style`(即 `ua style`)机器检查——导出必须有 `/*** ***/` 注释、接口字段必须有行尾注释、行注释必须中文,并强制**分层包 src 下单文件 ≤ 200 行**(`types.ts` 与 `index.ts` 作为类型/导出汇总豁免);有违规即退出码 1,改完才能提交。
|
||
|
||
## 项目结构(权威定义见 ARCHITECTURE.md)
|
||
|
||
分层目录,依赖方向单向 `apps → skin → core → design`:
|
||
|
||
- `packages/core/table-core`(@ui-arch/table-core):Headless 表格逻辑内核
|
||
- `packages/core/frame`(@ui-arch/frame):signal + hyperscript 微框架
|
||
- `packages/skin/ui`(@ui-arch/ui):70 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
||
- `packages/design/tokens`(@ui-arch/tokens):设计令牌
|
||
- `packages/tools/cli`(@ui-arch/cli):`ua` 命令行 + MCP 注册表服务(private)
|
||
- `apps/demo`(@ui-arch/demo):交互演示,产物 apps/demo/dist/demo.html
|
||
- `apps/docs`:文档站,纯产物(ua docs 生成)
|
||
|
||
**门禁一条龙**:`npm run check` = build + demo + style + typecheck + smoke + index + verify + lint-iterations + audit:visual,提交前必过。其中 `smoke` 是两段内核断言:`@ui-arch/frame` 14 条(信号读写与同值短路、effect 注销与条件分支重追踪、computed 链式派生、多订阅者扇出)+ `@ui-arch/table-core` 21 条(排序 / 筛选 / 分页 / 选择的派生管线);改内核语义前先跑它,别靠组件 demo 肉眼验。`ua audit:visual` 统计皮肤包里十三类硬编码视觉字面量(字号 / 动效时长 / 阴影 / 圆角 / 焦点环 / 内距 / 控件高度 / 字重 / 行高 / 层级 / 边框色 / 混色浓度 / transform 位移)并与 `.ua/visual-baseline.json` 做棘轮:任一类超过基线即退出码 1 并指出疑似引入的提交;迁移脚本 `npm run visual:migrate` 可把字面量幂等改写成令牌。`ua verify` 校验清单 ↔ 文档 ↔ 演示一致(docs.components 的 id 必须在 api.exports 有对应条目、props 必须带 n/t/d、每个文档字段名必须在组件实现源码里真实出现(改名后忘改文档会直接报错)、反向也校验 `src/types.ts` 里 `<组件>Props`(可用清单的 `propsType` 覆盖接口名,`false` 表示无入参)每个字段都在文档 props 表登记(新加字段忘了写文档会报错)、demo 锚点必须在 `apps/demo/main.ts` 中存在,且该组件必须被 demo 真实调用 `id(` / `id.`),检查皮肤包样式表无硬编码颜色(`#hex` 一律禁止,必须走 `--ua-*` 令牌)与令牌引用有效(`var(--ua-*)` 必须是 tokens.css 已定义或组件自设的变量)、核对每个 `--ua-color-*` 都在 `[data-theme='dark']` 里有覆盖值且暗色块没有凭空多出的变量名(新增颜色令牌漏写暗色值直接报错)、核对 `tokens.json` 的 `color` 键与 tokens.css 的 `--ua-color-*` 同名同值(名字按 camelCase → kebab 折算,亮色值与暗色值都比,双向查漏——只改一处时文档色板会凭空多/少一个令牌,过去只能靠人眼发现)、核对 `@keyframes` 没有「帧体完全相同但名字不同」的复制粘贴(同一段动效只该有一份声明,改名复制会让方向 / 时长各写各的,翻转态就出现过「朝反方向入场」),核对 README 的 `<!-- ua:components -->` 区块与「分组:」行都覆盖清单组件集合(漏写/多写/重复都报错),并交叉校验 backlog 的 done 条目与 `.ua/iterations.log` 的 done 留痕一一对应(另外查 backlog id 不重复、g 编号严格递增、同一 id 只有一条 done 留痕,且留痕 ts 带 +08:00、时间线不回退、不落在未来——都是过去手工插条目/手写时间戳踩过的坑);配方还要求编号连续、每条都有代码块与要点,且代码块里至少认出一个已注册组件 id(拼错组件名时 `ua recipes` 会把它列成空组件表)。
|
||
|
||
`ua verify` 另外校验 `ITERATION.md` 的《视觉回归抽查清单》:button / textField / select / modal / dataTable / toast 六段各 ≥3 条可勾选要点、每条维度标签必须落在边框 / 阴影 / 过渡 / 焦点环 / 暗色五类内、合计 ≥18 条且五维度全覆盖——视觉类条目收尾前照单过一遍,改清单时别把条目删漏。
|
||
|
||
**变更日志**:`CHANGELOG.md` 由 git 提交史生成(`npm run changelog`),**不进 `npm run check`**——它包含每个提交自身,提交后必然与历史差一条,只能作为「发版前刷新」步骤;`npm run changelog:check` 用于确认是否漂移。
|
||
|
||
**提交信息规范**:`COMMITTING.md`(`<type>(<scope>): <中文祈使句>`),`ua commit-lint` + commit-msg 钩子自动校验,迭代提交用 `iter(<条目id>): <subject>`。
|
||
|
||
## Agent 查询组件库的三种方式(`ua info <组件id>` 直接出 props/步骤/示例)
|
||
|
||
1. **MCP(推荐)**:在 `~/.workbuddy/mcp.json` 注册:
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"ui-arch-registry": {
|
||
"command": "node",
|
||
"args": ["<仓库绝对路径>/packages/tools/cli/bin/ua.js", "mcp"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
可用工具:`list_components` / `get_component` / `search_components` / `get_tokens`(返回 --ua-* 令牌清单,避免硬编码颜色间距)/ `list_recipes` / `get_recipe`(取跨组件组合配方:骨架代码 + 要点 + 用到的组件 id,配好再逐个 `get_component` 查参数)。
|
||
|
||
2. **CLI**:`node packages/tools/cli/bin/ua.js list [--json|--components] | search <关键词> | info <name> [--json] | recipes [编号] [--json] | index | docs | style | verify | changelog`(`--json` 给脚本与 Agent 用,不必解析文本);`search` 覆盖 id / 标题 / 参数名 / 参数说明 / 步骤五层 + 配方三层(标题 / 配方组件 / 要点,命中行直接给 `ua recipes <编号>` 指路),命中非 id 标题时会标出命中字段(如「← 参数说明含『处理中』」),`--json` 输出 `{ components, recipes }` 两数组、各项带 `matched` 字段
|
||
|
||
3. **静态索引**:`.ua/index.json`(机器可读索引)、`llms.txt`(速览)或 **`llms-full.txt`(全量 Agent 文档:逐组件参数 / 回调 / 手把手步骤 / 令牌 / 组合配方,无图形纯文本,喂给 Agent 首选)**。
|
||
|
||
## 贡献新组件的强制约定
|
||
|
||
1. 按 `ARCHITECTURE.md` 分层模型确定目录归属:逻辑→core,渲染→skin,令牌→design,脚本→tools
|
||
2. 新包必须包含 `ua.manifest.json`(name/type/description/tags/api/usage),否则不会被索引;type 取值:headless-core / skin-dom / design-tokens / tooling
|
||
3. 行为逻辑放 core 包,DOM 渲染放 skin 包;皮肤间不互相依赖,公共逻辑下沉 core
|
||
4. 皮肤包禁止硬编码颜色/间距,一律使用 `--ua-*` 令牌
|
||
5. 选择类状态一律存 rowKey,不存行索引
|
||
6. 改动后运行 `npm run index` 刷新注册表;新增组件记得在 manifest 的 `docs.components` 里补参数表与手把手步骤,`npm run docs` 会同步生成人类版文档站与 llms-full.txt
|
||
|
||
## 新增组件落点清单(照单打勾,漏一处 `npm run check` 就会红)
|
||
|
||
一个新组件要动 10 处,缺任何一处 verify 都会报错,别靠记忆:
|
||
|
||
| # | 落点 | 具体动作 |
|
||
|---|---|---|
|
||
| 1 | `packages/skin/ui/src/<id>.ts` | 组件实现(单文件 ≤ 200 行,导出带 `/*** */` 注释) |
|
||
| 2 | `packages/skin/ui/src/types.ts` | `<组件>Props` 接口 + 逐字段行尾注释;嵌套项类型(如 `TabItem`)也放这里 |
|
||
| 3 | `packages/skin/ui/src/index.ts` | 末尾追加 `export { xxx } from './xxx.js';` |
|
||
| 4 | `packages/skin/ui/ui.css` | 样式只消费 `--ua-*`(禁 `#hex`),动效要带 `prefers-reduced-motion` 兜底;**禁止新增硬编码 `box-shadow` / 动效时长 / `font-size` 字面值**,一律用 elevation(`--ua-shadow-1..4`)/ motion(`--ua-duration-*` + `--ua-ease`)/ 字号(`--ua-font-size-*`)令牌,焦点环用 `--ua-focus-ring`,`npm run audit:visual` 会让计数上涨的提交直接红 |
|
||
| 5 | `packages/skin/ui/ua.manifest.json` → `api.exports` | 一行 `xxx(props):一句话说明` |
|
||
| 6 | 同上 → `docs.components` | `{ id, title, demo, props[], example, steps[] }`:props 里每个字段名必须在实现源码里真实出现,且 `<组件>Props` 的字段一个都不能漏(verify 双向校验) |
|
||
| 7 | `apps/demo/main.ts` | 新增 `section('<demo 锚点>', ...)` 并**真实调用**该组件(verify 会查) |
|
||
| 8 | `README.md` | `<!-- ua:components -->` 区块补 id、「分组:」行补归组(数字交给下一步自动同步) |
|
||
| 9 | `npm run sync-counts` | 自动把三份文档里的「N 个组件 / 共 N 个」改成清单实际数量(幂等;漏改时 verify 报行号) |
|
||
| 10 | `npm run docs` | 重新生成 `llms-full.txt` 与 `apps/docs/index.html`(不跑 verify 会报 llms-full 漂移) |
|
||
|
||
改**既有**组件的入参同样要走 5、6、10 三步;只加一个可选参数也要补文档行,否则双向校验失败。
|