@teamix-evo/skills 0.3.0 → 0.5.0
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.
- package/README.md +7 -3
- package/manifest.json +63 -46
- package/package.json +3 -3
- package/src/teamix-evo-code-opentrek/SKILL.md +94 -0
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/api-layering.md +8 -5
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/checklist.md +4 -2
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/error-and-loading.md +38 -25
- package/src/teamix-evo-code-opentrek/file-structure.md +282 -0
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/forms-and-validation.md +14 -12
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/reuse-first.md +27 -17
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/routing-and-codesplit.md +23 -21
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/testing.md +32 -28
- package/src/teamix-evo-code-uni-manager/SKILL.md +97 -0
- package/src/teamix-evo-code-uni-manager/api-layering.md +372 -0
- package/src/teamix-evo-code-uni-manager/checklist.md +195 -0
- package/src/teamix-evo-code-uni-manager/error-and-loading.md +391 -0
- package/src/teamix-evo-code-uni-manager/file-structure.md +341 -0
- package/src/teamix-evo-code-uni-manager/forms-and-validation.md +461 -0
- package/src/teamix-evo-code-uni-manager/reuse-first.md +190 -0
- package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +452 -0
- package/src/teamix-evo-code-uni-manager/testing.md +398 -0
- package/src/teamix-evo-design-opentrek/SKILL.md +64 -0
- package/src/teamix-evo-design-opentrek/boundaries.md +533 -0
- package/src/teamix-evo-design-opentrek/brand.md +154 -0
- package/src/teamix-evo-design-opentrek/checklist.md +85 -0
- package/src/teamix-evo-design-opentrek/components.md +294 -0
- package/src/teamix-evo-design-opentrek/flows.md +51 -0
- package/src/teamix-evo-design-opentrek/foundations.md +274 -0
- package/src/teamix-evo-design-opentrek/generation-flow.md +243 -0
- package/src/teamix-evo-design-opentrek/patterns/color-mapping.md +96 -0
- package/src/teamix-evo-design-opentrek/patterns/dashboard.md +33 -0
- package/src/teamix-evo-design-opentrek/patterns/detail-page.md +203 -0
- package/src/teamix-evo-design-opentrek/patterns/form-page.md +292 -0
- package/src/teamix-evo-design-opentrek/patterns/list-page.md +367 -0
- package/src/teamix-evo-design-opentrek/patterns/page-types.md +159 -0
- package/src/teamix-evo-design-opentrek/patterns/sidebar.md +122 -0
- package/src/teamix-evo-design-opentrek/philosophy.md +98 -0
- package/src/teamix-evo-design-opentrek/rules/README.md +39 -0
- package/src/teamix-evo-design-opentrek/rules/boundaries.rules.json +391 -0
- package/src/teamix-evo-design-uni-manager/SKILL.md +64 -0
- package/src/teamix-evo-design-uni-manager/boundaries.md +567 -0
- package/src/teamix-evo-design-uni-manager/brand.md +202 -0
- package/src/teamix-evo-design-uni-manager/checklist.md +115 -0
- package/src/teamix-evo-design-uni-manager/components.md +257 -0
- package/src/teamix-evo-design-uni-manager/flows.md +63 -0
- package/src/teamix-evo-design-uni-manager/foundations.md +261 -0
- package/src/teamix-evo-design-uni-manager/generation-flow.md +230 -0
- package/src/teamix-evo-design-uni-manager/patterns/dashboard.md +97 -0
- package/src/teamix-evo-design-uni-manager/patterns/detail-page.md +253 -0
- package/src/teamix-evo-design-uni-manager/patterns/form-page.md +366 -0
- package/src/teamix-evo-design-uni-manager/patterns/list-page.md +389 -0
- package/src/teamix-evo-design-uni-manager/patterns/page-types.md +167 -0
- package/src/teamix-evo-design-uni-manager/philosophy.md +108 -0
- package/src/teamix-evo-design-uni-manager/rules/README.md +49 -0
- package/src/teamix-evo-design-uni-manager/rules/boundaries.rules.json +418 -0
- package/src/teamix-evo-manage/SKILL.md +289 -0
- package/skills/teamix-evo-coding-conventions/SKILL.md +0 -92
- package/skills/teamix-evo-coding-conventions/file-structure.md +0 -273
- package/skills/teamix-evo-design-rules/SKILL.md +0 -86
- package/skills/teamix-evo-design-rules/boundaries.md +0 -89
- package/skills/teamix-evo-design-rules/checklist.md +0 -108
- package/skills/teamix-evo-design-rules/generation-flow.md +0 -142
- package/skills/teamix-evo-design-rules/prompts/page-design.md +0 -148
- package/skills/teamix-evo-design-rules-opentrek/SKILL.md +0 -48
- package/skills/teamix-evo-design-rules-opentrek/brand-rules.md +0 -74
- package/skills/teamix-evo-design-rules-uni-manager/SKILL.md +0 -51
- package/skills/teamix-evo-design-rules-uni-manager/ai-scenarios.md +0 -51
- package/skills/teamix-evo-design-rules-uni-manager/command-center.md +0 -108
- package/skills/teamix-evo-design-rules-uni-manager/danger-ops.md +0 -87
- package/skills/teamix-evo-manage/SKILL.md +0 -178
- package/skills/teamix-evo-ui-upgrade/SKILL.md +0 -75
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: teamix-evo-manage
|
|
3
|
+
description: |
|
|
4
|
+
Single entry point for the teamix-evo lifecycle: scaffold a new project, install the AI coding system into an existing repo, run / update / inspect / remove any teamix-evo package, and drive the placeholder→real UI migration loop after `npm create teamix-evo`.
|
|
5
|
+
TRIGGER when: (CLI) user runs or asks about `teamix-evo tokens ...` / `teamix-evo skills ...` / `teamix-evo ui ...` / `teamix-evo biz-ui ...` / `teamix-evo templates ...` / `teamix-evo lint ...` / `teamix-evo logs ...`, or `npm create teamix-evo` / `pnpm create teamix-evo`; (模糊初始化) "初始化一个项目"、"初始化一个工程"、"初始化一个 teamix-evo 工程"、"初始化一个 Teamix Evo 项目"、"create a teamix-evo project"、"set up teamix-evo from scratch"、"new teamix-evo app"; (具名变体初始化) "初始化一个 opentrek 工程 / op 工程 / OpenTrek 项目 / 探索者项目"、"初始化一个云管 / 云管控制台 / 云管项目 / uni-manager 工程 / 云管工程"、"new opentrek/uni-manager project"; (AI coding 接入) "给现有仓库装 teamix-evo"、"现有项目装一下 skills + ui"、"接入 AI coding 体系"、"装 teamix-evo 进这个项目"、"add teamix-evo to existing repo"、"install AI coding system"、"接入 opentrek 研发体系"、"接入 op 研发体系"、"接入 OpenTrek 研发体系"、"接入 opentrek 研发系统"、"接入 op 研发系统"、"接入云管研发体系"、"接入云管研发系统"、"接入 uni-manager 研发体系"、"接入 uni-manager 研发系统"、"接入统一管理研发体系"; (更新检测) "升级 teamix-evo"、"看看哪些要升级"、"update teamix-evo"、"check what needs updating"、"refresh installed teamix-evo packages"; (卸载 / 清单) "卸载 teamix-evo"、"看看装了哪些 teamix-evo 资源"、"remove the design system"、"list installed"; (placeholder→real 升级) "升级 UI"、"接入真组件"、"替换 placeholder"、"upgrade UI"、"replace placeholders"、"swap in real components"、"make the UI real", or user opens / edits `src/components/_placeholder/**`, project contains `.teamix-evo/create/pending-ui.json`, literal `@teamix-evo:placeholder` tag in code; (状态文件) user touches `.teamix-evo/config.json`、`.teamix-evo/manifest.json`、`.teamix-evo/create/pending-ui.json`.
|
|
6
|
+
SKIP: any content task — generating components, pages, services, or reviewing screens; changes to `src/` files outside the migration loop, design tokens, or business logic. Those go to teamix-evo-code-opentrek or teamix-evo-design-opentrek. SKIP if the user is mid-flow inside an already-initialized project asking to "新增页面 / 加按钮 / 调接口" — that's coding work, not lifecycle. SKIP pure styling / token tweaks — those go to ESLint + `tokens.overrides.css`.
|
|
7
|
+
Coordinates with: teamix-evo-design-opentrek (visual side after a screen is generated)、teamix-evo-code-opentrek (file placement / reuse rules) — manage is the entry point and precedes content skills, never co-triggers.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# teamix-evo-manage
|
|
11
|
+
|
|
12
|
+
Single entry skill for the **teamix-evo** toolkit lifecycle. Covers six scenarios:
|
|
13
|
+
|
|
14
|
+
1. Fuzzy init → ask user to pick a tokens variant.
|
|
15
|
+
2. Named-variant init → infer variant from business name, run scaffold directly.
|
|
16
|
+
3. AI coding install on existing repo (no scaffold step).
|
|
17
|
+
4. Update detection — only refresh what's already installed.
|
|
18
|
+
5. Uninstall.
|
|
19
|
+
6. Placeholder → real UI migration loop (post-`npm create teamix-evo`).
|
|
20
|
+
|
|
21
|
+
## 安装方式
|
|
22
|
+
|
|
23
|
+
本 skill 是 **entry skill**(lifecycle orchestrator),manifest 里声明 `scope: "global"`。**推荐全局安装一次**:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx teamix-evo skills add teamix-evo-manage --scope global
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`skills add`(默认 project scope)与 `npm create teamix-evo` **不会**自动装本 skill —— bulk 模式按 scope 自动跳过(ADR 0033)。如果用户在项目级显式 `skills add teamix-evo-manage --scope project`,CLI 给出"推荐 global"warning 但仍装入(用户自负责),代价是后续 IDE 会同时识别全局与项目两份副本。
|
|
30
|
+
|
|
31
|
+
## 自助升级
|
|
32
|
+
|
|
33
|
+
升级到最新版本(任何目录可跑 — 自动找全局 meta root):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx teamix-evo@latest skills update # 全部已装
|
|
37
|
+
npx teamix-evo@latest skills update teamix-evo-manage # 只升 manage 一个
|
|
38
|
+
npx teamix-evo@latest skills update --dry-run # 预览,不写盘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`@latest` 让 npx 拉最新 CLI + 最新 `@teamix-evo/skills` 包。命令头部会打印 CLI 版本与 skills 包版本,方便排查 npx cache 与包不同步的问题。
|
|
42
|
+
|
|
43
|
+
升级范围(ADR 0035 双闸):
|
|
44
|
+
|
|
45
|
+
- 只更新 lock 里**已装**的 skill — 新 skill 用 `skills add <id>` 显式加入,不会被 update 自动装上
|
|
46
|
+
- 只更新 scope 与当前 install scope 一致的 skill — 项目级 update 不会动全局 manage,反之亦然
|
|
47
|
+
- 版本完全一致时短路,不重写源(managed 区域用户改动不被来回备份)
|
|
48
|
+
|
|
49
|
+
<!-- teamix-evo:managed:start id="core" -->
|
|
50
|
+
|
|
51
|
+
## 决策树(动手前必看)
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
用户的指令命中本 skill
|
|
55
|
+
├── 目录里有 `.teamix-evo/`?
|
|
56
|
+
│ 是 ──▶ 4 (更新) / 5 (卸载)
|
|
57
|
+
│ 否 ──▶ 继续
|
|
58
|
+
├── 用户说出业务名 / variant?
|
|
59
|
+
│ 是 ──▶ 2 (具名变体初始化) — 用「业务名→variant 映射表」推断
|
|
60
|
+
│ 否 ──▶ 继续
|
|
61
|
+
├── 目录是空的(或只有 .git / README.md)?
|
|
62
|
+
│ 是 ──▶ 1 (模糊初始化) — 询问 variant 后转 2
|
|
63
|
+
│ 否 ──▶ 3 (AI coding 接入) — 跳过 scaffold,只跑 tokens/skills/ui init
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 业务名 → variant 映射
|
|
67
|
+
|
|
68
|
+
> 用户表述业务时,按下表锁定 variant,**不再询问**。表外的关键词必须询问。
|
|
69
|
+
|
|
70
|
+
| 用户原话(中/英) | variant |
|
|
71
|
+
| ----------------------------------------------------------------------------- | ------------- |
|
|
72
|
+
| 云管 / 云管控制台 / 云管项目 / 云管工程 / uni-manager / unimanager / 统一管理 | `uni-manager` |
|
|
73
|
+
| op / opentrek / OpenTrek / 探索者 | `opentrek` |
|
|
74
|
+
| _未提及业务,只说"做一个工程"_ | **询问** |
|
|
75
|
+
|
|
76
|
+
校验:`npx teamix-evo tokens list-variants` 列出当前 `@teamix-evo/tokens` 包内所有变体;若上表中的关键词指向尚未发布的变体,先告知用户该 variant 还未上线。
|
|
77
|
+
|
|
78
|
+
## CLI 命令面(完整)
|
|
79
|
+
|
|
80
|
+
CLI 二进制名 `teamix-evo`,所有命令都从这里发起。命令名以 `tokens`、`skills`、`ui`、`biz-ui`、`templates`、`logs` 六个 group 组织。
|
|
81
|
+
|
|
82
|
+
### Tokens(`@teamix-evo/tokens`)
|
|
83
|
+
|
|
84
|
+
| 目标 | 命令 |
|
|
85
|
+
| ------------ | ------------------------------------------------------------------- |
|
|
86
|
+
| 初始化 | `npx teamix-evo tokens init <variant>`(`<variant>` 必填,无默认) |
|
|
87
|
+
| 列出可选变体 | `npx teamix-evo tokens list-variants` |
|
|
88
|
+
| 列出已装资源 | `npx teamix-evo tokens list` |
|
|
89
|
+
| 升级 | `npx teamix-evo tokens update`(stub — 见 [ADR 0019](docs/adr/0019)) |
|
|
90
|
+
| 卸载 | `npx teamix-evo tokens uninstall [-y] [--keep-files]` |
|
|
91
|
+
|
|
92
|
+
- **`<variant>` 必填**。`tokens init` 之前必须先确定 variant(决策树或业务名映射)。
|
|
93
|
+
- `tokens update` 当前是 stub;权宜方案:删除 `.teamix-evo/tokens-lock.json` 与根 `tokens/`,重跑 `tokens init <variant>`。
|
|
94
|
+
- 资源分类(frozen / regenerable / managed)详见 [ADR 0003](docs/adr/0003-update-strategy-tri-state.md):`tokens.overrides.css` 是 `frozen`,用户改写永不被覆盖;`tokens.theme.css` / `tokens/base.tokens.json` 是 `regenerable`,每次 `update` 完整重写。ADR 0020 之后,`tokens init` 不再向工程根落 `AGENTS.md` / `DESIGN.md` 等 `managed` 文件 —— 设计纲领由 `teamix-evo-design-<variant>` skill 自包含。
|
|
95
|
+
|
|
96
|
+
### Skills(`@teamix-evo/skills`)
|
|
97
|
+
|
|
98
|
+
| 目标 | 命令 |
|
|
99
|
+
| -------- | ---------------------------------------------------- |
|
|
100
|
+
| 自举 | `npx teamix-evo skills init` |
|
|
101
|
+
| 增量装 | `npx teamix-evo skills add <name...>` |
|
|
102
|
+
| 列出全部 | `npx teamix-evo skills list`(alias `ls`) |
|
|
103
|
+
| 列出已装 | `npx teamix-evo skills list --installed` |
|
|
104
|
+
| 升级 | `npx teamix-evo skills update [name...] [--dry-run]` |
|
|
105
|
+
| 卸载 | `npx teamix-evo skills uninstall [-y]` |
|
|
106
|
+
| 漂移检测 | `npx teamix-evo skills doctor` |
|
|
107
|
+
| 重新镜像 | `npx teamix-evo skills sync [name...]` |
|
|
108
|
+
|
|
109
|
+
> 升级语义见 ADR 0035 双闸:仅升级 lock 已装且 scope 匹配的 skill;version 完全一致时短路;新 skill 用 `skills add <id>` 显式加入。
|
|
110
|
+
|
|
111
|
+
verb 分工(ADR 0034):
|
|
112
|
+
|
|
113
|
+
- **`skills init`**(无 ids):自举 — 按当前 tokens variant + install scope 装 manifest 里全部符合条件的 skill。已装的工程再跑会返回 `already-initialized`。
|
|
114
|
+
- **`skills add <name...>`**(必填 ids):增量 — 只装列出的 skill;已装的跳过(用 `update` 刷新)。不传 id 会被 commander 拒绝并输出 help。
|
|
115
|
+
|
|
116
|
+
首次交互式(无既有配置且无 flag 时):
|
|
117
|
+
|
|
118
|
+
1. 多选 IDE:**Qoder** / **Claude Code**(默认两者,至少一个)。等价 `--ide qoder,claude`。
|
|
119
|
+
2. Scope:**project**(默认,`.qoder/.claude` 在 cwd)/ **global**(`~/.qoder/~/.claude`)。等价 `--scope project|global`。
|
|
120
|
+
|
|
121
|
+
源镜像模型([ADR 0013](docs/adr/0013)):规范副本在 `.teamix-evo/skills/`,IDE 镜像在 `.qoder/skills/` 与 `.claude/skills/`。`doctor` 检测漂移,`sync` 重镜像(不升版本)。
|
|
122
|
+
|
|
123
|
+
### UI 组件(`@teamix-evo/ui`)
|
|
124
|
+
|
|
125
|
+
| 目标 | 命令 |
|
|
126
|
+
| ---------- | -------------------------------------- |
|
|
127
|
+
| 初始化 | `npx teamix-evo ui init [-y]` |
|
|
128
|
+
| 增加 entry | `npx teamix-evo ui add <id...>` |
|
|
129
|
+
| 列出 entry | `npx teamix-evo ui list [--installed]` |
|
|
130
|
+
|
|
131
|
+
- `ui init` 写 `.teamix-evo/config.json` 的 `packages.ui`(aliases / iconLibrary / tsx / rsc)。可交互元素的 `cursor: pointer` 由组件源码内显式声明,不再有全局 `preferences.css` —— 见 [ADR 0023](docs/adr/0023-cursor-pointer-explicit-in-component-source.md)
|
|
132
|
+
- `ui add` 自动解析 `registryDependencies`,组件源码写入 `src/components/ui/<id>.tsx`(frozen),并报告还需 `pnpm add` 的 npm 包。
|
|
133
|
+
- 没有 `ui upgrade` 子命令 — 组件升级走 `ui add` 覆盖即可。
|
|
134
|
+
|
|
135
|
+
### 业务组件(`@teamix-evo/biz-ui`)
|
|
136
|
+
|
|
137
|
+
| 目标 | 命令 |
|
|
138
|
+
| ---------- | ---------------------------------------------------- |
|
|
139
|
+
| 列出变体 | `npx teamix-evo biz-ui list-variants` |
|
|
140
|
+
| 增加 entry | `npx teamix-evo biz-ui add <id...> --variant <name>` |
|
|
141
|
+
|
|
142
|
+
- `--variant <name>` 必填(没有 auto-detect)。
|
|
143
|
+
- [ADR 0014](docs/adr/0014-ui-biz-ui-templates-tier.md):`tokens` / `biz-ui` / `templates` 共享 variant 名空间,与 `tokens init` 选定的 variant 一致。
|
|
144
|
+
|
|
145
|
+
### 页面模板(`@teamix-evo/templates`)
|
|
146
|
+
|
|
147
|
+
> ⚠️ **AI 默认不主动调用本 group**(见 [ADR 0031](docs/adr/0031-skill-templates-decoupling.md))。页面骨架由 `teamix-evo-design-<variant>` skill 的 `patterns/*.md` 驱动 ui + biz-ui 拼装;仅在用户**显式**说"用 templates 包装 frozen 骨架"时,才跳转本 group 命令。
|
|
148
|
+
|
|
149
|
+
| 目标 | 命令 |
|
|
150
|
+
| ---------- | ------------------------------------------------------- |
|
|
151
|
+
| 列出变体 | `npx teamix-evo templates list-variants` |
|
|
152
|
+
| 增加 entry | `npx teamix-evo templates add <id...> --variant <name>` |
|
|
153
|
+
|
|
154
|
+
同 `biz-ui` 的变体规则。模板源码写入 `src/templates/<id>.tsx`(frozen)。
|
|
155
|
+
|
|
156
|
+
### 日志(`@teamix-evo/logs`)
|
|
157
|
+
|
|
158
|
+
| 目标 | 命令 |
|
|
159
|
+
| ---------- | ----------------------------------- |
|
|
160
|
+
| 分析调用链 | `npx teamix-evo logs analyze [...]` |
|
|
161
|
+
|
|
162
|
+
- 读 vibe-logger 输出 `.teamix-evo/logs/ai/**/*.jsonl`,做 AI 调用链可视化。诊断 `runTokensInit` / `runUiAdd` 等编排流程时用。
|
|
163
|
+
|
|
164
|
+
## 场景 1 · 模糊初始化
|
|
165
|
+
|
|
166
|
+
**触发**:用户说"初始化一个项目 / 工程",未指明 variant。
|
|
167
|
+
|
|
168
|
+
**步骤**:
|
|
169
|
+
|
|
170
|
+
1. 确认目录(默认 `./<project-name>`,可由用户改)。
|
|
171
|
+
2. 列出 variants(`tokens list-variants` 的输出),让用户选(`AskUserQuestion`):
|
|
172
|
+
- OpenTrek(opentrek):AI 副驾驶 / 通用中后台
|
|
173
|
+
- Uni-Manager(uni-manager):云资源管理(大屏 / 拓扑 / 7 类 AI 场景)
|
|
174
|
+
3. 转场景 2,带上选定 variant 直跑。
|
|
175
|
+
|
|
176
|
+
## 场景 2 · 具名变体初始化(空目录 → 完整工程)
|
|
177
|
+
|
|
178
|
+
**触发**:用户在「业务名 → variant 映射」中能锁定 variant,或场景 1 询问后得到答复。
|
|
179
|
+
|
|
180
|
+
**唯一命令**:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npm create teamix-evo@latest <dir> --variant <name>
|
|
184
|
+
# 或 pnpm create teamix-evo <dir> --variant <name>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`create-teamix-evo` 的 `console` preset(默认且当前唯一)会自动一站式落地:
|
|
188
|
+
|
|
189
|
+
| 阶段 | 产物 |
|
|
190
|
+
| ---- | ---------------------------------------------------------------------------------------------------------- |
|
|
191
|
+
| 1 | Vite + React + TS scaffold(`src/`、`vite.config.ts` 等) |
|
|
192
|
+
| 2 | `tokens init <variant>` → 根 `tokens/` 目录(`tokens.theme.css` / `tokens.overrides.css`) |
|
|
193
|
+
| 3 | `skills add design-<variant> code-<variant>` → 项目级装 2 个 variant 内容 skill(manage 不在内,见 ADR 0033) |
|
|
194
|
+
| 4 | `ui init` → `.teamix-evo/config.json` |
|
|
195
|
+
| 5 | `ui add` → 真组件源码(button / card / input / form / table 等) |
|
|
196
|
+
| 6 | `lint init` → ESLint + Stylelint 配置 |
|
|
197
|
+
|
|
198
|
+
> 提示:`teamix-evo-manage` 是 entry skill,推荐**全局**装一次(`npx teamix-evo skills add teamix-evo-manage --scope global`)。create CLI 不会装它到 project,scaffold 完成后的 next-steps 会提示用户。
|
|
199
|
+
|
|
200
|
+
**完成后告知用户**:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
cd <dir>
|
|
204
|
+
pnpm dev # 立刻可跑
|
|
205
|
+
pnpm typecheck # 验证零类型错误
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## 场景 3 · AI coding 接入(现有仓库)
|
|
209
|
+
|
|
210
|
+
**触发**:用户已有 React/TS/Vite 仓库(已 `npm install` / 有 `package.json`),只想装 AI coding 体系。
|
|
211
|
+
|
|
212
|
+
**关键判断**:
|
|
213
|
+
|
|
214
|
+
- 跳过 scaffold(用户已有 `package.json`、`vite.config.ts`、`src/`)。
|
|
215
|
+
- `npm create teamix-evo` 会拒绝非空目录(除非 `--force` 且不含 `.teamix-evo/`),所以这里改用单包 CLI。
|
|
216
|
+
|
|
217
|
+
**步骤**:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# 1. 确定 variant(若用户未说,按映射表 / 询问)
|
|
221
|
+
npx teamix-evo tokens list-variants
|
|
222
|
+
npx teamix-evo tokens init <variant> # 装 tokens(写 tokens/ 与 .teamix-evo/tokens-lock.json)
|
|
223
|
+
|
|
224
|
+
# 2. 自举 skills(同源 Qoder + Claude;manage 是 global-only,自举自动跳过 — ADR 0033 + 0034)
|
|
225
|
+
npx teamix-evo skills init # 项目级装 design-<variant> + code-<variant>,默认两个 IDE 镜像
|
|
226
|
+
|
|
227
|
+
# 3. 装 ui 配置
|
|
228
|
+
npx teamix-evo ui init -y
|
|
229
|
+
npx teamix-evo ui add button # 可选:先装一个真组件验证
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**结束时告诉用户**:
|
|
233
|
+
|
|
234
|
+
- 已装的 skill 列表(从 `skills list --installed`)、tokens variant、ui aliases。
|
|
235
|
+
- 接下来怎么用:写新页面就触发 `teamix-evo-design-opentrek` / `teamix-evo-code-opentrek`。
|
|
236
|
+
- 若全局尚未安装 entry skill,补一句:`npx teamix-evo skills add teamix-evo-manage --scope global`(ADR 0033)。
|
|
237
|
+
|
|
238
|
+
## 场景 4 · 更新检测
|
|
239
|
+
|
|
240
|
+
**触发**:用户说"升级 / 看看哪些要升级 / update teamix-evo"。
|
|
241
|
+
|
|
242
|
+
**步骤**:
|
|
243
|
+
|
|
244
|
+
1. 读 `.teamix-evo/config.json` 的 `packages` 字段,看哪些已装(tokens / skills / ui / biz-ui / templates)。
|
|
245
|
+
2. 对每个已装包,跑对应 `list --installed`(若有该子命令)与上游 manifest 比对版本。
|
|
246
|
+
3. 仅对**已装**的包做 update:
|
|
247
|
+
- `npx teamix-evo tokens update`(stub — 仍提示用户清 + 重装)
|
|
248
|
+
- `npx teamix-evo skills update [name...] [--dry-run]` — 双闸 + version 短路 + 可选限定 id(ADR 0035)。先 `--dry-run` 给用户看清单,确认后再无 flag 跑一遍真升级
|
|
249
|
+
- 没有 `ui update`(组件升级走 `ui add` 覆盖即可)
|
|
250
|
+
|
|
251
|
+
**不要**给未安装的包做 install — 那是场景 2/3 的事。
|
|
252
|
+
|
|
253
|
+
## 场景 5 · 卸载
|
|
254
|
+
|
|
255
|
+
**触发**:用户说"卸载 teamix-evo / remove the design system"。
|
|
256
|
+
|
|
257
|
+
| 范围 | 命令 |
|
|
258
|
+
| --------------------------------------------- | ----------------------------------------------------- |
|
|
259
|
+
| Tokens | `npx teamix-evo tokens uninstall [-y] [--keep-files]` |
|
|
260
|
+
| Skills | `npx teamix-evo skills uninstall [-y]` |
|
|
261
|
+
| (UI 不提供卸载,组件源码用户拥有 → 用户手动删) | |
|
|
262
|
+
|
|
263
|
+
`tokens uninstall` 默认保留 `managed` 文件以保护用户编辑;`--keep-files` 完全保留物理文件,只清 manifest。
|
|
264
|
+
|
|
265
|
+
## 配置文件(信息性)
|
|
266
|
+
|
|
267
|
+
| 路径 | 所有者 | 说明 |
|
|
268
|
+
| ----------------------------- | ------ | --------------------------------------- |
|
|
269
|
+
| `.teamix-evo/config.json` | CLI | 已装包清单、版本、IDE / scope |
|
|
270
|
+
| `.teamix-evo/manifest.json` | CLI | 已装资源 ledger;diff / uninstall 的依据 |
|
|
271
|
+
| `tokens/tokens.overrides.css` | 用户 | 业务自定义 token 覆盖(`frozen`) |
|
|
272
|
+
|
|
273
|
+
**不要**手编 `config.json` / `manifest.json`,用对应 CLI 子命令。
|
|
274
|
+
|
|
275
|
+
## 常见错误与恢复路径(P8 — failures must be observable)
|
|
276
|
+
|
|
277
|
+
| 症状 | 原因 | 恢复路径 |
|
|
278
|
+
| -------------------------------------------------- | ------------------------------------------- | -------------------------------------------------- |
|
|
279
|
+
| `Unknown tokens variant "..."` | 拼写错误或上游未发布该 variant | `npx teamix-evo tokens list-variants` 列出当前可用 |
|
|
280
|
+
| `Target directory already contains a .teamix-evo/` | 误用 `npm create teamix-evo` 进已装目录 | 改走场景 4(更新)或场景 3(增量装) |
|
|
281
|
+
| `UI not initialized`(跑 `ui add` 时) | 未先跑 `ui init` | `npx teamix-evo ui init -y` 然后再 `ui add` |
|
|
282
|
+
| Vite/Tailwind 跑起来没样式 | `src/index.css` 缺少 tokens / Tailwind 导入 | 检查 `src/index.css` 的 `@import` 顺序 |
|
|
283
|
+
| Skills 在 IDE 不触发 | `.qoder/skills/` 或 `.claude/skills/` 漂移 | `npx teamix-evo skills doctor` 然后 `skills sync` |
|
|
284
|
+
|
|
285
|
+
<!-- teamix-evo:managed:end id="core" -->
|
|
286
|
+
|
|
287
|
+
## Notes for the user
|
|
288
|
+
|
|
289
|
+
> 这部分内容由你自由编辑。CLI 升级时只会替换 `id="core"` 区段,不会动这里的笔记。
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: teamix-evo-coding-conventions
|
|
3
|
-
description: |
|
|
4
|
-
Enforce teamix-evo coding conventions in consumer business apps — reuse-first against `@teamix-evo/ui` registry, API code under `src/services/`, `src/` layering and import boundaries.
|
|
5
|
-
TRIGGER when: user asks to "新增 / 重构 / 写一个" 组件 / 页面 / 接口 / 钩子 / 工具 / hook; phrases like "create a CRUD page"、"add an API call"、"extract a hook"、"refactor this fetch"、"调一下接口"、"加个组件"、"加个按钮"; file write under `src/pages/**`、`src/components/**`、`src/services/**`、`src/hooks/**`; AI is about to write any new `.tsx` / `.ts` file in a teamix-evo-installed project.
|
|
6
|
-
SKIP: pure visual / layout design questions about an already-existing screen with no code change (defer to teamix-evo-design-rules); teamix-evo lifecycle (init / update / uninstall) — those go to teamix-evo-manage; changes only to design tokens / styles / theme — those go to ESLint and `tokens.overrides.css`.
|
|
7
|
-
Coordinates with: teamix-evo-design-rules (run alongside when the change also creates a UI screen — design-rules handles the visual side, this skill handles file placement and reuse).
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# teamix-evo-coding-conventions
|
|
11
|
-
|
|
12
|
-
This skill bundles the **AI-readable engineering conventions** for consumer business apps that consume `@teamix-evo/*` packages. It complements [`teamix-evo-design-rules`](../teamix-evo-design-rules/SKILL.md) — design-rules tells AI *what a screen should look like*; this skill tells AI *where the code should live and what to reuse before writing new code*.
|
|
13
|
-
|
|
14
|
-
<!-- teamix-evo:managed:start id="core" -->
|
|
15
|
-
|
|
16
|
-
## When to use
|
|
17
|
-
|
|
18
|
-
Activate this skill whenever AI is about to **write or refactor code** inside a consumer app that has installed teamix-evo. Common signals:
|
|
19
|
-
|
|
20
|
-
- "新增一个 xxx 页面 / 列表页 / 详情页"
|
|
21
|
-
- "加一个 xxx 接口 / 调用 xxx API"
|
|
22
|
-
- "写一个 xxx 组件"
|
|
23
|
-
- "把这段重构一下"
|
|
24
|
-
- "create a CRUD page for orders"
|
|
25
|
-
- "add an API call to fetch users"
|
|
26
|
-
- Any time AI is about to create a new file under `src/pages/`、`src/components/`、`src/services/`、`src/hooks/`
|
|
27
|
-
|
|
28
|
-
If the task is purely about *visual design* of a screen (layout / colors / spacing), use [`teamix-evo-design-rules`](../teamix-evo-design-rules/SKILL.md) instead — or run both in tandem.
|
|
29
|
-
|
|
30
|
-
## What this skill does
|
|
31
|
-
|
|
32
|
-
Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-4 are baseline (always run); steps 5-7 are topic gates (run when the task touches that topic); step 8 is the final self-review.
|
|
33
|
-
|
|
34
|
-
1. **Reuse-first check** — read [`reuse-first.md`](reuse-first.md). Before creating any new component, query the `@teamix-evo/ui` registry (via MCP `list_components` / `find_components`) and grep the local project. Only write new code when no reuse path exists.
|
|
35
|
-
2. **Layering check** — read [`api-layering.md`](api-layering.md). Any code that talks to a backend goes under `src/services/<domain>.ts`. Components never call `fetch` / `axios` directly. Data hooks live in `src/hooks/` and consume services.
|
|
36
|
-
3. **Directory check** — read [`file-structure.md`](file-structure.md). Place the new file under the right top-level folder (pages / components / services / hooks / types / utils / lib / stores / contexts). Each folder has a single responsibility and an import boundary.
|
|
37
|
-
4. **Forms gate** — if the task involves a form, read [`forms-and-validation.md`](forms-and-validation.md). `react-hook-form` + `zod`; schema lives at `src/services/<domain>.schema.ts`. Never wire forms with raw `useState`.
|
|
38
|
-
5. **Error/loading gate** — if the task adds a page or data hook, read [`error-and-loading.md`](error-and-loading.md). Ensure global ErrorBoundary, page-level fallback, and three-state handling (`isPending` / `isError` / data) are in place; mutations report success/error via `toast`.
|
|
39
|
-
6. **Routing gate** — if the task adds a route or page-entry, read [`routing-and-codesplit.md`](routing-and-codesplit.md). Pages use `React.lazy`; auth/role guards live in `src/routes/guards.tsx`; 404 / 403 / 500 fallbacks exist.
|
|
40
|
-
7. **Testing gate** — read [`testing.md`](testing.md). Pure functions and zod schemas are **mandatory** to test; hooks and reusable components are recommended. Test files sit next to the source as `*.test.ts(x)`; `vitest` + `@testing-library/react` + `msw`.
|
|
41
|
-
8. **Self-review** — run [`checklist.md`](checklist.md). Every item must pass before declaring the change done. Anything failing must be fixed or surfaced to the user.
|
|
42
|
-
|
|
43
|
-
## Inputs the user provides
|
|
44
|
-
|
|
45
|
-
- Intent: "add a page", "add a service call", "refactor X", "extract a hook", etc.
|
|
46
|
-
- Optional: domain entity (`order`、`user`、`tenant`、`workflow`)
|
|
47
|
-
- Optional: existing file the change should land near
|
|
48
|
-
|
|
49
|
-
## Outputs
|
|
50
|
-
|
|
51
|
-
- Code placed under the conventional path (`src/pages/<id>/`、`src/services/<domain>.ts`、…)
|
|
52
|
-
- Reuse decisions explicitly logged ("reused `Button` from `@teamix-evo/ui`" / "no match found, wrote a new `OrderCard` under `src/components/`")
|
|
53
|
-
- Pass / fail status against [`checklist.md`](checklist.md)
|
|
54
|
-
|
|
55
|
-
## How to invoke (typical flow)
|
|
56
|
-
|
|
57
|
-
1. Parse user intent → identify which artifact is being created (page / component / service / hook / util / form / route)
|
|
58
|
-
2. Read [`reuse-first.md`](reuse-first.md) and run the reuse query (MCP first, then local grep)
|
|
59
|
-
3. Read [`file-structure.md`](file-structure.md) to pick the destination directory
|
|
60
|
-
4. If the change touches network / backend, read [`api-layering.md`](api-layering.md)
|
|
61
|
-
5. If the change involves a form, read [`forms-and-validation.md`](forms-and-validation.md)
|
|
62
|
-
6. If the change adds a page / data hook, read [`error-and-loading.md`](error-and-loading.md) for fallback / Skeleton / toast wiring
|
|
63
|
-
7. If the change adds a route or page entry, read [`routing-and-codesplit.md`](routing-and-codesplit.md)
|
|
64
|
-
8. Decide test coverage per [`testing.md`](testing.md); write `*.test.ts(x)` next to source
|
|
65
|
-
9. Write the code; cite each reuse / new-write decision in the response
|
|
66
|
-
10. Run through [`checklist.md`](checklist.md); list pass / fail explicitly
|
|
67
|
-
|
|
68
|
-
## Files in this skill
|
|
69
|
-
|
|
70
|
-
| File | Purpose |
|
|
71
|
-
| --- | --- |
|
|
72
|
-
| [`reuse-first.md`](reuse-first.md) | Decision flow for reusing existing components / utilities before writing new ones |
|
|
73
|
-
| [`file-structure.md`](file-structure.md) | Top-level `src/` folder layout、ownership、import boundaries、naming、global-state tier (useState → Context → store) |
|
|
74
|
-
| [`api-layering.md`](api-layering.md) | Where API code lives (`src/services/`)、how data flows from service → hook → component |
|
|
75
|
-
| [`forms-and-validation.md`](forms-and-validation.md) | `react-hook-form` + `zod` patterns、schema location、submit/error wiring |
|
|
76
|
-
| [`error-and-loading.md`](error-and-loading.md) | Global / page ErrorBoundary、react-query three-state、Suspense、toast、reportError |
|
|
77
|
-
| [`routing-and-codesplit.md`](routing-and-codesplit.md) | `React.lazy` per page、guards、404/403/500 fallback、search-params state、Suspense placement |
|
|
78
|
-
| [`testing.md`](testing.md) | `vitest` + RTL + msw、co-located tests、what is mandatory vs recommended |
|
|
79
|
-
| [`checklist.md`](checklist.md) | Multi-section self-review before declaring done |
|
|
80
|
-
|
|
81
|
-
## Relationship to other skills
|
|
82
|
-
|
|
83
|
-
- [`teamix-evo-design-rules`](../teamix-evo-design-rules/SKILL.md) — visual / interaction rules for screen generation. Run **alongside** this skill when the task includes UI; this skill never overrides design-rules on visual concerns.
|
|
84
|
-
- [`teamix-evo-manage`](../teamix-evo-manage/SKILL.md) — lifecycle (`init` / `update` / `uninstall` / `skills add`). Out of scope here.
|
|
85
|
-
|
|
86
|
-
## Why these conventions
|
|
87
|
-
|
|
88
|
-
- **Single source for UI** — `@teamix-evo/ui` is a source-injected component library (89 entries). Re-implementing `Button`、`Dialog`、`DataTable` etc. inside the consumer app fragments the design system and breaks token discipline.
|
|
89
|
-
- **Stable seams for change** — keeping API calls in `src/services/` means a backend rename only edits one file; keeping components free of fetch logic means they stay easy to test and reuse.
|
|
90
|
-
- **Predictable file location** — when AI (or a new teammate) opens an unfamiliar consumer app, the directory shape is the same across all teamix-evo-bootstrapped projects.
|
|
91
|
-
|
|
92
|
-
<!-- teamix-evo:managed:end -->
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
# 业务工程目录约定
|
|
2
|
-
|
|
3
|
-
> 业内主流 React/Vite 业务工程的标准目录骨架。本文件是 AI 决定"新建文件应该放在哪"的唯一参考。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 顶层 `src/` 骨架
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
src/
|
|
11
|
-
├── pages/ # 路由页面(每个目录对应一条路由)
|
|
12
|
-
├── components/ # 跨页面复用的业务组件
|
|
13
|
-
├── services/ # 后端通信(纯函数,见 api-layering.md)
|
|
14
|
-
├── hooks/ # 自定义 Hook(包含数据 hook、UI hook)
|
|
15
|
-
├── contexts/ # React Context(跨子树共享、低频更新的全局态)
|
|
16
|
-
├── stores/ # 高频全局态(zustand / jotai / redux,首次需要时引入,只用一种)
|
|
17
|
-
├── types/ # Domain / API 类型声明(.ts 仅类型,无运行时)
|
|
18
|
-
├── utils/ # 纯函数工具(无 React、无副作用)
|
|
19
|
-
├── lib/ # 三方 SDK 包装、http 实例、环境配置、monitor
|
|
20
|
-
├── routes/ # 路由配置 + 守卫(若用 react-router 集中式声明)
|
|
21
|
-
├── layouts/ # 应用级 / 区域级布局(ConsoleLayout、AuthLayout)
|
|
22
|
-
├── test/ # 测试基础设施(setup.ts、handlers.ts、render.tsx、fixtures/)
|
|
23
|
-
├── styles/ # 全局样式 / token 覆盖(尽量少)
|
|
24
|
-
├── assets/ # 图片 / 字体 / 静态文件
|
|
25
|
-
├── locales/ # i18n 资源(可选)
|
|
26
|
-
├── main.tsx # 应用入口
|
|
27
|
-
└── App.tsx # 根组件
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
> 没列出的目录按需补,但**不要**新增同义层(如同时有 `utils/` 和 `helpers/`、`api/` 和 `services/`、`views/` 和 `pages/`)。`*.test.ts(x)` 文件**就近**放在被测文件同目录,**不要**集中堆到顶层 `tests/`(见 [`testing.md`](testing.md))。
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 各目录职责与边界
|
|
35
|
-
|
|
36
|
-
### `src/pages/`
|
|
37
|
-
|
|
38
|
-
**职责**:路由页面。一个目录 = 一条路由。
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
src/pages/
|
|
42
|
-
├── orders/
|
|
43
|
-
│ ├── index.tsx # 列表页(/orders)
|
|
44
|
-
│ ├── [id].tsx # 详情页(/orders/:id),命名按路由方案
|
|
45
|
-
│ ├── _components/ # 仅本页面用的子组件(下划线前缀,不导出给外部)
|
|
46
|
-
│ │ └── OrderFilterBar.tsx
|
|
47
|
-
│ └── _hooks/ # 仅本页面用的 hook
|
|
48
|
-
│ └── useOrderFilter.ts
|
|
49
|
-
└── users/
|
|
50
|
-
└── ...
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
约束:
|
|
54
|
-
- 页面组件**默认 default export**,与文件名一致
|
|
55
|
-
- `_components/` `_hooks/` 用下划线前缀标记**私有**,**禁止跨页面 import**
|
|
56
|
-
- 跨页面用得到的组件/hook → 升到 `src/components/` `src/hooks/`
|
|
57
|
-
|
|
58
|
-
### `src/components/`
|
|
59
|
-
|
|
60
|
-
**职责**:跨页面复用的业务组件。
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
src/components/
|
|
64
|
-
├── OrderStatusBadge.tsx
|
|
65
|
-
├── UserAvatar.tsx
|
|
66
|
-
└── filters/
|
|
67
|
-
├── DateRangeFilter.tsx
|
|
68
|
-
└── StatusFilter.tsx
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
约束:
|
|
72
|
-
- 命名 PascalCase,文件名 = 组件名
|
|
73
|
-
- 单组件 = 单文件;复杂组件可建子目录 `<Name>/{index.tsx, types.ts, hooks.ts}`
|
|
74
|
-
- **不要**重复 `@teamix-evo/ui` 已经提供的能力(见 [reuse-first.md](reuse-first.md))
|
|
75
|
-
- **不要**写"小工具组件"如 `Wrapper`、`Container` —— 用 div + tailwind 即可
|
|
76
|
-
|
|
77
|
-
### `src/services/`
|
|
78
|
-
|
|
79
|
-
**职责**:后端通信纯函数。详见 [`api-layering.md`](api-layering.md)。
|
|
80
|
-
|
|
81
|
-
### `src/hooks/`
|
|
82
|
-
|
|
83
|
-
**职责**:跨页面复用的自定义 Hook。
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
src/hooks/
|
|
87
|
-
├── useOrderList.ts # 数据 hook(包 react-query)
|
|
88
|
-
├── useCreateOrder.ts
|
|
89
|
-
├── useDebounce.ts # UI hook
|
|
90
|
-
└── useMediaQuery.ts
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
约束:
|
|
94
|
-
- 命名必须 `use` 开头
|
|
95
|
-
- 单 hook = 单文件
|
|
96
|
-
- 数据 hook 调 `src/services/`,**禁止**直接 fetch
|
|
97
|
-
|
|
98
|
-
### 全局态选型决策
|
|
99
|
-
|
|
100
|
-
**装机时默认不预装任何状态库**。按"最小够用"逐级升级,不要直接跳到 zustand:
|
|
101
|
-
|
|
102
|
-
| 场景 | 用什么 |
|
|
103
|
-
| --- | --- |
|
|
104
|
-
| 组件内状态 | `useState` / `useReducer` |
|
|
105
|
-
| 跨少量组件、低频更新(当前用户、主题、语言、租户) | React `Context` |
|
|
106
|
-
| 跨域、多页面、**高频**更新的客户端态 | `src/stores/`(zustand / jotai / redux 选一) |
|
|
107
|
-
| 服务端数据(列表、详情、表单提交) | `react-query` / `swr`,**永远不进 Context、也不进 store** |
|
|
108
|
-
|
|
109
|
-
「高频」的粗略判定:一个状态被 10+ 处读取、且每秒可能变化一次以上 —— Context 会触发整子树重渲染,这时才有引 store 的收益。
|
|
110
|
-
|
|
111
|
-
Context 文件位置:
|
|
112
|
-
|
|
113
|
-
- 全应用级(UserContext、ThemeContext)→ `src/contexts/<Name>Context.tsx`
|
|
114
|
-
- 仅一个页面/子树用 → `src/pages/<id>/_components/<Name>Context.tsx`
|
|
115
|
-
|
|
116
|
-
> 如果项目自始至终只用 Context + react-query 就能解决,**不需要**建 `src/stores/`,也不需要引 zustand。等真出现跨域高频全局态再装。
|
|
117
|
-
|
|
118
|
-
### `src/stores/`
|
|
119
|
-
|
|
120
|
-
**职责**:跨域、高频更新的客户端全局态。**不是**全局态的默认入口,先看上方「全局态选型决策」。
|
|
121
|
-
|
|
122
|
-
约束:
|
|
123
|
-
|
|
124
|
-
- 一个项目**只用一种**状态库(zustand / jotai / redux 选一,首次需要时引入并固定)
|
|
125
|
-
- 按 domain 拆 store:`useOrderStore.ts`、`useUserStore.ts`
|
|
126
|
-
- **不要**把服务端数据放 store —— 用 `react-query` / `swr` 缓存(它们就是异步 store)
|
|
127
|
-
- **不要**为了消除一处 props drilling 就建 store —— 那是 Context 的场景
|
|
128
|
-
|
|
129
|
-
### `src/types/`
|
|
130
|
-
|
|
131
|
-
**职责**:类型声明。
|
|
132
|
-
|
|
133
|
-
约束:
|
|
134
|
-
- 只放 `.ts` 类型文件,**不导出运行时代码**
|
|
135
|
-
- 按 domain 拆:`order.ts`、`user.ts`
|
|
136
|
-
- 通用类型放 `api.ts`、`common.ts`
|
|
137
|
-
|
|
138
|
-
### `src/utils/`
|
|
139
|
-
|
|
140
|
-
**职责**:纯函数工具。
|
|
141
|
-
|
|
142
|
-
约束:
|
|
143
|
-
- **不依赖 React**(用了 React 应该是 hook,放 `src/hooks/`)
|
|
144
|
-
- **不依赖 DOM**(用了 DOM 应该是 lib 层包装)
|
|
145
|
-
- **不发请求**(发请求是 service)
|
|
146
|
-
- 一个文件一个主题:`format.ts`、`validate.ts`、`array.ts`
|
|
147
|
-
|
|
148
|
-
### `src/lib/`
|
|
149
|
-
|
|
150
|
-
**职责**:三方 SDK 包装、http 实例、env 读取。
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
src/lib/
|
|
154
|
-
├── http.ts # axios / fetch 实例(全局唯一)
|
|
155
|
-
├── env.ts # import.meta.env 的类型化封装
|
|
156
|
-
├── analytics.ts # 埋点 SDK 包装
|
|
157
|
-
└── map.ts # 第三方地图 SDK 包装
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
约束:
|
|
161
|
-
- 这一层**与 React 解耦**,可以在 Node / 测试中跑
|
|
162
|
-
- **不放业务逻辑** —— 业务逻辑去 service / hook
|
|
163
|
-
|
|
164
|
-
### `src/routes/`
|
|
165
|
-
|
|
166
|
-
仅当使用集中式路由声明(react-router data router)时才有:
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
src/routes/
|
|
170
|
-
├── index.tsx # createBrowserRouter 声明
|
|
171
|
-
└── guards.tsx # 鉴权守卫
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
文件路由(file-based routing)项目不需要这个目录。
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 命名约定
|
|
179
|
-
|
|
180
|
-
| 类型 | 风格 | 例 |
|
|
181
|
-
| --- | --- | --- |
|
|
182
|
-
| 目录 | kebab-case | `src/pages/order-detail/` |
|
|
183
|
-
| React 组件文件 | PascalCase.tsx | `OrderStatusBadge.tsx` |
|
|
184
|
-
| Hook 文件 | camelCase.ts,`use` 前缀 | `useOrderList.ts` |
|
|
185
|
-
| Service 文件 | camelCase.ts,domain 名 | `order.ts` |
|
|
186
|
-
| 工具文件 | camelCase.ts | `formatDate.ts` |
|
|
187
|
-
| 类型文件 | camelCase.ts,domain 名 | `order.ts` |
|
|
188
|
-
| 常量文件 | camelCase.ts 或 SCREAMING_SNAKE 导出 | `constants.ts` |
|
|
189
|
-
| 测试文件 | `*.test.ts(x)` 紧邻被测文件 | `formatDate.test.ts` |
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## 路径别名
|
|
194
|
-
|
|
195
|
-
业务工程默认配 `@/*` 指向 `src/*`,所有跨目录 import 走别名:
|
|
196
|
-
|
|
197
|
-
```ts
|
|
198
|
-
// ✅
|
|
199
|
-
import { Button } from '@teamix-evo/ui';
|
|
200
|
-
import { listOrders } from '@/services/order';
|
|
201
|
-
import { OrderStatusBadge } from '@/components/OrderStatusBadge';
|
|
202
|
-
|
|
203
|
-
// ❌
|
|
204
|
-
import { listOrders } from '../../../services/order';
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## Import 边界(单向依赖)
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
pages ──▶ components, hooks, services, types, utils, lib, stores
|
|
213
|
-
components ──▶ hooks, services, types, utils, lib (NOT pages)
|
|
214
|
-
hooks ──▶ services, types, utils, lib, stores (NOT components, NOT pages)
|
|
215
|
-
services ──▶ types, lib (NOT hooks, NOT components, NOT pages)
|
|
216
|
-
stores ──▶ types, utils, lib (NOT services, NOT hooks)
|
|
217
|
-
types ──▶ (no runtime imports)
|
|
218
|
-
utils ──▶ types only
|
|
219
|
-
lib ──▶ types only
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
要点:
|
|
223
|
-
- **services 不依赖 React** —— 它是纯函数层
|
|
224
|
-
- **types / utils / lib 是叶子层** —— 不依赖业务层,谁都能引
|
|
225
|
-
- **反向依赖直接否决**(component 不能 import page,service 不能 import hook)
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## 反模式速查
|
|
230
|
-
|
|
231
|
-
| 反模式 | 为什么禁 | 应该怎么做 |
|
|
232
|
-
| --- | --- | --- |
|
|
233
|
-
| `src/views/`、`src/screens/` 与 `src/pages/` 并存 | 同义层,认知爆炸 | 二选一,统一叫 `pages/` |
|
|
234
|
-
| `src/api/` 与 `src/services/` 并存 | 同义层 | 统一叫 `services/` |
|
|
235
|
-
| `src/utils/` 与 `src/helpers/` 并存 | 同义层 | 统一叫 `utils/` |
|
|
236
|
-
| 在 `src/components/` 里写 page-only 组件 | 抽象层级别错位 | 放 `src/pages/<id>/_components/` |
|
|
237
|
-
| 在 `src/utils/` 里写 React Hook | 边界错位 | 放 `src/hooks/` |
|
|
238
|
-
| 一个文件 export 5 个不相关的工具 | 命名失焦 | 拆成多文件,一个主题一个文件 |
|
|
239
|
-
| `index.ts` 大量 `export *` 当 barrel | 影响 tree-shaking、循环依赖 | 显式 named export 需要的几个 |
|
|
240
|
-
| 为消除一处 props drilling 直接引 zustand | 升级过度,徒增心智 | 用 React `Context` |
|
|
241
|
-
| 服务端数据塞进 Context / store | 与 query 缓存形成双源,易漂移 | 一律走 `react-query` / `swr` |
|
|
242
|
-
| 表单字段用一堆 `useState` 拼 | 字段越多越糟,校验散落 | `useForm` + `zodResolver`(见 [`forms-and-validation.md`](forms-and-validation.md)) |
|
|
243
|
-
| 页面顶部 `import` 不 lazy + 无 Suspense | 首屏 bundle 爆炸 / 进入即崩 | `React.lazy` + Layout 挂 Suspense(见 [`routing-and-codesplit.md`](routing-and-codesplit.md)) |
|
|
244
|
-
| 鉴权写在每个 page 顶部 | 散乱、易漏、UI 与 URL 两层不一致 | `src/routes/guards.tsx` 集中,URL 与 sidebar 两层都判 |
|
|
245
|
-
| 全局没有 ErrorBoundary | 任何未捕获异常直接白屏 | App 根挂 `ErrorBoundary` + `reportError` |
|
|
246
|
-
| 测试堆在顶层 `tests/` 目录 | 改文件忘记移动测试,易漂移 | `*.test.ts(x)` 就近紧邻被测文件 |
|
|
247
|
-
| `alert()` / `window.location.href = ...` | 阻断、丑、丢状态 | `toast.error()` / `useNavigate()` |
|
|
248
|
-
|
|
249
|
-
---
|
|
250
|
-
|
|
251
|
-
## 决策速查表
|
|
252
|
-
|
|
253
|
-
| AI 收到的请求 | 文件应该放在 |
|
|
254
|
-
| --- | --- |
|
|
255
|
-
| 新增订单列表页 | `src/pages/orders/index.tsx` |
|
|
256
|
-
| 新增订单状态徽章(跨页面用) | `src/components/OrderStatusBadge.tsx` |
|
|
257
|
-
| 新增订单状态徽章(只在订单页用) | `src/pages/orders/_components/OrderStatusBadge.tsx` |
|
|
258
|
-
| 新增"取消订单"接口调用 | `src/services/order.ts` 加 `cancelOrder` |
|
|
259
|
-
| 新增"取消订单"的 mutation hook | `src/hooks/useCancelOrder.ts` |
|
|
260
|
-
| 新增日期格式化函数 | `src/utils/format.ts`(先 grep 是否已存在) |
|
|
261
|
-
| 新增鉴权拦截器 | `src/lib/http.ts` 加 interceptor |
|
|
262
|
-
| 新增订单 domain 类型 | `src/types/order.ts` |
|
|
263
|
-
| 跨少量组件分享当前用户 / 主题 | `src/contexts/UserContext.tsx`(用 React Context) |
|
|
264
|
-
| 跨域高频全局态(首次需要) | `src/stores/useXxxStore.ts`(按需引 zustand,固定后只用一种) |
|
|
265
|
-
| 列表 / 详情等服务端数据 | `src/hooks/useXxx.ts` 包 `react-query`,**不进** store / Context |
|
|
266
|
-
| 新增"下单表单"(react-hook-form + zod) | `src/pages/orders/new/_components/CreateOrderForm.tsx` + `src/services/order.schema.ts` |
|
|
267
|
-
| 跨页面复用表单(地址 / 客户搜索) | `src/components/forms/<Name>Form.tsx` + 对应 schema |
|
|
268
|
-
| 新增路由 / 页面入口 | `src/routes/index.tsx` 注册 + `src/pages/<id>/index.tsx`(default export,被 `React.lazy` 引入) |
|
|
269
|
-
| 新增鉴权 / 角色守卫 | `src/routes/guards.tsx` |
|
|
270
|
-
| 全局 ErrorBoundary fallback 组件 | `src/components/GlobalErrorFallback.tsx` |
|
|
271
|
-
| Sentry / 日志上报包装 | `src/lib/monitor.ts`(`reportError(err, extra?)`) |
|
|
272
|
-
| 测试基础设施(msw handler / 自定义 render) | `src/test/handlers.ts` / `src/test/render.tsx` |
|
|
273
|
-
| 纯函数 / service / hook 的测试 | 同目录 `<name>.test.ts(x)`(就近,不集中) |
|