@wneng/create-keel 0.3.4 → 0.3.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wneng/create-keel",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Scaffolder for Contract First + Vibe Coding projects (keel conventions)",
5
5
  "keywords": [
6
6
  "scaffold",
@@ -7,12 +7,24 @@
7
7
 
8
8
  <!-- 一句话讲清楚这个 PR 改了什么、为什么 -->
9
9
 
10
+ ## 变更分级(Tier)
11
+
12
+ > 完整定义见 [`docs/governance/change-tiers.md`](../docs/governance/change-tiers.md)。**勾选一项**。
13
+
14
+ - [ ] **Tier 0** trivial — typo / 格式化 / patch 升级 / 补测试。无需契约 / ADR / PRD
15
+ - [ ] **Tier 1** bugfix — 修缺陷,无新行为。本 PR 描述含:重现 + 根因 + 修复 + 回归测试
16
+ - [ ] **Tier 2** small change — 局部小改(加按钮 / 排序 / 配置)。本 PR 描述含动机 + 方案 + 影响面
17
+ - [ ] **Tier 3** contract change — 改了 `contracts/`(加 API / 字段 / 错误码 / 事件)。已附契约锚点 + CHANGELOG 已同步
18
+ - [ ] **Tier 4** architecture / breaking — 跨服务 / 鉴权变化 / 删字段。已附 ADR + 详细设计 + 迁移 / 回滚预案
19
+ - [ ] **Tier 5** spike — 探索性改动。分支为 `spike/*`,**不会**合入 `main`(合入需重新走 Tier 1-4)
20
+
10
21
  ## 关联引用
11
22
 
12
- <!-- 至少填一项;契约 / 设计 / spec 三选一 -->
23
+ <!-- Tier 0/1/2 可省略;Tier 3+ 必须填 -->
13
24
 
14
25
  - 契约锚点:`contracts/openapi/api.yaml#/paths/...` 或 `contracts/events/event-catalog.yaml#/events/...`
15
26
  - 设计文档:`docs/04-后端详细设计/<slug>.md` 或 `docs/05-前端客户端详细设计/<slug>-<platform>.md`
27
+ - ADR(Tier 4 必填):`docs/02-系统方案与架构/adr-<NNNN>-<slug>.md`
16
28
  - spec:`.kiro/specs/<feature>/`(如适用)
17
29
 
18
30
  ## 变更类型
@@ -28,6 +28,15 @@ jobs:
28
28
  else
29
29
  echo "tools/governance-lint/ not present; skipping"
30
30
  fi
31
+ - |
32
+ # CODEOWNERS @TBD gate (AGENTS.md §3.1, docs/governance/git-workflow.md).
33
+ # The CODEOWNERS file ships with @TBD placeholders; CI must reject any
34
+ # merge that still contains them so reviewers are forced to assign real owners.
35
+ if [ -f CODEOWNERS ] && grep -q '@TBD' CODEOWNERS; then
36
+ echo "ERROR: CODEOWNERS still contains @TBD placeholder(s); replace with real Git accounts before merging."
37
+ grep -n '@TBD' CODEOWNERS || true
38
+ exit 1
39
+ fi
31
40
 
32
41
  contract-lint:
33
42
  stage: lint
@@ -7,12 +7,24 @@
7
7
 
8
8
  <!-- 一句话讲清楚这个 PR 改了什么、为什么 -->
9
9
 
10
+ ## 变更分级(Tier)
11
+
12
+ > 完整定义见 [`docs/governance/change-tiers.md`](../docs/governance/change-tiers.md)。**勾选一项**。
13
+
14
+ - [ ] **Tier 0** trivial — typo / 格式化 / patch 升级 / 补测试。无需契约 / ADR / PRD
15
+ - [ ] **Tier 1** bugfix — 修缺陷,无新行为。本 PR 描述含:重现 + 根因 + 修复 + 回归测试
16
+ - [ ] **Tier 2** small change — 局部小改(加按钮 / 排序 / 配置)。本 PR 描述含动机 + 方案 + 影响面
17
+ - [ ] **Tier 3** contract change — 改了 `contracts/`(加 API / 字段 / 错误码 / 事件)。已附契约锚点 + CHANGELOG 已同步
18
+ - [ ] **Tier 4** architecture / breaking — 跨服务 / 鉴权变化 / 删字段。已附 ADR + 详细设计 + 迁移 / 回滚预案
19
+ - [ ] **Tier 5** spike — 探索性改动。分支为 `spike/*`,**不会**合入 `main`(合入需重新走 Tier 1-4)
20
+
10
21
  ## 关联引用
11
22
 
12
- <!-- 至少填一项;契约 / 设计 / spec 三选一 -->
23
+ <!-- Tier 0/1/2 可省略;Tier 3+ 必须填 -->
13
24
 
14
25
  - 契约锚点:`contracts/openapi/api.yaml#/paths/...` 或 `contracts/events/event-catalog.yaml#/events/...`
15
26
  - 设计文档:`docs/04-后端详细设计/<slug>.md` 或 `docs/05-前端客户端详细设计/<slug>-<platform>.md`
27
+ - ADR(Tier 4 必填):`docs/02-系统方案与架构/adr-<NNNN>-<slug>.md`
16
28
  - spec:`.kiro/specs/<feature>/`(如适用)
17
29
 
18
30
  ## 变更类型
@@ -31,6 +31,15 @@ jobs:
31
31
  else
32
32
  echo "tools/governance-lint/ not present; skipping"
33
33
  fi
34
+ - name: codeowners-tbd-gate
35
+ run: |
36
+ # AGENTS.md §3.1 + docs/governance/git-workflow.md require real
37
+ # owners; @TBD placeholders must be replaced before merge.
38
+ if [ -f CODEOWNERS ] && grep -q '@TBD' CODEOWNERS; then
39
+ echo "ERROR: CODEOWNERS still contains @TBD placeholder(s); replace with real Git accounts before merging."
40
+ grep -n '@TBD' CODEOWNERS || true
41
+ exit 1
42
+ fi
34
43
 
35
44
  secret-scan:
36
45
  runs-on: ubuntu-latest
@@ -5,5 +5,5 @@ appliesWhen:
5
5
  priority: 20
6
6
  files:
7
7
  - from: files/asyncapi.yaml
8
- to: contracts/openapi/asyncapi.yaml
8
+ to: contracts/asyncapi/asyncapi.yaml
9
9
  render: true
@@ -8,5 +8,5 @@ files:
8
8
  to: contracts/openapi/api.yaml
9
9
  render: true
10
10
  - from: files/asyncapi.yaml
11
- to: contracts/openapi/asyncapi.yaml
11
+ to: contracts/asyncapi/asyncapi.yaml
12
12
  render: true
@@ -0,0 +1,135 @@
1
+ ---
2
+ last-reviewed: 2026-05-16
3
+ ---
4
+
5
+ # 变更分级(Change Tiers)
6
+
7
+ > AGENTS.md §6 的细则。澄清"先文档先契约再 code"在不同场景下应该有多厚。
8
+
9
+ ## 0. 为什么需要分级
10
+
11
+ `AGENTS.md` §2 的"Contract First"和 §6 的"先补契约和文档,再补实现"在小改动场景下容易被 AI 过度解读。常见误读:
12
+
13
+ - 改一个 typo → 想去补 PRD
14
+ - 修一个不涉及 API 的 bug → 想去更新 OpenAPI
15
+ - 加一行配置 → 想去写 ADR
16
+
17
+ 这浪费时间、噪声 PR、让团队反感框架本身。
18
+
19
+ **正确的理解**:
20
+ - **A. 方案讨论必须有书面结论**(载体可大可小)—— 总成立
21
+ - **B. 契约必须在 code 之前冻结**—— 仅当变更触及契约时成立
22
+
23
+ A + B 不是绑死的。改一个不动 API 的 bug,B 不触发;改一个 typo,A 也只需要 PR title + 一行描述。
24
+
25
+ ## 1. 六档 Tier
26
+
27
+ | Tier | 名称 | 典型场景 | A:方案记录的最小载体 | B:是否动契约 |
28
+ |---|---|---|---|---|
29
+ | **0** | trivial | 拼写、注释、格式化、补测试、依赖 patch 升级 | PR title + 1-2 行描述 | 不动 |
30
+ | **1** | bugfix | 修 NPE、错误的 SQL、UI 显示错位(无新行为) | PR 描述:**重现 + 根因 + 修复点 + 回归测试** | 不动 |
31
+ | **2** | small change | 加按钮 / 排序 / 导出列、调文案、加配置项 | PR 描述(含动机 + 方案 + 影响面),或 1 页 markdown 进 `docs/过程文档/drafts/` | 通常不动 |
32
+ | **3** | contract change | 加 API / 字段 / 错误码 / 事件 / 状态 | 简短设计章节(写在 `docs/04` 或 `docs/05` 的对应模块里)+ contracts 更新 + CHANGELOG | **必须**先冻结契约 |
33
+ | **4** | architecture / breaking | 新模块、跨服务、数据迁移、鉴权模型变化、删除字段 | PRD(若来自需求)→ ADR → 详细设计 → 契约 → code | **必须** ADR + 契约 + 迁移说明 |
34
+ | **5** | spike | 探索性、方案未明 | 在 `spike/*` 分支自由探索 | 合入 `main` 前补齐到对应 tier |
35
+
36
+ ## 2. 判定决策树
37
+
38
+ 按从严到宽顺序问自己:
39
+
40
+ 1. **改动改了 `contracts/` 任何文件?** → 至少 Tier 3
41
+ 2. **改动会改变 API / DB schema / 事件 / 鉴权 / 安全语义?**(即使现在 contracts 还没收录)→ Tier 3 或 4,**先把契约补上再继续**
42
+ 3. **删除或不兼容地修改了已有契约字段?** → Tier 4,**必须** ADR
43
+ 4. **跨服务、跨模块边界、跨执行环境(server↔web↔mobile)?** → Tier 4
44
+ 5. **会影响 ops/ 或 deploy/ 实际拓扑(新加一个 service / 新开一个端口 / 改加密策略)?** → Tier 4
45
+ 6. **是探索 / 调研,方案还不清楚?** → Tier 5(用 `spike/*` 分支)
46
+ 7. **以上都不是,纯局部、可逆的改动?** → 按体量定 Tier 0/1/2
47
+
48
+ ## 3. 反例(避免过度反应)
49
+
50
+ 下面这些情况 **不要** 升级 tier:
51
+
52
+ | 情形 | 正确 tier | 错误反应 |
53
+ |---|---|---|
54
+ | 修 `web/src/utils/format-date.ts` 的 typo 注释 | 0 | 写 PRD |
55
+ | `GET /users/{id}` 的实现里漏判 null,500 改 404 | 1(行为符合契约) | 改 OpenAPI |
56
+ | 给已有列表加"最近 7 天"筛选选项(前端筛选,后端无变化) | 2 | 写 ADR |
57
+ | `package.json` 里 `lodash 4.17.20 → 4.17.21`(patch) | 0 | 走完整升级流程 |
58
+ | 改 README 一段错别字 | 0 | 同步多份治理文件 |
59
+ | 重构一个内部 helper 函数(不导出) | 0 或 1 | 写详细设计 |
60
+ | 加测试覆盖既有功能 | 0 | 写 PRD |
61
+
62
+ 下面这些情况 **必须** 升级 tier:
63
+
64
+ | 情形 | 正确 tier | 误判风险 |
65
+ |---|---|---|
66
+ | 给 `GET /users/{id}` 加返回字段 `lastLoginAt` | 3 | 想成 Tier 2 / 文档"顺手补" |
67
+ | 给已有 List API 加 `?status=` 查询参数 | 3 | 想成 Tier 2 |
68
+ | 把鉴权从 cookie 改为 Bearer token | 4 | 想成 Tier 3 |
69
+ | 把 RBAC 从扁平改为支持继承 | 4 | 想成 Tier 3 |
70
+ | 引入新的消息队列 / 缓存层 / 第三方支付 | 4 | 想成 Tier 3 |
71
+ | 删除 `User.email` 字段 | 4 | 想成 Tier 3(删除 ≠ 兼容新增) |
72
+ | 升级 Spring Boot major 版本(3.x → 4.x) | 4 | 想成 Tier 0(只是版本号) |
73
+
74
+ ## 4. PR 模板里的 Tier 框
75
+
76
+ PR 模板顶部要求作者明示 tier。Reviewer 第一眼看到 tier 后:
77
+
78
+ - **Tier 0/1/2**:着重看代码 / 测试 / 描述完整性,不要求 ADR / 契约改动
79
+ - **Tier 3**:必须看到 contracts 同步、CHANGELOG 同步、契约锚点引用
80
+ - **Tier 4**:必须看到 ADR 存在或新增、详细设计文档、迁移 / 回滚预案
81
+ - **Tier 5**:分支必须是 `spike/*`;如果想合入 `main`,作者必须在合入 PR 中标明落地到了哪个 tier
82
+
83
+ CI 不强制校验 tier 标签(语义判定是 reviewer 的责任);但 CI **会**校验:
84
+
85
+ - 改了 `contracts/` 的 PR 必须同改 `contracts/CHANGELOG.md`(已有规则)
86
+ - `spike/*` 分支不能直接合入 `main`(PR 模板 + CODEOWNERS)
87
+
88
+ ## 5. AI 在 PR 描述中的引用义务
89
+
90
+ 按 tier 升级:
91
+
92
+ | Tier | 引用义务 |
93
+ |---|---|
94
+ | 0/1/2 | 不强制;PR 描述本身就是方案记录 |
95
+ | 3 | 必须引用契约锚点(如 `contracts/openapi/api.yaml#/paths/~1users/post`) |
96
+ | 4 | 必须引用 ADR / 详细设计文档;契约锚点也必须 |
97
+ | 5 | 必须标明 spike 分支与最终目标 tier |
98
+
99
+ AI 不要在 Tier 0/1/2 主动制造文档噪音;reviewer 也不要因"AI 没引用契约"而打回 Tier 0/1/2 的 PR。
100
+
101
+ ## 6. 与 spike 的关系
102
+
103
+ `spike/*` 分支是 Tier 5 的载体。它允许 AI 与开发者**暂时**绕过 Contract First:
104
+
105
+ 1. 创建 `spike/<topic>` 分支
106
+ 2. 自由写代码、跑实验、改方向
107
+ 3. 结论清楚后:
108
+ - 不采纳 → 文档进 `docs/过程文档/spike-investigations/`,分支保留备查
109
+ - 采纳 → 反向走完 Tier 1-4 该补的内容(PRD / ADR / 详细设计 / 契约),再合入 `main`
110
+
111
+ Spike 不是"绕过框架的永久后门"。`spike/*` 不能直接合入 `main`;合入 PR 必须用 `feat(...)` / `feat(ai)(...)` 等正式 type 重写。
112
+
113
+ ## 7. 何时升级 / 降级
114
+
115
+ 升级(向上):开发过程中发现影响面比预想大 → 立即升 tier,停下补对应文档 / 契约。
116
+
117
+ 降级(向下):通常**不允许**。一旦你声明 Tier 3+ 并写了契约 / ADR / 设计,就保留它。降级只在明确的"改动被裁掉了"场景下成立(例如:本来要加一个字段,最后发现可以用既有字段实现),此时把 tier 改成实际生效的层级,并在 PR 描述里写明。
118
+
119
+ ## 8. 与契约 SemVer 的关系
120
+
121
+ | Tier | 契约动作 | SemVer 影响 |
122
+ |---|---|---|
123
+ | 0/1/2 | 不动 | 无 |
124
+ | 3(兼容新增) | `MINOR` bump | `0.x.y → 0.(x+1).0`(pre-1.0)/ `x.y.z → x.(y+1).0`(≥1.0) |
125
+ | 3(破坏性,但还在 0.x) | `MINOR` bump + CHANGELOG 标 BREAKING | 同上(pre-1.0 允许) |
126
+ | 4(破坏性,≥1.0) | `MAJOR` bump | `x.y.z → (x+1).0.0` |
127
+
128
+ 完整版本策略 → [`../../contracts/README.md`](../../contracts/README.md)。
129
+
130
+ ## 9. 关联文档
131
+
132
+ - [`../../AGENTS.md`](../../AGENTS.md) §6(变更分级摘要)
133
+ - [`git-workflow.md`](git-workflow.md)(PR 模板与 CODEOWNERS 完整规则)
134
+ - [`checklists.md`](checklists.md)(每个 tier 的可勾选清单)
135
+ - [`../../contracts/README.md`](../../contracts/README.md)(契约 SemVer + CHANGELOG)
@@ -114,6 +114,9 @@ files:
114
114
  - from: files/governance-ai-access-modes.md
115
115
  to: docs/governance/ai-access-modes.md
116
116
  render: true
117
+ - from: files/governance-change-tiers.md
118
+ to: docs/governance/change-tiers.md
119
+ render: false
117
120
  - from: files/governance-checklists.md
118
121
  to: docs/governance/checklists.md
119
122
  render: true
@@ -57,7 +57,7 @@
57
57
 
58
58
  ## 2. 不可协商原则
59
59
 
60
- - **Contract First**:契约定义优先于代码实现。
60
+ - **Contract First**:契约定义优先于代码实现;变更触及契约时,**契约先冻结再写 code**(详见 §6 变更分级)。
61
61
  - 接口、事件、错误码、字典、状态机统一进入 `contracts/`,**禁止**在模块内部重复定义。
62
62
  - 由契约生成的 `generated/` 代码**禁止手改**;CI 校验"重新生成后 diff 为空"。
63
63
  - **禁止**提交 secret、私钥、真实 PII、真实用户数据。
@@ -93,6 +93,19 @@
93
93
  | 后端模块详细设计 | `docs/04-后端详细设计/` |
94
94
  | 前端 / 客户端模块详细设计 | `docs/05-前端客户端详细设计/` |
95
95
  <% if (it.options.integrations) { %>| 跨执行环境对接(已启用 `integrations`) | `docs/06-集成对接/<consumer>-to-<producer>/` |
96
+ <% } else { %>| 跨执行环境对接(**未启用 `integrations`**,启用后位于此目录) | `docs/06-集成对接/` |
97
+ <% } %><% if (it.options.roles && it.options.roles.includes('qa')) { %>| 测试计划 / 用例 / 缺陷库(已启用 qa 角色)| `docs/07-质量与测试/` |
98
+ <% } else { %>| 测试计划 / 用例 / 缺陷库(**未启用 qa 角色**,启用后位于此目录) | `docs/07-质量与测试/` |
99
+ <% } %><% if (it.options.roles && it.options.roles.includes('field')) { %>| 客户部署手册 / 上线作业书(已启用 field 角色,on-demand) | `docs/08-部署与现场实施/` |
100
+ <% } else { %>| 客户部署手册 / 上线作业书(**未启用 field 角色**) | `docs/08-部署与现场实施/`(启用后 on-demand)|
101
+ <% } %><% if (it.options.roles && it.options.roles.includes('data')) { %>| 埋点契约 / 看板 / 数据资产(已启用 data 角色) | `docs/09-数据与埋点/` |
102
+ <% } else { %>| 埋点契约 / 看板 / 数据资产(**未启用 data 角色**) | `docs/09-数据与埋点/` |
103
+ <% } %><% if (it.options.roles && it.options.roles.includes('legal-security')) { %>| 合规清单 / PIA / 安全证据(已启用 legal-security 角色,on-demand) | `docs/10-合规与安全/` |
104
+ <% } else { %>| 合规清单 / PIA / 安全证据(**未启用 legal-security 角色**) | `docs/10-合规与安全/`(启用后 on-demand) |
105
+ <% } %><% if (it.options.roles && it.options.roles.includes('marketing')) { %>| 产品介绍 / 白皮书 / 案例(已启用 marketing 角色,on-demand) | `docs/11-市场与对外材料/` |
106
+ <% } else { %>| 产品介绍 / 白皮书 / 案例(**未启用 marketing 角色**) | `docs/11-市场与对外材料/`(启用后 on-demand) |
107
+ <% } %><% if (it.options.roles && it.options.roles.includes('design')) { %>| 设计稿 / UI 规范(已启用 design 角色,on-demand) | `docs/design/` |
108
+ <% } else { %>| 设计稿 / UI 规范(**未启用 design 角色**) | `docs/design/`(启用后 on-demand) |
96
109
  <% } %>| 治理细则(CI / 安全 / Git / 资产 / 等) | `docs/governance/`(详见 §8) |
97
110
  | 架构图源、UI 稿、截图、设计稿 | `docs/assets/{diagrams,images,design}/` |
98
111
  | 行业标准、厂商手册、法规、合规参考 | `docs/references/{standards,vendors,legal}/` |
@@ -125,11 +138,28 @@
125
138
  - 完整规则 → [`docs/governance/integrations.md`](docs/governance/integrations.md)
126
139
  <% } %>
