create-vibe-workflow 0.1.0 → 0.2.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 +248 -57
- package/dist/adapters/next-only/skills.recommend.json +1 -0
- package/dist/adapters/node-api/skills.recommend.json +1 -0
- package/dist/cli.js +163 -5
- package/dist/cli.js.map +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +255 -44
- package/dist/generator.js.map +1 -1
- package/dist/questions.d.ts +11 -1
- package/dist/questions.d.ts.map +1 -1
- package/dist/questions.js +103 -16
- package/dist/questions.js.map +1 -1
- package/dist/templates/claude-md/CLAUDE.zh-CN.md +51 -46
- package/dist/templates/claude-md/next-only/CLAUDE.zh-CN.md +46 -0
- package/dist/templates/claude-md/node-api/CLAUDE.zh-CN.md +47 -0
- package/dist/templates/commands/gstack/cso.md.ejs +213 -0
- package/dist/templates/commands/gstack/office-hours.md.ejs +109 -0
- package/dist/templates/commands/gstack/review.md.ejs +192 -0
- package/dist/templates/commands/gstack/ship.md.ejs +256 -0
- package/dist/templates/commands/opsx/apply.md.ejs +106 -0
- package/dist/templates/commands/opsx/archive.md.ejs +88 -0
- package/dist/templates/commands/opsx/explore.md.ejs +84 -0
- package/dist/templates/commands/opsx/propose.md.ejs +185 -0
- package/dist/templates/commands/superpowers/brainstorm.md.ejs +240 -0
- package/dist/templates/commands/superpowers/tdd.md.ejs +230 -0
- package/dist/templates/commands/superpowers/verify.md.ejs +211 -0
- package/dist/templates/commands/workflow/plan.md.ejs +219 -0
- package/dist/templates/hooks/check-deps.mjs +66 -65
- package/dist/templates/memory/.gitkeep +0 -0
- package/dist/templates/memory/MEMORY.md.ejs +88 -0
- package/dist/templates/memory/dev-notes.md.ejs +61 -0
- package/dist/templates/memory/troubleshooting.md.ejs +30 -0
- package/dist/templates/rules/agents.md +49 -49
- package/dist/templates/rules/coding-style.md +156 -117
- package/dist/templates/rules/development-workflow.md +103 -50
- package/dist/templates/rules/git-workflow.md +103 -47
- package/dist/templates/rules/hooks.md +159 -0
- package/dist/templates/rules/hooks.md.ejs +159 -0
- package/dist/templates/rules/memory.md +106 -0
- package/dist/templates/rules/memory.md.ejs +106 -0
- package/dist/templates/rules/patterns.md +117 -48
- package/dist/templates/rules/performance.md +108 -0
- package/dist/templates/rules/performance.md.ejs +108 -0
- package/dist/templates/rules/security.md +52 -37
- package/dist/templates/rules/testing.md +83 -30
- package/dist/templates/settings/settings.template.json +18 -2
- package/dist/templates/skills/advanced/caveman/SKILL.md.ejs +144 -0
- package/dist/templates/skills/advanced/diagnose/SKILL.md.ejs +159 -0
- package/dist/templates/skills/advanced/grill-with-docs/SKILL.md.ejs +154 -0
- package/dist/templates/skills/advanced/improve-codebase-architecture/SKILL.md.ejs +172 -0
- package/dist/templates/skills/backend/backend-patterns/SKILL.md.ejs +263 -0
- package/dist/templates/skills/database/database-migrations/SKILL.md.ejs +202 -0
- package/dist/templates/skills/database/postgres-patterns/SKILL.md.ejs +235 -0
- package/dist/templates/skills/devops/deployment-patterns/SKILL.md.ejs +228 -0
- package/dist/templates/skills/devops/docker-patterns/SKILL.md.ejs +215 -0
- package/dist/templates/skills/frontend/frontend-patterns/SKILL.md.ejs +195 -0
- package/dist/templates/skills/skill-manifest.json +59 -0
- package/dist/templates/skills/skills-lock.template.json +12 -0
- package/dist/templates/skills/testing/e2e-testing/SKILL.md.ejs +224 -0
- package/dist/templates/skills/workflow/coding-standards/SKILL.md.ejs +143 -0
- package/dist/templates/skills/workflow/search-first/SKILL.md.ejs +103 -0
- package/dist/templates/skills/workflow/security-review/SKILL.md.ejs +146 -0
- package/dist/templates/skills/workflow/strategic-compact/SKILL.md.ejs +108 -0
- package/dist/templates/skills/workflow/tdd-workflow/SKILL.md.ejs +104 -0
- package/dist/templates/skills/workflow/verification-loop/SKILL.md.ejs +144 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +110 -0
- package/dist/utils.js.map +1 -0
- package/package.json +2 -2
- package/templates/claude-md/CLAUDE.zh-CN.md +51 -46
- package/templates/claude-md/next-only/CLAUDE.zh-CN.md +46 -0
- package/templates/claude-md/node-api/CLAUDE.zh-CN.md +47 -0
- package/templates/commands/gstack/cso.md.ejs +213 -0
- package/templates/commands/gstack/office-hours.md.ejs +109 -0
- package/templates/commands/gstack/review.md.ejs +192 -0
- package/templates/commands/gstack/ship.md.ejs +256 -0
- package/templates/commands/opsx/apply.md.ejs +106 -0
- package/templates/commands/opsx/archive.md.ejs +88 -0
- package/templates/commands/opsx/explore.md.ejs +84 -0
- package/templates/commands/opsx/propose.md.ejs +185 -0
- package/templates/commands/superpowers/brainstorm.md.ejs +240 -0
- package/templates/commands/superpowers/tdd.md.ejs +230 -0
- package/templates/commands/superpowers/verify.md.ejs +211 -0
- package/templates/commands/workflow/plan.md.ejs +219 -0
- package/templates/hooks/check-deps.mjs +66 -65
- package/templates/memory/.gitkeep +0 -0
- package/templates/memory/MEMORY.md.ejs +88 -0
- package/templates/memory/dev-notes.md.ejs +61 -0
- package/templates/memory/troubleshooting.md.ejs +30 -0
- package/templates/rules/agents.md +49 -49
- package/templates/rules/coding-style.md +156 -117
- package/templates/rules/development-workflow.md +103 -50
- package/templates/rules/git-workflow.md +103 -47
- package/templates/rules/hooks.md +159 -0
- package/templates/rules/memory.md +106 -0
- package/templates/rules/patterns.md +117 -48
- package/templates/rules/performance.md +108 -0
- package/templates/rules/security.md +52 -37
- package/templates/rules/testing.md +83 -30
- package/templates/settings/settings.template.json +18 -2
- package/templates/skills/advanced/caveman/SKILL.md.ejs +144 -0
- package/templates/skills/advanced/diagnose/SKILL.md.ejs +159 -0
- package/templates/skills/advanced/grill-with-docs/SKILL.md.ejs +154 -0
- package/templates/skills/advanced/improve-codebase-architecture/SKILL.md.ejs +172 -0
- package/templates/skills/backend/backend-patterns/SKILL.md.ejs +263 -0
- package/templates/skills/database/database-migrations/SKILL.md.ejs +202 -0
- package/templates/skills/database/postgres-patterns/SKILL.md.ejs +235 -0
- package/templates/skills/devops/deployment-patterns/SKILL.md.ejs +228 -0
- package/templates/skills/devops/docker-patterns/SKILL.md.ejs +215 -0
- package/templates/skills/frontend/frontend-patterns/SKILL.md.ejs +195 -0
- package/templates/skills/skill-manifest.json +59 -0
- package/templates/skills/skills-lock.template.json +12 -0
- package/templates/skills/testing/e2e-testing/SKILL.md.ejs +224 -0
- package/templates/skills/workflow/coding-standards/SKILL.md.ejs +143 -0
- package/templates/skills/workflow/search-first/SKILL.md.ejs +103 -0
- package/templates/skills/workflow/security-review/SKILL.md.ejs +146 -0
- package/templates/skills/workflow/strategic-compact/SKILL.md.ejs +108 -0
- package/templates/skills/workflow/tdd-workflow/SKILL.md.ejs +104 -0
- package/templates/skills/workflow/verification-loop/SKILL.md.ejs +144 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# E2E Testing — 端到端自动化测试
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:编写浏览器自动化测试、设计测试套件结构、调试测试失败时。
|
|
4
|
+
|
|
5
|
+
## 测试结构规范
|
|
6
|
+
|
|
7
|
+
### 测试文件组织
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
e2e/
|
|
11
|
+
├── specs/ # 测试用例文件
|
|
12
|
+
│ ├── auth/ # 按功能模块分组
|
|
13
|
+
│ │ ├── login.spec.{ext}
|
|
14
|
+
│ │ ├── register.spec.{ext}
|
|
15
|
+
│ │ └── password-reset.spec.{ext}
|
|
16
|
+
│ ├── checkout/
|
|
17
|
+
│ │ ├── cart.spec.{ext}
|
|
18
|
+
│ │ ├── payment.spec.{ext}
|
|
19
|
+
│ │ └── order-confirmation.spec.{ext}
|
|
20
|
+
│ └── profile/
|
|
21
|
+
│ └── edit-profile.spec.{ext}
|
|
22
|
+
├── pages/ # Page Object 模型
|
|
23
|
+
│ ├── LoginPage.{ext}
|
|
24
|
+
│ ├── CheckoutPage.{ext}
|
|
25
|
+
│ └── ProfilePage.{ext}
|
|
26
|
+
├── fixtures/ # 测试夹具(登录状态、测试数据)
|
|
27
|
+
│ ├── auth-fixtures.{ext}
|
|
28
|
+
│ └── test-users.json
|
|
29
|
+
└── helpers/ # 工具函数
|
|
30
|
+
├── test-utils.{ext}
|
|
31
|
+
└── db-helpers.{ext}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 测试用例命名
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
// 描述格式:{功能} — {场景} — {期望结果}
|
|
38
|
+
|
|
39
|
+
"用户登录 — 输入正确凭据 — 重定向到首页"
|
|
40
|
+
"用户登录 — 输入错误密码 — 显示错误提示"
|
|
41
|
+
"用户登录 — 连续 5 次失败 — 账号被临时锁定"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Page Object 模式
|
|
45
|
+
|
|
46
|
+
### 结构规范
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
每个页面一个类,包含:
|
|
50
|
+
1. 页面选择器(data-testid 优先)
|
|
51
|
+
2. 页面操作(方法)
|
|
52
|
+
3. 页面断言(验证方法)
|
|
53
|
+
|
|
54
|
+
示例结构:
|
|
55
|
+
class LoginPage {
|
|
56
|
+
// === 选择器 ===
|
|
57
|
+
emailInput() // data-testid="login-email"
|
|
58
|
+
passwordInput() // data-testid="login-password"
|
|
59
|
+
submitButton() // data-testid="login-submit"
|
|
60
|
+
errorMessage() // data-testid="login-error"
|
|
61
|
+
loadingIndicator() // data-testid="login-loading"
|
|
62
|
+
|
|
63
|
+
// === 操作 ===
|
|
64
|
+
async navigate() // 导航到登录页
|
|
65
|
+
async login(email, password) // 执行登录流程
|
|
66
|
+
async getErrorMessage() // 获取错误文案
|
|
67
|
+
|
|
68
|
+
// === 断言 ===
|
|
69
|
+
async expectLoginSuccess() // 验证登录成功
|
|
70
|
+
async expectValidationError() // 验证验证错误
|
|
71
|
+
async expectRateLimited() // 验证限流提示
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Selector 策略
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
【优先级从高到低】
|
|
79
|
+
|
|
80
|
+
1. data-testid(首选)
|
|
81
|
+
[data-testid="login-submit"]
|
|
82
|
+
优点:与样式/语义解耦,UI 变更不影响测试
|
|
83
|
+
|
|
84
|
+
2. 文本内容(推荐)
|
|
85
|
+
text="提交"
|
|
86
|
+
优点:接近用户视角
|
|
87
|
+
注意:注意国际化文案变化
|
|
88
|
+
|
|
89
|
+
3. ARIA 属性
|
|
90
|
+
[role="button"][name="提交"]
|
|
91
|
+
优点:语义清晰,辅助无障碍测试
|
|
92
|
+
|
|
93
|
+
4. CSS 选择器(次选)
|
|
94
|
+
.form > .actions > button.primary
|
|
95
|
+
注意:对 UI 变化敏感
|
|
96
|
+
|
|
97
|
+
5. XPath(不推荐,除非上面都不行)
|
|
98
|
+
脆弱、难读、POS 维护
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Wait 策略
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
【规则】
|
|
105
|
+
- 优先用自动等待(内置 auto-waiting)
|
|
106
|
+
- 特定场景用显式等待
|
|
107
|
+
- 禁止固定 sleep/等待
|
|
108
|
+
|
|
109
|
+
推荐方式(按优先级):
|
|
110
|
+
1. 自动等待
|
|
111
|
+
点击/输入等操作自动等待元素可交互
|
|
112
|
+
|
|
113
|
+
2. 定位器断言
|
|
114
|
+
expect(element).toBeVisible()
|
|
115
|
+
自动重试直到断言通过
|
|
116
|
+
|
|
117
|
+
3. 特定 URL/网络等待
|
|
118
|
+
waitForURL('**/dashboard')
|
|
119
|
+
waitForResponse(res => res.url().includes('/api/orders'))
|
|
120
|
+
|
|
121
|
+
4. 自定义等待(最后一招)
|
|
122
|
+
waitForFunction(() => document.title === 'Dashboard')
|
|
123
|
+
|
|
124
|
+
不推荐:
|
|
125
|
+
wait(3000) // 固定等待 — 慢且不可靠
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 测试数据管理
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
【测试数据策略】
|
|
132
|
+
|
|
133
|
+
独立数据:
|
|
134
|
+
每个测试创建自己的数据
|
|
135
|
+
优点:测试隔离性好
|
|
136
|
+
缺点:慢
|
|
137
|
+
|
|
138
|
+
共享数据:
|
|
139
|
+
beforeAll 创建一次,多个测试复用
|
|
140
|
+
优点:快
|
|
141
|
+
缺点:测试间耦合
|
|
142
|
+
|
|
143
|
+
推荐:独立数据(默认)+ 共享数据(只读场景)
|
|
144
|
+
|
|
145
|
+
数据清理:
|
|
146
|
+
- 每个测试清理自己创建的数据
|
|
147
|
+
- 或使用事务回滚(DB 测试)
|
|
148
|
+
- 或使用测试容器(Docker 重置)
|
|
149
|
+
|
|
150
|
+
测试账号:
|
|
151
|
+
- 专用测试账号(不要用真实用户)
|
|
152
|
+
- 每个环境使用不同账号
|
|
153
|
+
- 密码使用环境变量或 CI secret
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 失败诊断机制
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
失败时自动收集:
|
|
160
|
+
|
|
161
|
+
截图(Screenshot):
|
|
162
|
+
- 测试失败时自动截图
|
|
163
|
+
- 保留失败时的页面状态
|
|
164
|
+
- 命名:{测试文件}-{测试名}-{时间戳}.png
|
|
165
|
+
|
|
166
|
+
视频(Video):
|
|
167
|
+
- 录制整个测试运行过程
|
|
168
|
+
- 回放看到每一步操作
|
|
169
|
+
- 注意存储空间(差异压缩)
|
|
170
|
+
|
|
171
|
+
Trace(追踪):
|
|
172
|
+
- 记录每个操作的完整上下文
|
|
173
|
+
- 包括:网络请求、Console 日志、源码映射
|
|
174
|
+
- 可回放查看失败前的操作序列
|
|
175
|
+
|
|
176
|
+
Console 日志:
|
|
177
|
+
- 收集所有 console.error / console.warn
|
|
178
|
+
- 关联到具体测试用例
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## CI 集成配置
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
CI 运行策略:
|
|
185
|
+
- 只在包含 E2E 相关变更时触发
|
|
186
|
+
- 并行运行(分片)减少等待时间
|
|
187
|
+
- 重试策略:失败自动重试 1-2 次(针对 flaky 测试)
|
|
188
|
+
|
|
189
|
+
并行策略:
|
|
190
|
+
shardCount: 4 // 4 个分片并行
|
|
191
|
+
workers: 2 // 每个分片 2 个 worker
|
|
192
|
+
|
|
193
|
+
重试策略:
|
|
194
|
+
retries: 2 // 失败重试 2 次
|
|
195
|
+
maxFailures: 10 // 超过 10 个失败停止
|
|
196
|
+
|
|
197
|
+
环境变量:
|
|
198
|
+
BASE_URL // 测试目标 URL
|
|
199
|
+
CI // CI 环境标识
|
|
200
|
+
RETRY_COUNT // 重试次数
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Flaky 测试处理
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
识别 flaky 测试:
|
|
207
|
+
- 同一测试有时过有时不过
|
|
208
|
+
- 和代码变更无关的失败
|
|
209
|
+
|
|
210
|
+
常见原因及修复:
|
|
211
|
+
原因 | 修复
|
|
212
|
+
------------------------|-------------------------------
|
|
213
|
+
时序问题(异步未完成) | 用显式等待代替固定等待
|
|
214
|
+
测试间数据干扰 | 每个测试独立数据
|
|
215
|
+
环境/网络不稳定 | 合理重试策略
|
|
216
|
+
选择器脆弱 | 使用 data-testid
|
|
217
|
+
状态未清理 | beforeEach 清理状态
|
|
218
|
+
|
|
219
|
+
处理流程:
|
|
220
|
+
1. 标记为 flaky 但不阻塞 CI
|
|
221
|
+
2. 分析失败原因(trace + screenshot)
|
|
222
|
+
3. 修复根本原因
|
|
223
|
+
4. 验证不再 flaky 后取消标记
|
|
224
|
+
```
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Coding Standards — 编码规范
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:在生成代码或审查代码时,应用以下标准。
|
|
4
|
+
|
|
5
|
+
## 不可变性(最高优先级)
|
|
6
|
+
|
|
7
|
+
**永远创建新对象,绝不修改已有对象。**
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
// ❌ 错误 — 直接修改原对象
|
|
11
|
+
updateUser(user, "name", "newName") {
|
|
12
|
+
user.name = "newName" // 改变了原对象
|
|
13
|
+
return user
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ✅ 正确 — 返回新副本
|
|
17
|
+
updateUser(user, "name", "newName") {
|
|
18
|
+
return { ...user, name: "newName" }
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
为什么?
|
|
23
|
+
- 无副作用,调用方不会被意外影响
|
|
24
|
+
- 调试更容易(值不会"神秘改变")
|
|
25
|
+
- 并发安全(多个操作可安全共享数据)
|
|
26
|
+
|
|
27
|
+
## 文件组织
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
【原则】多小文件 > 少大文件
|
|
31
|
+
- 高内聚、低耦合
|
|
32
|
+
- 每个文件 200-400 行,上限 800 行
|
|
33
|
+
- 按功能/领域组织,不按类型组织
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 典型目录结构
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
src/
|
|
40
|
+
├── modules/
|
|
41
|
+
│ └── {module-name}/
|
|
42
|
+
│ ├── {module}.{ext} # 模块入口
|
|
43
|
+
│ ├── {module}.controller.{ext} # 路由/请求处理
|
|
44
|
+
│ ├── {module}.service.{ext} # 业务逻辑
|
|
45
|
+
│ ├── {module}.schema.{ext} # 校验 schema
|
|
46
|
+
│ ├── {module}.types.{ext} # 类型定义
|
|
47
|
+
│ └── {module}.test.{ext} # 测试
|
|
48
|
+
├── shared/
|
|
49
|
+
│ ├── utils/ # 通用工具函数
|
|
50
|
+
│ ├── types/ # 共享类型
|
|
51
|
+
│ └── constants/ # 常量
|
|
52
|
+
└── config/ # 配置
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 命名规范
|
|
56
|
+
|
|
57
|
+
| 类别 | 规范 | 示例 |
|
|
58
|
+
|------|------|------|
|
|
59
|
+
| 文件名 | kebab-case | `user-service.{ext}` |
|
|
60
|
+
| 目录名 | kebab-case | `user-module/` |
|
|
61
|
+
| 变量/函数 | camelCase | `getUserById` |
|
|
62
|
+
| 类/接口/类型 | PascalCase | `UserService` |
|
|
63
|
+
| 常量 | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT` |
|
|
64
|
+
| 枚举值 | UPPER_SNAKE_CASE | `Role.ADMIN` |
|
|
65
|
+
| 布尔前缀 | is/has/can/should | `isActive`, `hasPermission` |
|
|
66
|
+
| 私有成员 | 下划线前缀 | `_internalMethod` |
|
|
67
|
+
|
|
68
|
+
## 错误处理
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
【三条规则】
|
|
72
|
+
1. 所有可能失败的 IO 操作必须用 try-catch 包裹
|
|
73
|
+
2. 错误必须包含有用信息(上下文 + 原因)
|
|
74
|
+
3. 边界层(API/UI)必须将错误转为用户友好的形式
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 错误分层
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
系统边界层(API/Controller 等)
|
|
81
|
+
└─ 捕获所有异常,转为错误响应格式
|
|
82
|
+
└─ 业务逻辑层(Service)
|
|
83
|
+
└─ 抛出具名业务错误(ValidationError / NotFoundError 等)
|
|
84
|
+
└─ 数据访问层(Repository/DAO)
|
|
85
|
+
└─ 包装底层错误为数据访问错误
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 输入验证
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
【所有系统入口点必须验证输入】
|
|
92
|
+
- API 端点参数
|
|
93
|
+
- 表单提交数据
|
|
94
|
+
- 文件导入内容
|
|
95
|
+
- 外部 API 回调数据
|
|
96
|
+
- 消息队列消息
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 代码质量自查清单
|
|
100
|
+
|
|
101
|
+
- [ ] 命名清楚表达意图(好命名不需要注释解释)
|
|
102
|
+
- [ ] 函数不超过 50 行(超过则提取子函数)
|
|
103
|
+
- [ ] 文件不超过 800 行
|
|
104
|
+
- [ ] 嵌套不超过 4 层(超过则提前 return 或提取函数)
|
|
105
|
+
- [ ] 没有死代码(未使用的变量/函数/导入)
|
|
106
|
+
- [ ] 没有循环依赖
|
|
107
|
+
- [ ] 没有魔法数字/字符串(使用命名常量)
|
|
108
|
+
- [ ] 错误路径已处理
|
|
109
|
+
- [ ] 边界情况已覆盖(空值、零值、超长值)
|
|
110
|
+
- [ ] 日志包含足够的上下文信息
|
|
111
|
+
|
|
112
|
+
## 日志规范
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
【禁止】在生产代码中使用 console.log / print / println
|
|
116
|
+
|
|
117
|
+
级别使用:
|
|
118
|
+
error — 需要人工介入的异常(不可恢复)
|
|
119
|
+
warn — 可恢复但需要注意的情况(重试成功、降级)
|
|
120
|
+
info — 关键业务流程节点(用户注册、下单)
|
|
121
|
+
debug — 调试信息(仅在开发/调试环境输出)
|
|
122
|
+
|
|
123
|
+
每条日志应包含:
|
|
124
|
+
1. 操作标识(操作名、请求 ID)
|
|
125
|
+
2. 上下文数据(用户 ID、资源 ID 等,不含敏感信息)
|
|
126
|
+
3. 耗时/状态
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 注释规范
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
// 文档注释 — 公开 API 必须有
|
|
133
|
+
/** 描述函数行为及返回值 */
|
|
134
|
+
|
|
135
|
+
// 实现注释 — 解释"为什么"非"是什么"
|
|
136
|
+
// 使用轮询而非 WebSocket 因为客户端环境不支持长连接
|
|
137
|
+
|
|
138
|
+
// TODO 注释 — 必须有对应 Issue 跟踪
|
|
139
|
+
// TODO(#1234): 这个查询需要加索引
|
|
140
|
+
|
|
141
|
+
// 不需要的注释 — 代码本身已表达意图时
|
|
142
|
+
// ❌ 遍历用户列表 ← 这行代码已经说明了一切
|
|
143
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Search-First — 研究优先于编码
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:在实现任何新功能之前、在引入新依赖之前、在解决不熟悉的错误之前。
|
|
4
|
+
|
|
5
|
+
## 工作流
|
|
6
|
+
|
|
7
|
+
开始编码之前,先执行研究:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ ① 需求分析 明确要解决的问题、输入输出、约束条件 │
|
|
12
|
+
│ ② 并行搜索 同时搜索多个渠道(GitHub / 包管理器 / 文档 / 项目内) │
|
|
13
|
+
│ ③ 方案评估 对比候选方案的匹配度、维护状态、学习成本 │
|
|
14
|
+
│ ④ 决策 选择策略:复用/扩展/组合/自建 │
|
|
15
|
+
│ ⑤ 实现 开始编码 │
|
|
16
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## ① 需求分析 — 明确搜索目标
|
|
20
|
+
|
|
21
|
+
在搜索前,先明确:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
- 要解决什么具体问题?
|
|
25
|
+
- 输入是什么、输出是什么?
|
|
26
|
+
- 有什么约束(性能、安全、兼容性)?
|
|
27
|
+
- 是全新需求还是替代现有方案?
|
|
28
|
+
- 是否有内部已有类似实现?
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## ② 并行搜索 — 多源获取信息
|
|
32
|
+
|
|
33
|
+
同时搜索以下渠道:
|
|
34
|
+
|
|
35
|
+
### 搜索渠道清单
|
|
36
|
+
|
|
37
|
+
| 渠道 | 场景 | 搜索什么 |
|
|
38
|
+
|------|------|---------|
|
|
39
|
+
| GitHub 代码搜索 | 寻找参考实现 | 类似功能的仓库、代码片段、Issue 讨论 |
|
|
40
|
+
| 包管理器(npm/PyPI/crates.io 等) | 寻找可复用库 | 功能匹配的包、下载量、最近更新 |
|
|
41
|
+
| 官方文档 | 确认 API 用法 | 版本迁移、配置项、最佳实践 |
|
|
42
|
+
| 项目内代码 | 复用已有模式 | 相邻模块的实现方式、工具函数库 |
|
|
43
|
+
| AI 知识库 | 模式/最佳实践 | 常用设计模式、已知解决方案 |
|
|
44
|
+
|
|
45
|
+
### 搜索方法
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
// GitHub 搜索示例
|
|
49
|
+
搜索: "language:{lang} {keyword} implementation"
|
|
50
|
+
搜索: "topic:{topic} language:{lang}"
|
|
51
|
+
|
|
52
|
+
// 包管理器搜索
|
|
53
|
+
搜索: "{keyword}" → 检查:最近更新、周下载量、依赖树大小
|
|
54
|
+
|
|
55
|
+
// 项目内搜索
|
|
56
|
+
搜索: 相邻功能模块的目录结构和使用模式
|
|
57
|
+
搜索: 项目中已使用的类似库/工具
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## ③ 方案评估 — 对比候选方案
|
|
61
|
+
|
|
62
|
+
对每个候选方案,评估以下维度:
|
|
63
|
+
|
|
64
|
+
| 维度 | 评估问题 |
|
|
65
|
+
|------|---------|
|
|
66
|
+
| 功能匹配 | 覆盖需求的百分之多少? |
|
|
67
|
+
| 维护状态 | 最近更新?Issue 响应?主仓库活跃? |
|
|
68
|
+
| 成熟度 | 版本号(<1.0 谨慎)、Star 数、被依赖数 |
|
|
69
|
+
| 学习成本 | 文档质量、示例数量、概念复杂度 |
|
|
70
|
+
| 集成成本 | 需要多少胶水代码?和现有技术栈兼容? |
|
|
71
|
+
| 安全 | 已知漏洞?权限模型? |
|
|
72
|
+
| 性能 | 基准测试?内存/CPU 影响? |
|
|
73
|
+
| 社区 | 问题是否有解答?Stack Overflow 讨论? |
|
|
74
|
+
|
|
75
|
+
## ④ 决策矩阵 — 选择策略
|
|
76
|
+
|
|
77
|
+
| 情况 | 策略 | 行动 |
|
|
78
|
+
|------|------|------|
|
|
79
|
+
| 有成熟的库覆盖 90%+ 需求 | **采用(Adopt)** | 引入依赖,按文档使用 |
|
|
80
|
+
| 有接近的库但需少量定制 | **扩展(Extend)** | 引入后包装/配置/插件 |
|
|
81
|
+
| 多个库各覆盖一部分 | **组合(Compose)** | 引入多个库,编写胶水层 |
|
|
82
|
+
| 没有合适的库 | **自建(Build)** | 参考调研结果自行实现 |
|
|
83
|
+
|
|
84
|
+
### 不引入依赖的情况
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
- 功能少于 50 行代码可实现
|
|
88
|
+
- 库有已知安全漏洞且不及时修复
|
|
89
|
+
- 库的依赖树过大(间接引入 >50 个包)
|
|
90
|
+
- 库与项目技术栈不兼容
|
|
91
|
+
- 只有一个函数需要但库是整个框架
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## ⑤ 反模式
|
|
95
|
+
|
|
96
|
+
| 反模式 | 问题 | 正确做法 |
|
|
97
|
+
|--------|------|---------|
|
|
98
|
+
| 已知有库但非要自建 | 浪费时间,维护成本高 | 先用库,不够再替换 |
|
|
99
|
+
| 先写代码再搜索 | 可能走错方向 | 先搜索再编码 |
|
|
100
|
+
| 只看第一个结果 | 错过更好的方案 | 至少对比 3 个候选 |
|
|
101
|
+
| 引入大库只用小功能 | 膨胀依赖树 | 自己写或用微库 |
|
|
102
|
+
| 不验证就采用 | 发现不匹配时已投入大量时间 | 先写 PoC 验证 |
|
|
103
|
+
| 搜索完不看 License | 法律风险 | 确认 License 兼容性 |
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Security Review — 提交前安全检查
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:在准备提交代码前,或者修改了涉及认证/授权/用户数据/支付/外部 API 调用的代码时。
|
|
4
|
+
|
|
5
|
+
## 安全检查清单
|
|
6
|
+
|
|
7
|
+
以下所有检查项必须在每次提交前执行:
|
|
8
|
+
|
|
9
|
+
### 1. 密钥管理
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
[ ] 无硬编码密钥(API Key、密码、Token、JWT Secret)
|
|
13
|
+
[ ] 无硬编码数据库连接字符串
|
|
14
|
+
[ ] 无硬编码第三方服务凭据
|
|
15
|
+
[ ] 配置文件中无真实凭据(只有占位符或环境变量引用)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 2. 输入验证
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
[ ] 所有用户输入使用 schema 校验(长度/格式/类型/范围)
|
|
22
|
+
[ ] 文件上传有类型/大小限制
|
|
23
|
+
[ ] 批量操作有数量上限
|
|
24
|
+
[ ] URL 参数/路径参数已校验
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 3. SQL / NoSQL 注入防护
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
[ ] 使用参数化查询或 ORM 内置防护
|
|
31
|
+
[ ] 无字符串拼接 SQL 语句
|
|
32
|
+
[ ] NoSQL 查询使用参数化(非原始字符串注入)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 4. XSS 防护
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
[ ] 用户生成内容输出时已转义
|
|
39
|
+
[ ] 富文本内容经 HTML Sanitizer 过滤
|
|
40
|
+
[ ] CSP(Content Security Policy)已配置
|
|
41
|
+
[ ] 无 `innerHTML` / `dangerouslySetInnerHTML` 等危险 API
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 5. CSRF 防护
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
[ ] 有状态修改操作(POST/PUT/DELETE)有 CSRF 保护
|
|
48
|
+
[ ] SameSite Cookie 已设置
|
|
49
|
+
[ ] API 使用 Token 认证时无需额外 CSRF(但需确认)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 6. 认证与授权
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
[ ] 认证失败的响应不泄露用户是否存在
|
|
56
|
+
[ ] 令牌有有效期和刷新机制
|
|
57
|
+
[ ] 每次操作验证资源所有权(防止 IDOR)
|
|
58
|
+
[ ] 未认证用户无法访问受保护资源
|
|
59
|
+
[ ] 权限不足的用户得到 403 而非 401
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 7. 速率限制
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[ ] 认证端点有登录尝试限制
|
|
66
|
+
[ ] 公开 API 端点有速率限制
|
|
67
|
+
[ ] 文件上传端点有额外限制
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 8. 错误消息与日志
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
[ ] 错误消息不泄露内部细节(堆栈、路径、SQL、配置)
|
|
74
|
+
[ ] 日志中不记录密码、Token、信用卡等敏感数据
|
|
75
|
+
[ ] 生产环境关闭调试模式/详细错误
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 常见漏洞修复模板
|
|
79
|
+
|
|
80
|
+
### 修复硬编码密钥
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
// ❌ 错误
|
|
84
|
+
apiKey = "sk-xxxxxxxxxxxxxxxx"
|
|
85
|
+
|
|
86
|
+
// ✅ 正确
|
|
87
|
+
apiKey = env("API_KEY")
|
|
88
|
+
if apiKey is empty → throw "API_KEY not configured"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 修复 SQL 注入
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
// ❌ 错误
|
|
95
|
+
query = "SELECT * FROM users WHERE id = '" + userId + "'"
|
|
96
|
+
|
|
97
|
+
// ✅ 正确
|
|
98
|
+
query = "SELECT * FROM users WHERE id = $1"
|
|
99
|
+
execute(query, [userId])
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 修复 IDOR(越权)
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
// ❌ 错误 — 只检查资源存在,不检查所有权
|
|
106
|
+
resource = db.find(resourceId)
|
|
107
|
+
return resource
|
|
108
|
+
|
|
109
|
+
// ✅ 正确 — 验证当前用户拥有该资源
|
|
110
|
+
resource = db.find(resourceId)
|
|
111
|
+
if resource.ownerId != currentUserId → throw 403
|
|
112
|
+
return resource
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 安全错误响应
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
// ❌ 错误 — 泄露内部信息
|
|
119
|
+
response 500: { "error": "Cannot read property 'x' of null at /src/services/user.js:42" }
|
|
120
|
+
|
|
121
|
+
// ✅ 正确 — 泛化错误
|
|
122
|
+
response 500: { "error": "Internal server error" }
|
|
123
|
+
// 日志中保留完整信息供调试
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 安全扫描命令
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# 依赖漏洞扫描
|
|
130
|
+
audit # 检查依赖中的已知漏洞
|
|
131
|
+
|
|
132
|
+
# 密钥扫描(防止敏感信息提交)
|
|
133
|
+
# 使用 pre-commit hook 或 CI 中的密钥扫描工具
|
|
134
|
+
|
|
135
|
+
# 静态安全分析
|
|
136
|
+
lint --security # 运行安全规则集
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 严重程度分级
|
|
140
|
+
|
|
141
|
+
| 级别 | 定义 | 行动要求 |
|
|
142
|
+
|------|------|---------|
|
|
143
|
+
| CRITICAL | 可直接导致数据泄露/服务入侵 | 必须修复,阻断提交 |
|
|
144
|
+
| HIGH | 在特定条件下可被利用 | 必须修复 |
|
|
145
|
+
| MEDIUM | 增加攻击面 | 建议修复 |
|
|
146
|
+
| LOW | 最佳实践偏离 | 记录待办 |
|