@teamix-evo/mcp 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # 0001. UI 组件研发三层对齐:能力 = shadcn ∪ antd / 理念 = design / 工程 = shadcn
2
2
 
3
- - **Status**: Accepted
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-05-15
5
5
  - **Region**: 0001–0099 工程哲学
6
6
  - **Related ADR**: [0005 UI 包不分 variant](0005-ui-no-variant.md) / [0014 ui/biz-ui/templates 三层](0014-ui-biz-ui-templates-tier.md)(本 ADR 在三个粒度上落实)
@@ -15,21 +15,21 @@ teamix-evo 的 ui 包面对一个上游生态的取舍问题:**shadcn/ui** 与 *
15
15
 
16
16
  ## Options Considered
17
17
 
18
- | 选项 | 优点 | 缺点 |
19
- | ---- | ---- | ---- |
20
- | 全盘对齐 shadcn | 工程一致、生态成熟 | antd 用户惯用的能力(loading / icon prop / shape / block 等)缺失 |
21
- | 全盘对齐 antd | 能力完整、中后台用户熟悉 | 工程笨重(less + ConfigProvider 运行时主题),与源码注入模式不兼容 |
22
- | **三层切分对齐(本决策)** | 各取所长,覆盖最广 | 每新增组件需做并集对照表(维护成本) |
18
+ | 选项 | 优点 | 缺点 |
19
+ | ------------------------ | ------------------------ | --------------------------------------------------------------- |
20
+ | 全盘对齐 shadcn | 工程一致、生态成熟 | antd 用户惯用的能力(loading / icon prop / shape / block 等)缺失 |
21
+ | 全盘对齐 antd | 能力完整、中后台用户熟悉 | 工程笨重(less + ConfigProvider 运行时主题),与源码注入模式不兼容 |
22
+ | **三层切分对齐(本决策)** | 各取所长,覆盖最广 | 每新增组件需做并集对照表(维护成本) |
23
23
 
24
24
  ## Decision
25
25
 
26
26
  UI 组件研发的对齐规则按三层切分,**任何冲突时三层切分优先于其它细则**:
27
27
 
28
- | 维度 | 对齐对象 | 含义 |
29
- | ---- | -------- | ---- |
30
- | **能力 / 功能** | **shadcn ∪ antd 的合集** | shadcn 缺什么、antd 有什么,补;反之亦然。**做并集,不做交集** |
31
- | **设计理念** | **`@teamix-evo/design` 的 OpenTrek 体系** | 视觉 / 间距 / 圆角 / 字号 / 阴影 / 动效 / 交互预期 / AI 生成纪律全部走 design,**不参照 antd 视觉,也不参照 shadcn 视觉** |
32
- | **代码实现 / 部署 / 规范** | **shadcn** | 文件结构、源码注入分发、cva 范式、forwardRef + Slot、TypeScript 写法、命名风格、registryDependencies 思想全部对齐 shadcn,**不照搬 antd 的运行时主题 / less / 样式封装方式** |
28
+ | 维度 | 对齐对象 | 含义 |
29
+ | -------------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
30
+ | **能力 / 功能** | **shadcn ∪ antd 的合集** | shadcn 缺什么、antd 有什么,补;反之亦然。**做并集,不做交集** |
31
+ | **设计理念** | **`@teamix-evo/design` 的 OpenTrek 体系** | 视觉 / 间距 / 圆角 / 字号 / 阴影 / 动效 / 交互预期 / AI 生成纪律全部走 design,**不参照 antd 视觉,也不参照 shadcn 视觉** |
32
+ | **代码实现 / 部署 / 规范** | **shadcn** | 文件结构、源码注入分发、cva 范式、forwardRef + Slot、TypeScript 写法、命名风格、registryDependencies 思想全部对齐 shadcn,**不照搬 antd 的运行时主题 / less / 样式封装方式** |
33
33
 
34
34
  简记:**能力做并集,理念跟 design,工程跟 shadcn**。
35
35
 
@@ -1,6 +1,6 @@
1
1
  # 0005. UI 包不分 variant,所有视觉差异通过 design tokens 实现
2
2
 
3
- - **Status**: Accepted
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-05-14
5
5
  - **Region**: 0100–0999 协议与工具
6
6
  - **Related ADR**: [0001 三层对齐](0001-three-layer-alignment.md) / [0006 UI 升级机制无 baseline](0006-ui-upgrade-no-baseline.md) / [0010 design 默认+变体](0010-design-default-and-variants.md) / [0014 ui/biz-ui/templates 三层](0014-ui-biz-ui-templates-tier.md)
@@ -24,9 +24,9 @@
24
24
 
25
25
  ## Options Considered
26
26
 
27
- | 选项 | 优点 | 缺点 |
28
- | ---- | ---- | ---- |
29
- | UI 按 variant 切分 | 单 variant 内组件可深度定制视觉 | 维护成本随 variant 数量线性增长;同步问题 |
27
+ | 选项 | 优点 | 缺点 |
28
+ | ------------------------------------ | -------------------------------------------------- | ------------------------------------------------------- |
29
+ | UI 按 variant 切分 | 单 variant 内组件可深度定制视觉 | 维护成本随 variant 数量线性增长;同步问题 |
30
30
  | **UI 不分 variant,靠 token(本决策)** | 一套组件吃所有 variant;切换 variant 仅改 design 包 | 强依赖 semantic 命名稳定;variant 间语义集合必须严格对齐 |
31
31
 
32
32
  ## Decision
@@ -1,6 +1,6 @@
1
1
  # 0006. UI 升级机制不预埋 baseline,依靠 AI + skill 做语义合并
2
2
 
3
- - **Status**: Accepted
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-05-14
5
5
  - **Region**: 0100–0999 协议与工具
6
6
  - **Related ADR**: [0003 资源升级三态语义](0003-update-strategy-tri-state.md) / [0005 UI 包不分 variant](0005-ui-no-variant.md) / [0013 Skills source-mirror 模型](0013-skills-source-mirror.md)(skills upgrade 同型动作:同样无 baseline,靠语义合并 + skill 引导)