127
140
 
128
- ## 6. 核心协作规则
141
+ ## 6. 核心协作规则(变更分级)
129
142
 
130
- - 先补契约和文档,再补实现。
131
- - AI 生成代码必须在 PR / commit 中显式引用契约锚点和设计文档。
132
- - `spike/*` 分支允许暂时跳过契约;合入 `main` 前必须补齐。
143
+ 变更分**六档**,文档与契约的"厚度"匹配影响面。完整判定决策树、反例、与 SemVer 关系 → [`docs/governance/change-tiers.md`](docs/governance/change-tiers.md)。
144
+
145
+ | Tier | 典型 | 文档要求 | 契约动作 |
146
+ |---|---|---|---|
147
+ | 0 trivial | typo / 格式化 / patch 升级 / 补测试 | PR title + 1-2 行描述 | 不动 |
148
+ | 1 bugfix | 修 NPE / SQL / UI 错位(无新行为) | PR 描述:重现 + 根因 + 修复 + 回归测试 | 不动 |
149
+ | 2 small | 加按钮 / 排序 / 文案 / 配置项 | PR 描述(动机 + 方案 + 影响面) | 通常不动 |
150
+ | 3 contract | 加 API / 字段 / 错误码 / 事件 / 状态 | 简短设计章节进 `docs/04` 或 `docs/05` | **必须**先冻结契约 + CHANGELOG |
151
+ | 4 arch | 跨服务 / 鉴权变化 / 删字段 / breaking | PRD(如来自需求)→ ADR → 详细设计 → 契约 → code | **必须** ADR + 契约 + 迁移说明 |
152
+ | 5 spike | 探索 / 方案未明 | `spike/*` 分支自由探索 | 合入 `main` 前补到对应 tier |
153
+
154
+ **判定**:改 `contracts/` → 至少 Tier 3;改鉴权 / 跨服务 / 删字段 → Tier 4;纯局部 → 0/1/2;探索 → 5。
155
+
156
+ **AI 引用义务**(按 tier 升级):
157
+ - Tier 0/1/2:PR 描述自身即方案记录,**不强制**引用契约或 ADR
158
+ - Tier 3+:必须显式引用契约锚点(如 `contracts/openapi/api.yaml#/paths/~1users/post`)
159
+ - Tier 4:必须引用 ADR / 详细设计文档
160
+
161
+ 其他:
162
+ - `spike/*` 分支允许暂时跳过契约(即 Tier 5);合入 `main` 前必须补齐到对应 tier
133
163
  - 完整 PR 模板与 CODEOWNERS → [`docs/governance/git-workflow.md`](docs/governance/git-workflow.md)
