dev-playbooks-cn 1.0.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/LICENSE +21 -0
- package/README.md +466 -0
- package/bin/devbooks.js +987 -0
- package/package.json +43 -0
- package/skills/Skills/344/275/277/347/224/250/350/257/264/346/230/216.md +446 -0
- package/skills/Skill/345/274/200/345/217/221/346/214/207/345/215/227.md +248 -0
- package/skills/_shared/context-detection-template.md +315 -0
- package/skills/_shared/mcp-enhancement-template.md +144 -0
- package/skills/_shared/references//351/200/232/347/224/250/345/256/210/351/227/250/345/215/217/350/256/256.md +114 -0
- package/skills/_template/config-discovery-template.md +126 -0
- package/skills/devbooks-brownfield-bootstrap/SKILL.md +167 -0
- package/skills/devbooks-brownfield-bootstrap/references//344/273/243/347/240/201/345/257/274/350/210/252/347/255/226/347/225/245.md +203 -0
- package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226.md +96 -0
- package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226/346/217/220/347/244/272/350/257/215.md +115 -0
- package/skills/devbooks-brownfield-bootstrap/references//346/234/257/350/257/255/350/241/250/346/250/241/346/235/277.md +42 -0
- package/skills/devbooks-brownfield-bootstrap/scripts/cod-update.sh +357 -0
- package/skills/devbooks-brownfield-bootstrap/templates/project-profile-template.md +172 -0
- package/skills/devbooks-c4-map/SKILL.md +151 -0
- package/skills/devbooks-c4-map/references/C4/346/236/266/346/236/204/345/234/260/345/233/276/346/217/220/347/244/272/350/257/215.md +33 -0
- package/skills/devbooks-c4-map/references//345/210/206/345/261/202/347/272/246/346/235/237/346/243/200/346/237/245/346/270/205/345/215/225.md +185 -0
- package/skills/devbooks-code-review/SKILL.md +175 -0
- package/skills/devbooks-code-review/references/PR/346/250/241/346/235/277/344/270/216/346/214/207/345/215/227.md +321 -0
- package/skills/devbooks-code-review/references//344/273/243/347/240/201/350/257/204/345/256/241/346/217/220/347/244/272/350/257/215.md +100 -0
- package/skills/devbooks-code-review/references//345/235/217/345/221/263/351/201/223/351/200/237/346/237/245/350/241/250.md +495 -0
- package/skills/devbooks-code-review/references//350/265/204/346/272/220/347/256/241/347/220/206/345/256/241/346/237/245/346/270/205/345/215/225.md +311 -0
- package/skills/devbooks-coder/SKILL.md +219 -0
- package/skills/devbooks-coder/references//344/273/243/347/240/201/345/256/236/347/216/260/346/217/220/347/244/272/350/257/215.md +70 -0
- package/skills/devbooks-coder/references//344/275/216/351/243/216/351/231/251/346/224/271/345/212/250/346/212/200/346/234/257.md +275 -0
- package/skills/devbooks-coder/references//346/227/245/345/277/227/350/247/204/350/214/203.md +329 -0
- package/skills/devbooks-coder/references//347/274/226/347/240/201/351/243/216/346/240/274/347/273/206/345/210/231.md +351 -0
- package/skills/devbooks-coder/references//351/224/231/350/257/257/347/240/201/350/247/204/350/214/203.md +463 -0
- package/skills/devbooks-delivery-workflow/SKILL.md +217 -0
- package/skills/devbooks-delivery-workflow/references//344/272/244/344/273/230/351/252/214/346/224/266/345/267/245/344/275/234/346/265/201.md +256 -0
- package/skills/devbooks-delivery-workflow/references//345/216/237/345/236/213-/347/224/237/344/272/247/345/217/214/350/275/250/346/250/241/345/274/217.md +168 -0
- package/skills/devbooks-delivery-workflow/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +133 -0
- package/skills/devbooks-delivery-workflow/scripts/ac-trace-check.sh +330 -0
- package/skills/devbooks-delivery-workflow/scripts/audit-scope.sh +262 -0
- package/skills/devbooks-delivery-workflow/scripts/change-check.sh +1040 -0
- package/skills/devbooks-delivery-workflow/scripts/change-codemod-scaffold.sh +135 -0
- package/skills/devbooks-delivery-workflow/scripts/change-evidence.sh +152 -0
- package/skills/devbooks-delivery-workflow/scripts/change-scaffold.sh +442 -0
- package/skills/devbooks-delivery-workflow/scripts/change-spec-delta-scaffold.sh +136 -0
- package/skills/devbooks-delivery-workflow/scripts/constitution-check.sh +237 -0
- package/skills/devbooks-delivery-workflow/scripts/env-match-check.sh +128 -0
- package/skills/devbooks-delivery-workflow/scripts/fitness-check.sh +387 -0
- package/skills/devbooks-delivery-workflow/scripts/guardrail-check.sh +519 -0
- package/skills/devbooks-delivery-workflow/scripts/handoff-check.sh +141 -0
- package/skills/devbooks-delivery-workflow/scripts/hygiene-check.sh +340 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-from-openspec.sh +385 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-to-v2-gates.sh +202 -0
- package/skills/devbooks-delivery-workflow/scripts/progress-dashboard.sh +319 -0
- package/skills/devbooks-delivery-workflow/scripts/prototype-promote.sh +341 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-preview.sh +203 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-promote.sh +118 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-rollback.sh +124 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-stage.sh +117 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-all.sh +78 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-npm-package.sh +123 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-openspec-free.sh +81 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-slash-commands.sh +146 -0
- package/skills/devbooks-delivery-workflow/templates/handoff.md +50 -0
- package/skills/devbooks-design-backport/SKILL.md +73 -0
- package/skills/devbooks-design-backport/references//345/233/236/345/206/231/350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +196 -0
- package/skills/devbooks-design-doc/SKILL.md +121 -0
- package/skills/devbooks-design-doc/references//345/276/256/346/234/215/345/212/241/350/256/276/350/256/241/346/270/205/345/215/225.md +149 -0
- package/skills/devbooks-design-doc/references//350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +189 -0
- package/skills/devbooks-design-doc/references//351/232/220/347/247/201/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +240 -0
- package/skills/devbooks-entropy-monitor/SKILL.md +188 -0
- package/skills/devbooks-entropy-monitor/references//347/206/265/345/272/246/351/207/217/346/226/271/346/263/225/350/256/272.md +223 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-measure.sh +449 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-report.sh +303 -0
- package/skills/devbooks-entropy-monitor/templates/thresholds.json +99 -0
- package/skills/devbooks-federation/SKILL.md +264 -0
- package/skills/devbooks-federation/scripts/federation-check.sh +144 -0
- package/skills/devbooks-federation/templates/federation.yaml +89 -0
- package/skills/devbooks-impact-analysis/SKILL.md +135 -0
- package/skills/devbooks-impact-analysis/references//345/275/261/345/223/215/345/210/206/346/236/220/346/217/220/347/244/272/350/257/215.md +82 -0
- package/skills/devbooks-impact-analysis/scripts/graph-cache.sh +214 -0
- package/skills/devbooks-implementation-plan/SKILL.md +83 -0
- package/skills/devbooks-implementation-plan/references//347/274/226/347/240/201/350/256/241/345/210/222/346/217/220/347/244/272/350/257/215.md +99 -0
- package/skills/devbooks-index-bootstrap/SKILL.md +240 -0
- package/skills/devbooks-proposal-author/SKILL.md +83 -0
- package/skills/devbooks-proposal-author/references//346/217/220/346/241/210/346/222/260/345/206/231/346/217/220/347/244/272/350/257/215.md +66 -0
- package/skills/devbooks-proposal-challenger/SKILL.md +86 -0
- package/skills/devbooks-proposal-challenger/references//344/274/246/347/220/206/344/270/216/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +176 -0
- package/skills/devbooks-proposal-challenger/references//346/217/220/346/241/210/350/264/250/347/226/221/346/217/220/347/244/272/350/257/215.md +57 -0
- package/skills/devbooks-proposal-debate-workflow/SKILL.md +78 -0
- package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/345/267/245/344/275/234/346/265/201.md +24 -0
- package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/346/250/241/346/235/277.md +35 -0
- package/skills/devbooks-proposal-debate-workflow/scripts/proposal-debate-check.sh +102 -0
- package/skills/devbooks-proposal-judge/SKILL.md +78 -0
- package/skills/devbooks-proposal-judge/references//346/217/220/346/241/210/350/243/201/345/206/263/346/217/220/347/244/272/350/257/215.md +37 -0
- package/skills/devbooks-router/SKILL.md +346 -0
- package/skills/devbooks-spec-contract/SKILL.md +191 -0
- package/skills/devbooks-spec-contract/references/API/350/256/276/350/256/241/346/214/207/345/215/227.md +349 -0
- package/skills/devbooks-spec-contract/references//345/245/221/347/272/246/344/270/216/346/225/260/346/215/256/345/256/232/344/271/211/346/217/220/347/244/272/350/257/215.md +85 -0
- package/skills/devbooks-spec-contract/references//350/247/204/346/240/274/345/217/230/346/233/264/346/217/220/347/244/272/350/257/215.md +63 -0
- package/skills/devbooks-spec-contract/references//351/232/220/345/274/217/345/217/230/346/233/264/346/243/200/346/265/213/346/217/220/347/244/272/350/257/215.md +183 -0
- package/skills/devbooks-spec-contract/scripts/implicit-change-detect.sh +378 -0
- package/skills/devbooks-spec-gardener/SKILL.md +72 -0
- package/skills/devbooks-spec-gardener/references//350/247/204/346/240/274/345/233/255/344/270/201/346/217/220/347/244/272/350/257/215.md +41 -0
- package/skills/devbooks-test-owner/SKILL.md +172 -0
- package/skills/devbooks-test-owner/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +228 -0
- package/skills/devbooks-test-owner/references//345/274/202/346/255/245/347/263/273/347/273/237/346/265/213/350/257/225/347/255/226/347/225/245.md +316 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/344/273/243/347/240/201/346/217/220/347/244/272/350/257/215.md +208 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/345/210/206/345/261/202/347/255/226/347/225/245.md +281 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/351/251/261/345/212/250.md +394 -0
- package/skills/devbooks-test-owner/references//350/247/243/344/276/235/350/265/226/346/212/200/346/234/257/351/200/237/346/237/245/350/241/250.md +432 -0
- package/skills/devbooks-test-reviewer/SKILL.md +189 -0
- package/templates/.devbooks/config.yaml +88 -0
- package/templates/claude-commands/devbooks/apply.md +38 -0
- package/templates/claude-commands/devbooks/archive.md +33 -0
- package/templates/claude-commands/devbooks/backport.md +19 -0
- package/templates/claude-commands/devbooks/bootstrap.md +19 -0
- package/templates/claude-commands/devbooks/c4.md +19 -0
- package/templates/claude-commands/devbooks/challenger.md +19 -0
- package/templates/claude-commands/devbooks/code.md +19 -0
- package/templates/claude-commands/devbooks/debate.md +19 -0
- package/templates/claude-commands/devbooks/delivery.md +19 -0
- package/templates/claude-commands/devbooks/design.md +19 -0
- package/templates/claude-commands/devbooks/entropy.md +19 -0
- package/templates/claude-commands/devbooks/federation.md +19 -0
- package/templates/claude-commands/devbooks/gardener.md +19 -0
- package/templates/claude-commands/devbooks/impact.md +19 -0
- package/templates/claude-commands/devbooks/index.md +19 -0
- package/templates/claude-commands/devbooks/judge.md +19 -0
- package/templates/claude-commands/devbooks/plan.md +19 -0
- package/templates/claude-commands/devbooks/proposal.md +19 -0
- package/templates/claude-commands/devbooks/quick.md +42 -0
- package/templates/claude-commands/devbooks/review.md +19 -0
- package/templates/claude-commands/devbooks/router.md +19 -0
- package/templates/claude-commands/devbooks/spec.md +19 -0
- package/templates/claude-commands/devbooks/test-review.md +19 -0
- package/templates/claude-commands/devbooks/test.md +19 -0
- package/templates/dev-playbooks/README.md +458 -0
- package/templates/dev-playbooks/changes/.gitkeep +1 -0
- package/templates/dev-playbooks/constitution.md +116 -0
- package/templates/dev-playbooks/project.md +96 -0
- package/templates/dev-playbooks/scripts/.gitkeep +1 -0
- package/templates/dev-playbooks/specs/_meta/anti-patterns/.gitkeep +2 -0
- package/templates/dev-playbooks/specs/_meta/glossary.md +47 -0
- package/templates/dev-playbooks/specs/_meta/project-profile.md +79 -0
- package/templates/dev-playbooks/specs/architecture/fitness-rules.md +95 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
# 错误码规范
|
|
2
|
+
|
|
3
|
+
借鉴 VS Code 错误处理模式,本文档定义了应用程序错误码的标准规范。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1) 错误码设计原则
|
|
8
|
+
|
|
9
|
+
### 1.1 可读性
|
|
10
|
+
|
|
11
|
+
错误码应该人类可读,便于理解和记忆。
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
// 推荐:语义化错误码
|
|
15
|
+
'USER_NOT_FOUND'
|
|
16
|
+
'INVALID_EMAIL_FORMAT'
|
|
17
|
+
'PAYMENT_DECLINED'
|
|
18
|
+
|
|
19
|
+
// 避免:纯数字或无意义编码
|
|
20
|
+
'E10001'
|
|
21
|
+
'ERR_X7B2'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 1.2 唯一性
|
|
25
|
+
|
|
26
|
+
每个错误码在整个系统中应该是唯一的。
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// 使用前缀区分模块
|
|
30
|
+
'AUTH_INVALID_TOKEN'
|
|
31
|
+
'AUTH_SESSION_EXPIRED'
|
|
32
|
+
'ORDER_NOT_FOUND'
|
|
33
|
+
'ORDER_ALREADY_PAID'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 1.3 稳定性
|
|
37
|
+
|
|
38
|
+
错误码一旦发布就不应该改变含义。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2) 错误码格式
|
|
43
|
+
|
|
44
|
+
### 标准格式
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
<MODULE>_<CATEGORY>_<DESCRIPTION>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| 部分 | 说明 | 示例 |
|
|
51
|
+
|------|------|------|
|
|
52
|
+
| MODULE | 模块/服务名 | `AUTH`, `ORDER`, `USER` |
|
|
53
|
+
| CATEGORY | 错误类别 | `INVALID`, `NOT_FOUND`, `FAILED` |
|
|
54
|
+
| DESCRIPTION | 具体描述 | `TOKEN`, `EMAIL`, `PAYMENT` |
|
|
55
|
+
|
|
56
|
+
### 示例
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// 认证模块
|
|
60
|
+
'AUTH_INVALID_CREDENTIALS'
|
|
61
|
+
'AUTH_TOKEN_EXPIRED'
|
|
62
|
+
'AUTH_PERMISSION_DENIED'
|
|
63
|
+
|
|
64
|
+
// 用户模块
|
|
65
|
+
'USER_NOT_FOUND'
|
|
66
|
+
'USER_ALREADY_EXISTS'
|
|
67
|
+
'USER_INVALID_EMAIL'
|
|
68
|
+
|
|
69
|
+
// 订单模块
|
|
70
|
+
'ORDER_NOT_FOUND'
|
|
71
|
+
'ORDER_INVALID_STATUS'
|
|
72
|
+
'ORDER_PAYMENT_FAILED'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 3) 错误类别
|
|
78
|
+
|
|
79
|
+
### 标准类别
|
|
80
|
+
|
|
81
|
+
| 类别 | HTTP 状态码 | 说明 |
|
|
82
|
+
|------|------------|------|
|
|
83
|
+
| `INVALID` | 400 | 输入验证失败 |
|
|
84
|
+
| `UNAUTHORIZED` | 401 | 未认证 |
|
|
85
|
+
| `FORBIDDEN` | 403 | 无权限 |
|
|
86
|
+
| `NOT_FOUND` | 404 | 资源不存在 |
|
|
87
|
+
| `CONFLICT` | 409 | 资源冲突 |
|
|
88
|
+
| `RATE_LIMITED` | 429 | 限流 |
|
|
89
|
+
| `INTERNAL` | 500 | 内部错误 |
|
|
90
|
+
| `UNAVAILABLE` | 503 | 服务不可用 |
|
|
91
|
+
| `TIMEOUT` | 504 | 超时 |
|
|
92
|
+
|
|
93
|
+
### 映射表
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const ERROR_STATUS_MAP: Record<string, number> = {
|
|
97
|
+
// 400 Bad Request
|
|
98
|
+
'INVALID': 400,
|
|
99
|
+
'VALIDATION': 400,
|
|
100
|
+
'MALFORMED': 400,
|
|
101
|
+
|
|
102
|
+
// 401 Unauthorized
|
|
103
|
+
'UNAUTHORIZED': 401,
|
|
104
|
+
'UNAUTHENTICATED': 401,
|
|
105
|
+
|
|
106
|
+
// 403 Forbidden
|
|
107
|
+
'FORBIDDEN': 403,
|
|
108
|
+
'PERMISSION': 403,
|
|
109
|
+
|
|
110
|
+
// 404 Not Found
|
|
111
|
+
'NOT_FOUND': 404,
|
|
112
|
+
'MISSING': 404,
|
|
113
|
+
|
|
114
|
+
// 409 Conflict
|
|
115
|
+
'CONFLICT': 409,
|
|
116
|
+
'DUPLICATE': 409,
|
|
117
|
+
'ALREADY_EXISTS': 409,
|
|
118
|
+
|
|
119
|
+
// 429 Too Many Requests
|
|
120
|
+
'RATE_LIMITED': 429,
|
|
121
|
+
'THROTTLED': 429,
|
|
122
|
+
|
|
123
|
+
// 500 Internal Server Error
|
|
124
|
+
'INTERNAL': 500,
|
|
125
|
+
'UNEXPECTED': 500,
|
|
126
|
+
|
|
127
|
+
// 503 Service Unavailable
|
|
128
|
+
'UNAVAILABLE': 503,
|
|
129
|
+
'MAINTENANCE': 503,
|
|
130
|
+
|
|
131
|
+
// 504 Gateway Timeout
|
|
132
|
+
'TIMEOUT': 504,
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 4) 错误类实现
|
|
139
|
+
|
|
140
|
+
### 基础错误类
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
interface ErrorDetails {
|
|
144
|
+
[key: string]: unknown;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
class AppError extends Error {
|
|
148
|
+
public readonly code: string;
|
|
149
|
+
public readonly statusCode: number;
|
|
150
|
+
public readonly details?: ErrorDetails;
|
|
151
|
+
public readonly timestamp: string;
|
|
152
|
+
public readonly isOperational: boolean;
|
|
153
|
+
|
|
154
|
+
constructor(
|
|
155
|
+
code: string,
|
|
156
|
+
message: string,
|
|
157
|
+
statusCode: number = 500,
|
|
158
|
+
details?: ErrorDetails
|
|
159
|
+
) {
|
|
160
|
+
super(message);
|
|
161
|
+
this.name = this.constructor.name;
|
|
162
|
+
this.code = code;
|
|
163
|
+
this.statusCode = statusCode;
|
|
164
|
+
this.details = details;
|
|
165
|
+
this.timestamp = new Date().toISOString();
|
|
166
|
+
this.isOperational = true; // 区分业务错误和系统错误
|
|
167
|
+
|
|
168
|
+
Error.captureStackTrace(this, this.constructor);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
toJSON() {
|
|
172
|
+
return {
|
|
173
|
+
code: this.code,
|
|
174
|
+
message: this.message,
|
|
175
|
+
statusCode: this.statusCode,
|
|
176
|
+
details: this.details,
|
|
177
|
+
timestamp: this.timestamp,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 具体错误类
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// 验证错误
|
|
187
|
+
class ValidationError extends AppError {
|
|
188
|
+
constructor(field: string, message: string) {
|
|
189
|
+
super(
|
|
190
|
+
`VALIDATION_${field.toUpperCase()}_INVALID`,
|
|
191
|
+
message,
|
|
192
|
+
400,
|
|
193
|
+
{ field }
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 未找到错误
|
|
199
|
+
class NotFoundError extends AppError {
|
|
200
|
+
constructor(resource: string, id: string) {
|
|
201
|
+
super(
|
|
202
|
+
`${resource.toUpperCase()}_NOT_FOUND`,
|
|
203
|
+
`${resource} with id '${id}' not found`,
|
|
204
|
+
404,
|
|
205
|
+
{ resource, id }
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 认证错误
|
|
211
|
+
class AuthenticationError extends AppError {
|
|
212
|
+
constructor(reason: string) {
|
|
213
|
+
super(
|
|
214
|
+
`AUTH_${reason.toUpperCase()}`,
|
|
215
|
+
`Authentication failed: ${reason}`,
|
|
216
|
+
401
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// 权限错误
|
|
222
|
+
class ForbiddenError extends AppError {
|
|
223
|
+
constructor(action: string, resource: string) {
|
|
224
|
+
super(
|
|
225
|
+
'AUTH_PERMISSION_DENIED',
|
|
226
|
+
`You don't have permission to ${action} ${resource}`,
|
|
227
|
+
403,
|
|
228
|
+
{ action, resource }
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 冲突错误
|
|
234
|
+
class ConflictError extends AppError {
|
|
235
|
+
constructor(resource: string, conflict: string) {
|
|
236
|
+
super(
|
|
237
|
+
`${resource.toUpperCase()}_CONFLICT`,
|
|
238
|
+
`${resource} conflict: ${conflict}`,
|
|
239
|
+
409,
|
|
240
|
+
{ resource, conflict }
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## 5) 错误码注册表
|
|
249
|
+
|
|
250
|
+
### 中央注册表
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// errors/registry.ts
|
|
254
|
+
export const ERROR_REGISTRY = {
|
|
255
|
+
// ===== 认证模块 (AUTH_*) =====
|
|
256
|
+
AUTH_INVALID_CREDENTIALS: {
|
|
257
|
+
message: 'Invalid username or password',
|
|
258
|
+
statusCode: 401,
|
|
259
|
+
recoverable: true,
|
|
260
|
+
},
|
|
261
|
+
AUTH_TOKEN_EXPIRED: {
|
|
262
|
+
message: 'Authentication token has expired',
|
|
263
|
+
statusCode: 401,
|
|
264
|
+
recoverable: true,
|
|
265
|
+
},
|
|
266
|
+
AUTH_TOKEN_INVALID: {
|
|
267
|
+
message: 'Invalid authentication token',
|
|
268
|
+
statusCode: 401,
|
|
269
|
+
recoverable: false,
|
|
270
|
+
},
|
|
271
|
+
AUTH_PERMISSION_DENIED: {
|
|
272
|
+
message: 'You do not have permission to perform this action',
|
|
273
|
+
statusCode: 403,
|
|
274
|
+
recoverable: false,
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
// ===== 用户模块 (USER_*) =====
|
|
278
|
+
USER_NOT_FOUND: {
|
|
279
|
+
message: 'User not found',
|
|
280
|
+
statusCode: 404,
|
|
281
|
+
recoverable: false,
|
|
282
|
+
},
|
|
283
|
+
USER_ALREADY_EXISTS: {
|
|
284
|
+
message: 'User already exists',
|
|
285
|
+
statusCode: 409,
|
|
286
|
+
recoverable: false,
|
|
287
|
+
},
|
|
288
|
+
USER_INVALID_EMAIL: {
|
|
289
|
+
message: 'Invalid email format',
|
|
290
|
+
statusCode: 400,
|
|
291
|
+
recoverable: true,
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
// ===== 订单模块 (ORDER_*) =====
|
|
295
|
+
ORDER_NOT_FOUND: {
|
|
296
|
+
message: 'Order not found',
|
|
297
|
+
statusCode: 404,
|
|
298
|
+
recoverable: false,
|
|
299
|
+
},
|
|
300
|
+
ORDER_INVALID_STATUS: {
|
|
301
|
+
message: 'Invalid order status transition',
|
|
302
|
+
statusCode: 400,
|
|
303
|
+
recoverable: false,
|
|
304
|
+
},
|
|
305
|
+
ORDER_PAYMENT_FAILED: {
|
|
306
|
+
message: 'Payment processing failed',
|
|
307
|
+
statusCode: 402,
|
|
308
|
+
recoverable: true,
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
// ===== 系统错误 (SYSTEM_*) =====
|
|
312
|
+
SYSTEM_INTERNAL_ERROR: {
|
|
313
|
+
message: 'An internal error occurred',
|
|
314
|
+
statusCode: 500,
|
|
315
|
+
recoverable: false,
|
|
316
|
+
},
|
|
317
|
+
SYSTEM_SERVICE_UNAVAILABLE: {
|
|
318
|
+
message: 'Service temporarily unavailable',
|
|
319
|
+
statusCode: 503,
|
|
320
|
+
recoverable: true,
|
|
321
|
+
},
|
|
322
|
+
SYSTEM_RATE_LIMITED: {
|
|
323
|
+
message: 'Too many requests, please try again later',
|
|
324
|
+
statusCode: 429,
|
|
325
|
+
recoverable: true,
|
|
326
|
+
},
|
|
327
|
+
} as const;
|
|
328
|
+
|
|
329
|
+
export type ErrorCode = keyof typeof ERROR_REGISTRY;
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### 使用注册表
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
function createError(code: ErrorCode, details?: ErrorDetails): AppError {
|
|
336
|
+
const config = ERROR_REGISTRY[code];
|
|
337
|
+
return new AppError(
|
|
338
|
+
code,
|
|
339
|
+
config.message,
|
|
340
|
+
config.statusCode,
|
|
341
|
+
details
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// 使用
|
|
346
|
+
throw createError('USER_NOT_FOUND', { userId: '12345' });
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## 6) 错误响应格式
|
|
352
|
+
|
|
353
|
+
### API 错误响应
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
interface ErrorResponse {
|
|
357
|
+
error: {
|
|
358
|
+
code: string;
|
|
359
|
+
message: string;
|
|
360
|
+
details?: ErrorDetails;
|
|
361
|
+
timestamp: string;
|
|
362
|
+
requestId?: string;
|
|
363
|
+
documentation?: string;
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// 示例响应
|
|
368
|
+
{
|
|
369
|
+
"error": {
|
|
370
|
+
"code": "USER_NOT_FOUND",
|
|
371
|
+
"message": "User with id '12345' not found",
|
|
372
|
+
"details": {
|
|
373
|
+
"userId": "12345"
|
|
374
|
+
},
|
|
375
|
+
"timestamp": "2024-01-15T10:30:00.000Z",
|
|
376
|
+
"requestId": "req-abc-123",
|
|
377
|
+
"documentation": "https://docs.example.com/errors/USER_NOT_FOUND"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Express 错误处理中间件
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
function errorHandler(
|
|
386
|
+
err: Error,
|
|
387
|
+
req: Request,
|
|
388
|
+
res: Response,
|
|
389
|
+
next: NextFunction
|
|
390
|
+
) {
|
|
391
|
+
if (err instanceof AppError) {
|
|
392
|
+
return res.status(err.statusCode).json({
|
|
393
|
+
error: {
|
|
394
|
+
code: err.code,
|
|
395
|
+
message: err.message,
|
|
396
|
+
details: err.details,
|
|
397
|
+
timestamp: err.timestamp,
|
|
398
|
+
requestId: req.id,
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// 未知错误
|
|
404
|
+
console.error('Unexpected error:', err);
|
|
405
|
+
return res.status(500).json({
|
|
406
|
+
error: {
|
|
407
|
+
code: 'SYSTEM_INTERNAL_ERROR',
|
|
408
|
+
message: 'An unexpected error occurred',
|
|
409
|
+
timestamp: new Date().toISOString(),
|
|
410
|
+
requestId: req.id,
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## 7) 错误文档
|
|
419
|
+
|
|
420
|
+
### 文档模板
|
|
421
|
+
|
|
422
|
+
```markdown
|
|
423
|
+
## USER_NOT_FOUND
|
|
424
|
+
|
|
425
|
+
**HTTP 状态码**: 404
|
|
426
|
+
|
|
427
|
+
**描述**: 请求的用户不存在
|
|
428
|
+
|
|
429
|
+
**可能原因**:
|
|
430
|
+
- 用户 ID 不正确
|
|
431
|
+
- 用户已被删除
|
|
432
|
+
- 没有访问该用户的权限
|
|
433
|
+
|
|
434
|
+
**解决方案**:
|
|
435
|
+
1. 检查用户 ID 是否正确
|
|
436
|
+
2. 确认用户未被删除
|
|
437
|
+
3. 确认有足够的访问权限
|
|
438
|
+
|
|
439
|
+
**示例响应**:
|
|
440
|
+
```json
|
|
441
|
+
{
|
|
442
|
+
"error": {
|
|
443
|
+
"code": "USER_NOT_FOUND",
|
|
444
|
+
"message": "User with id '12345' not found"
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## 8) 检查清单
|
|
453
|
+
|
|
454
|
+
设计错误码时确认:
|
|
455
|
+
|
|
456
|
+
- [ ] 错误码是否语义化?(人类可读)
|
|
457
|
+
- [ ] 错误码是否唯一?(全局不重复)
|
|
458
|
+
- [ ] 错误码是否包含模块前缀?
|
|
459
|
+
- [ ] HTTP 状态码是否正确映射?
|
|
460
|
+
- [ ] 错误消息是否对用户友好?
|
|
461
|
+
- [ ] 敏感信息是否脱敏?
|
|
462
|
+
- [ ] 是否记录到错误注册表?
|
|
463
|
+
- [ ] 是否有文档说明?
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devbooks-delivery-workflow
|
|
3
|
+
description: devbooks-delivery-workflow:把一次变更跑成可追溯闭环(Design→Plan→Trace→Verify→Implement→Archive),明确 DoD、追溯矩阵与角色隔离(Test Owner 与 Coder 分离)。用户说"跑一遍闭环/交付验收/追溯矩阵/DoD/关账归档/验收工作流"等时使用。
|
|
4
|
+
tools:
|
|
5
|
+
- Glob
|
|
6
|
+
- Grep
|
|
7
|
+
- Read
|
|
8
|
+
- Write
|
|
9
|
+
- Edit
|
|
10
|
+
- Bash
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# DevBooks:交付验收工作流(闭环骨架)
|
|
14
|
+
|
|
15
|
+
## 前置:配置发现(协议无关)
|
|
16
|
+
|
|
17
|
+
- `<truth-root>`:当前真理目录根
|
|
18
|
+
- `<change-root>`:变更包目录根
|
|
19
|
+
|
|
20
|
+
执行前**必须**按以下顺序查找配置(找到后停止):
|
|
21
|
+
1. `.devbooks/config.yaml`(如存在)→ 解析并使用其中的映射
|
|
22
|
+
2. `dev-playbooks/project.md`(如存在)→ DevBooks 2.0 协议,使用默认映射
|
|
23
|
+
4. `project.md`(如存在)→ template 协议,使用默认映射
|
|
24
|
+
5. 若仍无法确定 → **停止并询问用户**
|
|
25
|
+
|
|
26
|
+
**关键约束**:
|
|
27
|
+
- 如果配置中指定了 `agents_doc`(规则文档),**必须先阅读该文档**再执行任何操作
|
|
28
|
+
- 禁止猜测目录根
|
|
29
|
+
- 禁止跳过规则文档阅读
|
|
30
|
+
|
|
31
|
+
## 参考骨架(按需读取)
|
|
32
|
+
|
|
33
|
+
- 工作流:`references/交付验收工作流.md`
|
|
34
|
+
- 模板:`references/变更验证与追溯模板.md`
|
|
35
|
+
|
|
36
|
+
## 可选检查脚本
|
|
37
|
+
|
|
38
|
+
脚本位于本 Skill 的 `scripts/` 目录(可执行;优先"跑脚本拿结果",而不是把脚本正文读进上下文)。
|
|
39
|
+
|
|
40
|
+
- 初始化变更包骨架:`change-scaffold.sh <change-id> --project-root <repo-root> --change-root <change-root> --truth-root <truth-root>`
|
|
41
|
+
- 一键校验变更包:`change-check.sh <change-id> --mode <proposal|apply|review|archive|strict> --role <test-owner|coder|reviewer> --project-root <repo-root> --change-root <change-root> --truth-root <truth-root>`
|
|
42
|
+
- 结构守门决策校验(strict 会自动调用):`guardrail-check.sh <change-id> --project-root <repo-root> --change-root <change-root>`
|
|
43
|
+
- 初始化 spec delta 骨架:`change-spec-delta-scaffold.sh <change-id> <capability> --project-root <repo-root> --change-root <change-root>`
|
|
44
|
+
- 证据采集(把 tests/命令输出落盘到 evidence):`change-evidence.sh <change-id> --label <name> --project-root <repo-root> --change-root <change-root> -- <command> [args...]`
|
|
45
|
+
- 大规模机械变更(LSC)codemod 脚本骨架:`change-codemod-scaffold.sh <change-id> --name <codemod-name> --project-root <repo-root> --change-root <change-root>`
|
|
46
|
+
- 卫生检查(临时文件/进程清理):`hygiene-check.sh <change-id> --project-root <repo-root> --change-root <change-root>`
|
|
47
|
+
|
|
48
|
+
## 质量闸门脚本(v2)
|
|
49
|
+
|
|
50
|
+
以下脚本用于强化质量闸门,拦截"假完成":
|
|
51
|
+
|
|
52
|
+
- 角色交接检查:`handoff-check.sh <change-id> --project-root <repo-root> --change-root <change-root>`
|
|
53
|
+
- 环境声明检查:`env-match-check.sh <change-id> --project-root <repo-root> --change-root <change-root>`
|
|
54
|
+
- 审计全量扫描:`audit-scope.sh <directory> --format <markdown|json>`
|
|
55
|
+
- 进度仪表板:`progress-dashboard.sh <change-id> --project-root <repo-root> --change-root <change-root>`
|
|
56
|
+
- v2 闸门迁移:`migrate-to-v2-gates.sh <change-id> --project-root <repo-root> --change-root <change-root>`
|
|
57
|
+
|
|
58
|
+
### change-check.sh v2 新增检查项
|
|
59
|
+
|
|
60
|
+
| 检查项 | 触发模式 | 说明 | AC |
|
|
61
|
+
|--------|----------|------|-----|
|
|
62
|
+
| `check_evidence_closure()` | archive, strict | 验证 `evidence/green-final/` 存在且非空 | AC-001 |
|
|
63
|
+
| `check_task_completion_rate()` | strict | 验证任务完成率 100%(支持 SKIP-APPROVED) | AC-002 |
|
|
64
|
+
| `check_role_boundaries()` | apply --role | 验证角色边界(扩展自 check_no_tests_changed) | AC-003 |
|
|
65
|
+
| `check_skip_approval()` | strict | 验证 P0 任务跳过有审批记录 | AC-005 |
|
|
66
|
+
| `check_env_match()` | archive, strict | 调用 env-match-check.sh 检查环境声明 | AC-006 |
|
|
67
|
+
| `check_test_failure_in_evidence()` | archive, strict | 检测 Green 证据中的失败模式 | AC-007 |
|
|
68
|
+
|
|
69
|
+
### change-check.sh 基础检查项
|
|
70
|
+
|
|
71
|
+
| 检查项 | 触发模式 | 说明 |
|
|
72
|
+
|--------|----------|------|
|
|
73
|
+
| `check_proposal()` | 所有模式 | 检查 proposal.md 格式与决策状态 |
|
|
74
|
+
| `check_design()` | 所有模式 | 检查 design.md 结构(AC 列表、Problem Context 等) |
|
|
75
|
+
| `check_tasks()` | 所有模式 | 检查 tasks.md 结构(主线计划区、断点区) |
|
|
76
|
+
| `check_verification()` | 所有模式 | 检查 verification.md 四大必填节 |
|
|
77
|
+
| `check_spec_deltas()` | 所有模式 | 检查 specs/ 目录下 spec delta 格式 |
|
|
78
|
+
| `check_implicit_changes()` | apply, archive, strict | 检测隐式变更(依赖、配置、构建) |
|
|
79
|
+
|
|
80
|
+
### 角色边界约束
|
|
81
|
+
|
|
82
|
+
| 角色 | 禁止修改 |
|
|
83
|
+
|------|----------|
|
|
84
|
+
| Coder | `tests/**`、`verification.md`、`.devbooks/` |
|
|
85
|
+
| Test Owner | `src/**` |
|
|
86
|
+
| Reviewer | 代码文件(`.ts`、`.js`、`.py`、`.sh` 等) |
|
|
87
|
+
|
|
88
|
+
详细说明参见:`docs/quality-gates-guide.md`
|
|
89
|
+
|
|
90
|
+
## 架构合规检查(依赖卫士)
|
|
91
|
+
|
|
92
|
+
在合并前进行架构合规检查,防止依赖方向违规。
|
|
93
|
+
|
|
94
|
+
### guardrail-check.sh 完整选项
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
guardrail-check.sh <change-id> [options]
|
|
98
|
+
|
|
99
|
+
Options:
|
|
100
|
+
--project-root <dir> 项目根目录
|
|
101
|
+
--change-root <dir> 变更包目录
|
|
102
|
+
--truth-root <dir> 真理目录(包含 architecture/c4.md)
|
|
103
|
+
--role <role> 角色权限检查 (coder|test-owner|reviewer)
|
|
104
|
+
--check-lockfile 检查 lockfile 变更是否声明
|
|
105
|
+
--check-engineering 检查工程系统变更是否声明
|
|
106
|
+
--check-layers 检查分层约束违规(依赖卫士核心)
|
|
107
|
+
--check-cycles 检查循环依赖
|
|
108
|
+
--check-hotspots 警告热点文件变更
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 分层约束检查内容
|
|
112
|
+
|
|
113
|
+
`--check-layers` 会检测以下违规:
|
|
114
|
+
|
|
115
|
+
| 违规类型 | 示例 | 严重程度 |
|
|
116
|
+
|----------|------|----------|
|
|
117
|
+
| 下层引用上层 | `base/` 导入 `platform/` | 🔴 Critical |
|
|
118
|
+
| common 引用 browser/node | `common/` 导入 `browser/` | 🔴 Critical |
|
|
119
|
+
| common 使用 DOM API | `document.` 在 common 中 | 🔴 Critical |
|
|
120
|
+
| core 引用 contrib | 违反扩展点设计 | 🟡 High |
|
|
121
|
+
|
|
122
|
+
### 推荐用法
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# 完整架构检查(合并前)
|
|
126
|
+
guardrail-check.sh <change-id> \
|
|
127
|
+
--truth-root devbooks \
|
|
128
|
+
--check-layers \
|
|
129
|
+
--check-cycles \
|
|
130
|
+
--check-hotspots \
|
|
131
|
+
--check-lockfile \
|
|
132
|
+
--check-engineering
|
|
133
|
+
|
|
134
|
+
# 快速检查(日常开发)
|
|
135
|
+
guardrail-check.sh <change-id> --check-layers --check-cycles
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### CI 集成示例
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
# .github/workflows/pr.yml
|
|
142
|
+
- name: Architecture Compliance Check
|
|
143
|
+
run: |
|
|
144
|
+
./scripts/guardrail-check.sh ${{ github.event.pull_request.number }} \
|
|
145
|
+
--truth-root devbooks \
|
|
146
|
+
--check-layers \
|
|
147
|
+
--check-cycles
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 上下文感知
|
|
153
|
+
|
|
154
|
+
本 Skill 在执行前自动检测上下文,选择合适的工作流阶段。
|
|
155
|
+
|
|
156
|
+
检测规则参考:`skills/_shared/context-detection-template.md`
|
|
157
|
+
|
|
158
|
+
### 检测流程
|
|
159
|
+
|
|
160
|
+
1. 检测变更包是否存在
|
|
161
|
+
2. 检测当前阶段(proposal/apply/archive)
|
|
162
|
+
3. 检测闸门状态
|
|
163
|
+
|
|
164
|
+
### 本 Skill 支持的模式
|
|
165
|
+
|
|
166
|
+
| 模式 | 触发条件 | 行为 |
|
|
167
|
+
|------|----------|------|
|
|
168
|
+
| **初始化模式** | 变更包不存在 | 创建变更包骨架 |
|
|
169
|
+
| **检查模式** | 带 --check 参数 | 只运行闸门检查 |
|
|
170
|
+
| **完整闭环** | 无特殊参数 | 执行完整 Design→Archive 流程 |
|
|
171
|
+
|
|
172
|
+
### 检测输出示例
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
检测结果:
|
|
176
|
+
- 变更包:存在
|
|
177
|
+
- 当前阶段:apply
|
|
178
|
+
- 闸门状态:proposal ✓, design ✓, tasks ✓
|
|
179
|
+
- 运行模式:检查模式(apply 阶段)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## MCP 增强
|
|
185
|
+
|
|
186
|
+
本 Skill 支持 MCP 运行时增强,自动检测并启用高级功能。
|
|
187
|
+
|
|
188
|
+
MCP 增强规则参考:`skills/_shared/mcp-enhancement-template.md`
|
|
189
|
+
|
|
190
|
+
### 依赖的 MCP 服务
|
|
191
|
+
|
|
192
|
+
| 服务 | 用途 | 超时 |
|
|
193
|
+
|------|------|------|
|
|
194
|
+
| `mcp__ckb__getStatus` | 检测 CKB 索引可用性 | 2s |
|
|
195
|
+
|
|
196
|
+
### 检测流程
|
|
197
|
+
|
|
198
|
+
1. 调用 `mcp__ckb__getStatus`(2s 超时)
|
|
199
|
+
2. 在工作流状态报告中标注索引可用性
|
|
200
|
+
3. 若不可用 → 建议在 apply 阶段前生成索引
|
|
201
|
+
|
|
202
|
+
### 增强模式 vs 基础模式
|
|
203
|
+
|
|
204
|
+
| 功能 | 增强模式 | 基础模式 |
|
|
205
|
+
|------|----------|----------|
|
|
206
|
+
| 架构检查 | 精确依赖分析 | 基于 import 语句 |
|
|
207
|
+
| 热点预警 | CKB 实时分析 | 不可用 |
|
|
208
|
+
| 影响评估 | 调用图分析 | 文件级估算 |
|
|
209
|
+
|
|
210
|
+
### 降级提示
|
|
211
|
+
|
|
212
|
+
当 MCP 不可用时,输出以下提示:
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
⚠️ CKB 索引不可用,架构检查将使用基础模式。
|
|
216
|
+
建议运行 /devbooks:index 生成索引以启用精确检查。
|
|
217
|
+
```
|