@@ -20,11 +20,11 @@ UI 包采用源码注入分发(`teamix-evo ui add <id>` 把组件源码写到业
20
20
 
21
21
  ## Options Considered
22
22
 
23
- | 选项 | 优点 | 缺点 |
24
- | ---- | ---- | ---- |
25
- | 三方合并 + baseline | 精确 | baseline 必须随 ui add 一起落地到业务项目(污染),且需历史快照管理 |
26
- | 完全覆盖 | 简单 | 丢用户定制 |
27
- | **AI 语义合并 + skill 引导(本决策)** | 不污染、简化、AI 兜底语义判断 | 比三方合并精确度差,大改时仍需人介入 |
23
+ | 选项 | 优点 | 缺点 |
24
+ | ------------------------------------ | ----------------------------- | ---------------------------------------------------------------- |
25
+ | 三方合并 + baseline | 精确 | baseline 必须随 ui add 一起落地到业务项目(污染),且需历史快照管理 |
26
+ | 完全覆盖 | 简单 | 丢用户定制 |
27
+ | **AI 语义合并 + skill 引导(本决策)** | 不污染、简化、AI 兜底语义判断 | 比三方合并精确度差,大改时仍需人介入 |
28
28
 
29
29
  ## Decision
30
30
 
@@ -1,6 +1,6 @@
1
1
  # 0010. `@teamix-evo/design` 采用 `default + variants/<name>/` 模型,工程默认与业务变体彻底解耦
2
2
 
3
- - **Status**: Proposed
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-05-18
5
5
  - **Region**: 0100–0999 协议与工具
6
6
  - **Related ADR**: [0001 三层对齐](0001-three-layer-alignment.md) / [0005 UI 不分 variant](0005-ui-no-variant.md) / [0007 治理文档放根](0007-governance-docs-at-root.md) / [0008 ESLint 视觉规则 warn 基线](0008-eslint-visual-rules-warn-baseline.md) / [0014 ui/biz-ui/templates 三层](0014-ui-biz-ui-templates-tier.md)
@@ -134,19 +134,19 @@ design 包改 token 名(如 `--color-fg-muted` → `--color-text-muted`),`design
134
134
 
135
135
  ## Implementation status
136
136
 
137
- - **本 ADR**:仅锁方向;**不实现代码**
138
- - **目标版本**:v0.7
139
- - **拆解任务**(留给 v0.7 PR):
140
- 1. lock schema v2 + migration(0.5)
141
- 2. snapshot 模块 + `restore` 命令(1)
142
- 3. managed-region 解析器(1.5)
143
- 4. `design update` 真实现 + 三态分流(2.5)
144
- 5. `teamix-evo init`(已有工程接入)(2)
145
- 6. `teamix-evo update` orchestrator(1)
146
- 7. `design switch` + variant migration(1.5)
147
- 8. token rename hint 写入 + skill `teamix-evo-upgrade`(2)
148
- 9. W1.4 tokens 提层兼容迁移(0.5)
149
- 10. 文档站 5 命令导引 + 端到端 example(1.5)
137
+ - **本 ADR**:方向锁定 + **D1 全量落地完成(v0.8 发版批次)**
138
+ - **当前版本**:v0.8 发版周期
139
+ - **拆解任务**:
140
+ 1. lock schema v2 + migration(`project-config-schema-v2`)
141
+ 2. snapshot 模块 + `restore` 命令(`snapshot-module` + `restore-command`)
142
+ 3. managed-region 解析器(`registry-split-managed-regions`)
143
+ 4. `tokens update` 真实现 + 三态分流(`tokens-update-tristate-dispatch`)
144
+ 5. `teamix-evo init`(已有工程接入;6 类冲突 + wizard + partial 恢复)
145
+ 6. `teamix-evo update` orchestrator(`add-update-command`)
146
+ 7. `teamix-evo switch` + variant migration(`cli-switch-command`)
147
+ 8. token rename hint 写入 + skill `teamix-evo-upgrade`(`tokens-rename-hint` + `skills-add-upgrade-skill`)
148
+ 9. W1.4 tokens 提层兼容迁移(`cli-init-tokens-migrate`)
149
+ 10. 文档站 5 命令导引 + TrekClaw e2e example(`packages/docs/docs/cli/index.md` + `example-trekclaw.md`)
150
150
 
151
151
  ## Source
152
152
 
@@ -97,3 +97,31 @@ default | muted | primary | success | warning | destructive
97
97
  - 二次回退触发:用户对 `tone` 命名的业界流行度质疑(2026-05-29 下午)—— 实测 `tone` 仅 Polaris 一家,业界主流是 `color` / `variant`,本 ADR 据此从 `tone` 回退到 `color`
98
98
  - 关联记忆:`shadcn基线项目语义色双prop命名决策` / `语义色标准档位不包含info色的决策` / `shadcn 新组件代码规范`
99
99
  - 关联组件:Icon / Spinner / Button / Badge / Tag(本 ADR 立项前已落地的混合命名,本次统一)
100
+
101
+ ## Addendum: Tag `status` 8 档枚举(2026-06)
102
+
103
+ Tag 在原 `variant`(形态) + `color`(语义色 5 档)正交体系基础上,新增 `variant='status'` 形态 + `status` prop 表达**业务状态机**轴(参考 teamix-pro `@ali/teamix-status-tag` 与 antd Upload/Result 的 `status` prop 习惯)。
104
+
105
+ **8 档命名与 token 映射**
106
+
107
+ | `status` | 中文 | 底层 token | 默认图标(`showIcon`) |
108
+ | --------- | ------ | ---------------------------- | ------------------------------ |
109
+ | `default` | 默认 | `--color-muted-foreground` | `Circle` |
110
+ | `success` | 成功 | `--color-success` | `CheckCircle2` |
111
+ | `running` | 运行中 | `--color-primary` | `PlayCircle` |
112
+ | `error` | 失败 | `--color-destructive` | `XCircle` |
113
+ | `warning` | 提醒 | `--color-warning` | `AlertCircle` |
114
+ | `pause` | 暂停 | `--color-muted-foreground` | `PauseCircle` |
115
+ | `loading` | 加载中 | `--color-muted-foreground` | `Loader2`(自带 `animate-spin`) |
116
+ | `help` | 帮助 | **新增 `--color-help`** 4 档 | `HelpCircle` |
117
+
118
+ **与本 ADR 主体的关系**
119
+
120
+ - `status` 是**业务状态机轴**(本 ADR §一明确不治理),非颜色枚举 —— 8 档名称直接采纳运行态业务话术(`running` / `pause` / `loading`),**不与 `color` 5 档同名约束**
121
+ - 例外:`status='error'` 与 `color='destructive'` 在底层共用 `--color-destructive` token —— 业务状态机轴允许用 `error` 字面值(antd 习惯,运行态自然语义),颜色轴仍只接受 `destructive`(本 ADR 主体规则不变)
122
+ - `status='running'` 与 `color='primary'` 共用 `--color-primary` —— 同理,语义独立但底层映射对齐
123
+ - `variant='status'` 与 `color` / `palette` / 自定义 `icon` **互斥**:状态形态由 `status` 闭环驱动颜色与图标,无外部颜色注入
124
+
125
+ **Token 增量**
126
+
127
+ 仅 `--color-help` 一档新增(双变体 OpenTrek + uni-manager 同步),其余 token 均已存在。详见同期 changeset `tag-status-variant`。
@@ -1,6 +1,6 @@
1
1
  # 0025. 组件 props 必须显式声明 + 数据录入类必须暴露 value/onChange 受控套
2
2
 
3
- - **Status**: Accepted
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-06-01
5
5
  - **Region**: 0100–0999 协议与工具
6
6
  - **Related ADR**: [ADR 0023](0023-cursor-pointer-explicit-in-component-source.md) · [ADR 0024](0024-scoped-css-radix-state-conflict.md)
@@ -32,10 +32,10 @@ Radix 的命名(`onCheckedChange` / `onValueChange`)与 antd / cd / 业务习惯
32
32
 
33
33
  ## Options Considered
34
34
 
35
- | 选项 | 优点 | 缺点 |
36
- | --- | --- | --- |
37
- | A. 维持现状(空 extends 透传) | 写法少,类型自动完整 | meta props 空 / AI 不可用 / Storybook 控件缺数据源 |
38
- | B. **显式列出每个支持的 prop + JSDoc 中文注释** | meta 自动表完整;Storybook controls 完整;AI 可读 | 每个组件多 ~20 行类型声明,需对齐 Radix 行为 |
35
+ | 选项 | 优点 | 缺点 |
36
+ | ----------------------------------------------- | ----------------------------------------------- | -------------------------------------------------- |
37
+ | A. 维持现状(空 extends 透传) | 写法少,类型自动完整 | meta props 空 / AI 不可用 / Storybook 控件缺数据源 |
38
+ | B. **显式列出每个支持的 prop + JSDoc 中文注释** | meta 自动表完整;Storybook controls 完整;AI 可读 | 每个组件多 ~20 行类型声明,需对齐 Radix 行为 |
39
39
 
40
40
  ## Decision
41
41
 
@@ -77,6 +77,7 @@ export interface CheckboxProps
77
77
  ```
78
78
 
79
79
  **关键点**:
80
+
80
81
  - 用 `Omit<RadixProps, 'overridden-keys'>` 排除被本地重写的字段,避免类型冲突
81
82
  - 所有暴露给业务的 prop **必须**带中文 JSDoc(`generate-meta.ts` 提取的就是这部分)
82
83
  - **不在 interface 暴露的 prop = 不支持** — 不允许"暗中支持但不声明"
@@ -85,14 +86,14 @@ export interface CheckboxProps
85
86
 
86
87
  数据录入类(用户输入 / 选择 / 调整某个 value 的组件)**必须**至少有这一对受控 prop:
87
88
 
88
- | 组件类型 | 受控 value | 受控 onChange | 非受控初值 |
89
- | --- | --- | --- | --- |
90
- | 单值输入(Input / Textarea / NumberInput / DatePicker / TimePicker / ColorPicker / Select 单选 / Combobox 单选) | `value` | `onChange` 或 Radix 命名(透传时显式声明) | `defaultValue` |
91
- | 布尔值(Checkbox / Switch) | `checked` | `onCheckedChange` | `defaultChecked` |
92
- | 多值(Select 多选 / Combobox 多选 / CheckboxGroup) | `value: string[]` | `onChange: (next: string[]) => void` | `defaultValue: string[]` |
93
- | 数值滑动(Slider / Rate) | `value: number[]` 或 `value: number` | `onValueChange` 或 `onChange` | `defaultValue` |
94
- | 树形(Tree / TreeSelect) | `value` / `selectedKeys` / `checkedKeys` | 对应 onChange / onSelect / onCheck | `default*` |
95
- | 级联(Cascader) | `value: string[]` | `onChange: (path, options) => void` | `defaultValue` |
89
+ | 组件类型 | 受控 value | 受控 onChange | 非受控初值 |
90
+ | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ---------------------------------------- | ------------------------ |
91
+ | 单值输入(Input / Textarea / NumberInput / DatePicker / TimePicker / ColorPicker / Select 单选 / Combobox 单选) | `value` | `onChange` 或 Radix 命名(透传时显式声明) | `defaultValue` |
92
+ | 布尔值(Checkbox / Switch) | `checked` | `onCheckedChange` | `defaultChecked` |
93
+ | 多值(Select 多选 / Combobox 多选 / CheckboxGroup) | `value: string[]` | `onChange: (next: string[]) => void` | `defaultValue: string[]` |
94
+ | 数值滑动(Slider / Rate) | `value: number[]` 或 `value: number` | `onValueChange` 或 `onChange` | `defaultValue` |
95
+ | 树形(Tree / TreeSelect) | `value` / `selectedKeys` / `checkedKeys` | 对应 onChange / onSelect / onCheck | `default*` |
96
+ | 级联(Cascader) | `value: string[]` | `onChange: (path, options) => void` | `defaultValue` |
96
97
 
97
98
  业务工程**必须能用受控模式跑通**;非受控只是便利封装。
98
99
 
@@ -1,6 +1,6 @@
1
1
  # 0026. 组件级 token 别名(`--radius-{component}` 等)的创建准则
2
2
 
3
- - **Status**: Accepted
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-06-02
5
5
  - **Region**: 0100–0999 协议与工具
6
6
  - **Related ADR**: [ADR 0020](0020-design-to-tokens-skill-fusion.md)(tokens 包 / skill 边界) · [ADR 0022](0022-preferences-css-boundary.md)(已 superseded,曾约束 preferences.css 不放 token alias)
@@ -15,20 +15,20 @@ W4–W5 优化时多次遇到"组件圆角该怎么定义"的问题。早期默
15
15
 
16
16
  这暴露了两类完全不同的 token 角色:
17
17
 
18
- | 层 | 类型 | 例子 | 谁定义 | 谁消费 |
19
- | --- | --- | --- | --- | --- |
18
+ | 层 | 类型 | 例子 | 谁定义 | 谁消费 |
19
+ | ------- | ---------------- | ------------------------------------------------------------------------------ | --------------------- | ------------------------------------------------------------------- |
20
20
  | Layer 1 | scale primitives | `--radius-sm` / `--radius-md` / `--radius-lg` / `--radius-xl` / `--radius-2xl` | 各 variant 可独立覆盖 | 所有组件,通过 Tailwind 标准 utility `rounded-{sm\|md\|lg\|xl\|2xl}` |
21
- | Layer 2 | 组件语义别名 | `--radius-dialog` / `--radius-tag` | 各 variant 可独立覆盖 | 仅该组件,通过 `rounded-[var(...)]` arbitrary value |
21
+ | Layer 2 | 组件语义别名 | `--radius-dialog` / `--radius-tag` | 各 variant 可独立覆盖 | 仅该组件,通过 `rounded-[var(...)]` arbitrary value |
22
22
 
23
23
  ADR 0022(已 superseded)曾约束"preferences.css 边界",但没有规范"什么时候可以加 Layer 2 别名"。本 ADR 补这一条。
24
24
 
25
25
  ## Options Considered
26
26
 
27
- | 选项 | 优点 | 缺点 |
28
- | --- | --- | --- |
29
- | A. 严格一层 — 所有组件走 scale,不允许 Layer 2 | token 架构最简 / 一致性最强 | 跨变体视觉差异大的组件被强制对齐,失去变体差异化能力(opentrek Dialog 必须从 16 收到 6,失去"圆润"视觉特征) |
30
- | B. **二层模式 — 优先 scale,严控 Layer 2 创建条件(推荐)** | scale 是默认路径(简单);Layer 2 作为 escape hatch,有明确触发条件 | 需要 ADR 守门;否则 Layer 2 会无序蔓延变成"杂物间" |
31
- | C. 全自由 — 任何组件都可加 `--radius-{name}` | 最大灵活性 | 跟 ADR 之前踩坑的"AI / 业务工程不知道该用哪个 token"反模式重合;token 数量爆炸 |
27
+ | 选项 | 优点 | 缺点 |
28
+ | -------------------------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
29
+ | A. 严格一层 — 所有组件走 scale,不允许 Layer 2 | token 架构最简 / 一致性最强 | 跨变体视觉差异大的组件被强制对齐,失去变体差异化能力(opentrek Dialog 必须从 16 收到 6,失去"圆润"视觉特征) |
30
+ | B. **二层模式 — 优先 scale,严控 Layer 2 创建条件(推荐)** | scale 是默认路径(简单);Layer 2 作为 escape hatch,有明确触发条件 | 需要 ADR 守门;否则 Layer 2 会无序蔓延变成"杂物间" |
31
+ | C. 全自由 — 任何组件都可加 `--radius-{name}` | 最大灵活性 | 跟 ADR 之前踩坑的"AI / 业务工程不知道该用哪个 token"反模式重合;token 数量爆炸 |
32
32
 
33
33
  ## Decision
34
34
 
@@ -39,8 +39,8 @@ ADR 0022(已 superseded)曾约束"preferences.css 边界",但没有规范"什么
39
39
  新增组件 / 优化组件时,**圆角默认**写:
40
40
 
41
41
  ```tsx
42
- className="rounded-md" // 走 --radius-md (uni-manager 2 / opentrek 6 / Tailwind 默认 6)
43
- className="rounded-lg" // 走 --radius-lg (uni-manager 4 / opentrek 8 / Tailwind 默认 8)
42
+ className = 'rounded-md'; // 走 --radius-md (uni-manager 2 / opentrek 6 / Tailwind 默认 6)
43
+ className = 'rounded-lg'; // 走 --radius-lg (uni-manager 4 / opentrek 8 / Tailwind 默认 8)
44
44
  ```
45
45
 
46
46
  各 variant 在 `@theme {}` 块里覆盖 `--radius-sm/md/lg/xl/2xl` 满足该 variant 的视觉调性。
@@ -49,22 +49,22 @@ className="rounded-lg" // 走 --radius-lg (uni-manager 4 / opentrek 8 / Tailwin
49
49
 
50
50
  ### 规则 B — 满足以下**全部**条件才可创建 Layer 2 别名
51
51
 
52
- | # | 条件 | 备注 |
53
- | --- | --- | --- |
54
- | 1 | 跨变体的目标值**无法被同一个 scale 档同时满足** | 例:Dialog 在 opentrek 想要 16px,uni-manager 想要 2px。无任何 `rounded-{sm\|md\|lg\|xl\|2xl}` 在两个 variant 同时落到这两个值 |
55
- | 2 | 该组件视觉**确实有跨变体差异化的设计意图**,不是 token 命名洁癖 | 例:Dialog 跨变体差异是"圆润感 vs 锐利感"的设计语言,非可省略 |
56
- | 3 | 不能通过组合 `cn()` / 变体 className 实现 | 同一 `<Dialog>` 源码不能写"变体感知 className",所以 Dialog 必须有 token alias |
57
- | 4 | 命名清晰指向具体组件 | `--radius-{component-id}`,如 `--radius-dialog` / `--radius-tag` |
52
+ | # | 条件 | 备注 |
53
+ | --- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
54
+ | 1 | 跨变体的目标值**无法被同一个 scale 档同时满足** | 例:Dialog 在 opentrek 想要 16px,uni-manager 想要 2px。无任何 `rounded-{sm\|md\|lg\|xl\|2xl}` 在两个 variant 同时落到这两个值 |
55
+ | 2 | 该组件视觉**确实有跨变体差异化的设计意图**,不是 token 命名洁癖 | 例:Dialog 跨变体差异是"圆润感 vs 锐利感"的设计语言,非可省略 |
56
+ | 3 | 不能通过组合 `cn()` / 变体 className 实现 | 同一 `<Dialog>` 源码不能写"变体感知 className",所以 Dialog 必须有 token alias |
57
+ | 4 | 命名清晰指向具体组件 | `--radius-{component-id}`,如 `--radius-dialog` / `--radius-tag` |
58
58
 
59
59
  不满足全部 4 条 → **走 Layer 1 scale**。
60
60
 
61
61
  ### 规则 C — 现存 Layer 2 别名 audit(本 ADR 落地时)
62
62
 
63
- | Token | 状态 | 理由 |
64
- | --- | --- | --- |
65
- | `--radius-button` | **已移除**(W1-Button 优化时) | 走 `rounded-md` 即可(uni 2 / opentrek 6 / 标准 6),无变体差异化需求 |
66
- | `--radius-dialog` | **保留** | uni 2 / opentrek 16 跨档不可对齐;有"圆润 vs 锐利"设计语言差异;Dialog/AlertDialog/Sheet 共享 |
67
- | `--radius-tag` | **保留** | uni 4 / opentrek 4(同值但不在任一 variant 的同一 scale 档:opentrek `rounded-sm`=4 ✓ / uni `rounded-sm`=0 ✗);需 alias 才能跨变体对齐 |
63
+ | Token | 状态 | 理由 |
64
+ | ----------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
65
+ | `--radius-button` | **已移除**(W1-Button 优化时) | 走 `rounded-md` 即可(uni 2 / opentrek 6 / 标准 6),无变体差异化需求 |
66
+ | `--radius-dialog` | **保留** | uni 2 / opentrek 16 跨档不可对齐;有"圆润 vs 锐利"设计语言差异;Dialog/AlertDialog/Sheet 共享 |
67
+ | `--radius-tag` | **保留** | uni 4 / opentrek 4(同值但不在任一 variant 的同一 scale 档:opentrek `rounded-sm`=4 ✓ / uni `rounded-sm`=0 ✗);需 alias 才能跨变体对齐 |
68
68
 
69
69
  ### 规则 D — 同样模式适用于其他 token namespace
70
70
 
@@ -1,6 +1,6 @@
1
1
  # 0027. 组件视觉属性全轴对齐设计系统基线
2
2
 
3
- - **Status**: Partially superseded by [ADR 0032](./0032-opentrek-v4.1-brand-token-alignment.md)(opentrek radius 档位升级,本 ADR 表 1 中 opentrek 列已不准)
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-06-02
5
5
  - **Region**: 0001–0099 工程哲学
6
6
  - **Related ADR**: 0010 (design-default-and-variants), 0026 (component-level-token-alias), 0032 (opentrek-v4.1-brand-token-alignment)
@@ -1,6 +1,6 @@
1
1
  # 0028. UI 组件分类对齐 Ant Design 5.x + 引入 `deprecated` 类
2
2
 
3
- - **Status**: Accepted
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
4
  - **Date**: 2026-06-02
5
5
  - **Region**: 0100–0999 协议与工具
6
6
  - **Related ADR**: 0014 (ui-biz-ui-templates-tier), 0025 (component-props-explicit)
@@ -51,15 +51,16 @@ teamix-evo 定位**中后台研发**(opentrek + uni-manager 都是管控台),**A
51
51
 
52
52
  ### 完整组件归类(87 个)
53
53
 
54
- - **general(3)**:button、icon、typography
55
- - **layout(7)**:flex、grid、page-header、resizable、separator、sidebar、space
56
- - **navigation(5)**:affix、breadcrumb、dropdown-menu、pagination、steps
57
- - **data-entry(20)**:auto-complete、cascader、checkbox、color-picker、date-picker、field、filter-bar、form、input、input-number、label、radio-group、rate、select、slider、switch、time-picker、transfer、tree-select、upload
58
- - **data-display(19)**:accordion、avatar、badge、calendar、card、carousel、collapsible、data-table、descriptions、empty、hover-card、item、statistic、table、tabs、tag、timeline、tooltip、tree
59
- - **feedback(15)**[^1]:alert、alert-dialog、command、dialog、drawer、notification、popconfirm、popover、progress、result、sheet、skeleton、sonner、spinner、watermark
60
- - **deprecated(18)**[^1]:已有 — aspect-ratio、image、kbd;新增 — app、anchor、context-menu、float-button、menubar、navigation-menu、tour、toggle-group、toggle、segmented、native-select、mentions、input-otp、scroll-area、masonry
54
+ - **general(3)**:button、icon、typography
55
+ - **layout(6)**:flex、grid、page-header、resizable、separator、sidebar
56
+ - **navigation(5)**:affix、breadcrumb、dropdown-menu、pagination、steps
57
+ - **data-entry(20)**:auto-complete、cascader、checkbox、color-picker、date-picker、field、filter-bar、form、input、input-number、label、radio-group、rate、select、slider、switch、time-picker、transfer、tree-select、upload
58
+ - **data-display(19)**:accordion、avatar、badge、calendar、card、carousel、collapsible、data-table、descriptions、empty、hover-card、item、statistic、table、tabs、tag、timeline、tooltip、tree
59
+ - **feedback(14)**[^1]alert、alert-dialog、command、dialog、notification、popconfirm、popover、progress、result、sheet、skeleton、sonner、spinner、watermark
60
+ - **deprecated(19)**[^1][^2]:已有 — aspect-ratio、image、kbd;新增 — app、anchor、context-menu、float-button、menubar、navigation-menu、tour、toggle-group、toggle、segmented、native-select、mentions、input-otp、scroll-area、masonry、drawer
61
61
 
62
- [^1]: 2026-06-02 补丁 — `command` 原拟归 deprecated(“仅 Storybook 留档”),但事实上被 active 的 `select` / `auto-complete` 运行时强 import,不能不外发;同时作为 Combobox / Select / AutoComplete 同源下拉内核(ADR 0029)在架构上起底座作用。故从 deprecated 撤回,与 popover 同档归 `feedback`(反馈式弹层底座),feedback 类目从 14 件变 15 件;deprecated 类目从 19 件变 18 件。
62
+ [^1]: 2026-06-02 补丁 — `command` 原拟归 deprecated("仅 Storybook 留档"),但事实上被 active 的 `select` / `auto-complete` 运行时强 import,不能不外发;同时作为 Combobox / Select / AutoComplete 同源下拉内核(ADR 0029)在架构上起底座作用。故从 deprecated 撤回,与 popover 同档归 `feedback`(反馈式弹层底座)
63
+ [^2]: 2026-06-04 补丁 — `drawer` 从 feedback 移入 deprecated,因其是 Sheet 的纯别名 re-export,无独立实现;`space` 从 layout 移除,因其从未实现为独立 entry,Flex 已完整覆盖 antd Space 能力。feedback 15→14,layout 7→6,deprecated 18→19。
63
64
 
64
65
  ### 与 AntD 的偏离
65
66
 
@@ -1,3 +1,9 @@
1
+ # 0029. Input 拆分 + 移除 prefix/suffix/addon 快捷 prop + AutoComplete 内核同源化
2
+
3
+ - **Status**: Superseded by [0036](./0036-ui-v2-shadcn-baseline-rebuild.md)
4
+ - **Date**: 2026-06-02
5
+ - **Region**: 0100–0999 协议与工具
6
+
1
7
  ## Context
2
8
 
3
9
  历史包袱:`<Input>` 同时承载两套表达"前后缀"的 API:
@@ -0,0 +1,146 @@
1
+ # 0036. UI 组件库 v2:以 shadcn v4 为基线全量重建
2
+
3
+ - **Status**: Accepted
4
+ - **Date**: 2026-06-05
5
+ - **Region**: 0001–0099 工程哲学
6
+ - **Related ADR**: Supersedes 0001, 0005, 0006, 0010, 0025, 0026, 0027, 0028, 0029
7
+
8
+ ## Context
9
+
10
+ `@teamix-evo/ui` v1 从 shadcn v3 出发,叠加 antd 能力并集,积累了 87+ 组件。过程中出现以下问题:
11
+
12
+ 1. **双对标负担**:每个组件都要做"shadcn ∪ antd 并集",决策成本高、更新难跟进
13
+ 2. **旧 shadcn 架构绑定**:forwardRef、`@layer base` border 兜底、hsl 色值等 v3 模式已过时
14
+ 3. **Token 分层不清**:全局 token 与组件级行为覆盖混在一个 theme.css 里(uni-manager 544 行)
15
+ 4. **文档多源漂移**:meta.md 手写、Storybook 描述手写、TSDoc 各写各的,三处信息不同步
16
+ 5. **能力增强方向模糊**:antd 为锚点导致"追赶 antd"而非"面向业务场景"
17
+
18
+ 同时,shadcn 已演进到 v4(radix-nova style、React 19 patterns、data-slot、oklch、Tailwind v4 @theme),架构显著优于 v3。
19
+
20
+ ## Decision
21
+
22
+ ### D1. 全量废弃 v1 组件源码,以 shadcn v4 (radix-nova) 为基线重建
23
+
24
+ - 现有 `packages/ui/src/` 内容备份到 `packages/ui/src-v1-archive/`
25
+ - 从 shadcn v4 最新版初始化全部基线组件
26
+ - 超出 shadcn 的组件按 shadcn 工程风格自研
27
+
28
+ ### D2. Token 架构:`theme.css` + `overrides.css` 两文件制
29
+
30
+ 每个变体目录结构:
31
+
32
+ ```
33
+ packages/tokens/variants/{variant}/
34
+ ├── theme.css ← @theme token 声明(Tailwind v4 消费)
35
+ └── overrides.css ← 变体组件行为覆盖([data-theme] scoped CSS)
36
+ ```
37
+
38
+ - `base.tokens.json` 删除(原为 AI 生成辅助文件,非运行时依赖)
39
+ - `theme.css` 为全局 token 声明唯一源
40
+ - `overrides.css` 处理跨变体的组件级行为差异(focus 机制、button shadow、dialog padding 等)
41
+
42
+ ### D3. `data-theme` 属性双变体统一声明
43
+
44
+ 所有消费方项目必须在 `<html>` 上声明 `data-theme`:
45
+
46
+ ```html
47
+ <html data-theme="opentrek">
48
+ <!-- 或 "uni-manager" -->
49
+ </html>
50
+ ```
51
+
52
+ - 脚手架自动写入
53
+ - `ui init` CLI 输出提示(AI coding 场景由 AI 添加)
54
+ - 即使 opentrek 的 `overrides.css` 为空也要声明,防御未来升级
55
+
56
+ ### D4. 能力增强不再对齐 antd,由用户定义目标
57
+
58
+ - 废弃"shadcn ∪ antd 并集"策略(旧 ADR 0001)
59
+ - 组件能力需求由用户逐组件提供,以业务场景为导向
60
+ - shadcn 组件作为基线,增强能力按 shadcn 工程风格实现
61
+
62
+ ### D5. TSDoc 为唯一文档手写源
63
+
64
+ 信息流:
65
+
66
+ ```
67
+ TSDoc (唯一手写源)
68
+ ├──→ Storybook autodocs plugin → 组件名、描述、何时使用、API 表
69
+ ├──→ gen:meta 脚本 → meta.md(自动生成,CI 守门)
70
+ └──→ MCP server → 读 meta.md 或直接 parse TSDoc
71
+ ```
72
+
73
+ TSDoc 自定义标签:
74
+
75
+ - `@when` — 何时使用(列表形式)
76
+ - 首段 — 组件中文名 + 描述
77
+
78
+ 开发者只手写两个文件:
79
+
80
+ 1. `<id>.tsx`(含 TSDoc + Props interface JSDoc)
81
+ 2. `<id>.stories.tsx`(仅代码演示 Stories)
82
+
83
+ ### D6. Storybook 页面结构
84
+
85
+ 每个组件的 autodocs 页包含:
86
+
87
+ 1. **组件名 + 中文名**(`meta.title`)
88
+ 2. **描述**(从 TSDoc 首段提取)
89
+ 3. **何时使用**(从 TSDoc `@when` 提取)
90
+ 4. **代码演示**(手写 Stories)
91
+ 5. **API Props 表**(autodocs 从 TypeScript interface + JSDoc 自动生成)
92
+
93
+ ### D7. shadcn v4 工程模式对齐
94
+
95
+ | 特性 | 采用 |
96
+ | ---------------------------------- | ----------------------- |
97
+ | `data-slot` 属性系统 | ✅ 所有组件标记 |
98
+ | React 19 函数组件(无 forwardRef) | ✅ 默认不加,按需后补 |
99
+ | cva(class-variance-authority) | ✅ 有枚举 prop 的组件用 |
100
+ | Tailwind v4 `@theme inline` | ✅ |
101
+ | oklch 或 hex 色值 | 按用户新 token design |
102
+ | `radix-ui` 单包导入 | ✅ |
103
+ | lucide-react 图标 | ✅ |
104
+ | `cn()` = clsx + tailwind-merge | ✅ |
105
+
106
+ ### D8. React 18 兼容
107
+
108
+ - 默认使用 shadcn v4 写法(无 forwardRef)
109
+ - React 18 下 ref 不会转发,绝大多数场景无影响
110
+ - 极少数需要 ref 的组件后续按需单独加 forwardRef
111
+
112
+ ### D9. 旧 ADR 归档
113
+
114
+ 以下 ADR 标记为 `Superseded by 0036`:
115
+
116
+ | ADR | 原决策 | 被取代原因 |
117
+ | ---- | -------------------------- | --------------------------------- |
118
+ | 0001 | 三层对齐(能力/理念/工程) | 不再做 antd 并集 |
119
+ | 0005 | UI 包不分 variant | 现在用 data-theme + overrides.css |
120
+ | 0006 | UI 升级机制无 baseline | 全量重建,旧升级策略不适用 |
121
+ | 0010 | design 默认+变体模型 | 纯变体,无 default 基线 |
122
+ | 0025 | Props 显式声明规范 | TSDoc 新范式取代 |
123
+ | 0026 | 组件级 token alias | overrides.css 取代组件内 token |
124
+ | 0027 | 组件视觉 token 对齐 | 全量重建,旧对齐规则不适用 |
125
+ | 0028 | UI 组件分类 | 新组件清单由用户定义 |
126
+ | 0029 | Input 拆分 | 全量重建,旧拆分决策不适用 |
127
+
128
+ ## Consequences
129
+
130
+ - **Positive**:
131
+ - 与 shadcn 社区完全同步,享受生态红利
132
+ - Token 分层清晰,新增变体仅需两个 CSS 文件
133
+ - 文档单源(TSDoc),消除多源漂移
134
+ - 组件源码精简(shadcn v4 比 v1 并集代码少 60%+)
135
+ - AI 生成/理解成本大幅降低(标准 shadcn 模式)
136
+ - **Negative**:
137
+ - 需要全量重写所有组件(一次性大投入)
138
+ - 旧版本消费方无法平滑升级(breaking change)
139
+ - 放弃 antd 并集意味着部分能力需用户显式提需求
140
+ - **Trade-off**:
141
+ - 用"一次性重建成本"换"长期维护效率 + AI 友好度"
142
+ - 用"用户主动提需求"换"不再盲目追赶 antd"
143
+
144
+ ## Source
145
+
146
+ 2026-06-05 架构分析讨论。基于对 shadcn v4 (radix-nova, shadcn@4.10.0) 源码的深度分析,对比现有 v1 架构的 7 个痛点,做出全量重建决策。
@@ -0,0 +1,426 @@
1
+ # 0037. FilterBar v2 重做:组合式架构 + shadcn 三段式子组件
2
+
3
+ - **Status**: Accepted
4
+ - **Date**: 2026-06-08
5
+ - **Region**: 0100–0999 协议与工具
6
+ - **Related ADR**: 0014(UI/Biz-UI/Templates 三层)、0023(cursor-pointer 显式声明)、0036(UI v2 shadcn 基线重建)
7
+
8
+ ## Context
9
+
10
+ `@teamix-evo/ui` 当前的 [filter-bar/index.tsx](../../packages/ui/src/components/filter-bar/index.tsx) 仅 122 行,本质是一个"折叠 Flex 容器 + 重置按钮",并未承载"筛选栏"语义:
11
+
12
+ | 现状 | 问题 |
13
+ | --------------------------------------------- | --------------------------------------------------------------------------------------- |
14
+ | 不接表单状态(无 form prop / context) | 无法管理多字段、防抖、提交、重置 |
15
+ | 仅一个 `expanded` 布尔切壳,无形态体系 | 截图所示的 inline / panel / 紧凑搜索条 / 纯面板 / 自定义按钮组 5 种业务形态全部无法落地 |
16
+ | `maxRows` 已声明但未实现 | DEVELOPMENT_PLAN §14.3 已挂账技术债 |
17
+ | 仅 `FilterBarItem` 一个无 form 语义的视觉容器 | 与 ui v2 范式(data-slot + 复合子组件)严重脱节 |
18
+
19
+ 参考资料:
20
+
21
+ - 旧实现 `packages/ui/_legacy/components/filter-bar/`(568 行,5 件套子组件 + RHF context + 栅格)— 架构方向正确但未对齐 shadcn v4 范式(\_legacy 归档目录已于 2026-06-10 删除,历史可通过 `git show 8cfeab8cb256:packages/ui/_legacy/components/filter-bar/filter-bar.tsx` 回溯)
22
+ - 业务源码 [teamix-pro/packages/pro/src/form/Filter/](file:///Users/lyca/Documents/workspace/teamix/teamix-pro/packages/pro/src/form/Filter/)(1404 行,Formily/alicloudfe 体系)— 能力齐全但技术栈不可直接搬
23
+ - 业务文档 [teamix-pro/.../docs/filter.md](file:///Users/lyca/Documents/workspace/teamix/teamix-pro/packages/pro/src/form/docs/filter.md):定义了 `mode='inline'|'panel'|'bar'` 三种模式 + 高级筛选 + 异步默认值 + bindUrl + filterCondition 等 14 项能力
24
+ - 5 张业务截图覆盖:单字段并排筛选 / 高级筛选默认收起 / 纯面板模式 / 紧凑搜索条 + 高级筛选 / 自定义按钮组
25
+
26
+ 业界命名扫描:FilterBar(SAP Fiori / Linear)、QueryFilter(antd-pro)、DataTableToolbar(shadcn TanStack Table 示例)、Filters(Notion/Vercel)。**FilterBar 认知度最广**,但子组件命名缺乏行业共识。
27
+
28
+ shadcn v4 三段式范式(Card / Dialog / Sheet / AlertDialog 全用)已是事实标准:`<Root>` + `<RootHeader>` + `<RootContent>` + `<RootFooter>` + `<RootTrigger>`。
29
+
30
+ 不能不做:
31
+
32
+ - ListPage 模板(biz-ui v0.8 主用场)需要稳定 FilterBar 语义
33
+ - DEVELOPMENT_PLAN §14.3 / §14.4 列为硬债待清
34
+ - 当前 122 行版本既"承诺了 maxRows 但未实现",又"占了 FilterBar 命名但未给出筛选语义",必须收敛
35
+
36
+ ## Options Considered
37
+
38
+ | 选项 | 优点 | 缺点 |
39
+ | --------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------ |
40
+ | A. 在现有 122 行基础上增量扩展 | 改动小、API 不破坏 | 当前架构无 form context,每加一项能力都是补丁;过渡期 API 不稳;放大债务 |
41
+ | B. **完全重写 + 组合式 + 三段式子组件**(推荐) | 契合 shadcn v4 范式、子组件可独立组合、API 干净一致、消除债务 | 一次性破坏当前 API(影响面:仅 stories 和已归档的旧 demo) |
42
+ | C. 保留现版本作 `FilterBarSimple`,新做 `FilterBar` | 共存、零破坏 | 两套并存增加 AI 心智负担;命名空间冲突;ADR 0036 全量重建精神不符 |
43
+ | D. 沿用 `mode='inline'\|'panel'\|'bar'` enum 切形态 | 与 antd-pro QueryFilter 直接对齐 | 反 shadcn 组合式理念;mode 分支膨胀;形态变化要改 enum 而非 children |
44
+
45
+ 选 B:与 ADR 0036 的"全量重建 + shadcn v4 范式"一脉相承。
46
+
47
+ ## Decision
48
+
49
+ ### D1. 主组件名保留 `FilterBar`
50
+
51
+ 业界认知度最高,与 ui v2 现有 `Sidebar` / `Menubar` / 未来 `Toolbar` 同一"-Bar"命名系。**不引入** `QueryBar` / `DataFilters` 等新概念。
52
+
53
+ ### D2. 子组件命名采用 shadcn 三段式
54
+
55
+ | 子组件 | 职责 | 对齐范式 |
56
+ | ------------------ | ---------------------------------------------------------- | --------------------------------------- |
57
+ | `FilterBar` | 容器 Root,注入 form context + addonBefore/addonAfter 槽位 | `Card` / `Dialog` Root |
58
+ | `FilterBarHeader` | 顶部行内区(多字段并排,透明背景) | `Card.Header` / `Dialog.Header` |
59
+ | `FilterBarSearch` | 紧凑 key+value 搜索条(`fields` prop 切换搜索字段) | shadcn `Command` 语义近邻 |
60
+ | `FilterBarTrigger` | "高级筛选 ▽" 按钮,自动读 open 状态 | `Collapsible.Trigger` / `Sheet.Trigger` |
61
+ | `FilterBarContent` | 折叠面板(灰底 + 栅格),传入即显示 Trigger | `Collapsible.Content` |
62
+ | `FilterBarFooter` | 重置 + 搜索按钮组(支持 `actions` 自定义) | `Card.Footer` / `Dialog.Footer` |
63
+ | `FilterBarField` | 字段包装(label + control + message + 列宽) | `Form.Field` 语义近邻 |
64
+
65
+ **形态由 children 组合决定,不引入 `mode` enum**:
66
+
67
+ ```tsx
68
+ // 形态 1:inline 单纯(截图 1)
69
+ <FilterBar form={form}>
70
+ <FilterBarHeader>{/* 多字段 */}</FilterBarHeader>
71
+ </FilterBar>
72
+
73
+ // 形态 2:inline + 高级筛选面板(截图 2)
74
+ <FilterBar form={form}>
75
+ <FilterBarHeader>
76
+ {/* 多字段 */}
77
+ <FilterBarTrigger />
78
+ </FilterBarHeader>
79
+ <FilterBarContent columns={3}>
80
+ <FilterBarField name="dateRange" label="起止时间">
81
+ <DateRangePicker />
82
+ </FilterBarField>
83
+ {/* ... */}
84
+ <FilterBarFooter />
85
+ </FilterBarContent>
86
+ </FilterBar>
87
+
88
+ // 形态 3:纯面板(截图 3 上)— 不写 Header
89
+ <FilterBar form={form} defaultOpen>
90
+ <FilterBarTrigger />
91
+ <FilterBarContent columns={3}>
92
+ {/* fields */}
93
+ <FilterBarFooter />
94
+ </FilterBarContent>
95
+ </FilterBar>
96
+
97
+ // 形态 4:紧凑搜索条 + 高级筛选(截图 4/5)
98
+ <FilterBar form={form}>
99
+ <FilterBarHeader>
100
+ <FilterBarSearch
101
+ fields={[
102
+ { name: 'instanceId', label: '实例 ID' },
103
+ { name: 'instanceName', label: '实例名称' },
104
+ ]}
105
+ />
106
+ <FilterBarTrigger />
107
+ </FilterBarHeader>
108
+ <FilterBarContent>{/* ... */}</FilterBarContent>
109
+ </FilterBar>
110
+ ```
111
+
112
+ ### D3. Props 命名对齐 shadcn / Tailwind 通用约定
113
+
114
+ | 决策 prop | 旧/参考来源 | 选定值 | 理由 |
115
+ | ---------- | --------------------------- | ----------------------------------------------------------- | ------------------------------------------ |
116
+ | 默认展开 | `defaultExpanded`(v1) | `defaultOpen` | 对齐 shadcn Collapsible/Sheet/Dialog |
117
+ | 受控展开 | `expanded` | `open` | 同上 |
118
+ | 展开变化 | `onExpandChange` | `onOpenChange` | 同上 |
119
+ | 防抖时间 | `filterDebounce`(pro) | `debounceMs` | 通用度高,与 React 生态 hook 命名一致 |
120
+ | 列数 | `columns`(v1) | `columns` 接受 `number \| { base, sm, md, lg }` | 直接接受响应式对象,对齐 Tailwind 断点别名 |
121
+ | 重置强清 | `forceClear`(pro) | `clearOnReset` | 更语义化 |
122
+ | 自定义按钮 | `buttonGroup` schema(pro) | `actions` ReactNode(在 `<FilterBarFooter actions={...}>`) | 用 React 组合替代 schema |
123
+ | URL 同步 | `bindUrl`(pro) | **不内置**,外置 `useFilterBarUrlSync` hook(未来) | 单一职责,避免组件内置路由依赖 |
124
+
125
+ 事件 prop:`onFilter` / `onReset` / `onChange` / `onInit` / `onOpenChange`,全部基于 RHF `useForm` 实例语义。
126
+
127
+ ### D4. 能力范围(A+B 档位)
128
+
129
+ **v0.x 首版必须实现**:
130
+
131
+ - ✅ 5 种核心形态(inline / inline+panel / 纯面板 / 紧凑搜索条+面板 / 自定义按钮组)
132
+ - ✅ form context(基于 `react-hook-form` + `FormProvider`)
133
+ - ✅ 行内区 onChange 防抖触发 onFilter(`debounceMs` 默认 300)
134
+ - ✅ 面板 open/close(受控 + 非受控)+ Trigger 联动
135
+ - ✅ 栅格(`columns: number | ResponsiveColumns`,5 档断点参考已归档 `_legacy/hooks/use-breakpoint.ts`(git history `8cfeab8cb256`),但**不依赖客户 Tailwind 配置**)
136
+ - ✅ `addonBefore` / `addonAfter` 槽位(截图 2 左 +创建任务 / 右 ⚙️)
137
+ - ✅ `FilterBarFooter` 默认渲染"重置 + 搜索",`actions` prop 可完全替换
138
+ - ✅ `FilterBarField` 替代 FormField + 自带 maxWidth 推断(多栏 400 / 单双栏 600,参 \_legacy 历史 git `8cfeab8cb256`)
139
+ - ✅ `clearOnReset` 强清(对齐 RHF `reset(undefined, { keepDefaultValues: false })`)
140
+ - ✅ `formRef` / `onInit` / `triggerFilter()` / `triggerReset()` / `setAsyncValues()`
141
+
142
+ ### D5. 暂不做(明确 backlog)
143
+
144
+ - ❌ 已选 Tag 标签栏(`getFilterTagDataSource`) — 强依赖 ProField displayValue 协议,shadcn 体系下需先抽 Field meta 协议
145
+ - ❌ `bindUrl` URL 同步 — 拆为独立 hook(未来 ADR)
146
+ - ❌ `filterCondition` 保存搜索条件 — 业务功能,应放 biz-ui 或业务侧
147
+ - ❌ 国际化文案表 — 暂硬编码中文,待 ui v2 i18n 体系成熟统一接入
148
+
149
+ ### D6. 工程模式严格对齐 ADR 0036
150
+
151
+ - 所有子组件函数式(默认无 forwardRef,需要时单独补)
152
+ - `data-slot` 属性:`filter-bar` / `filter-bar-header` / `filter-bar-search` / `filter-bar-trigger` / `filter-bar-content` / `filter-bar-footer` / `filter-bar-field`
153
+ - `cva` 仅在子组件确有视觉变体时引入(如 `FilterBarContent` 的 `compact` / `comfortable` 留给后续)
154
+ - `cn()` + `@/lib/utils` import
155
+ - 内联样式,**不抽 class 常量文件**
156
+ - 复用现有 ui 组件:[Collapsible](../../packages/ui/src/components/collapsible/index.tsx) 做面板、[Button](../../packages/ui/src/components/button/index.tsx) 做按钮、[Select](../../packages/ui/src/components/select/index.tsx) 做搜索条字段切换
157
+ - token 全走语义 utility:`bg-muted/40` / `border-border` / `ring-ring` / `text-muted-foreground`,无颜色字面量
158
+ - TSDoc 单源(`@description` + `@when`),`pnpm gen:meta` 自动生成 meta.md
159
+
160
+ ### D7. Stories 七类法 + 5 个核心 Story
161
+
162
+ `数据录入 · Data Entry/FilterBar 筛选栏`,5 个 Story 一一对应 5 张业务截图:
163
+
164
+ 1. `Inline` — 多字段并排实时筛选(截图 1)
165
+ 2. `WithAdvancedPanel` — 行内 + 默认收起的高级筛选面板(截图 2)
166
+ 3. `PurePanel` — 纯面板模式(截图 3 上半)
167
+ 4. `WithKeySearch` — 紧凑搜索条 + 高级筛选(截图 4 / 5 下半)
168
+ 5. `CustomActions` — 自定义按钮组(截图 5 上半)
169
+
170
+ ### D8. 历史代码处理
171
+
172
+ - 现有 [packages/ui/src/components/filter-bar/](../../packages/ui/src/components/filter-bar/) 完全重写(不保留 122 行旧实现,不做兼容层)
173
+ - `_legacy/components/filter-bar/`(已归档删除,git `8cfeab8cb256`)仅作设计参考,不复制代码
174
+ - DEVELOPMENT_PLAN §14.3(FilterBar `maxRows` 补实现)随本 ADR 落地一并清账:移除 `maxRows`,由 `FilterBarContent` 的 `defaultOpen=false` + `Collapsible` 内置滚动替代
175
+
176
+ ## Consequences
177
+
178
+ - **Positive**:
179
+ - 与 shadcn v4 范式(Card/Dialog/Sheet 三段式)完全统一,AI 生成与人工迁移成本最低
180
+ - 形态由 children 组合决定,未来新增形态(如 `FilterBarStatusFilter` 分面 chip)只需加子组件
181
+ - props 命名对齐 shadcn 通用约定(open/onOpenChange/defaultOpen),跨组件迁移肌肉记忆
182
+ - 一次性清账:FilterBar v0 含糊定义 + maxRows 历史债同时收敛
183
+ - 为 biz-ui ListPage / Templates 提供稳定基座
184
+ - **Negative**:
185
+ - 当前 122 行 `FilterBar` / `FilterBarItem` API 直接 break;但实际消费方仅 stories,影响极小
186
+ - 旧 `FilterBarItem` 名称下线(不再有视觉 Item,由 `FilterBarField` 接管语义)
187
+ - 紧凑搜索条 `FilterBarSearch` 是 v2 新增组件,初期 demo 需要打磨
188
+ - **Trade-off**:
189
+ - 用"一次性 API 重写"换"长期形态可扩展性 + AI 友好"
190
+ - 用"暂时不做 Tag/bindUrl/filterCondition"换"v0 首版聚焦核心 80% 场景"
191
+ - 用"内置 RHF 依赖"换"业务侧零样板代码"(biz-ui 已统一 RHF 栈,不引新依赖)
192
+
193
+ ## Source
194
+
195
+ - 2026-06-08 用户提出 FilterBar 重做需求,附 5 张业务截图与 [teamix-pro/packages/pro/src/form/docs/filter.md](file:///Users/lyca/Documents/workspace/teamix/teamix-pro/packages/pro/src/form/docs/filter.md) 完整能力定义
196
+ - `packages/ui/_legacy/components/filter-bar/filter-bar.tsx` 568 行(已归档删除,git `8cfeab8cb256` 可回溯,架构方向参考)
197
+ - [teamix-pro Filter index.tsx / Layout.tsx / SimpleFilter.tsx / LightFilter.tsx / AdvancedFilter.tsx](file:///Users/lyca/Documents/workspace/teamix/teamix-pro/packages/pro/src/form/Filter/) 1404 行(能力锚点)
198
+ - shadcn v4 [Card](https://ui.shadcn.com/docs/components/card) / [Dialog](https://ui.shadcn.com/docs/components/dialog) / [Sheet](https://ui.shadcn.com/docs/components/sheet) / [Collapsible](https://ui.shadcn.com/docs/components/collapsible) 三段式范式
199
+ - [DEVELOPMENT_PLAN.md §14.3](../../packages/ui/DEVELOPMENT_PLAN.md) FilterBar maxRows 历史债
200
+ - [ADR 0036](./0036-ui-v2-shadcn-baseline-rebuild.md) UI v2 shadcn 基线重建(本 ADR 在其指导下落地)
201
+
202
+ ## v2.1 增补(2026-06-08)· FilterBarField 双形态
203
+
204
+ ### 问题
205
+
206
+ v2 首版 `FilterBarField` 仅提供 `render` prop(函数接受 `field` 后返回 JSX)。这个设计避免了 cloneElement 的 prop 名错配,但在 **Storybook dynamic source(Show code)** 展示时函数体会被序列化为 `() => {}`,导致 demo show code 看不到实际使用的筛选控件(Select / Input 等)。这与仓库 "AI 友好" 原则冲突:AI 抓 demo 主要依赖 show code 信号。
207
+
208
+ ### 决策
209
+
210
+ `FilterBarField` 同时支持两种形态,按优先级使用:
211
+
212
+ 1. **`children` 静态 JSX(首选)** — 推荐与默认写法,AI 友好
213
+
214
+ ```tsx
215
+ <FilterBarField name="status" label="状态">
216
+ <Select>
217
+ <SelectTrigger>
218
+ <SelectValue placeholder="全部" />
219
+ </SelectTrigger>
220
+ <SelectContent>
221
+ <SelectItem value="running">运行中</SelectItem>
222
+ </SelectContent>
223
+ </Select>
224
+ </FilterBarField>
225
+ ```
226
+
227
+ 2. **`render` 函数(逆出舱)** — 适用于适配表不覆盖的自定义控件
228
+ ```tsx
229
+ <FilterBarField
230
+ name="status"
231
+ render={({ field }) => <CustomPicker {...field} />}
232
+ />
233
+ ```
234
+
235
+ ### prop 桥接适配表
236
+
237
+ `children` 模式下,内部用 `useController` 拿到 `field`,然后按子元素身份用 `cloneElement` 注入所需 prop:
238
+
239
+ | 子元素 识别键(`type.displayName \|\| type.name`) | 注入 prop |
240
+ | -------------------------------------------------- | ----------------------------------- |
241
+ | `Checkbox` / `Switch` | `checked` + `onCheckedChange` |
242
+ | `Select` / `RadioGroup` / `Slider` / `ToggleGroup` | `value` + `onValueChange` |
243
+ | `Input` / `Textarea` / `InputNumber` / 其它 | `value` + `onChange`(event-style) |
244
+
245
+ > RHF `field.onChange` 内部会统一提取 `event.target.value`,所以 event-style 与 value-style 可同一 callback 实例适配。
246
+
247
+ ### 不在适配表中的子元素
248
+
249
+ - 仅注入 `value` + `onChange` 默认对,并在开发环境警告:“未识别的受控控件(displayName=X),请改用 `render` prop”
250
+ - 适配表后续可增量扩展(如 DatePicker / Combobox / Cascader),**不制定为封闭表**
251
+
252
+ ### 互斥与优先级
253
+
254
+ - 同时传 `children` 与 `render`:`children` 优先,dev 环境警告可能的误用
255
+ - `children` 必须是单个 React 元素(`React.Children.only`);多子元素场景强制走 `render`
256
+
257
+ ### Trade-off
258
+
259
+ - **增**:~30 行 prop 桥接逻躑 + 6 个子元素识别 key
260
+ - **收**:demo show code 直接展示 `<Select>` / `<Input>` 真实 JSX;business 写法更声明式;AI 抓的 meta + demo 信号不再丢失控件类型
261
+ - **负**:不在适配表中的自定义控件上需要识别的人工介入(退化到 render prop)— 可接受
262
+ - **不破坏性**:`render` prop 作为 v2 首版 API 保留,仅从必填变可选
263
+
264
+ ### 升级路径
265
+
266
+ - @teamix-evo/ui: minor(API 拓展,向后兼容)
267
+ - 现有 `render` 写法零修改可运行
268
+ - 推荐逐步迁到 `children` 写法以获得 demo show code 可视性
269
+
270
+ ## v2.2 增补(2026-06-08)· FilterBarSearch 三段化 + Footer→Actions 收敛
271
+
272
+ ### 触发动因
273
+
274
+ v2.1 落地后 review 发现三处与「组合式架构」主线不一致的设计点,本轮统一收敛:
275
+
276
+ 1. **FilterBarSearch 用 `fields` 配置式**:与 FilterBarField 双形态(首选 children)API 风格不一致;不支持声明式扩展(自定义按钮图标 / 替换 Key 选择器)
277
+ 2. **FilterBarFooter 命名偏窄**:FilterBar 此容器只放按钮组(重置/搜索/自定义动作),语义是「操作区」而非 shadcn 通用的「页脚任意内容」。生态对齐应改 `Actions`
278
+ 3. **FilterBarFooter 用 `actions` prop 配置式**:与 shadcn DialogFooter / CardFooter / SheetFooter 全部用 children 模式不一致,AI 生成易困惑
279
+
280
+ ### 决策
281
+
282
+ #### D1. FilterBarSearch 拆三段子组件
283
+
284
+ 废弃 `fields` prop,改为三段 children:
285
+
286
+ ```tsx
287
+ <FilterBarSearch>
288
+ <FilterBarSearchKey
289
+ options={[
290
+ { name: 'instanceId', label: '实例 ID' },
291
+ { name: 'instanceName', label: '实例名称' },
292
+ ]}
293
+ />
294
+ <FilterBarSearchValue />
295
+ <FilterBarSearchAction />
296
+ </FilterBarSearch>
297
+ ```
298
+
299
+ | 子组件 | 职责 |
300
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
301
+ | `FilterBarSearch` | 紧凑容器(`h-8` + 边框 + focus-within ring),提供 `FilterBarSearchContext`(active 字段 / options / exclusive) |
302
+ | `FilterBarSearchKey` | 字段切换 Select;`options: { name, label, placeholder? }[]` 声明可切字段 |
303
+ | `FilterBarSearchValue` | 跟随 active 字段的 Input;自动取 `active.placeholder` 或「请输入{label}」 |
304
+ | `FilterBarSearchAction` | 默认 🔍 图标按钮 + `triggerFilter`;children 完全替换图标内容 |
305
+
306
+ 实现要点:Key 的 `options` 通过 useEffect 注册到 SearchContext;Value 从 ctx 拿 active option 的 name+label+placeholder;三段共用 `useFilterBar` 拿 `form` / `triggerFilter`。
307
+
308
+ #### D2. FilterBarFooter 重命名为 FilterBarActions
309
+
310
+ `data-slot` 同步改为 `filter-bar-actions`。`FilterBarFooter` 命名移除(v2 未发版,无破坏负担)。理由:
311
+
312
+ - shadcn 生态:DialogFooter / CardFooter / SheetFooter 是「任意底部内容」语义
313
+ - FilterBar 此容器只放按钮组(业务语义 = 操作区)
314
+ - antd / TeamixPro 业务侧肌肉记忆全部叫 `Actions` / `FilterActions`
315
+
316
+ #### D3. FilterBarActions 改 children 模式
317
+
318
+ ```tsx
319
+ // 默认(不写 children)
320
+ <FilterBarActions /> // → 渲染默认「重置 + 搜索」
321
+
322
+ // 自定义(与 DialogFooter / CardFooter 一致)
323
+ <FilterBarActions>
324
+ <Button variant="ghost">清空</Button>
325
+ <Button variant="outline">保存条件</Button>
326
+ <Button>查询</Button>
327
+ </FilterBarActions>
328
+ ```
329
+
330
+ 删除 `actions` / `showReset` / `showSubmit` / `resetText` / `submitText` 五个 prop —— children 完全替换语义可直接覆盖所有定制需求。
331
+
332
+ #### D4. FilterBarActions 在 Content 内保留 col-span-full + justify-end
333
+
334
+ | 选项 | 行为 | 选择 |
335
+ | --------------------------------------- | --------------------------------------------------------------------- | ------- |
336
+ | α. 当前:`col-span-full + justify-end` | 独占一行右对齐 | ✅ 选定 |
337
+ | β. `grid auto-flow` 自然填充 | Field 不满栅格时同行右对齐,但独占一行时变左对齐 — **破坏可预期视觉** | 否 |
338
+ | γ. React.Children 数 Field 数量条件判断 | 智能但响应式 columns(`{ base, md }`)下退化;额外运行时复杂度 | 否 |
339
+
340
+ 理由:方案 α 100% 视觉可预期 + 无运行时开销 + 响应式断点下仍稳定;「Field 不满栅格」长尾场景业务侧可改 columns 自行填满。
341
+
342
+ ### 受影响 API(v2 未发版,不计 breaking)
343
+
344
+ | 旧 API | 新 API |
345
+ | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
346
+ | `<FilterBarSearch fields={[...]} />` | `<FilterBarSearch><FilterBarSearchKey options={[...]} /><FilterBarSearchValue /><FilterBarSearchAction /></FilterBarSearch>` |
347
+ | `<FilterBarFooter />` | `<FilterBarActions />` |
348
+ | `<FilterBarFooter actions={...} />` | `<FilterBarActions>...</FilterBarActions>` |
349
+ | `<FilterBarFooter showReset={false} />` | `<FilterBarActions><Button>查询</Button></FilterBarActions>` |
350
+ | `FilterBarSearchField` 类型 | `FilterBarSearchOption` 类型 |
351
+
352
+ ### Trade-off
353
+
354
+ - **增**:3 个 Search 子组件 + 1 个 SearchContext(~80 行);Actions 命名变更影响所有 demo 与 changeset 升级指引
355
+ - **收**:完成「形态由 children 决定」的最后一公里收敛(除 FilterBar Root 的 Provider props 外,所有形态决策都在 children);与 shadcn 生态肌肉记忆 100% 对齐
356
+ - **不引入**:mode enum / 配置式 fields / 配置式 actions 三种形式
357
+
358
+ ## v2.3 增补(2026-06-08)· FilterBarField 四 layout 模式
359
+
360
+ ### 触发动因
361
+
362
+ v2.2 落地后业务对照原型截图发现 Header 内字段视觉与 FilterBarSearch 容器不一致:
363
+
364
+ - v2.0 实现的 Header 字段是「label 左外 + 控件横向(控件自带边框)」—— 即 inline 风格
365
+ - 业务原型是「label 嵌入外框内左侧(控件去边框)」—— 即 outline 风格,与 FilterBarSearch 容器同高 + 同圆角
366
+
367
+ 同时 Content 内默认 horizontal(label 左 + 控件右)对齐业务成熟表单习惯,需要长表单形态时可显式切 vertical。
368
+
369
+ ### 决策
370
+
371
+ `FilterBarField` 新增 `layout` prop,4 个枚举值:
372
+
373
+ | 值 | 视觉 | 适用 section |
374
+ | ------------ | ----------------------------------------- | ------------------- |
375
+ | `inline` | label 左外 + 控件横向(控件自带边框) | Header |
376
+ | `outline` | label 嵌入外框内左侧(控件去边框) | Header(**默认**) |
377
+ | `vertical` | label 上 + 控件下(控件自带边框) | Content |
378
+ | `horizontal` | label 左外 + 控件右(控件占栕格列剩余宽) | Content(**默认**) |
379
+
380
+ ### 默认推断
381
+
382
+ - 不传 layout 时:`section === 'header'` → `outline`;`section === 'content'` → `vertical`
383
+ - 用户可显式传 `layout="..."` 覆盖
384
+
385
+ ### outline / horizontal 控件去边框策略
386
+
387
+ outline 容器自带边框,子控件必须去除自身边框/背景/focus ring 以避免双边框。采用 Tailwind v4 子元素选择器在 outline 容器的 className 中声明,**不动 cloneElement**(与 RHF 桥接逻辑分离):
388
+
389
+ ```
390
+ [&_[data-slot=select-trigger]]:border-0
391
+ [&_[data-slot=select-trigger]]:bg-transparent
392
+ [&_[data-slot=select-trigger]]:shadow-none
393
+ [&_[data-slot=select-trigger]]:h-full
394
+ [&_[data-slot=select-trigger]]:focus-visible:ring-0
395
+ [&_[data-slot=input]]:border-0
396
+ [&_[data-slot=input]]:bg-transparent
397
+ [&_[data-slot=input]]:shadow-none
398
+ [&_[data-slot=input]]:h-full
399
+ [&_[data-slot=input]]:focus-visible:ring-0
400
+ [&_[data-slot=textarea]]:border-0
401
+ [&_[data-slot=textarea]]:bg-transparent
402
+ [&_[data-slot=textarea]]:shadow-none
403
+ [&_[data-slot=input-number]]:border-0
404
+ [&_[data-slot=input-number]]:bg-transparent
405
+ [&_[data-slot=input-number]]:shadow-none
406
+ [&_[data-slot=combobox-trigger]]:border-0
407
+ [&_[data-slot=combobox-trigger]]:bg-transparent
408
+ [&_[data-slot=combobox-trigger]]:shadow-none
409
+ ```
410
+
411
+ 覆盖控件:Input / Textarea / Select / InputNumber / Combobox。Checkbox / Switch / RadioGroup / Slider 不适用 outline(语义不匹配,仅限 Input 类控件),这些控件请用 inline / vertical / horizontal。
412
+
413
+ ### 容器与 label 样式表
414
+
415
+ | layout | 容器 className | label className |
416
+ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
417
+ | `inline` | `flex items-center gap-2` | `text-xs text-muted-foreground shrink-0` |
418
+ | `outline` | `flex h-8 items-center overflow-hidden rounded-md border border-input bg-card focus-within:border-ring focus-within:ring-1 focus-within:ring-ring` + outline 子选择器集 | `flex h-full shrink-0 items-center pl-3 pr-2 text-xs text-muted-foreground`(不画 border-r,只靠 padding) |
419
+ | `vertical` | `flex min-w-0 flex-col gap-1.5` | `text-xs font-medium text-foreground` |
420
+ | `horizontal` | `flex items-center gap-3` | `text-xs text-muted-foreground shrink-0` |
421
+
422
+ ### Trade-off
423
+
424
+ - **增**:layout prop 与 4 分支渲染(~50 行);outline 子选择器 className 集(~18 个 utility)
425
+ - **收**:Header 默认与业务原型、FilterBarSearch 容器视觉 100% 对齐(同 h-8 + 同 rounded-md);4 种形态全可装配;与 RHF 桥接逻辑完全解耦
426
+ - **不破坏**:v2 未发版,不计 breaking;v2.0〔2.2 的 stories 默认行为发生变化(Header 字段从 inline → outline)是期望内
@@ -0,0 +1,99 @@
1
+ # 0038. create 工程根落地 AGENTS.md 作为 skill 触发兜底
2
+
3
+ - **Status**: Accepted
4
+ - **Date**: 2026-06-11
5
+ - **Region**: 0100–0999 协议与工具
6
+ - **Related ADR**: [0015](0015-skill-description-trigger-contract.md)(skill description trigger 契约)、[0020](0020-design-to-tokens-skill-fusion.md)(废止"承载知识"的 AGENTS.md)、[0033](0033-entry-skill-global-only-scope.md)(entry skill 全局 scope)
7
+
8
+ ## Context
9
+
10
+ [ADR 0015](0015-skill-description-trigger-contract.md) 把 skill 触发依据收敛到 SKILL.md frontmatter 的 `description`(TRIGGER / SKIP / Coordinates 三段),让"何时进上下文"成为协议字段。但 description-based 触发存在固有的**欠触发风险**:
11
+
12
+ - Qoder / Claude Code / Cursor 各自对 description 的扫描时机、token 预算、缓存策略不同,跨 IDE 命中率不一致
13
+ - 用户 prompt 的措辞稍偏("调一下这个页面" / "改一下这个" / "顺便写个" 等模糊措辞)就可能命中阈值之下,design / code skill 静默不上
14
+ - 早期对话先聊需求再写代码时,trigger 关键词可能根本没出现;等真要写代码时上下文已长,skill 不一定还在窗口里
15
+
16
+ 业界两种成熟兜底方案:
17
+
18
+ - **OpenAI Codex / Cursor / Sourcegraph 等正在收敛 `AGENTS.md`** —— 项目根的 AGENTS.md 被 IDE 默认扫描进上下文,用作"无论用户说什么,AI 在这个工程里都先看一眼"的元入口
19
+ - **Claude Code 同时支持 `CLAUDE.md` 与 `AGENTS.md`** —— 二者机制相同,AGENTS.md 是跨 IDE 收敛后的事实标准
20
+
21
+ [ADR 0020](0020-design-to-tokens-skill-fusion.md) 已明确**禁止**在装机产物里落 AGENTS.md,但其禁止的对象是"承载设计纲领 / 品牌 / patterns 的 AGENTS.md"——理由是双源失同步、装机产物臃肿、AI 单次读 skill 即可获完整上下文。**本 ADR 启用的是另一类性质完全不同的 AGENTS.md**:只列已装 skill 的触发摘要,不复制 skill 正文,不承载任何规则本身。
22
+
23
+ 不能不做:
24
+
25
+ - create-teamix-evo 落地的工程默认装两个 variant skill(design + code),但用户实际编码时命中率不可观测
26
+ - 业务侧反馈:"AI 经常不主动读 skill,要手动 @ 一下才行"——正是 description 欠触发的症状
27
+ - 没有兜底机制时,skill 投入越多边际收益越低(写得再好不触发等于零)
28
+
29
+ ## Options Considered
30
+
31
+ | 选项 | 优点 | 缺点 |
32
+ | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
33
+ | A. 仅在 SKILL.md 的 description 里堆更多 trigger 关键词 | 不破坏 ADR 0020 字面意思 | 治标不治本;description 已有 ~400 字符压力(ADR 0015);跨 IDE 扫描差异仍在;过触发风险反而上升 |
34
+ | B. 落 CLAUDE.md + .qoder/AGENTS.md(IDE 各自子目录) | 各 IDE 各取所需 | 工程根失去通用入口;多文件需同步;AGENTS.md 收敛事实标准被绕开 |
35
+ | **C. 工程根落 AGENTS.md,内容动态从已装 SKILL.md frontmatter 抽取(选定)** | 真单源(skill 改 description 自动生效);与业界标准对齐;不重复 skill 正文,不违反 ADR 0020 实质边界 | 与 ADR 0020 字面冲突,需本 ADR 显式划清"指路型 ≠ 知识型"边界 |
36
+
37
+ ## Decision
38
+
39
+ ### 1. 性质定位:指路兜底,非知识承载
40
+
41
+ - 工程根 `AGENTS.md` **仅承载已装 skill 的触发摘要**,不复制任何 skill 正文
42
+ - 内容上限:≤ 50 行;每个 skill ≤ 10 行(一句能力声明 + TRIGGER + SKIP + 文件位置)
43
+ - 规则、生成流程、boundaries、checklist 等**全部仍在 skill 内**,AGENTS.md 只是"看到这些场景请先去读对应 skill"的索引
44
+
45
+ ### 2. 与 ADR 0020 的边界
46
+
47
+ | 维度 | ADR 0020 禁止的 AGENTS.md | 本 ADR 启用的 AGENTS.md |
48
+ | ---------- | --------------------------------------- | ---------------------------------------------- |
49
+ | 内容 | 设计纲领 / 品牌 / patterns / philosophy | 已装 skill 的触发摘要(TRIGGER / SKIP) |
50
+ | 来源 | 模板手写 | 运行时从 SKILL.md frontmatter description 解析 |
51
+ | 单源关系 | 与 skill 双源失同步 | 与 skill description 单源(动态生成) |
52
+ | 体积 | 数百行 | ≤ 50 行 |
53
+ | 失同步代价 | skill 改了,AGENTS.md 没改 → 规则冲突 | 重新生成即对齐,无人工双写 |
54
+
55
+ ADR 0020 §1 / §6 / §7 的废止结论**不被本 ADR 覆盖**——设计纲领 / patterns / brand 仍只在 skill 中维护。
56
+
57
+ ### 3. 内容范围
58
+
59
+ - **包含**:装在工程级(scope: project)的 variant skill —— `teamix-evo-design-<variant>`、`teamix-evo-code-<variant>`
60
+ - **不包含**:`teamix-evo-manage` —— 按 [ADR 0033](0033-entry-skill-global-only-scope.md),entry skill 是全局 scope 由用户独立装,不进工程级触发兜底
61
+ - 未来新增的工程级 skill 自动加入(generator 按 `.teamix-evo/skills/` 目录扫描)
62
+
63
+ ### 4. 状态:regenerable
64
+
65
+ - 同 `.teamix-evo/manifest.json`,重跑 `npm create teamix-evo` 或 `teamix-evo skills add` 时刷新
66
+ - 用户的工程自定义内容**不写入此文件**——AGENTS.md 在本 ADR 下是"machine-owned"
67
+
68
+ ### 5. 文件位置:项目根 `AGENTS.md`
69
+
70
+ - 不落 `CLAUDE.md`、`.cursor/rules/`、`.qoder/AGENTS.md` 等 IDE 专有路径
71
+ - 业界正在收敛 AGENTS.md 为跨 IDE 事实标准;Claude Code 已支持 AGENTS.md,单文件即可满足主流 IDE
72
+ - 如未来某 IDE 强制要求专有路径,再起独立 ADR
73
+
74
+ ### 6. 落地范围(本期)
75
+
76
+ - create-teamix-evo orchestrator 在 skills add 之后插入 `generateAgentsMd` 步骤
77
+ - `teamix-evo skills add` CLI 主动重写 AGENTS.md(提到 core API 层)暂不在本期;本期只在 create 链路落,待 v0.7 跟随 skills CLI 演进同步扩展
78
+
79
+ ## Consequences
80
+
81
+ - **Positive**:
82
+ - 欠触发兜底:IDE 默认扫工程根 AGENTS.md,用户 prompt 模糊时 skill 触发条件已被预热进上下文
83
+ - 真单源:内容从 SKILL.md frontmatter 抽取,skill 改 description 重新生成即对齐,无双写
84
+ - 跨 IDE 一致:AGENTS.md 是 OpenAI / Anthropic / Cursor / Qoder 等正在收敛的事实标准
85
+ - 与 ADR 0020 边界清晰:本 ADR 启用"指路型",0020 仍禁止"知识型",两者并存不冲突
86
+ - **Negative**:
87
+ - 工程根多一个文件(≤ 50 行,可接受)
88
+ - frontmatter 解析逻辑在 create 包内手写(~30 行简易 YAML 提取,未引入 gray-matter 依赖)
89
+ - 未来 SKILL.md frontmatter 结构变化时 generator 需同步更新(已有 ADR 0015 约束 description 三段结构,变化频率低)
90
+ - **Trade-off**:
91
+ - 用"工程根多一个 50 行的 regenerable 文件 + ADR 划边界成本"换"description 欠触发风险大幅缓解 + 跨 IDE 命中可观测"
92
+ - 放弃"装机产物绝对干净"的极简主义,换"AI 触发可靠性"
93
+
94
+ ## Source
95
+
96
+ - 2026-06-11 用户与 AI 的设计讨论 —— 担忧用户 prompt 措辞偏移导致 design / code skill 欠触发,提议在 create 落地时加 AGENTS.md 引导
97
+ - [ADR 0015](0015-skill-description-trigger-contract.md):description 三段契约(TRIGGER / SKIP / Coordinates)
98
+ - [ADR 0020](0020-design-to-tokens-skill-fusion.md):废止"承载知识"的 AGENTS.md(本 ADR 划清边界,不覆盖 0020)
99
+ - [ADR 0033](0033-entry-skill-global-only-scope.md):entry skill 全局 scope,不进工程级触发兜底
@@ -0,0 +1,104 @@
1
+ # 0040. 组件源码层升级流程(ui / biz-ui staging-driven upgrade)
2
+
3
+ - **Status**: Accepted
4
+ - **Date**: 2026-06-11
5
+ - **Region**: 0100–0999 协议与工具
6
+ - **Related ADR**: 0014, 0019, 0036
7
+
8
+ ## Context
9
+
10
+ ADR 0019 D7 落地了 tokens / skills 的升级链路,但显式注释中标注 `ui` 不进入 `runProjectUpdate` orchestrator —
11
+ `packages/cli/src/core/project-update.ts` L22-L25 写道:
12
+
13
+ > `ui` is intentionally NOT updated by this orchestrator — UI components are frozen (ADR 0019)…
14
+
15
+ ADR 0006(UI 升级无 baseline)已被 ADR 0036 supersede,但 0036 只重建了 ui 基线本身,没给出"装机后如何升级"的路径。
16
+ 结果是:
17
+
18
+ 1. 用户装了 `@teamix-evo/ui` v0.7 的 button.tsx 之后,新版 v0.8 改了 cva variants —— CLI 没法引导他升
19
+ 2. 用户从 shadcn 原生项目接入 teamix-evo —— 检测到 `src/components/ui/` 但缺乏迁移路径
20
+ 3. biz-ui 同上,且多了变体维度
21
+
22
+ 约束:
23
+
24
+ - **frozen 边界不可破**:CLI 永不直接覆盖 `src/components/ui/**`([ADR 0019 §D4](0019-project-upgrade-flow.md))
25
+ - **目标用户是小白**:只能跟 AI 对话操作,AI 必须能在 1-2 句话说清"哪些组件要升、风险多大"
26
+ - **AI token 预算有限**:不能让 AI 现读全量源码做 diff
27
+ - 装机时 [ui-installer.ts](../../packages/cli/src/core/ui-installer.ts) 已经把"客户端 alias rewrite 后的 hash"
28
+ 存进 `.teamix-evo/manifest.json` 的 `installed.resources[i].hash`,可作为升级基线
29
+
30
+ ## Options Considered
31
+
32
+ | 选项 | 优点 | 缺点 |
33
+ | ------------------------------------------------------ | ------------------------------------ | -------------------------------------------------------------------------------- |
34
+ | A. registry 加 component 级 hash + version | CLI 不用读 source 也能判断"远端变了" | 装机时 CLI 必读 source(要做 import rewrite),加 hash 收益边际;schema 改动放大 |
35
+ | B. 不改 schema,CLI 现场算 latest hash 跟 installed 比 | 无 schema 改动;逻辑直白 | 每次 update 都要读全量 source(已经必读,无额外成本) |
36
+ | C. 全量源码丢给 AI 自己 diff | 零 CLI 工程量 | AI token 暴增;quest 节奏卡顿;判断不一致 |
37
+
38
+ ## Decision
39
+
40
+ 新增"组件源码层升级"闭环,由 CLI 产 staging、skill 引导落盘,分 6 段决策:
41
+
42
+ 1. **D1 流派识别(installed manifest 真源)**:以 `.teamix-evo/manifest.json` 为强信号源,按"有无 ui 包记录 ×
43
+ 有无 components.json × 有无未登记 ui 文件"四档判定 `teamix-evo` / `mixed` / `shadcn-native` / `custom-only`,
44
+ 不靠 AST 启发式扫描。
45
+
46
+ 2. **D2 基线对比策略**:复用 `installed.resources[i].hash`(pre-transform 后)。CLI 升级时把远端 latest source
47
+ 按客户当前 `aliases` 做 `rewriteImports`、再 `computeHash`,与 installed 侧 hash 对比 —— 一致即 unchanged,
48
+ 不一致即变更。**registry schema 不动**(采纳选项 B)。
49
+
50
+ 3. **D3 risk-level 六档**:unchanged / upgradable-low / upgradable-medium / risky / breaking / foreign。CLI 用
51
+ regex 启发(export 增删、cva variants 增删)打分,AI 二次确认。AST 级判定推后,当前规模够用。
52
+
53
+ 4. **D4 frozen 边界**:CLI 只产 staging 物料 + 元 manifest,**永不写** `src/components/ui/**`、
54
+ `src/components/biz-ui/**`。`teamix-evo ui upgrade --apply` 输出错误并指引用户走 skill。
55
+
56
+ 5. **D5 命令面(双入口)**:
57
+
58
+ - `teamix-evo update` orchestrator 加 `ui` / `biz-ui` step(默认 dry-run-only,全量 staging)
59
+ - 独立子命令 `teamix-evo ui upgrade [id]` / `teamix-evo biz-ui upgrade [id]`(单组件 staging)
60
+
61
+ 6. **D6 skill 接管语义层**:`teamix-evo-upgrade` skill 加 "Component Source Upgrade" 章节,按 risk 分批引导:
62
+ unchanged 跳过 / upgradable-low 批量 confirm / medium 单组件 confirm / risky+breaking 必逐个对话。
63
+ `teamix-evo-manage` 命令表加 ui/biz-ui upgrade 入口 + 新场景 `ui-source-upgrade`。
64
+
65
+ Staging 目录结构:
66
+
67
+ ```
68
+ .teamix-evo/.upgrade-staging/<category>-<fs-iso-ts>/
69
+ ├── meta.json # UpgradeStagingManifest(schemaVersion=1)
70
+ ├── <id>/
71
+ │ ├── current.tsx # 从 installed.target 复制
72
+ │ └── incoming.tsx # 远端 source + alias rewrite
73
+ └── ...
74
+ ```
75
+
76
+ > v1 不预生成 `diff.unified.patch`——`UpgradeStagingDiffSchema.diffRelPath` 保留为可选字段供后续 v2 引入;v1 由 skill 直接对 `current.tsx` 与 `incoming.tsx` diff。
77
+
78
+ 新增 schema:`UpgradeStagingManifestSchema` 落到 `@teamix-evo/registry`,被 CLI / skill 共用。
79
+
80
+ ## Consequences
81
+
82
+ - **Positive**:
83
+
84
+ - 升级闭环完整:用户能用 `teamix-evo ui upgrade` + skill 引导走完版本演进
85
+ - 守住 frozen:CLI 物料归 CLI,业务代码归用户 + AI,边界清晰
86
+ - quest 友好:AI 拿到的是已分级的 manifest,不需现读源码
87
+ - shadcn-native 项目有了迁移入口(lineage 报告 + skill 引导,而非自动覆盖)
88
+
89
+ - **Negative**:
90
+
91
+ - `.teamix-evo/.upgrade-staging/` 会占磁盘(每次 update 一份,需要 skill 主动归档到 `.processed/`)
92
+ - regex risk 启发有误判风险(cva 解析、export 检测都不严格)→ AI 兜底 + 后续 AST 升级
93
+ - biz-ui 多 variant 维度,staging 一次只覆盖一个 variant(用户切 variant 时另起 staging)
94
+
95
+ - **Trade-off**:
96
+ - 选 B 不改 registry schema:节省了协议工程量,代价是每次 update 必读 latest source(其实本来就要读)
97
+ - 选 dry-run 而非 `--apply`:守住边界,代价是必须依赖 skill 才能闭环(不能裸命令完成升级)
98
+
99
+ ## Source
100
+
101
+ - 用户对话 2026-06-11:将 `teamix-evo-manage` 闭环扩展到 ui / biz-ui 升级
102
+ - ADR 0019 D7 留白
103
+ - ADR 0036(ui v2 baseline 重建后无升级路径)
104
+ - `packages/cli/src/core/project-update.ts` L22-L25(既有"ui not updated"注释将被本 ADR 推翻)
@@ -25,16 +25,16 @@ ADR 按编号区段对应 [PLAN §12](../../PLAN.md#12-五层模型驱动的演
25
25
 
26
26
  | # | 标题 | 状态 | 日期 |
27
27
  | ---- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ---------- |
28
- | 0001 | [三层对齐(能力/理念/工程)](0001-three-layer-alignment.md) | Accepted | 2026-05-15 |
28
+ | 0001 | [三层对齐(能力/理念/工程)](0001-three-layer-alignment.md) | Superseded by 0036 | 2026-05-15 |
29
29
  | 0002 | [包命名方案](0002-package-naming.md) | Accepted | 2026-05-13 |
30
30
  | 0003 | [资源升级三态语义](0003-update-strategy-tri-state.md) | Accepted | 2026-05-13 |
31
31
  | 0004 | [CLI 命令结构](0004-cli-command-structure.md) | Accepted | 2026-05-13 |
32
- | 0005 | [UI 包不分 variant](0005-ui-no-variant.md) | Accepted | 2026-05-14 |
33
- | 0006 | [UI 升级机制无 baseline](0006-ui-upgrade-no-baseline.md) | Accepted | 2026-05-14 |
32
+ | 0005 | [UI 包不分 variant](0005-ui-no-variant.md) | Superseded by 0036 | 2026-05-14 |
33
+ | 0006 | [UI 升级机制无 baseline](0006-ui-upgrade-no-baseline.md) | Superseded by 0036 | 2026-05-14 |
34
34
  | 0007 | [治理文档放根目录,与 packages/docs/ 分离](0007-governance-docs-at-root.md) | Accepted | 2026-05-17 |
35
35
  | 0008 | [ESLint 视觉规则暂为 warn 级,等待 design 补 token](0008-eslint-visual-rules-warn-baseline.md) | Accepted | 2026-05-17 |
36
36
  | 0009 | [registry-mcp 作为 AI 协议层的第一个 MCP server](0009-registry-mcp-protocol-layer.md) | Superseded in part by 0011 | 2026-05-17 |
37
- | 0010 | [design 默认+变体模型(default + variants/ + extends,文件级覆盖)](0010-design-default-and-variants.md) | Proposed | 2026-05-18 |
37
+ | 0010 | [design 默认+变体模型(default + variants/ + extends,文件级覆盖)](0010-design-default-and-variants.md) | Superseded by 0036 | 2026-05-18 |
38
38
  | 0011 | [MCP 单包单 bin 多 group + registry-mcp 改名 mcp](0011-mcp-single-package-multi-group.md) | Proposed | 2026-05-18 |
39
39
  | 0012 | [ESLint/Stylelint 双包共享 lint-core 内核](0012-lint-shared-core.md) | Proposed | 2026-05-18 |
40
40
  | 0013 | [Skills source-mirror 模型(.teamix-evo/skills/ 为源)](0013-skills-source-mirror.md) | Proposed | 2026-05-18 |
@@ -42,9 +42,17 @@ ADR 按编号区段对应 [PLAN §12](../../PLAN.md#12-五层模型驱动的演
42
42
  | 0019 | [已有工程升级 Teamix Evo 流程(语义合并 / 变体迁移 / cva codemod)](0019-project-upgrade-flow.md) | Proposed | 2026-05-21 |
43
43
  | 0021 | [语义色 API 统一治理(`tone`/`status`/`variant` 三分 + 字面值对齐 token)](0021-semantic-color-api-unification.md) | Accepted | 2026-05-29 |
44
44
  | 0022 | [preferences.css 边界约束(仅装机偏好,禁止组件级 utility / token alias)](0022-preferences-css-boundary.md) | Accepted | 2026-05-31 |
45
- | 0029 | [Input 拆分 + 移除 prefix/suffix/addon 快捷 prop + AutoComplete 内核同源化](0029-input-split-and-prefix-suffix-removal.md) | Accepted | 2026-06-02 |
45
+ | 0025 | [组件 Props 显式声明规范](0025-component-props-explicit-declaration.md) | Superseded by 0036 | 2026-06-01 |
46
+ | 0026 | [组件级 token 别名创建准则](0026-component-level-token-alias.md) | Superseded by 0036 | 2026-06-02 |
47
+ | 0027 | [组件视觉属性全轴对齐设计系统基线](0027-component-visual-token-alignment.md) | Superseded by 0036 | 2026-06-02 |
48
+ | 0028 | [UI 组件分类对齐 Ant Design 5.x](0028-ui-component-categorization.md) | Superseded by 0036 | 2026-06-02 |
49
+ | 0029 | [Input 拆分 + 移除 prefix/suffix/addon 快捷 prop + AutoComplete 内核同源化](0029-input-split-and-prefix-suffix-removal.md) | Superseded by 0036 | 2026-06-02 |
46
50
  | 0030 | [uni-manager 变体 design + code skill 落地 + 通用规则反哺 opentrek](0030-skill-uni-manager-uplift.md) | Accepted | 2026-06-02 |
47
51
  | 0031 | [AI Skill 链路解耦 `@teamix-evo/templates` 包(patterns/ 单一默认来源)](0031-skill-templates-decoupling.md) | Accepted | 2026-06-02 |
52
+ | 0036 | [UI 组件库 v2:以 shadcn v4 为基线全量重建](0036-ui-v2-shadcn-baseline-rebuild.md) | Accepted | 2026-06-05 |
53
+ | 0037 | [FilterBar v2 重做:组合式架构 + shadcn 三段式子组件](0037-filter-bar-composable-architecture.md) | Accepted | 2026-06-08 |
54
+ | 0038 | [create 工程根落地 AGENTS.md 作为 skill 触发兜底](0038-create-agents-md-skill-trigger-fallback.md) | Accepted | 2026-06-11 |
55
+ | 0040 | [组件源码层升级流程(ui / biz-ui staging-driven upgrade)](0040-component-source-layer-upgrade-flow.md) | Accepted | 2026-06-11 |
48
56
 
49
57
  ## 写新 ADR 的流程
50
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamix-evo/mcp",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Model Context Protocol server for teamix-evo. Single bin / single process / multiple tool groups (registry now; design / adr / scenario coming v0.6-v0.8). Renamed from @teamix-evo/registry-mcp per ADR 0011.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "@modelcontextprotocol/sdk": "^1.29.0",
23
23
  "zod": "^3.23.0",
24
- "@teamix-evo/registry": "0.6.0"
24
+ "@teamix-evo/registry": "0.8.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/node": "^20.0.0",