134
164
  - 契约 SemVer / CHANGELOG / 废弃流程 → [`contracts/README.md`](contracts/README.md)
135
165
 
@@ -174,6 +204,7 @@
174
204
  | 集成对接 | [`docs/governance/integrations.md`](docs/governance/integrations.md) |
175
205
  | ops / deploy 完整规则 | [`docs/governance/deploy-ops.md`](docs/governance/deploy-ops.md) |
176
206
  | tools / scripts 完整规则 | [`docs/governance/tools-scripts.md`](docs/governance/tools-scripts.md) |
207
+ | 变更分级(六档 Tier) | [`docs/governance/change-tiers.md`](docs/governance/change-tiers.md) |
177
208
  | 完整 checklist | [`docs/governance/checklists.md`](docs/governance/checklists.md) |
178
209
  | 治理细则索引 | [`docs/governance/README.md`](docs/governance/README.md) |
179
210
 
@@ -13,7 +13,11 @@ module.exports = {
13
13
  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
14
14
  rules: {
15
15
  '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
16
- '@typescript-eslint/no-explicit-any': 'warn',
16
+ // docs/03-工程规范与研发基础设施/coding-style-typescript.md forbids `any`.
17
+ // Use `unknown` + narrowing, or define the missing type. Escape hatch:
18
+ // a per-line `// eslint-disable-next-line @typescript-eslint/no-explicit-any`
19
+ // with a comment explaining why.
20
+ '@typescript-eslint/no-explicit-any': 'error',
17
21
  '@typescript-eslint/consistent-type-imports': 'warn',
18
22
  },
19
23
  ignorePatterns: ['dist', 'node_modules', 'generated'],
@@ -27,7 +27,11 @@ module.exports = {
27
27
  'react/react-in-jsx-scope': 'off',
28
28
  'react/prop-types': 'off',
29
29
  '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
30
- '@typescript-eslint/no-explicit-any': 'warn',
30
+ // docs/03-工程规范与研发基础设施/coding-style-typescript.md forbids `any`.
31
+ // Use `unknown` + narrowing, or define the missing type. Escape hatch:
32
+ // a per-line `// eslint-disable-next-line @typescript-eslint/no-explicit-any`
33
+ // with a comment explaining why.
34
+ '@typescript-eslint/no-explicit-any': 'error',
31
35
  '@typescript-eslint/consistent-type-imports': 'warn',
32
36
  },
33
37
  ignorePatterns: ['dist', 'node_modules', 'generated'],
@@ -21,7 +21,11 @@ module.exports = {
21
21
  ],
22
22
  rules: {
23
23
  '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
24
- '@typescript-eslint/no-explicit-any': 'warn',
24
+ // docs/03-工程规范与研发基础设施/coding-style-typescript.md forbids `any`.
25
+ // Use `unknown` + narrowing, or define the missing type. Escape hatch:
26
+ // a per-line `// eslint-disable-next-line @typescript-eslint/no-explicit-any`
27
+ // with a comment explaining why.
28
+ '@typescript-eslint/no-explicit-any': 'error',
25
29
  'vue/multi-word-component-names': 'off',
26
30
  },
27
31
  ignorePatterns: ['dist', 'node_modules', 'generated'],