jsharness 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/.harness/README.md +199 -0
- package/.harness/agents/code-reviewer/contract.yaml +64 -0
- package/.harness/agents/developer/contract.yaml +72 -0
- package/.harness/agents/gate-controller/contract.yaml +64 -0
- package/.harness/agents/project-manager/contract.yaml +77 -0
- package/.harness/agents/prompt-templates.md +352 -0
- package/.harness/agents/requirements-analyst/contract.yaml +64 -0
- package/.harness/agents/solution-designer/contract.yaml +75 -0
- package/.harness/agents/tester/contract.yaml +92 -0
- package/.harness/config/models.yaml +67 -0
- package/.harness/dev-map/backend/api-definition.md +131 -0
- package/.harness/dev-map/backend/auth-security.md +131 -0
- package/.harness/dev-map/backend/conventions-java.md +471 -0
- package/.harness/dev-map/backend/conventions.md +192 -0
- package/.harness/dev-map/backend/database.md +106 -0
- package/.harness/dev-map/backend/structure.md +140 -0
- package/.harness/dev-map/decisions.md +275 -0
- package/.harness/dev-map/frontend/api-integration.md +139 -0
- package/.harness/dev-map/frontend/components.md +178 -0
- package/.harness/dev-map/frontend/conventions.md +416 -0
- package/.harness/dev-map/frontend/state-management.md +170 -0
- package/.harness/dev-map/frontend/structure.md +103 -0
- package/.harness/dev-map/overview.md +267 -0
- package/.harness/docs/integration-test-plan.md +248 -0
- package/.harness/docs/team-guidelines/README.md +161 -0
- package/.harness/docs/team-guidelines/arch-team.md +811 -0
- package/.harness/docs/team-guidelines/collaboration.md +556 -0
- package/.harness/docs/team-guidelines/pm-team.md +337 -0
- package/.harness/docs/team-guidelines/qa-team.md +562 -0
- package/.harness/docs/team-guidelines/rd-team.md +714 -0
- package/.harness/docs/training-materials.md +280 -0
- package/.harness/gate/baseline.js +220 -0
- package/.harness/gate/checks/build-gates-frontend.js +152 -0
- package/.harness/gate/checks/build-gates-java.js +155 -0
- package/.harness/gate/checks/build-gates.js +119 -0
- package/.harness/gate/checks/engineering-consistency.js +138 -0
- package/.harness/gate/checks/security-quality.js +129 -0
- package/.harness/gate/checks/static-compliance.js +313 -0
- package/.harness/gate/checks/test-compliance.js +114 -0
- package/.harness/gate/index.js +315 -0
- package/.harness/mcp/config.yaml +435 -0
- package/.harness/rules/global/coding-standard.md +232 -0
- package/.harness/rules/global/commit-convention.md +165 -0
- package/.harness/rules/global/process-discipline.md +192 -0
- package/.harness/rules/global/security-baseline.md +306 -0
- package/.harness/rules/project/frontend-vue3.md +293 -0
- package/.harness/rules/project/java-backend.md +460 -0
- package/.harness/rules/project/web-specific.md +231 -0
- package/.harness/skills/build.md +192 -0
- package/.harness/skills/code-review.md +251 -0
- package/.harness/skills/docker-build.md +227 -0
- package/.harness/skills/docs-update.md +164 -0
- package/.harness/skills/java-build.md +261 -0
- package/.harness/skills/lint-check.md +482 -0
- package/.harness/skills/task-board-maintenance.md +105 -0
- package/.harness/skills/test-api.md +461 -0
- package/.harness/skills/test-e2e.md +431 -0
- package/.harness/skills/test-unit.md +649 -0
- package/.harness/skills/vue-frontend-build.md +344 -0
- package/.harness/specs/quality-feedback/implementation-guide.md +350 -0
- package/.harness/task-board.md +121 -0
- package/.harness/workflow/definition.yaml +504 -0
- package/.harness/workflow/validate.js +320 -0
- package/.harness/workflow/variants.yaml +253 -0
- package/README.md +237 -0
- package/bin/jsharness.js +53 -0
- package/lib/index.mjs +778 -0
- package/package.json +1 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# MCP 外部系统集成配置
|
|
2
|
+
|
|
3
|
+
> **当前阶段**: 阶段一(只读集成)— 基础框架已搭建
|
|
4
|
+
> **安全级别**: 高 — 涉及外部系统访问,需严格控制权限
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## MCP Server 配置
|
|
9
|
+
|
|
10
|
+
```yaml
|
|
11
|
+
# .harness/mcp/config.yaml
|
|
12
|
+
mcp_server:
|
|
13
|
+
name: "harness-mcp-bridge"
|
|
14
|
+
version: "1.0.0"
|
|
15
|
+
|
|
16
|
+
# 连接的外部系统
|
|
17
|
+
systems:
|
|
18
|
+
gitlab:
|
|
19
|
+
type: "gitlab_api"
|
|
20
|
+
base_url: "${GITLAB_URL}" # 环境变量注入
|
|
21
|
+
token_ref: "GITLAB_ACCESS_TOKEN" # 不硬编码凭证
|
|
22
|
+
enabled: true
|
|
23
|
+
|
|
24
|
+
jenkins:
|
|
25
|
+
type: "jenkins_api"
|
|
26
|
+
base_url: "${JENKINS_URL}"
|
|
27
|
+
credentials_ref: "JENKINS_API_TOKEN"
|
|
28
|
+
user_ref: "JENKINS_USER"
|
|
29
|
+
enabled: true
|
|
30
|
+
|
|
31
|
+
docker_registry:
|
|
32
|
+
type: "docker_registry_api"
|
|
33
|
+
registry_url: "${DOCKER_REGISTRY_URL}"
|
|
34
|
+
credentials_ref: "DOCKER_REGISTRY_TOKEN"
|
|
35
|
+
enabled: false # 阶段二才启用
|
|
36
|
+
|
|
37
|
+
# 安全设置
|
|
38
|
+
security:
|
|
39
|
+
rate_limit:
|
|
40
|
+
requests_per_minute: 30
|
|
41
|
+
burst: 10
|
|
42
|
+
audit_logging: true # 记录所有 MCP 操作
|
|
43
|
+
allowed_operations: # 阶段一限制为只读
|
|
44
|
+
- "git:*" # Git 操作(阶段二细分)
|
|
45
|
+
- "ci:status:read" # CI 状态读取
|
|
46
|
+
- "issue:list" # Issue 列表读取
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 阶段一:只读集成 Tools 定义
|
|
50
|
+
|
|
51
|
+
### Git 只读 Tools
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// mcp/tools/git-read.js
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Tool: git_status
|
|
58
|
+
* 获取仓库当前状态(分支、修改的文件等)
|
|
59
|
+
*/
|
|
60
|
+
{
|
|
61
|
+
name: "git_status",
|
|
62
|
+
description: "获取当前 Git 仓库的状态信息",
|
|
63
|
+
parameters: {
|
|
64
|
+
path: { type: "string", description: "仓库路径", default: "." }
|
|
65
|
+
},
|
|
66
|
+
readOnly: true,
|
|
67
|
+
handler: async ({ path }) => {
|
|
68
|
+
return {
|
|
69
|
+
branch: execSync(`git -C ${path} rev-parse --abbrev-ref HEAD`).toString().trim(),
|
|
70
|
+
changedFiles: JSON.parse(execSync(`git -C ${path} status --porcelain=json`).toString()),
|
|
71
|
+
lastCommit: execSync(`git -C ${path} log -1 --format="%H|%s|%an|%ai"`).toString().trim()
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Tool: git_diff
|
|
78
|
+
* 获取指定范围或文件的 diff 内容
|
|
79
|
+
*/
|
|
80
|
+
{
|
|
81
|
+
name: "git_diff",
|
|
82
|
+
description: "查看代码变更的差异内容",
|
|
83
|
+
parameters: {
|
|
84
|
+
ref: { type: "string", description: "Git 引用 (commit/branch)" },
|
|
85
|
+
filePattern: { type: "string", description: "文件模式过滤", optional: true }
|
|
86
|
+
},
|
|
87
|
+
readOnly: true
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Tool: git_pr_read
|
|
92
|
+
* 读取 PR/MR 的详细信息(不创建或修改)
|
|
93
|
+
*/
|
|
94
|
+
{
|
|
95
|
+
name: "git_pr_read",
|
|
96
|
+
description: "读取 Pull Request / Merge Request 的详细信息",
|
|
97
|
+
parameters: {
|
|
98
|
+
prNumber: { type: "number", description: "PR 编号" },
|
|
99
|
+
includeDiffs: { type: "boolean", description: "是否包含 diff", optional: true }
|
|
100
|
+
},
|
|
101
|
+
readOnly: true
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### CI 只读 Tools
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
// mcp/tools/ci-read.js
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Tool: ci_build_status
|
|
112
|
+
* 查询 CI 构建状态
|
|
113
|
+
*/
|
|
114
|
+
{
|
|
115
|
+
name: "ci_build_status",
|
|
116
|
+
description: "查询 Jenkins/GitLab CI 的构建状态和结果",
|
|
117
|
+
parameters: {
|
|
118
|
+
jobName: { type: "string", description: "构建任务名称" },
|
|
119
|
+
buildNumber: { type: "number", description: "构建编号(可选,默认最新)" }
|
|
120
|
+
},
|
|
121
|
+
readOnly: true,
|
|
122
|
+
handler: async ({ jobName, buildNumber }) => {
|
|
123
|
+
const url = `${jenkinsUrl}/job/${jobName}/${buildNumber || 'lastBuild'}/api/json`;
|
|
124
|
+
// ... fetch 并返回构建状态、耗时、结果等
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Tool: ci_build_logs
|
|
130
|
+
* 读取构建日志
|
|
131
|
+
*/
|
|
132
|
+
{
|
|
133
|
+
name: "ci_build_logs",
|
|
134
|
+
description: "读取 CI 构建日志(用于排查失败原因)",
|
|
135
|
+
parameters: {
|
|
136
|
+
jobName: { type: "string" },
|
|
137
|
+
buildNumber: { type: "number" },
|
|
138
|
+
maxLines: { type: "number", optional: true, default: 200 }
|
|
139
|
+
},
|
|
140
|
+
readOnly: true
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Issue 只读 Tools
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
// mcp/tools/issue-read.js
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Tool: issue_list
|
|
151
|
+
* 列出 Issues
|
|
152
|
+
*/
|
|
153
|
+
{
|
|
154
|
+
name: "issue_list",
|
|
155
|
+
description: "列出项目 Issues(支持按状态/标签/负责人筛选)",
|
|
156
|
+
parameters: {
|
|
157
|
+
state: { enum: ["opened", "closed", "all"], default: "opened" },
|
|
158
|
+
labels: { type: "array", optional: true },
|
|
159
|
+
assignee: { type: "string", optional: true },
|
|
160
|
+
perPage: { type: "number", default: 20 }
|
|
161
|
+
},
|
|
162
|
+
readOnly: true
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Tool: issue_detail
|
|
167
|
+
* 获取 Issue 详情
|
|
168
|
+
*/
|
|
169
|
+
{
|
|
170
|
+
name: "issue_detail",
|
|
171
|
+
description: "获取单个 Issue 的完整详情(含评论)",
|
|
172
|
+
parameters: {
|
|
173
|
+
issueId: { type: "number/string" },
|
|
174
|
+
includeComments: { type: "boolean", default: true }
|
|
175
|
+
},
|
|
176
|
+
readOnly: true
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 阶段二:写入集成(规划中)
|
|
181
|
+
|
|
182
|
+
以下工具将在完成阶段一验证后逐步开放:
|
|
183
|
+
|
|
184
|
+
| Tool | 操作 | 审批要求 | 风险等级 |
|
|
185
|
+
|------|------|----------|----------|
|
|
186
|
+
| `ci_trigger_build` | 触发 CI 构建 | 需人工审批 | 中 |
|
|
187
|
+
| `pr_create_comment` | 在 PR 上评论 | Agent 自动 | 低 |
|
|
188
|
+
| `pr_create` | 创建 PR/MR | 需人工审批 | 中 |
|
|
189
|
+
| `docker_push` | 推送 Docker 镜像 | 需人工审批 | 高 |
|
|
190
|
+
| `issue_create` | 创建 Issue | PM Agent 可用 | 低 |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
# ════════════════════════════════════════════════════════
|
|
195
|
+
# Java 后端专属 Tools 定义
|
|
196
|
+
# ════════════════════════════════════════════════════════
|
|
197
|
+
|
|
198
|
+
> **适用技术栈**: Spring Boot / Maven / SonarQube
|
|
199
|
+
> **触发条件**: 项目包含 pom.xml 时启用
|
|
200
|
+
|
|
201
|
+
## Java 只读 Tools 定义
|
|
202
|
+
|
|
203
|
+
### SonarQube 质量读取
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
// mcp/tools/sonarqube-read.js
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Tool: sonarqube_project_metrics
|
|
210
|
+
* 读取项目的 SonarQube 质量指标
|
|
211
|
+
*/
|
|
212
|
+
{
|
|
213
|
+
name: "sonarqube_project_metrics",
|
|
214
|
+
description: "获取指定项目在 SonarQube 中的代码质量指标(覆盖率、Bug数、漏洞等)",
|
|
215
|
+
parameters: {
|
|
216
|
+
projectKey: { type: "string", description: "SonarQube 项目标识 (如 com.jieshun:backend)" },
|
|
217
|
+
metrics: {
|
|
218
|
+
type: "array",
|
|
219
|
+
description: "需要查询的指标列表",
|
|
220
|
+
optional: true,
|
|
221
|
+
default: ["coverage", "bugs", "vulnerabilities", "code_smells", "duplicated_lines_density"]
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
readOnly: true,
|
|
225
|
+
handler: async ({ projectKey, metrics }) => {
|
|
226
|
+
const url = `${sonarqubeUrl}/api/measures/component?component=${projectKey}&metricKeys=${metrics.join(',')}`;
|
|
227
|
+
// 返回各指标的当前值和趋势
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Tool: sonarqube_quality_gate
|
|
233
|
+
* 查询项目的 Quality Gate 状态
|
|
234
|
+
*/
|
|
235
|
+
{
|
|
236
|
+
name: "sonarqube_quality_gate",
|
|
237
|
+
description: "查询 SonarQube Quality Gate 通过状态及失败原因",
|
|
238
|
+
parameters: {
|
|
239
|
+
projectKey: { type: "string" }
|
|
240
|
+
},
|
|
241
|
+
readOnly: true,
|
|
242
|
+
handler: async ({ projectKey }) => {
|
|
243
|
+
const url = `${sonarqubeUrl}/api/qualitygates/project_status?projectKey=${projectKey}`;
|
|
244
|
+
// 返回 PASS/FAIL + 失败的具体条件
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Maven 构件查询
|
|
250
|
+
|
|
251
|
+
```javascript
|
|
252
|
+
// mcp/tools/maven-read.js
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Tool: maven_dependency_tree
|
|
256
|
+
* 查询项目的 Maven 依赖树(远程或本地)
|
|
257
|
+
*/
|
|
258
|
+
{
|
|
259
|
+
name: "maven_dependency_info",
|
|
260
|
+
description: "查询指定依赖的版本信息、是否存在安全漏洞",
|
|
261
|
+
parameters: {
|
|
262
|
+
groupId: { type: "string", description: "Maven groupId" },
|
|
263
|
+
artifactId: { type: "string", description: "Maven artifactId" },
|
|
264
|
+
version: { type: "string", optional: true, description: "版本号,不填则查最新" }
|
|
265
|
+
},
|
|
266
|
+
readOnly: true,
|
|
267
|
+
handler: async ({ groupId, artifactId, version }) => {
|
|
268
|
+
// 查询 Maven Central Repository API
|
|
269
|
+
// 返回:可用版本列表、最新稳定版、是否有已知 CVE
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Tool: maven_central_search
|
|
275
|
+
* 在 Maven Central 中搜索构件
|
|
276
|
+
*/
|
|
277
|
+
{
|
|
278
|
+
name: "maven_central_search",
|
|
279
|
+
description: "在 Maven Central Repository 中搜索库/组件",
|
|
280
|
+
parameters: {
|
|
281
|
+
query: { type: "string", description: "搜索关键词" },
|
|
282
|
+
rows: { type: "number", optional: true, default: 10 }
|
|
283
|
+
},
|
|
284
|
+
readOnly: true
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Jenkins Maven Job 工具
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
// mcp/tools/jenkins-java.js
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Tool: jenkins_maven_job_status
|
|
295
|
+
* 查询 Maven 类型 Jenkins Job 的构建详情
|
|
296
|
+
*/
|
|
297
|
+
{
|
|
298
|
+
name: "jenkins_maven_job_status",
|
|
299
|
+
description: "查询 Maven 项目的 Jenkins 构建:编译结果、测试结果、JaCoCo覆盖率",
|
|
300
|
+
parameters: {
|
|
301
|
+
jobName: { type: "string", description: "Jenkins Job 名称 (如 backend-maven-build)" },
|
|
302
|
+
buildNumber: { type: "number", optional: true, default: "lastBuild" },
|
|
303
|
+
includeCoverage: { type: "boolean", optional: true, default: true }
|
|
304
|
+
},
|
|
305
|
+
readOnly: true,
|
|
306
|
+
handler: async ({ jobName, buildNumber, includeCoverage }) => {
|
|
307
|
+
// 查询 Jenkins API
|
|
308
|
+
// 返回:
|
|
309
|
+
// - 编译状态 (SUCCESS/FAILURE)
|
|
310
|
+
// - 测试通过率
|
|
311
|
+
// - JaCoCo 覆盖率(如果 includeCoverage=true)
|
|
312
|
+
// - Surefire 报告摘要
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## MCP Systems 配置 — Java 扩展
|
|
318
|
+
|
|
319
|
+
### 新增系统连接
|
|
320
|
+
|
|
321
|
+
```yaml
|
|
322
|
+
# .harness/mcp/config.yaml → systems 下追加
|
|
323
|
+
|
|
324
|
+
# === Java 后端专用系统 ===
|
|
325
|
+
sonarqube:
|
|
326
|
+
type: "sonarqube_api"
|
|
327
|
+
base_url: "${SONARQUBE_URL}" # 如 http://localhost:9000
|
|
328
|
+
token_ref: "SONARQUBE_TOKEN"
|
|
329
|
+
enabled: true # Java 项目必须启用
|
|
330
|
+
|
|
331
|
+
maven_repo:
|
|
332
|
+
type: "maven_central_api"
|
|
333
|
+
base_url: "https://search.maven.org/solrsearch/select" # 公开,无需凭证
|
|
334
|
+
enabled: true
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### 权限矩阵扩展
|
|
338
|
+
|
|
339
|
+
```yaml
|
|
340
|
+
# permission_matrix 追加 Java 相关工具权限
|
|
341
|
+
|
|
342
|
+
developer:
|
|
343
|
+
allowed_tools:
|
|
344
|
+
# ... 已有 ...
|
|
345
|
+
- "sonarqube:*:read" # 读取质量数据
|
|
346
|
+
- "maven:*:read" # 查询依赖信息
|
|
347
|
+
- "jenkins:maven-job:read" # 查看 Maven Job 状态
|
|
348
|
+
blocked_tools:
|
|
349
|
+
- "sonarqube:*:write" # 不能修改 Quality Gate
|
|
350
|
+
- "jenkins:maven-job:trigger" # 触发需审批
|
|
351
|
+
|
|
352
|
+
tester:
|
|
353
|
+
allowed_tools:
|
|
354
|
+
# ... 已有 ...
|
|
355
|
+
- "sonarqube:*:read"
|
|
356
|
+
- "jenkins:maven-job:read"
|
|
357
|
+
|
|
358
|
+
gate_controller:
|
|
359
|
+
allowed_tools:
|
|
360
|
+
# ... 已有 ...
|
|
361
|
+
- "sonarqube:quality_gate:read" # 重点:检查 QG 状态
|
|
362
|
+
- "sonarqube:*:read"
|
|
363
|
+
- "security:scan:java" # Java 安全扫描结果
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## 阶段三:完整闭环(远期规划)
|
|
367
|
+
|
|
368
|
+
- 制品上传 Tool
|
|
369
|
+
- 部署触发/回滚 Tool(需多级审批)
|
|
370
|
+
- 状态回写 Tool(GitLab → TaskBoard)
|
|
371
|
+
- 通知发送 Tool(钉钉/企业微信/Slack)
|
|
372
|
+
|
|
373
|
+
## 安全部署配置
|
|
374
|
+
|
|
375
|
+
### 权限控制矩阵
|
|
376
|
+
|
|
377
|
+
```yaml
|
|
378
|
+
permission_matrix:
|
|
379
|
+
# 角色 → Tool 类别 映射
|
|
380
|
+
project_manager:
|
|
381
|
+
allowed_tools:
|
|
382
|
+
- "git:read:*"
|
|
383
|
+
- "issue:read:*"
|
|
384
|
+
- "issue:create" # 阶段二
|
|
385
|
+
- "taskboard:*"
|
|
386
|
+
blocked_tools:
|
|
387
|
+
- "ci:write:*"
|
|
388
|
+
- "docker:*"
|
|
389
|
+
- "deploy:*"
|
|
390
|
+
|
|
391
|
+
requirements_analyst:
|
|
392
|
+
allowed_tools:
|
|
393
|
+
- "git:read:*"
|
|
394
|
+
- "issue:read:*"
|
|
395
|
+
- "dev-map:read:*"
|
|
396
|
+
blocked_tools:
|
|
397
|
+
- "issue:write:*"
|
|
398
|
+
- "ci:*"
|
|
399
|
+
|
|
400
|
+
developer:
|
|
401
|
+
allowed_tools:
|
|
402
|
+
- "git:read:*"
|
|
403
|
+
- "ci:status:read"
|
|
404
|
+
- "pr:create" # 阶段二
|
|
405
|
+
- "pr:read:*"
|
|
406
|
+
blocked_tools:
|
|
407
|
+
- "ci:trigger:*" # 必须审批
|
|
408
|
+
- "deploy:*"
|
|
409
|
+
|
|
410
|
+
gate_controller:
|
|
411
|
+
allowed_tools:
|
|
412
|
+
- "git:read:*"
|
|
413
|
+
- "ci:status:read"
|
|
414
|
+
- "security:scan:*"
|
|
415
|
+
|
|
416
|
+
tester:
|
|
417
|
+
allowed_tools:
|
|
418
|
+
- "git:read:*"
|
|
419
|
+
- "ci:status:read"
|
|
420
|
+
- "ci:logs:read"
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### 凭证注入方案
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
优先级:
|
|
427
|
+
1. 环境变量(运行时注入)← 推荐
|
|
428
|
+
2. 密钥管理服务(Vault / AWS Secrets Manager)← 生产环境
|
|
429
|
+
3. .env 文件(仅本地开发,不入库)
|
|
430
|
+
4. MCP 配置文件中的加密字段 ← 不推荐
|
|
431
|
+
|
|
432
|
+
禁止:
|
|
433
|
+
- ❌ 硬编码在任何代码或配置中
|
|
434
|
+
- ❌ 提交到版本控制系统的任何形式的凭证
|
|
435
|
+
```
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# 通用编码规范规则 (coding-standard)
|
|
2
|
+
|
|
3
|
+
> **级别**: 必须遵守 | **适用范围**: 全局(前端+后端)
|
|
4
|
+
|
|
5
|
+
## 1. ESLint / Prettier 强制规则
|
|
6
|
+
|
|
7
|
+
所有代码必须通过以下检查:
|
|
8
|
+
|
|
9
|
+
| 规则类别 | 要求 |
|
|
10
|
+
|----------|------|
|
|
11
|
+
| **ESLint** | 零 error,零 warning(除已白名单的规则) |
|
|
12
|
+
| **Prettier** | 格式化后无 diff 变更 |
|
|
13
|
+
| **TypeScript** | `strict: true` 模式,禁止 `any` 类型(除非有明确注释说明原因) |
|
|
14
|
+
|
|
15
|
+
### 前端特有
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
// ✅ 正确:使用明确的类型
|
|
19
|
+
const userId: string = user.id;
|
|
20
|
+
|
|
21
|
+
// ❌ 错误:禁止裸 any
|
|
22
|
+
const data = response.data; // 隐式 any
|
|
23
|
+
|
|
24
|
+
// ⚠️ 允许但有条件:必须注释 why
|
|
25
|
+
const legacyData: any = parseLegacyFormat(raw); // Legacy API, 待重构
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 后端特有
|
|
29
|
+
|
|
30
|
+
- 所有公开 API 入口必须有参数校验(使用 Joi/Zod/类装饰器)
|
|
31
|
+
- 数据库操作必须使用 ORM/Query Builder,禁止拼接 SQL
|
|
32
|
+
|
|
33
|
+
## 2. 命名约定
|
|
34
|
+
|
|
35
|
+
| 类型 | 约定 | 示例 |
|
|
36
|
+
|------|------|------|
|
|
37
|
+
| **文件名** | kebab-case | `user-service.ts`, `login-form.vue` |
|
|
38
|
+
| **组件名** | PascalCase | `UserProfile`, `DataTable` |
|
|
39
|
+
| **变量/函数** | camelCase | `getUserById`, `isLoading` |
|
|
40
|
+
| **常量** | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT`, `API_BASE_URL` |
|
|
41
|
+
| **类/接口/类型** | PascalCase | `UserService`, `IUserRepository` |
|
|
42
|
+
| **CSS 类名** | BEM 规范 | `block__element--modifier` |
|
|
43
|
+
| **环境变量** | UPPER_SNAKE_CASE 前缀 | `APP_PORT`, `DB_HOST` |
|
|
44
|
+
|
|
45
|
+
### 组件文件命名规范
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
components/
|
|
49
|
+
├── features/ # 功能组件(业务逻辑)
|
|
50
|
+
│ └── user-profile/
|
|
51
|
+
│ ├── UserProfile.vue # 主组件
|
|
52
|
+
│ ├── UserProfile.test.vue # 测试
|
|
53
|
+
│ ├── useUserProfile.ts # Composable (Hook)
|
|
54
|
+
│ └── index.ts # 导出
|
|
55
|
+
├── ui/ # 通用 UI 组件
|
|
56
|
+
│ └── button/
|
|
57
|
+
│ └── Button.vue
|
|
58
|
+
└── layouts/ # 布局组件
|
|
59
|
+
└── MainLayout.vue
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 3. 代码风格要求
|
|
63
|
+
|
|
64
|
+
### 3.1 文件长度限制
|
|
65
|
+
|
|
66
|
+
| 文件类型 | 最大行数 | 说明 |
|
|
67
|
+
|----------|---------|------|
|
|
68
|
+
| 单个组件文件 | 300 行 | 超出必须拆分 |
|
|
69
|
+
| 单个工具函数文件 | 200 行 | 超出必须拆分 |
|
|
70
|
+
| 测试文件 | 500 行 | 按场景分文件 |
|
|
71
|
+
| 配置文件 | 100 行 | 复杂配置抽离 |
|
|
72
|
+
|
|
73
|
+
### 3.2 函数复杂度
|
|
74
|
+
|
|
75
|
+
- 单个函数不超过 50 行
|
|
76
|
+
- 圈复杂度 ≤ 10
|
|
77
|
+
- 嵌套层级 ≤ 4 层
|
|
78
|
+
- 函数参数 ≤ 5 个(超出使用对象参数)
|
|
79
|
+
|
|
80
|
+
### 3.3 导入顺序
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// 1. 外部库(按字母序)
|
|
84
|
+
import { ref, computed, onMounted } from 'vue';
|
|
85
|
+
|
|
86
|
+
// 2. 内部共享模块
|
|
87
|
+
import { apiClient } from '@/lib/api';
|
|
88
|
+
import { ElButton } from 'element-plus';
|
|
89
|
+
|
|
90
|
+
// 3. 相邻模块
|
|
91
|
+
import { UserProfile } from './UserProfile.vue';
|
|
92
|
+
|
|
93
|
+
// 4. 类型导入(与对应库分组)
|
|
94
|
+
import type { User } from '@/types';
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3.4 禁止模式
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// ❌ 禁止:console.log 残留到生产代码
|
|
101
|
+
console.log('debug:', data);
|
|
102
|
+
|
|
103
|
+
// ❌ 禁止:debugger 语句
|
|
104
|
+
debugger;
|
|
105
|
+
|
|
106
|
+
// ❌ 禁止:硬编码魔法数字
|
|
107
|
+
if (status === 37) { ... }
|
|
108
|
+
|
|
109
|
+
// ✅ 正确:使用有命名的常量
|
|
110
|
+
const ORDER_STATUS_SHIPPED = 37;
|
|
111
|
+
if (status === ORDER_STATUS_SHIPPED) { ... }
|
|
112
|
+
|
|
113
|
+
// ❌ 禁止:var 声明
|
|
114
|
+
var x = 1;
|
|
115
|
+
|
|
116
|
+
// ❌ 禁止:嵌套三元表达式
|
|
117
|
+
const result = a ? (b ? c : d) : e;
|
|
118
|
+
|
|
119
|
+
// ✅ 正确:使用早返回或提取函数
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## 4. 错误处理规范
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// ✅ 正确:统一的错误处理模式
|
|
126
|
+
try {
|
|
127
|
+
const result = await apiClient.fetchUser(id);
|
|
128
|
+
return result;
|
|
129
|
+
} catch (error) {
|
|
130
|
+
// 区分可恢复和不可恢复错误
|
|
131
|
+
if (isRecoverableError(error)) {
|
|
132
|
+
logger.warn('Recoverable error', { error, id });
|
|
133
|
+
return fallbackValue;
|
|
134
|
+
}
|
|
135
|
+
// 不可恢复错误向上抛出
|
|
136
|
+
throw new UserFetchError('Failed to fetch user', { cause: error, id });
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 5. 注释规范
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
/**
|
|
144
|
+
* 根据用户 ID 获取用户信息
|
|
145
|
+
*
|
|
146
|
+
* @param id - 用户唯一标识符(UUID v4 格式)
|
|
147
|
+
* @returns 用户基本信息,不存在时返回 null
|
|
148
|
+
* @throws {ValidationError} 当 ID 格式无效时抛出
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* const user = await getUserById('550e8400-e29b-41d4-a716-446655440000');
|
|
152
|
+
*/
|
|
153
|
+
async function getUserById(id: string): Promise<User | null>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**注释要求**:
|
|
157
|
+
- 所有公开 API 必须有 JSDoc
|
|
158
|
+
- 复杂逻辑必须有行内注释解释「为什么」而非「是什么」
|
|
159
|
+
- TODO/FIXME 必须关联 Issue 编号:`TODO(#123): 说明`
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 6. AI 辅助编码通用约束
|
|
164
|
+
|
|
165
|
+
> **来源**: `files/AI_RULE.md` (v1.0.0) | **归档日期**: 2026-05-21
|
|
166
|
+
> 本章节为跨语言通用规则,适用于 AI 辅助代码生成场景。
|
|
167
|
+
|
|
168
|
+
### 6.1 基础约束(A01-A06)
|
|
169
|
+
|
|
170
|
+
| 规则 ID | 要求 |
|
|
171
|
+
|---------|------|
|
|
172
|
+
| A01 | 匹配项目当前框架/语言版本,不得使用项目未引入的依赖版本 |
|
|
173
|
+
| A02 | 沿用项目已有命名风格和模式,先阅读同目录下已有文件再生成 |
|
|
174
|
+
| A03 | 单次代码长度 ≤ 80 行,超长逻辑必须拆分 |
|
|
175
|
+
| A04 | 使用 4 空格缩进,遵循 .editorconfig 配置 |
|
|
176
|
+
| A05 | 必须 包含 try-catch 或 throws 声明 |
|
|
177
|
+
| A06 | 禁止空 catch 块(catch 中至少有日志记录),禁止顶层异常泄漏 |
|
|
178
|
+
|
|
179
|
+
### 6.2 依赖与引入规范(A07-A10)
|
|
180
|
+
|
|
181
|
+
| 规则 ID | 要求 |
|
|
182
|
+
|---------|------|
|
|
183
|
+
| A07 | 复用优于新建:先检查项目中是否有相同功能的工具类或依赖,优先复用 |
|
|
184
|
+
| A08 | import 按规范排序(第三方库 → 项目内部),禁止引入未使用的 import |
|
|
185
|
+
| A09 | 禁止使用 @Deprecated 的 API,优先使用推荐替代方案 |
|
|
186
|
+
| A10 | 新依赖版本与项目现有版本兼容,不得随意升级或降级 |
|
|
187
|
+
|
|
188
|
+
### 6.3 业务代码规范(A11-A16)
|
|
189
|
+
|
|
190
|
+
| 规则 ID | 要求 |
|
|
191
|
+
|---------|------|
|
|
192
|
+
| A11 | Controller 只做路由转发和参数校验,业务逻辑下沉到 Service 层 |
|
|
193
|
+
| A12 | Service 负责**业务编排**,协调多个 Mapper/外部服务完成流程 |
|
|
194
|
+
| A13 | SQL 参数绑定必须使用预编译方式(`#{}` / `?` / named parameter),禁止字符串拼接 |
|
|
195
|
+
| A14 | 操作集合前必须判空(null check 或 Optional),禁止对可能为 null 的集合直接调用方法 |
|
|
196
|
+
| A15 | 循环内禁止执行数据库查询或 HTTP 请求(N+1 防范),大数据量循环考虑分批处理 |
|
|
197
|
+
| A16 | 使用 Enum 枚举替代魔法数字/字符串 |
|
|
198
|
+
|
|
199
|
+
### 6.4 并发与资源管理(A17-A20)
|
|
200
|
+
|
|
201
|
+
| 规则 ID | 要求 |
|
|
202
|
+
|---------|------|
|
|
203
|
+
| A17 | 多线程使用合理线程池配置(ThreadPoolExecutor),禁止 new Thread() 或 Executors 无界工厂 |
|
|
204
|
+
| A18 | I/O 流、数据库连接、HTTP Client 等资源必须 try-with-resources 或 finally 释放,禁止资源泄漏 |
|
|
205
|
+
| A19 | ThreadLocal 使用完毕后必须 remove() 清理,防止内存泄漏 |
|
|
206
|
+
| A20 | 跨进程互斥必须使用分布式锁(如 Redisson),禁止 JVM 内置锁解决跨进程问题 |
|
|
207
|
+
|
|
208
|
+
### 6.5 注释与文档规范(A21-A24)
|
|
209
|
+
|
|
210
|
+
| 规则 ID | 要求 |
|
|
211
|
+
|---------|------|
|
|
212
|
+
| A21 | public class/interface 必须包含完整的 JSDoc/JavaDoc 注释 |
|
|
213
|
+
| A22 | 关键步骤处必须有行内注释解释"**为什么**"这样做,关注 why 而非 what |
|
|
214
|
+
| A23 | TODO 必须附带具体场景说明,格式:`// TODO: [场景描述] - 待[具体动作]` |
|
|
215
|
+
| A24 | 重构或修改时相关注释必须同步更新,禁止注释与代码不一致 |
|
|
216
|
+
|
|
217
|
+
### 6.6 接口/DTO/实体规范(A25-A28)
|
|
218
|
+
|
|
219
|
+
| 规则 ID | 要求 |
|
|
220
|
+
|---------|------|
|
|
221
|
+
| A25 | DTO/Entity/VO 类属性必须为 private,通过 getter/setter 或 Lombok 访问,禁止 public 字段 |
|
|
222
|
+
| A26 | API 返回结果必须使用统一 Result<T> 封装类,禁止返回原始对象 |
|
|
223
|
+
| A27 | 分页查询返回包含标准分页结构(list + total + pages),请求参数包含 page/pageSize |
|
|
224
|
+
| A28 | 时间字段使用 LocalDateTime / Instant 等现代时间 API,禁用 Date / Timestamp / SimpleDateFormat |
|
|
225
|
+
|
|
226
|
+
### 6.7 异常处理规范(A29-A31)
|
|
227
|
+
|
|
228
|
+
| 规则 ID | 要求 |
|
|
229
|
+
|---------|------|
|
|
230
|
+
| A29 | catch 块必须精确捕获具体异常类型,禁止笼统 `catch(Exception e)` 吞掉所有异常 |
|
|
231
|
+
| A30 | 日志中必须包含足够上下文信息(参数、状态、关键变量),便于问题排查 |
|
|
232
|
+
| A31 | 业务规则违反必须抛出项目自定义业务异常(如 BusinessException/JscicdBizException),携带错误码和错误信息 |
|