ethan-skill 1.6.0 → 1.8.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.
Files changed (87) hide show
  1. package/README.md +83 -24
  2. package/dist/cli/index.js +21 -21
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/loader/custom-pipeline-loader.d.ts +15 -0
  5. package/dist/loader/custom-pipeline-loader.d.ts.map +1 -0
  6. package/dist/loader/custom-pipeline-loader.js +131 -0
  7. package/dist/loader/custom-pipeline-loader.js.map +1 -0
  8. package/dist/skills/11-api-design.d.ts +3 -0
  9. package/dist/skills/11-api-design.d.ts.map +1 -0
  10. package/dist/skills/11-api-design.js +214 -0
  11. package/dist/skills/11-api-design.js.map +1 -0
  12. package/dist/skills/12-security-review.d.ts +3 -0
  13. package/dist/skills/12-security-review.d.ts.map +1 -0
  14. package/dist/skills/12-security-review.js +194 -0
  15. package/dist/skills/12-security-review.js.map +1 -0
  16. package/dist/skills/13-deployment.d.ts +3 -0
  17. package/dist/skills/13-deployment.d.ts.map +1 -0
  18. package/dist/skills/13-deployment.js +189 -0
  19. package/dist/skills/13-deployment.js.map +1 -0
  20. package/dist/skills/14-prd.d.ts +3 -0
  21. package/dist/skills/14-prd.d.ts.map +1 -0
  22. package/dist/skills/14-prd.js +214 -0
  23. package/dist/skills/14-prd.js.map +1 -0
  24. package/dist/skills/15-git-workflow.d.ts +3 -0
  25. package/dist/skills/15-git-workflow.d.ts.map +1 -0
  26. package/dist/skills/15-git-workflow.js +288 -0
  27. package/dist/skills/15-git-workflow.js.map +1 -0
  28. package/dist/skills/16-unit-testing.d.ts +3 -0
  29. package/dist/skills/16-unit-testing.d.ts.map +1 -0
  30. package/dist/skills/16-unit-testing.js +298 -0
  31. package/dist/skills/16-unit-testing.js.map +1 -0
  32. package/dist/skills/17-system-design.d.ts +3 -0
  33. package/dist/skills/17-system-design.d.ts.map +1 -0
  34. package/dist/skills/17-system-design.js +294 -0
  35. package/dist/skills/17-system-design.js.map +1 -0
  36. package/dist/skills/18-database-optimize.d.ts +3 -0
  37. package/dist/skills/18-database-optimize.d.ts.map +1 -0
  38. package/dist/skills/18-database-optimize.js +294 -0
  39. package/dist/skills/18-database-optimize.js.map +1 -0
  40. package/dist/skills/19-docker.d.ts +3 -0
  41. package/dist/skills/19-docker.d.ts.map +1 -0
  42. package/dist/skills/19-docker.js +360 -0
  43. package/dist/skills/19-docker.js.map +1 -0
  44. package/dist/skills/20-cicd.d.ts +3 -0
  45. package/dist/skills/20-cicd.d.ts.map +1 -0
  46. package/dist/skills/20-cicd.js +364 -0
  47. package/dist/skills/20-cicd.js.map +1 -0
  48. package/dist/skills/21-performance.d.ts +3 -0
  49. package/dist/skills/21-performance.d.ts.map +1 -0
  50. package/dist/skills/21-performance.js +139 -0
  51. package/dist/skills/21-performance.js.map +1 -0
  52. package/dist/skills/22-refactoring.d.ts +3 -0
  53. package/dist/skills/22-refactoring.d.ts.map +1 -0
  54. package/dist/skills/22-refactoring.js +235 -0
  55. package/dist/skills/22-refactoring.js.map +1 -0
  56. package/dist/skills/23-observability.d.ts +3 -0
  57. package/dist/skills/23-observability.d.ts.map +1 -0
  58. package/dist/skills/23-observability.js +266 -0
  59. package/dist/skills/23-observability.js.map +1 -0
  60. package/dist/skills/24-design-patterns.d.ts +3 -0
  61. package/dist/skills/24-design-patterns.d.ts.map +1 -0
  62. package/dist/skills/24-design-patterns.js +258 -0
  63. package/dist/skills/24-design-patterns.js.map +1 -0
  64. package/dist/skills/index.d.ts +14 -0
  65. package/dist/skills/index.d.ts.map +1 -1
  66. package/dist/skills/index.js +57 -1
  67. package/dist/skills/index.js.map +1 -1
  68. package/dist/skills/pipeline.d.ts +2 -1
  69. package/dist/skills/pipeline.d.ts.map +1 -1
  70. package/dist/skills/pipeline.js +41 -3
  71. package/dist/skills/pipeline.js.map +1 -1
  72. package/dist/skills/skills.test.js +3 -3
  73. package/dist/skills/skills.test.js.map +1 -1
  74. package/dist/templates/templates.test.js +2 -3
  75. package/dist/templates/templates.test.js.map +1 -1
  76. package/package.json +1 -1
  77. package/rules/claude-code/CLAUDE.md +3048 -3
  78. package/rules/cline/.clinerules +2838 -2
  79. package/rules/codebuddy/CODEBUDDY.md +2977 -2
  80. package/rules/continue/.continuerules +2838 -2
  81. package/rules/copilot/copilot-instructions.md +2935 -2
  82. package/rules/cursor/.cursorrules +3033 -2
  83. package/rules/cursor/smart-flow.mdc +3033 -2
  84. package/rules/jetbrains/smart-flow.md +2935 -2
  85. package/rules/lingma/smart-flow.md +2964 -3
  86. package/rules/windsurf/.windsurf/rules/smart-flow.md +2936 -3
  87. package/rules/zed/smart-flow.rules +2823 -1
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /**
3
+ * 自定义 Pipeline 加载器
4
+ * 从项目的 .ethan/pipelines/ 目录加载用户自定义 Pipeline(YAML 或 JSON 格式)
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.loadCustomPipelines = loadCustomPipelines;
41
+ exports.generatePipelineTemplate = generatePipelineTemplate;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const CUSTOM_PIPELINES_DIR = '.ethan/pipelines';
45
+ /**
46
+ * 从指定目录加载自定义 Pipeline 定义
47
+ * 支持 .yaml、.yml、.json 格式
48
+ */
49
+ function loadCustomPipelines(cwd = process.cwd()) {
50
+ const pipelinesDir = path.join(cwd, CUSTOM_PIPELINES_DIR);
51
+ if (!fs.existsSync(pipelinesDir))
52
+ return [];
53
+ const files = fs.readdirSync(pipelinesDir).filter((f) => /\.(ya?ml|json)$/i.test(f));
54
+ const pipelines = [];
55
+ for (const file of files) {
56
+ const filePath = path.join(pipelinesDir, file);
57
+ try {
58
+ const raw = fs.readFileSync(filePath, 'utf-8');
59
+ let data;
60
+ if (/\.json$/i.test(file)) {
61
+ data = JSON.parse(raw);
62
+ }
63
+ else {
64
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
65
+ const yaml = require('js-yaml');
66
+ data = yaml.load(raw);
67
+ }
68
+ const pipeline = validateCustomPipeline(data, file);
69
+ if (pipeline) {
70
+ pipelines.push(pipeline);
71
+ }
72
+ }
73
+ catch (err) {
74
+ console.warn(` ⚠️ Failed to load custom pipeline: ${file} — ${err.message}`);
75
+ }
76
+ }
77
+ return pipelines;
78
+ }
79
+ /**
80
+ * 验证自定义 Pipeline 数据结构,返回合法的 PipelineDefinition 或 null
81
+ */
82
+ function validateCustomPipeline(data, filename) {
83
+ if (typeof data !== 'object' || data === null) {
84
+ console.warn(` ⚠️ ${filename}: root must be an object`);
85
+ return null;
86
+ }
87
+ const d = data;
88
+ const required = ['id', 'name', 'description', 'skillIds'];
89
+ for (const key of required) {
90
+ if (!d[key]) {
91
+ console.warn(` ⚠️ ${filename}: missing required field "${key}"`);
92
+ return null;
93
+ }
94
+ }
95
+ if (!Array.isArray(d.skillIds) || d.skillIds.length === 0) {
96
+ console.warn(` ⚠️ ${filename}: "skillIds" must be a non-empty array`);
97
+ return null;
98
+ }
99
+ return {
100
+ id: String(d.id),
101
+ name: String(d.name),
102
+ description: String(d.description),
103
+ skillIds: d.skillIds.map(String),
104
+ };
105
+ }
106
+ /**
107
+ * 生成自定义 Pipeline 的 YAML 模板文件
108
+ */
109
+ function generatePipelineTemplate() {
110
+ return `# Ethan 自定义 Pipeline 模板
111
+ # Pipeline 是多个 Skill 的有序组合,支持链式工作流
112
+
113
+ id: my-pipeline # 唯一标识符(用于 ethan pipeline run <id>)
114
+ name: 我的工作流 # 显示名称
115
+ description: 一句话描述这条 Pipeline 的用途
116
+
117
+ # skillIds: 按执行顺序填写 Skill ID
118
+ # 可用内置 Skill ID:
119
+ # requirement-understanding, task-breakdown, solution-design,
120
+ # implementation, progress-tracking, task-report, weekly-report,
121
+ # code-review, debug, tech-research,
122
+ # api-design, security-review, deployment, prd
123
+ # 也可以使用自定义 Skill 的 ID(需先在 .ethan/skills/ 中定义)
124
+ skillIds:
125
+ - requirement-understanding
126
+ - solution-design
127
+ - implementation
128
+ - code-review
129
+ `;
130
+ }
131
+ //# sourceMappingURL=custom-pipeline-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-pipeline-loader.js","sourceRoot":"","sources":["../../src/loader/custom-pipeline-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SkillDefinition } from './types';
2
+ export declare const apiDesignSkill: SkillDefinition;
3
+ //# sourceMappingURL=11-api-design.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"11-api-design.d.ts","sourceRoot":"","sources":["../../src/skills/11-api-design.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,eAAO,MAAM,cAAc,EAAE,eAkN5B,CAAC"}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.apiDesignSkill = void 0;
4
+ exports.apiDesignSkill = {
5
+ id: 'api-design',
6
+ name: '接口设计',
7
+ nameEn: 'api_design',
8
+ order: 11,
9
+ description: '基于业务需求设计清晰、可演进的 RESTful / GraphQL 接口规范,输出接口文档',
10
+ descriptionEn: 'Design RESTful or GraphQL APIs with clear contracts, versioning strategy, and documentation',
11
+ detailDescription: `根据业务需求和系统边界,设计语义清晰、可版本演进的 API 接口,
12
+ 覆盖路径设计、请求/响应体、状态码、认证鉴权、错误处理和分页策略,
13
+ 最终输出标准化接口规范文档(OpenAPI 3.0 风格)。`,
14
+ triggers: [
15
+ '接口设计',
16
+ 'API 设计',
17
+ 'api design',
18
+ '设计接口',
19
+ '接口规范',
20
+ 'RESTful 设计',
21
+ 'GraphQL 设计',
22
+ '设计 REST API',
23
+ '设计 API',
24
+ '@ethan api',
25
+ '@ethan 接口',
26
+ '/接口设计',
27
+ ],
28
+ steps: [
29
+ {
30
+ title: '1. 明确业务边界与资源模型',
31
+ content: `- 梳理本次需要暴露的**核心业务实体**(资源)
32
+ - 确定资源间的关联关系:一对一 / 一对多 / 多对多
33
+ - 识别操作类型:CRUD、操作型动作(如 /activate、/cancel)
34
+ - 确认调用方(Web / App / 第三方 / 内部服务)
35
+ - 确认认证方式:JWT / OAuth2 / API Key / Session`,
36
+ },
37
+ {
38
+ title: '2. 设计 URL 路径与 HTTP 方法',
39
+ content: `遵循 REST 语义设计路径:
40
+
41
+ **命名规范**
42
+ - 使用复数名词表示集合:\`/users\`、\`/orders\`
43
+ - 资源嵌套不超过 2 层:\`/users/{id}/orders\`
44
+ - 动作使用子资源表达:\`POST /orders/{id}/cancel\`
45
+ - 使用小写 kebab-case:\`/user-profiles\`
46
+
47
+ **HTTP 方法映射**
48
+ | 方法 | 场景 | 幂等性 |
49
+ |------|------|--------|
50
+ | GET | 查询(单个/列表) | ✅ |
51
+ | POST | 创建 / 触发动作 | ❌ |
52
+ | PUT | 全量更新 | ✅ |
53
+ | PATCH | 局部更新 | ✅ |
54
+ | DELETE | 删除 | ✅ |
55
+
56
+ **版本控制**
57
+ - URL 版本:\`/api/v1/users\`(推荐,可见性高)
58
+ - Header 版本:\`Accept: application/vnd.api+json;version=1\``,
59
+ },
60
+ {
61
+ title: '3. 设计请求与响应体',
62
+ content: `**请求体规范**
63
+ - Content-Type 统一 \`application/json\`
64
+ - 字段使用 camelCase(Web 侧)或 snake_case(按团队规范统一)
65
+ - 必填字段明确标注,给出示例值
66
+ - 枚举值给出完整列表和含义
67
+
68
+ **统一响应体格式**
69
+ \`\`\`json
70
+ {
71
+ "code": 0, // 0=成功,非0=错误码
72
+ "message": "ok", // 描述信息
73
+ "data": { ... }, // 业务数据(成功时)
74
+ "requestId": "uuid" // 链路追踪 ID
75
+ }
76
+ \`\`\`
77
+
78
+ **分页响应**
79
+ \`\`\`json
80
+ {
81
+ "code": 0,
82
+ "data": {
83
+ "list": [...],
84
+ "total": 100,
85
+ "page": 1,
86
+ "pageSize": 20
87
+ }
88
+ }
89
+ \`\`\`
90
+
91
+ **HTTP 状态码使用**
92
+ - 200 OK / 201 Created / 204 No Content
93
+ - 400 Bad Request(参数错误)/ 401 Unauthorized / 403 Forbidden
94
+ - 404 Not Found / 409 Conflict / 422 Unprocessable Entity
95
+ - 500 Internal Server Error(不暴露内部细节)`,
96
+ },
97
+ {
98
+ title: '4. 设计错误码体系',
99
+ content: `建立业务错误码规范,避免所有错误都返回 500:
100
+
101
+ **错误码设计**
102
+ \`\`\`
103
+ 模块前缀 + 序号:
104
+ 1001xx — 用户模块
105
+ 1002xx — 订单模块
106
+ 1003xx — 支付模块
107
+ \`\`\`
108
+
109
+ **示例**
110
+ \`\`\`json
111
+ {
112
+ "code": 100101,
113
+ "message": "用户不存在",
114
+ "data": null,
115
+ "requestId": "abc-123"
116
+ }
117
+ \`\`\`
118
+
119
+ - 错误信息面向**开发者**(不直接展示给终端用户)
120
+ - 敏感错误(如数据库异常)统一返回 \`"系统繁忙,请稍后重试"\`
121
+ - 提供错误码文档(维护在 API 文档中)`,
122
+ },
123
+ {
124
+ title: '5. 安全与性能设计',
125
+ content: `**安全**
126
+ - 所有修改类操作(POST/PUT/PATCH/DELETE)必须鉴权
127
+ - 列表接口加入数据权限隔离(用户只能看自己的数据)
128
+ - 文件上传接口限制文件类型和大小
129
+ - 敏感字段(手机号、身份证)在响应中脱敏:\`138****8888\`
130
+ - 接口加入速率限制(Rate Limiting)
131
+
132
+ **性能**
133
+ - 列表接口支持分页(禁止无限制全量返回)
134
+ - 大数据量接口提供游标分页(cursor-based)
135
+ - 支持字段过滤:\`?fields=id,name,email\`
136
+ - 耗时操作改为异步:POST 立即返回 \`taskId\`,GET 轮询状态`,
137
+ },
138
+ {
139
+ title: '6. 输出接口规范文档',
140
+ content: `按以下格式输出每个接口的文档:
141
+
142
+ \`\`\`markdown
143
+ ## POST /api/v1/users — 创建用户
144
+
145
+ **描述**:注册新用户账号
146
+
147
+ **认证**:不需要
148
+
149
+ **请求体**
150
+ | 字段 | 类型 | 必填 | 描述 |
151
+ |------|------|------|------|
152
+ | username | string | ✅ | 用户名,3-20字符,字母数字下划线 |
153
+ | email | string | ✅ | 邮箱地址 |
154
+ | password | string | ✅ | 密码,最少8位 |
155
+
156
+ **响应示例(201 Created)**
157
+ \`\`\`json
158
+ {
159
+ "code": 0,
160
+ "message": "ok",
161
+ "data": {
162
+ "id": "usr_abc123",
163
+ "username": "john_doe",
164
+ "email": "john@example.com",
165
+ "createdAt": "2024-01-01T00:00:00Z"
166
+ }
167
+ }
168
+ \`\`\`
169
+
170
+ **错误码**
171
+ | code | message | 场景 |
172
+ |------|---------|------|
173
+ | 100101 | 邮箱已被注册 | 邮箱重复 |
174
+ | 100102 | 用户名不合法 | 格式校验失败 |
175
+ \`\`\``,
176
+ },
177
+ ],
178
+ outputFormat: 'Markdown 接口规范文档,含路径设计、请求/响应体、错误码表、安全说明,风格参考 OpenAPI 3.0',
179
+ examples: [
180
+ {
181
+ input: '设计一个用户登录接口',
182
+ output: `## POST /api/v1/auth/login — 用户登录
183
+
184
+ **请求体**
185
+ | 字段 | 类型 | 必填 | 描述 |
186
+ |------|------|------|------|
187
+ | email | string | ✅ | 邮箱 |
188
+ | password | string | ✅ | 密码 |
189
+
190
+ **响应(200 OK)**
191
+ \`\`\`json
192
+ {
193
+ "code": 0,
194
+ "data": {
195
+ "accessToken": "eyJ...",
196
+ "refreshToken": "eyJ...",
197
+ "expiresIn": 3600
198
+ }
199
+ }
200
+ \`\`\`
201
+
202
+ **错误码**:100201 账号不存在 / 100202 密码错误 / 100203 账号已锁定`,
203
+ },
204
+ ],
205
+ notes: [
206
+ 'URL 路径不使用动词,操作语义由 HTTP 方法表达',
207
+ 'GraphQL 场景用 Schema First 原则,先定义类型再实现 resolver',
208
+ '接口变更优先保持向后兼容,破坏性变更必须升版本号',
209
+ '内部服务间调用(RPC/gRPC)可不遵循 REST 规范',
210
+ ],
211
+ category: '执行侧',
212
+ nextSkill: 'implementation',
213
+ };
214
+ //# sourceMappingURL=11-api-design.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"11-api-design.js","sourceRoot":"","sources":["../../src/skills/11-api-design.ts"],"names":[],"mappings":";;;AAEa,QAAA,cAAc,GAAoB;IAC7C,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,EAAE;IACT,WAAW,EAAE,+CAA+C;IAC5D,aAAa,EAAE,6FAA6F;IAC5G,iBAAiB,EAAE;;+BAEU;IAC7B,QAAQ,EAAE;QACR,MAAM;QACN,QAAQ;QACR,YAAY;QACZ,MAAM;QACN,MAAM;QACN,YAAY;QACZ,YAAY;QACZ,aAAa;QACb,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,OAAO;KACR;IACD,KAAK,EAAE;QACL;YACE,KAAK,EAAE,gBAAgB;YACvB,OAAO,EAAE;;;;0CAI2B;SACrC;QACD;YACE,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE;;;;;;;;;;;;;;;;;;;2DAmB4C;SACtD;QACD;YACE,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAiCsB;SAChC;QACD;YACE,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;uBAsBQ;SAClB;QACD;YACE,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE;;;;;;;;;;;yCAW0B;SACpC;QACD;YACE,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCR;SACF;KACF;IACD,YAAY,EACV,yDAAyD;IAC3D,QAAQ,EAAE;QACR;YACE,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;kDAoBoC;SAC7C;KACF;IACD,KAAK,EAAE;QACL,6BAA6B;QAC7B,+CAA+C;QAC/C,0BAA0B;QAC1B,+BAA+B;KAChC;IACD,QAAQ,EAAE,KAAK;IACf,SAAS,EAAE,gBAAgB;CAC5B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SkillDefinition } from './types';
2
+ export declare const securityReviewSkill: SkillDefinition;
3
+ //# sourceMappingURL=12-security-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"12-security-review.d.ts","sourceRoot":"","sources":["../../src/skills/12-security-review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,eAAO,MAAM,mBAAmB,EAAE,eA8LjC,CAAC"}
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.securityReviewSkill = void 0;
4
+ exports.securityReviewSkill = {
5
+ id: 'security-review',
6
+ name: '安全审查',
7
+ nameEn: 'security_review',
8
+ order: 12,
9
+ description: '基于 OWASP Top 10 对代码和依赖进行安全扫描,识别漏洞并给出修复建议',
10
+ descriptionEn: 'Security audit based on OWASP Top 10, covering code vulnerabilities and dependency risks',
11
+ detailDescription: `对代码变更或系统模块进行安全专项审查,
12
+ 覆盖 OWASP Top 10、依赖漏洞、密钥泄露、权限校验、数据加密等维度,
13
+ 按 Critical/High/Medium/Low 四级输出风险列表和修复建议。`,
14
+ triggers: [
15
+ '安全审查',
16
+ '安全扫描',
17
+ '安全检查',
18
+ '漏洞扫描',
19
+ 'security review',
20
+ 'security audit',
21
+ 'OWASP',
22
+ '安全风险',
23
+ '代码安全',
24
+ '@ethan 安全',
25
+ '@ethan security',
26
+ '/安全审查',
27
+ ],
28
+ steps: [
29
+ {
30
+ title: '1. 确定审查范围',
31
+ content: `- 明确审查对象:代码变更 / 整个模块 / 依赖包 / 部署配置
32
+ - 确认技术栈(Node.js / Java / Python / 前端框架等)
33
+ - 了解数据敏感程度:是否涉及 PII(用户个人信息)、金融数据
34
+ - 确认暴露面:公网 API / 内部服务 / 用户上传入口
35
+ - 收集现有安全策略(如 CSP、CORS 配置)`,
36
+ },
37
+ {
38
+ title: '2. OWASP Top 10 逐项检查',
39
+ content: `按 OWASP 2021 Top 10 逐项扫描:
40
+
41
+ **A01 失效的访问控制**
42
+ - 垂直越权:普通用户能否访问管理员接口?
43
+ - 水平越权:用户A能否读取用户B的数据?
44
+ - IDOR(不安全的直接对象引用):接口参数是否直接暴露内部 ID?
45
+ - 前端隐藏菜单 ≠ 权限控制,后端必须强制校验
46
+
47
+ **A02 加密失效**
48
+ - 密码是否使用 bcrypt/argon2(禁止 MD5/SHA1)
49
+ - 传输层是否强制 HTTPS
50
+ - 敏感字段(身份证、银行卡)是否静态加密存储
51
+ - Cookie 是否设置 Secure + HttpOnly + SameSite
52
+
53
+ **A03 注入**
54
+ - SQL 注入:是否使用 ORM 参数化查询(禁止字符串拼接)
55
+ - XSS:用户输入是否经过 HTML 转义后再输出
56
+ - Command 注入:是否调用 shell 命令且参数含用户输入
57
+ - LDAP/XML/NOSQL 注入场景检查
58
+
59
+ **A04 不安全设计**
60
+ - 是否存在无限重试(暴力破解风险)
61
+ - 重要操作缺少二次确认(如删除账号、大额转账)
62
+ - 密码重置流程是否可被枚举
63
+
64
+ **A05 安全配置错误**
65
+ - 生产环境是否关闭 Debug 模式、详细错误堆栈
66
+ - 是否暴露 \`.env\`、\`.git\`、\`node_modules\` 等目录
67
+ - 默认账号/密码是否修改
68
+ - CORS 是否配置为 \`*\`(应按域名白名单)
69
+
70
+ **A06 自带缺陷和过时的组件**
71
+ - 运行 \`npm audit\` / \`pip-audit\` / \`mvn dependency-check\`
72
+ - 检查高危 CVE(CVSS ≥ 7.0)
73
+ - 框架和运行时是否在安全维护期内
74
+
75
+ **A07 身份识别和认证失败**
76
+ - JWT 是否验证签名和过期时间
77
+ - Session 是否在登出时服务端失效
78
+ - 多因素认证(MFA)是否支持
79
+
80
+ **A08 软件和数据完整性失败**
81
+ - 第三方 CDN 资源是否加 SRI(Subresource Integrity)
82
+ - CI/CD 管道是否允许未授权修改部署配置
83
+ - 序列化数据是否来自可信来源
84
+
85
+ **A09 安全日志和监控失败**
86
+ - 登录成功/失败是否记录 IP 和时间戳
87
+ - 高危操作(删除、权限变更)是否有审计日志
88
+ - 日志中是否意外记录了密码或 Token
89
+
90
+ **A10 服务端请求伪造(SSRF)**
91
+ - 接受 URL 参数的接口是否限制可访问的域名/IP
92
+ - 是否阻断对内网地址(10.x/172.x/192.168.x/127.x)的请求`,
93
+ },
94
+ {
95
+ title: '3. 密钥与凭据扫描',
96
+ content: `- 扫描代码中是否硬编码了:API Key、数据库密码、JWT Secret、云账号 AK/SK
97
+ - 检查 \`.env\` 文件是否被提交到 Git(查 \`.gitignore\`)
98
+ - 历史 commit 是否包含敏感信息(可用 \`git log -S "password"\` 搜索)
99
+ - 推荐工具:
100
+ - \`gitleaks\` — 扫描 git 历史中的密钥
101
+ - \`trufflehog\` — 高熵字符串检测
102
+ - GitHub Secret Scanning(如在 GitHub 托管)`,
103
+ },
104
+ {
105
+ title: '4. 依赖漏洞扫描',
106
+ content: `根据技术栈运行对应命令:
107
+
108
+ \`\`\`bash
109
+ # Node.js
110
+ npm audit --audit-level=high
111
+ npx audit-ci --high
112
+
113
+ # Python
114
+ pip install pip-audit && pip-audit
115
+
116
+ # Java/Maven
117
+ mvn dependency-check:check
118
+
119
+ # Docker 镜像
120
+ trivy image your-image:tag
121
+ \`\`\`
122
+
123
+ 重点关注:
124
+ - CVSS Score ≥ 7.0 的高危/严重漏洞
125
+ - 直接依赖优先修复(间接依赖通过升级父包解决)
126
+ - 有修复版本的立即升级,无修复的评估缓解措施`,
127
+ },
128
+ {
129
+ title: '5. 按风险级别输出报告',
130
+ content: `\`\`\`markdown
131
+ ## 安全审查报告
132
+
133
+ **审查范围**:[模块/文件/PR]
134
+ **审查日期**:[日期]
135
+ **整体风险等级**:🔴 Critical / 🟠 High / 🟡 Medium / 🟢 Low
136
+
137
+ ---
138
+
139
+ ### 🔴 Critical(立即修复,阻止上线)
140
+
141
+ - [ ] \`auth.ts:45\` SQL 注入漏洞:用户 ID 直接拼接查询字符串
142
+ **修复**:使用 ORM 参数化查询 \`db.query('SELECT * FROM users WHERE id = ?', [id])\`
143
+ **CVE**:— **CVSS**:9.8
144
+
145
+ ### 🟠 High(本次迭代修复)
146
+
147
+ - [ ] \`upload.ts:23\` 文件上传未限制类型,可上传 .php 执行文件
148
+ **修复**:白名单校验扩展名,并检查 MIME type
149
+
150
+ ### 🟡 Medium(计划修复)
151
+
152
+ - [ ] 缺少登录频率限制(Rate Limiting),存在暴力破解风险
153
+ **修复**:引入 express-rate-limit,5次失败后锁定15分钟
154
+
155
+ ### 🟢 Low(建议改进)
156
+
157
+ - [ ] Session Cookie 缺少 SameSite=Strict 属性
158
+
159
+ ### ✅ 已做好的安全措施
160
+ - [值得肯定的安全实践]
161
+
162
+ ### 统计
163
+ Critical: X | High: Y | Medium: Z | Low: W
164
+ \`\`\``,
165
+ },
166
+ ],
167
+ outputFormat: 'Markdown 安全审查报告,含 OWASP 维度检查结果、风险级别(Critical/High/Medium/Low)、修复建议和优先级',
168
+ examples: [
169
+ {
170
+ input: '帮我检查这个用户注册接口的安全问题',
171
+ output: `## 安全审查报告
172
+
173
+ ### 🔴 Critical
174
+ - [ ] 密码使用 MD5 明文存储
175
+ 修复:改用 bcrypt(saltRounds=12)
176
+
177
+ ### 🟠 High
178
+ - [ ] 邮箱重复注册返回 "邮箱已被注册",可被枚举已注册用户
179
+ 修复:统一返回 "注册成功,请查收验证邮件"
180
+
181
+ ### 🟢 Low
182
+ - [ ] 注册成功后在响应中返回了 passwordHash 字段
183
+ 修复:注册响应体移除敏感字段`,
184
+ },
185
+ ],
186
+ notes: [
187
+ 'Critical 问题必须在上线前修复,不接受任何例外',
188
+ '前端安全校验只是 UX 辅助,所有安全逻辑必须在后端实现',
189
+ '依赖漏洞扫描建议加入 CI 流程自动运行(每次 PR 触发)',
190
+ '安全审查不能替代专业渗透测试,重大系统上线前建议委托专业团队',
191
+ ],
192
+ category: '质量侧',
193
+ };
194
+ //# sourceMappingURL=12-security-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"12-security-review.js","sourceRoot":"","sources":["../../src/skills/12-security-review.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAoB;IAClD,EAAE,EAAE,iBAAiB;IACrB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,EAAE;IACT,WAAW,EAAE,0CAA0C;IACvD,aAAa,EAAE,0FAA0F;IACzG,iBAAiB,EAAE;;0CAEqB;IACxC,QAAQ,EAAE;QACR,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,iBAAiB;QACjB,gBAAgB;QAChB,OAAO;QACP,MAAM;QACN,MAAM;QACN,WAAW;QACX,iBAAiB;QACjB,OAAO;KACR;IACD,KAAK,EAAE;QACL;YACE,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE;;;;0BAIW;SACrB;QACD;YACE,KAAK,EAAE,sBAAsB;YAC7B,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CAqD4B;SACtC;QACD;YACE,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE;;;;;;yCAM0B;SACpC;QACD;YACE,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;wBAoBS;SACnB;QACD;YACE,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCR;SACF;KACF;IACD,YAAY,EACV,wEAAwE;IAC1E,QAAQ,EAAE;QACR;YACE,KAAK,EAAE,mBAAmB;YAC1B,MAAM,EAAE;;;;;;;;;;;;iBAYG;SACZ;KACF;IACD,KAAK,EAAE;QACL,6BAA6B;QAC7B,8BAA8B;QAC9B,gCAAgC;QAChC,gCAAgC;KACjC;IACD,QAAQ,EAAE,KAAK;CAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SkillDefinition } from './types';
2
+ export declare const deploymentSkill: SkillDefinition;
3
+ //# sourceMappingURL=13-deployment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"13-deployment.d.ts","sourceRoot":"","sources":["../../src/skills/13-deployment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,eAAO,MAAM,eAAe,EAAE,eAyL7B,CAAC"}