@teamix-evo/mcp 0.3.0 → 0.4.2

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.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +225 -178
  3. package/dist/cli.js.map +1 -1
  4. package/dist/data/adr/0001-three-layer-alignment.md +54 -0
  5. package/dist/data/adr/0002-package-naming.md +50 -0
  6. package/dist/data/adr/0003-update-strategy-tri-state.md +62 -0
  7. package/dist/data/adr/0004-cli-command-structure.md +61 -0
  8. package/dist/data/adr/0005-ui-no-variant.md +67 -0
  9. package/dist/data/adr/0006-ui-upgrade-no-baseline.md +67 -0
  10. package/dist/data/adr/0007-governance-docs-at-root.md +62 -0
  11. package/dist/data/adr/0008-eslint-visual-rules-warn-baseline.md +110 -0
  12. package/dist/data/adr/0009-registry-mcp-protocol-layer.md +87 -0
  13. package/dist/data/adr/0010-design-default-and-variants.md +319 -0
  14. package/dist/data/adr/0011-mcp-single-package-multi-group.md +169 -0
  15. package/dist/data/adr/0012-lint-shared-core.md +215 -0
  16. package/dist/data/adr/0013-skills-source-mirror.md +154 -0
  17. package/dist/data/adr/0014-ui-biz-ui-templates-tier.md +274 -0
  18. package/dist/data/adr/0015-skill-description-trigger-contract.md +122 -0
  19. package/dist/data/adr/0016-design-md-brand-charter.md +93 -0
  20. package/dist/data/adr/0017-mcp-design-group.md +107 -0
  21. package/dist/data/adr/0018-ai-context-routing.md +112 -0
  22. package/dist/data/adr/0019-project-upgrade-flow.md +156 -0
  23. package/dist/data/adr/0020-design-to-tokens-skill-fusion.md +139 -0
  24. package/dist/data/adr/0021-semantic-color-api-unification.md +99 -0
  25. package/dist/data/adr/0022-preferences-css-boundary.md +75 -0
  26. package/dist/data/adr/0023-cursor-pointer-explicit-in-component-source.md +70 -0
  27. package/dist/data/adr/0024-scoped-css-radix-state-conflict.md +99 -0
  28. package/dist/data/adr/0025-component-props-explicit-declaration.md +144 -0
  29. package/dist/data/adr/0026-component-level-token-alias.md +107 -0
  30. package/dist/data/adr/0027-component-visual-token-alignment.md +127 -0
  31. package/dist/data/adr/0028-ui-component-categorization.md +111 -0
  32. package/dist/data/adr/0029-input-split-and-prefix-suffix-removal.md +62 -0
  33. package/dist/data/adr/0030-skill-uni-manager-uplift.md +56 -0
  34. package/dist/data/adr/0031-skill-templates-decoupling.md +77 -0
  35. package/dist/data/adr/0032-opentrek-v4.1-brand-token-alignment.md +129 -0
  36. package/dist/data/adr/0033-entry-skill-global-only-scope.md +64 -0
  37. package/dist/data/adr/0034-skills-cli-verb-alignment.md +61 -0
  38. package/dist/data/adr/0035-skills-update-scope-and-lock-gates.md +69 -0
  39. package/dist/data/adr/README.md +75 -0
  40. package/dist/data/adr/_template.md +36 -0
  41. package/dist/index.d.ts +64 -59
  42. package/dist/index.js +232 -186
  43. package/dist/index.js.map +1 -1
  44. package/package.json +2 -2
@@ -0,0 +1,319 @@
1
+ # 0010. `@teamix-evo/design` 采用 `default + variants/<name>/` 模型,工程默认与业务变体彻底解耦
2
+
3
+ - **Status**: Proposed
4
+ - **Date**: 2026-05-18
5
+ - **Region**: 0100–0999 协议与工具
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)
7
+
8
+ ## Context
9
+
10
+ `@teamix-evo/design` 当前以 [`packages/design/library/opentrek/`](../../packages/design/library/opentrek/) 一个 variant 形式存在,把"5 层模型机理"和"OpenTrek 品牌内容"**塞在同一棵目录树**里:
11
+
12
+ | OpenTrek 现内容 | 本质属于 |
13
+ | -------------------------------------------------------------------------- | ----------------------------------- |
14
+ | `philosophy/principles.md`(Clarity / Efficiency / Predictability / Safety) | 通用 B 端工程原则,**不带品牌色彩** |
15
+ | `foundations/tokens/{base,semantic}.json`(中性灰系 + 标准语义) | 通用 B 端 token 骨架,**不带品牌色** |
16
+ | `foundations/tokens/`(品牌色) | OpenTrek 专属 |
17
+ | `brand/` / `voice.md`(若存在) | OpenTrek 专属 |
18
+ | `business/` | OpenTrek 业务上下文 |
19
+ | `patterns/`(部分) | 通用 B 端模式 |
20
+ | `scenarios/`(部分) | 通用 B 端骨架 |
21
+ | `ai-rules/` | **L4 协议层内容**,误塞 L3 知识层 |
22
+
23
+ 三个直接后果:
24
+
25
+ 1. **再加变体(uni-manager 等)成本巨大** —— 没有"差异化 vs 共性"的边界,每个新变体被迫从 OpenTrek 整树 fork 后再删
26
+ 2. **default 不存在** —— 业务消费方装机时拿到的"中性 B 端基线"和 OpenTrek 品牌内容**绑死**;不要 OpenTrek 就什么都没有
27
+ 3. **协议归属混淆** —— `ai-rules/` 是给 AI 看的执行规则,属于 L4 协议层(`packages/skills/`),误塞 L3 让两边语义都不干净
28
+
29
+ 业界对照:
30
+
31
+ | 系统 | 多变体模型 | 命名 |
32
+ | -------------------------- | ------------------------- | -------- |
33
+ | antd | theme(亮/暗/紧凑) | `theme` |
34
+ | MUI | theme | `theme` |
35
+ | Chakra | theme | `theme` |
36
+ | Tailwind | preset | `preset` |
37
+ | shadcn | style(new-york / default) | `style` |
38
+ | Stitches / Vanilla Extract | theme | `theme` |
39
+
40
+ 业界**没有**为"装机时选定 + 源码注入式 + 不可运行时切换"的品牌身份场景给出统一术语。本仓 schema 已用 `variant`,且与 cva 的"组件 variant"(scope:组件级)清晰区分(本 ADR 的"变体"scope:品牌级)。
41
+
42
+ ## Options Considered
43
+
44
+ ### 关于打包方式
45
+
46
+ | 选项 | 优点 | 缺点 |
47
+ | ------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
48
+ | A. 单包内部切(`packages/design/{default,variants/}`)(本决策) | 简单;一次安装;与现状增量演进而非重写;变体之间 schema/ADR 演进同步零成本 | 内部业务变体捆绑发布(对外卖时不优雅) |
49
+ | B. 多包(`@teamix-evo/design`(core) + `@teamix-evo/design-opentrek` + ...) | 变体独立版本与发布;私有变体可发到企业 npm | 装机要选/装两个包,CLI 复杂度上升;schema/ADR 演进需多包同步;v0.6 阶段只有 1-2 个变体,B 的复杂度收益 < 0 |
50
+ | C. 混合(default 内置 + 变体外置) | default 强保证,变体独立演进 | 适合 v1.0 开放外部变体后再切换,v0.6 还不需要 |
51
+
52
+ ### 关于内部命名
53
+
54
+ | 候选 | 评分 | 给本仓用的问题 |
55
+ | ----------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
56
+ | `theme` | ★★★★★ 业界最熟 | **运行时切换**语义,跟"装机时选品牌身份"不同;且和"亮色/暗色 theme"概念冲突 |
57
+ | `preset` | ★★★★(Tailwind/Vite/Babel) | 偏**构建配置**感,不太能装载 philosophy / scenarios 这类知识层内容 |
58
+ | `style` | ★★★(shadcn 用) | 语义最贴近(装机时选 + 源码注入 + 不可运行时切),但**普及度有限** |
59
+ | `variant`(本决策) | ★★ | schema 已用;和 cva variant scope 清晰(组件级 vs 品牌级);改名成本 = 改 schema + 改 cli + 改文档,且 P7 已为多个术语付过命名锁的代价 |
60
+ | `pack` | ★ | 自创感强,但容器语义清晰(`DesignPackManifest` 已用) |
61
+
62
+ 最终选 `variant` + `pack` 组合:**`pack` 作顶层容器,`variant` 作内部成员**(default 视作内置变体),术语层级自洽。
63
+
64
+ ### 关于变体合并粒度
65
+
66
+ | 选项 | 优点 | 缺点 |
67
+ | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
68
+ | 目录级完全替换(原方案,2026-05-18 弃用) | 算法极简 | variant 一旦声明某 subdir,必须提供该 subdir 完整内容 — 仅改一个 token 文件却要写完整 patterns/ 目录 |
69
+ | **文件级覆盖(本决策,2026-05-18 用户改动)** | 算法仍简单;variant 可只写需要差异化的文件,其余 fall back 到 default;支持"新增文件"(变体专属内容)与"覆盖文件"(替换 default 同路径)两种姿势 | 文件粒度的整体覆盖,**不做内容深合并**(不解析 JSON / Markdown) |
70
+ | 内容深合并(JSON-level / Markdown-level) | 最精细 | 合并算法复杂;装机时谁覆盖谁难调试;schema 必须区分 merge/override;违反 P8 失败可观察(合并冲突难定位) |
71
+
72
+ ### 关于 `_template` 起点
73
+
74
+ | 选项 | 评价 |
75
+ | ------------------- | ------------------------------------------------------------------------------------------------------ |
76
+ | 完全空目录 | 设计师 fork 时仍要重新想"目录怎么排、文件怎么命名",每次造一遍轮子 |
77
+ | **minimal**(本决策) | 结构合法可解析(manifest.json 可通过 Zod) + 1-2 个最小可工作示例 + 完整 README;让"加变体"动作成本恒定低 |
78
+
79
+ ### 关于 `pack.lock.json`
80
+
81
+ 业务侧 `.teamix-evo/design/` 是否暴露已装变体名:
82
+
83
+ | 选项 | 评价 |
84
+ | --------------------------------- | ---------------------------------------------------------------------------------- |
85
+ | 不暴露 | 简单,但 `teamix-evo doctor` / AI 上下文 / 升级流程都丢失"装的是哪一变体"的关键信号 |
86
+ | **暴露 `pack.lock.json`**(本决策) | 升级 / 切换 / 验证 / AI 上下文锚点都有据可查 |
87
+
88
+ ## Decision
89
+
90
+ ### 1. 包内目录结构(打包方式 A)
91
+
92
+ ```text
93
+ packages/design/
94
+ ├── default/ # 内置变体(B 端通用基线,中性,不带任何品牌)
95
+ │ ├── pack.json # name: "default", version, 无 extends
96
+ │ ├── philosophy/
97
+ │ │ ├── principles.md # 4 P 原则(从 OpenTrek 升入,中性表述)
98
+ │ │ ├── safety-hierarchy.md # Safety > Predictability > Clarity > Efficiency
99
+ │ │ └── README.md
100
+ │ ├── foundations/
101
+ │ │ ├── tokens/
102
+ │ │ │ ├── base.tokens.json # 中性灰系 + 标准语义 + 状态色 + 布局 + 遮罩
103
+ │ │ │ ├── semantic.tokens.json
104
+ │ │ │ ├── pack.json
105
+ │ │ │ └── README.md
106
+ │ │ ├── motion/
107
+ │ │ ├── types/ # branded TS types
108
+ │ │ └── README.md
109
+ │ ├── patterns/ # 通用模式 spec(list/detail/form/wizard/dashboard)
110
+ │ └── scenarios/ # 通用骨架(CRUD/审批/设置/导入导出)— 多数为空 + README
111
+
112
+ ├── variants/
113
+ │ ├── _template/ # minimal 模板(新变体的起点)
114
+ │ ├── opentrek/ # OpenTrek delta(brand + voice + token 颜色)
115
+ │ └── uni-manager/ # Uni-manager 空骨架(展示多变体接入路径)
116
+
117
+ ├── DESIGN.md # managed 模板(给消费方装机用)
118
+ ├── manifest.json # 顶层 pack manifest:列出 default + 所有 variants
119
+ └── README.md
120
+ ```
121
+
122
+ ### 2. 命名规范
123
+
124
+ | 概念 | 形态 | 示例 | 用途 |
125
+ | ------------------------------- | -------------------- | ------------------------------------- | ------------------------------------------------------------ |
126
+ | 顶层容器 | "pack" | `DesignPackManifest` | schema / 术语 |
127
+ | 内置基线 | "default" | `packages/design/default/` | 目录 + manifest name |
128
+ | 业务变体 | "variant" | `packages/design/variants/<name>/` | 目录 + manifest name |
129
+ | 继承关系 | "extends" | `pack.json` 的 `extends: "default"` | schema 字段 |
130
+ | **variant id**(机器名) | lowercase kebab-case | `opentrek`, `uni-manager`, `acme-erp` | 目录名 / CLI 参数 / import 路径 / `pack.json` 的 `name` 字段 |
131
+ | **variant displayName**(人类名) | 原始大小写 | `OpenTrek`, `Uni-manager`, `Acme ERP` | 文档标题 / npm 描述 / CLI 输出 |
132
+
133
+ `pack.json` 强制两个字段:
134
+
135
+ ```jsonc
136
+ {
137
+ "name": "opentrek",
138
+ "displayName": "OpenTrek",
139
+ "extends": "default",
140
+ "version": "0.5.0"
141
+ }
142
+ ```
143
+
144
+ CLI / 文档 / npm 描述自动用 `displayName` 渲染面向人的输出;所有路径与解析用 `name`。
145
+
146
+ ### 3. 抽取规则(从 OpenTrek 现状到 default + variants/opentrek/)
147
+
148
+ | 现 OpenTrek 内容 | 去向 |
149
+ | ------------------------------------------- | --------------------------------------------------- |
150
+ | `philosophy/principles.md`(4 P 原则) | → `default/philosophy/principles.md`(中性表述) |
151
+ | `philosophy/voice.md`(若存在)/ tone | → `variants/opentrek/philosophy/` |
152
+ | `brand/`(logo / 调性) | → `variants/opentrek/brand/` |
153
+ | `foundations/tokens/`(中性 base / 标准语义) | → `default/foundations/tokens/` |
154
+ | `foundations/tokens/`(品牌色 delta) | → `variants/opentrek/foundations/tokens/` |
155
+ | `patterns/`(通用) | → `default/patterns/` |
156
+ | `patterns/`(OpenTrek 专属,若存在) | → `variants/opentrek/patterns/` |
157
+ | `scenarios/`(通用骨架,空 + README) | → `default/scenarios/` |
158
+ | `scenarios/`(OpenTrek 专属) | → `variants/opentrek/scenarios/` |
159
+ | `business/` | → `packages/biz-ui/variants/opentrek/`(见 ADR 0014) |
160
+ | `ai-rules/` | → `packages/skills/`(L4 协议层归口,见 ADR 0013) |
161
+ | `adr/_template.md` | 删除(治理 ADR 统一在根 `docs/adr/`,见 ADR 0007) |
162
+
163
+ > OpenTrek 的 4 原则**全升 default**:它本就是中性 B 端原则,不带 OpenTrek 调性;OpenTrek 变体只贡献 brand + voice + token 品牌色 delta + 私有 pattern。
164
+
165
+ ### 4. 变体合并:文件级覆盖(2026-05-18 用户改动:由原"目录级完全替换"升级)
166
+
167
+ CLI 装机时,**walk 全树,文件粒度逐个判断**:
168
+
169
+ ```text
170
+ walk default/ 全树:
171
+ 对每个文件路径 P:
172
+ if variants/<name>/P 存在 → 输出 variant 的 P(替换 default 同路径)
173
+ else → 输出 default 的 P
174
+ walk variants/<name>/ 全树:
175
+ 对每个 default 中不存在的文件路径 Q → 直接附加到产物(变体专属新增)
176
+ ```
177
+
178
+ variant 写入有两种姿势:
179
+
180
+ | 姿势 | 含义 | 例子 |
181
+ | ---------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
182
+ | **覆盖**(同路径) | 替换 default 同路径文件,**variant 文件须自包含完整内容** | `variants/opentrek/foundations/tokens/base.tokens.json` 替换 default 的同名文件;variant 要写完整 token 集(default 默认 + opentrek 改动后的最终内容) |
183
+ | **新增**(新路径) | default 没有这个文件 — 纯附加,不存在合并问题 | `variants/opentrek/brand/logo-spec.md` / `variants/opentrek/scenarios/travel-approval.md` |
184
+
185
+ **不做内容深合并**(不解析 JSON 字段、不解析 Markdown 段落):
186
+
187
+ - 想只改一个 token 颜色 → variant 仍要写完整的 `base.tokens.json`(把 default 的内容拷过来再改);**或** 把 delta 写成新文件(如 `brand.tokens.json`),consumer 侧 Style Dictionary 多源合并由它处理
188
+ - 工具层只懂"文件存在 / 不存在"两种状态,不解析文件内容 — 算法零歧义,符合 P8 失败可观察(差异定位到具体文件,不到字段)
189
+
190
+ ### 5. `_template` 起点 = minimal
191
+
192
+ ```text
193
+ packages/design/variants/_template/
194
+ ├── pack.json # 合法 manifest, name="_template", extends="default"
195
+ ├── philosophy/
196
+ │ ├── README.md # "本变体哲学补充写这里;不写则继承 default"
197
+ │ └── voice.md # 最小 stub:"## Tone\n(待填写)\n## Tense\n(待填写)"
198
+ ├── foundations/
199
+ │ ├── tokens/
200
+ │ │ ├── README.md
201
+ │ │ └── base.tokens.json # 1 个示例 brand color override
202
+ │ └── motion/
203
+ │ └── README.md
204
+ ├── patterns/
205
+ │ └── README.md # "本变体专属 pattern 写这里;通用 pattern 在 default"
206
+ ├── scenarios/
207
+ │ └── README.md
208
+ ├── brand/
209
+ │ └── README.md # "logo / 调性 / 品牌色清单写这里"
210
+ └── README.md # "如何 fork:1) 复制目录;2) 改 pack.json 的 name/displayName;..."
211
+ ```
212
+
213
+ ### 6. 业务侧 `pack.lock.json`
214
+
215
+ 业务消费方装机后产出:
216
+
217
+ ```jsonc
218
+ // .teamix-evo/design/pack.lock.json
219
+ {
220
+ "default": { "version": "0.5.0", "from": "@teamix-evo/design" },
221
+ "variant": {
222
+ "name": "opentrek",
223
+ "displayName": "OpenTrek",
224
+ "version": "0.5.0",
225
+ "from": "@teamix-evo/design"
226
+ },
227
+ "linked": {
228
+ "biz-ui": "@teamix-evo/biz-ui#opentrek" // 软关联,装机时校验存在
229
+ },
230
+ "installedAt": "2026-05-18T..."
231
+ }
232
+ ```
233
+
234
+ `teamix-evo doctor` / 后续升级 / AI 上下文 / 跨包变体一致性校验都从此 lock 文件读。
235
+
236
+ ### 7. Schema 增量(`packages/registry/src/schema/`)
237
+
238
+ 新建 `design-pack.ts`,**只承载协议字段**;具体文件清单由 loader 物理 walk 文件系统得出(见 §4 文件级覆盖):
239
+
240
+ ```ts
241
+ export const DesignPackManifestSchema = z.object({
242
+ name: z.string(), // "default" | "opentrek" | ...
243
+ displayName: z.string(), // 人类可读名
244
+ version: z.string(),
245
+ extends: z.string().optional(), // "default";default 自身无此字段
246
+ linked: z
247
+ .object({
248
+ 'biz-ui': z.string().optional(), // 关联的 biz-ui 变体,装机时校验存在 — ADR 0014
249
+ templates: z.string().optional(), // 关联的 templates 变体,装机时校验存在 — ADR 0014
250
+ })
251
+ .optional(),
252
+ });
253
+ ```
254
+
255
+ **为什么不在 manifest 里声明文件清单**(philosophy / foundations / patterns / scenarios 路径列表):
256
+
257
+ - 变体作者新增文件时容易忘记登记,manifest 与文件系统漂移,违反 P2
258
+ - loader 直接 walk 文件系统 `default/` 与 `variants/<name>/` 即可 100% 准确发现文件,无需 manifest 同步
259
+ - 减少 schema 字段 = 减少出错面;manifest 只负责"协议级身份"(name / extends / linked),不重复文件系统的事实
260
+
261
+ ### 8. CLI 增量(`packages/cli/`)
262
+
263
+ ```bash
264
+ teamix-evo design init --variant opentrek # 装 default + opentrek 合并产物
265
+ teamix-evo design list-variants # 列出可用变体(扫 packages/design/variants/)
266
+ teamix-evo design switch --variant uni # 切变体(后续,带迁移指引)
267
+ ```
268
+
269
+ ## Consequences
270
+
271
+ - **Positive**:
272
+ - 多变体接入路径清晰 —— uni-manager 等新变体 fork `_template/` 即可,工作量恒定低
273
+ - 默认 B 端基线独立可消费 —— 业务方可只装 default、不绑任何品牌,完成中性装机
274
+ - 命名锁完整(P7) —— `pack` / `default` / `variants` / `extends` / variant id kebab-case + displayName 一并锁,后续不再付改名代价
275
+ - L4 协议归位 —— `ai-rules/` 迁出 design 后,L3 知识层与 L4 协议层语义干净
276
+ - **解开 ADR 0008 还款的前置依赖** —— v0.6 补 success/warning/info / 布局尺寸 / 遮罩 token 落在 `default/foundations/tokens/`,正好用上新结构
277
+ - **Negative**:
278
+ - OpenTrek `business/` 整体外迁 biz-ui,与 OpenTrek 一同消费的方需调整 import 路径
279
+ - 变体一致性需人工同步(opentrek 在 design / biz-ui 中各有目录),v0.6 给手工 check 脚本,v0.9 才有 doctor
280
+ - 业界没用 `variant` 这套术语 —— 新接触者要花一段时间区分本仓 design variant(品牌级)和 cva variant(组件级)
281
+ - **Trade-off**:
282
+ - 用"变体目录二次同步成本"换"工程默认与业务彻底解耦 + 多变体可插拔 + L4 协议归位"
283
+ - 用"文件级覆盖不解析内容"换"算法零歧义 + 调试可定位到具体文件 + 符合 P3 frozen 与 P8 失败可观察精神"
284
+ - 变体精细继承(只改一个 token 而不写完整文件)的能力转移到 consumer 侧 Style Dictionary 多源合并,不在工具层做 — **复杂度推到正确的层**
285
+
286
+ ## Implementation note
287
+
288
+ 落地工作量(v0.6,共 ~8 人日,见 [PLAN §6.2 / §12.5](../../PLAN.md)):
289
+
290
+ 1. 写本 ADR + 命名锁(0.5)
291
+ 2. `packages/registry/src/schema/design-pack.ts` + Zod + 单测(1)
292
+ 3. 目录重排:从 OpenTrek 抽 default 共性(2)
293
+ 4. OpenTrek delta 提取 → `variants/opentrek/`(1)
294
+ 5. `_template/` minimal + `variants/uni-manager/` 空骨架(0.5)
295
+ 6. CLI `design init` / `list-variants` 合并逻辑 + 单测(1.5)
296
+ 7. `packages/design/AGENTS.md` 重写 + `docs/architecture.md` §2 三轨咬合表更新(1)
297
+ 8. `pack.lock.json` schema + cli 写入 + doctor 雏形 check(0.5)
298
+
299
+ ## Amendments
300
+
301
+ ### 2026-05-21 · tokens 装机路径提层(W1.4) → 2026-05-27 再次提层至根目录
302
+
303
+ 装机产物布局变更:`foundations/tokens/*` 最终落地为消费者项目根 **`tokens/*`**(而非 `.teamix-evo/tokens/`)。
304
+
305
+ - **范围**:**仅装机产物**,**design 包内部源码结构不动** —— 仍是 `default/foundations/tokens/` + `variants/<v>/foundations/tokens/`,walk-and-merge 协议未变
306
+ - **理由**:tokens 是消费者最常编辑的资源(覆盖颜色、圆角、阴影),放根目录文件树一眼可见,import 路径最短(`../tokens/theme.css`)
307
+ - **兼容**:[`packages/mcp/src/design-loader.ts`](../../packages/mcp/src/design-loader.ts) 的 `readTokens` 优先读根 `tokens/`,fallback 到 `.teamix-evo/tokens/` 再 fallback 到旧路径 `<rootDir>/foundations/tokens/`(保护已装项目)
308
+ - **迁移**:旧装机若想升级,`mv .teamix-evo/tokens tokens` 即可。详见 [ADR 0019](0019-project-upgrade-flow.md)
309
+
310
+ 具体分类规则见 [`packages/cli/src/core/design-pack-classify.ts`](../../packages/cli/src/core/design-pack-classify.ts)。
311
+
312
+ ## Source
313
+
314
+ - 2026-05-18 用户讨论(轮 1):["把 design 内容按五层架构重构,工程默认 + 业务变体隔离"](从 5 层映射 / B 端 console 默认 / OpenTrek 退化为变体三个角度推演)
315
+ - 2026-05-18 用户改动(轮 2):变体合并由"目录级完全替换"升级为**文件级覆盖**;DesignPackManifest schema 简化(只留协议字段,文件清单由 loader walk 文件系统);`linked.templates` 字段加入(对应 [ADR 0014](0014-ui-biz-ui-templates-tier.md) 中 templates 变更为 variant-aware)
316
+ - 2026-05-21 用户改动(轮 3):**tokens 装机路径提层**(W1.4) —— `.teamix-evo/design/foundations/tokens/` → `.teamix-evo/tokens/`,理由:消费侧最常编辑,减深路径
317
+ - [`packages/design/library/opentrek/`](../../packages/design/library/opentrek/):现状内容
318
+ - [PLAN §12.2 五层模型与现状评分](../../PLAN.md#122-五层模型与现状评分):L3 知识层 65% 现状,本 ADR 提升至 ~85%
319
+ - [ADR 0008](0008-eslint-visual-rules-warn-baseline.md):design token gap 与 v0.6 ratchet 还款 —— 本 ADR 是其前置基础设施
@@ -0,0 +1,169 @@
1
+ # 0011. MCP server 形态 = **单包 / 单 bin / 多 tool group**;`registry-mcp` 改名 `mcp`
2
+
3
+ - **Status**: Proposed
4
+ - **Date**: 2026-05-18
5
+ - **Region**: 0100–0999 协议与工具
6
+ - **Related ADR**: [0007 治理文档放根](0007-governance-docs-at-root.md) / [0009 registry-mcp 协议层](0009-registry-mcp-protocol-layer.md)(本 ADR Superseded by 部分内容) / [0010 design 默认+变体](0010-design-default-and-variants.md)
7
+
8
+ ## Context
9
+
10
+ [ADR 0009](0009-registry-mcp-protocol-layer.md) 把 `@teamix-evo/registry-mcp` 作为**第一个**协议层 MCP server,只暴露 ui registry 一个知识维度。后续路线 ([PLAN §12.5/12.6/12.7](../../PLAN.md#12-五层模型驱动的演进规划v05)) 还有 4 个待建:
11
+
12
+ - `tokens-mcp`(v0.6)— 暴露 design tokens(本 ADR 后改为 design group)
13
+ - `adr-mcp`(v0.7)— 暴露决策档案
14
+ - `skills-mcp`(v0.7)— 暴露 SKILL.md
15
+ - `scenario-mcp`(v0.8)— 暴露 Scenario Pack
16
+
17
+ 按"按知识维度切包"的思路推下去,会是 5 个 MCP 包 / 5 个 bin / 5 条 `.mcp.json` 配置 / 5 个进程 —— **这是分类视角强加给生产视角**的产物,代价没人算过:
18
+
19
+ | 维度 | 多包多 bin 的代价 |
20
+ | --- | --- |
21
+ | 启动开销 | 每个 stdio server 子进程 ~50–200ms 冷启动;5 个并启 = 250–1000ms |
22
+ | stdio 噪音 | 5 个进程的日志 / 错误 / 重连各自一套 |
23
+ | 共享代码漂移 | manifest-loader / 路径解析 / 错误格式 / 测试 fixture 跨 5 个包同步成本高 |
24
+ | 版本同步 | schema 改一次要发 5 个包;Changesets 五项 |
25
+ | 用户配置 | 业务侧 `.mcp.json` 5 条,每条的 env / args 略不同,易写错 |
26
+ | schema 一致性 | 跨包 Zod schema 对齐 = 反熵脚本要做交叉校验 |
27
+ | 包管理负担 | 每个包独立 `package.json` / `tsconfig.json` / `tsup.config.ts` / `tests/`,5 倍样板 |
28
+
29
+ 而**多个 MCP server 并不会让 AI 编辑器更智能**:Cursor / Claude Code / Cline 看到 5 个 server 的体验和 1 个 server 暴露 5 类工具的体验**几乎一样**,模型在 `tools/list` 里看到的是工具集合,不是 server 边界。
30
+
31
+ ## Options Considered
32
+
33
+ | 选项 | 包数 | bin 数 | `.mcp.json` 条目 | 评价 |
34
+ | --- | ---: | ---: | ---: | --- |
35
+ | ① 多包多 bin | 5 | 5 | 5 | 最重(当前规划路径) |
36
+ | ② 单包多 bin | 1 | 5 | 5 | 同样起 5 进程,但版本/utils 共享 |
37
+ | **③ 单包单 bin 多 tool group**(本决策) | 1 | 1 | 1 | 一个进程,工具按 group 注册 |
38
+
39
+ > v0.6 阶段总共也就 ~10 个 tool,一个 server 完全装得下;真到 30+ tool 再考虑切 ②(单包多 bin、按维度起进程)。**P2 single source(规则一处变更)在选项 ③ 下天然成立**。
40
+
41
+ ## Decision
42
+
43
+ ### 1. 包形态:单包 `@teamix-evo/mcp`
44
+
45
+ ```
46
+ packages/mcp/
47
+ ├── src/
48
+ │ ├── server.ts # 主 server,创建 Server 实例 + 注册所有 tool group
49
+ │ ├── groups/
50
+ │ │ ├── registry.ts # list_components / get_component_meta / find_components
51
+ │ │ ├── design.ts # list_tokens / get_pattern / get_philosophy(v0.6)
52
+ │ │ ├── adr.ts # list_adrs / get_adr(v0.7)
53
+ │ │ └── scenario.ts # list_scenarios / get_scenario(v0.8)
54
+ │ ├── manifest-loader.ts # 共享:resolve manifest 路径(env / cwd 回溯)
55
+ │ ├── pack-loader.ts # 共享:resolve design pack 路径
56
+ │ ├── types.ts # 共享类型
57
+ │ └── cli.ts # 单 bin entry
58
+ ├── tests/
59
+ │ ├── groups/
60
+ │ │ ├── registry.test.ts # 现 registry-mcp tests 迁入
61
+ │ │ ├── design.test.ts # v0.6
62
+ │ │ └── ...
63
+ │ └── manifest-loader.test.ts
64
+ └── package.json # bin: { "teamix-evo-mcp": "./dist/cli.js" }
65
+ ```
66
+
67
+ ### 2. `.mcp.json` 形态(单条配置启动所有 group)
68
+
69
+ ```jsonc
70
+ {
71
+ "mcpServers": {
72
+ "teamix-evo": {
73
+ "type": "stdio",
74
+ "command": "node",
75
+ "args": ["./packages/mcp/dist/cli.js"],
76
+ "env": {
77
+ "TEAMIX_EVO_UI_MANIFEST": "./packages/ui/manifest.json",
78
+ "TEAMIX_EVO_DESIGN_ROOT": "./packages/design",
79
+ "TEAMIX_EVO_ADR_ROOT": "./docs/adr"
80
+ }
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### 3. Tool group 注册模式
87
+
88
+ 每个 group 导出一个注册函数,在 `server.ts` 集中注册:
89
+
90
+ ```ts
91
+ // packages/mcp/src/server.ts
92
+ import { registerRegistryGroup } from './groups/registry.js';
93
+ import { registerDesignGroup } from './groups/design.js';
94
+ // ...
95
+
96
+ export function createServer(opts: ServerOptions): Server {
97
+ const server = new Server({ name: 'teamix-evo', version: '0.6.0' }, ...);
98
+ registerRegistryGroup(server, opts);
99
+ registerDesignGroup(server, opts); // v0.6 起
100
+ registerAdrGroup(server, opts); // v0.7 起
101
+ registerScenarioGroup(server, opts);// v0.8 起
102
+ return server;
103
+ }
104
+ ```
105
+
106
+ 每个 group 内部:用 MCP SDK 的 `setRequestHandler(ListToolsRequestSchema, ...)` / `setRequestHandler(CallToolRequestSchema, ...)` 注册自己的 tools(group 之间 tool 名不允许冲突;以 `<group>_<verb>` 形态预防,如 `design_list_tokens` / `adr_get_adr`)。
107
+
108
+ ### 4. 改名(P7 命名锁,免费窗口期内执行)
109
+
110
+ `@teamix-evo/registry-mcp` 尚未发布,改名零成本:
111
+
112
+ | 旧 | 新 |
113
+ | --- | --- |
114
+ | 包名 `@teamix-evo/registry-mcp` | `@teamix-evo/mcp` |
115
+ | 目录 `packages/registry-mcp/` | `packages/mcp/` |
116
+ | bin `teamix-evo-registry-mcp` | `teamix-evo-mcp` |
117
+ | `.mcp.json` 条目名 `teamix-evo-registry` | `teamix-evo` |
118
+
119
+ > 改名只在 v0.6 启动前完成才是免费的;一旦发到 npm,改名要走 deprecation。本 ADR 必须在 v0.6 实施第一周完成改名,否则锁住"registry-mcp"作为既成事实。
120
+
121
+ ### 5. 工具命名约定
122
+
123
+ 为防止跨 group tool 名冲突,采用 `<group>_<verb>_<noun>` 风格:
124
+
125
+ | Group | Tool 命名 |
126
+ | --- | --- |
127
+ | registry(已存在) | `list_components` / `get_component_meta` / `find_components` —— **保留无前缀**(P7,已被 AI 模型记住) |
128
+ | design(v0.6) | `design_list_tokens` / `design_get_pattern` / `design_get_philosophy` |
129
+ | adr(v0.7) | `adr_list` / `adr_get` / `adr_find` |
130
+ | scenario(v0.8) | `scenario_list` / `scenario_get_pack` |
131
+
132
+ > registry group 工具不加前缀是**特例**:它们已在 [ADR 0009](0009-registry-mcp-protocol-layer.md) 的 v0.5 落地中固化,改名会破坏现有 IDE 接入。其余 group 一律带前缀。
133
+
134
+ ### 6. 升级 ADR 0009 状态
135
+
136
+ [ADR 0009](0009-registry-mcp-protocol-layer.md) 的"包形态 / bin 名 / `.mcp.json` 条目名"段被本 ADR 取代,但**核心决策(MCP 作为协议层 / stdio / 三个 registry tool)依然有效**。0009 标 `Superseded in part by 0011`(标记为部分被取代,不删除)。
137
+
138
+ ## Consequences
139
+
140
+ - **Positive**:
141
+ - **进程数从 5 降到 1** —— 启动延迟、stdio 噪音、调试复杂度全面降级
142
+ - **共享 utils 一处** —— manifest-loader / pack-loader / 错误格式 / 类型 / 测试 fixture 单点维护
143
+ - **schema 演进零跨包同步** —— 改一次 schema,一个包 build 即生效
144
+ - **业务侧 `.mcp.json` 简洁** —— 只有 1 条配置,认知负担最低
145
+ - **改名零成本** —— v0.6 启动前 `registry-mcp` 还未发布,P7 命名锁本次为免费窗口期
146
+ - **Negative**:
147
+ - 单进程承载所有 group —— 一个 group 的 bug 可能影响整体(实践中 MCP server 都是无状态查询,影响半径小)
148
+ - 包体积增大(预计 ~3 倍) —— 业务侧 `node_modules/@teamix-evo/mcp` 装的是全部 group 的代码;但 stdio server 仅在 IDE 启动时加载,不影响 runtime
149
+ - tool 命名约定要求新 group 必须带前缀 —— 增加约定一条,但比"全 namespace"宽松(registry 历史保留)
150
+ - **Trade-off**:
151
+ - 用"包体积 + 单进程影响半径"换"开发 / 调试 / 分发 / 用户配置全面简化"
152
+ - 用"工具命名约定的一条新规"换"跨 group 引用 / 文档生成 / AI 工具发现的全局唯一性"
153
+
154
+ ## Implementation note
155
+
156
+ 落地工作量(v0.6,共 ~1 人日):
157
+
158
+ 1. 写本 ADR + 改名审查(0.2)
159
+ 2. `packages/registry-mcp/` → `packages/mcp/`(目录、`package.json`、`tsup.config.ts`、`bin`、test fixture 路径)(0.3)
160
+ 3. 引入 `groups/` 目录结构,把现有 registry tools 迁入 `groups/registry.ts`(0.3)
161
+ 4. `.mcp.json` 改写 + 根 `AGENTS.md` 引用更新 + ADR 0009 标 `Superseded in part`(0.2)
162
+
163
+ design / adr / scenario 三个 group 的 tool 实现不在本 ADR 范围 —— 按 v0.6 / v0.7 / v0.8 路线图各自单独 ADR 或并入设计 ADR。
164
+
165
+ ## Source
166
+
167
+ - [ADR 0009](0009-registry-mcp-protocol-layer.md):registry-mcp 第一版决策
168
+ - 2026-05-18 用户讨论:["MCP server,你建议是多个,而不是一个 mcp 包,包含多个 server?"](三种形态对比 + 单 bin 多 group 论证)
169
+ - [PLAN §12.5–12.7](../../PLAN.md#125-v06--闸层补强--协议层雏形12-18-人日):原"5 个 MCP server"路线由本 ADR 改写为"1 个 server / 4 个 group"