@blueking/bkui-knowledge 0.0.1-beta.1 → 0.0.1-beta.11

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 (50) hide show
  1. package/README.md +166 -58
  2. package/bin/bkui-knowledge.js +229 -86
  3. package/knowledge/manifest.json +38 -1
  4. package/knowledge/skills/.template/README.md +1 -1
  5. package/knowledge/skills/bk-security-redlines/SKILL.md +47 -0
  6. package/knowledge/skills/bk-security-redlines/references/auth-check.md +73 -0
  7. package/knowledge/skills/bk-security-redlines/references/data-encryption.md +78 -0
  8. package/knowledge/skills/bk-security-redlines/references/input-validation.md +96 -0
  9. package/knowledge/skills/bk-skill-creator/SKILL.md +37 -0
  10. package/knowledge/skills/bk-skill-creator/references/common-mistakes.md +43 -0
  11. package/knowledge/skills/bk-skill-creator/references/quick-start.md +42 -0
  12. package/knowledge/skills/bk-skill-creator/references/skill-checklist.md +93 -0
  13. package/knowledge/skills/bk-skill-creator/references/structure-guide.md +88 -0
  14. package/knowledge/skills/bk-skill-creator/references/writing-tips.md +153 -0
  15. package/knowledge/skills/bkui-quick-start/SKILL.md +52 -0
  16. package/knowledge/skills/bkui-quick-start/references/components-list.md +17 -0
  17. package/knowledge/skills/bkui-quick-start/references/skills-index.md +26 -0
  18. package/knowledge/skills/external/vue-skills/LICENSE +21 -0
  19. package/knowledge/skills/external/vue-skills/README.md +69 -0
  20. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/SKILL.md +42 -0
  21. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/codeactions-save-performance.md +79 -0
  22. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/data-attributes-config.md +74 -0
  23. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/deep-watch-numeric.md +102 -0
  24. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/define-model-update-event.md +79 -0
  25. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/duplicate-plugin-detection.md +102 -0
  26. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/fallthrough-attributes.md +63 -0
  27. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/hmr-vue-ssr.md +124 -0
  28. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/module-resolution-bundler.md +81 -0
  29. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/pinia-store-mocking.md +159 -0
  30. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/script-setup-jsdoc.md +85 -0
  31. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/strict-css-modules.md +68 -0
  32. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/unplugin-auto-import-conflicts.md +97 -0
  33. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/volar-3-breaking-changes.md +66 -0
  34. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/vue-directive-comments.md +73 -0
  35. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/vue-router-typed-params.md +81 -0
  36. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/vue-tsc-strict-templates.md +69 -0
  37. package/knowledge/skills/external/vue-skills/skills/vue-best-practices/rules/with-defaults-union-types.md +102 -0
  38. package/knowledge/skills/web-security-guide/SKILL.md +48 -0
  39. package/knowledge/skills/web-security-guide/references/access-control.md +123 -0
  40. package/knowledge/skills/web-security-guide/references/auth-session.md +99 -0
  41. package/knowledge/skills/web-security-guide/references/csrf.md +59 -0
  42. package/knowledge/skills/web-security-guide/references/data-exposure.md +108 -0
  43. package/knowledge/skills/web-security-guide/references/deserialization.md +59 -0
  44. package/knowledge/skills/web-security-guide/references/injection.md +357 -0
  45. package/knowledge/skills/web-security-guide/references/logging-monitoring.md +47 -0
  46. package/knowledge/skills/web-security-guide/references/security-config.md +73 -0
  47. package/knowledge/skills/web-security-guide/references/ssrf.md +55 -0
  48. package/knowledge/skills/web-security-guide/references/xss.md +134 -0
  49. package/package.json +3 -3
  50. package/server/mcp-core.js +48 -33
@@ -7,15 +7,43 @@
7
7
  * 2. 启动 MCP stdio 服务
8
8
  *
9
9
  * 用法(用户只需配置一次):
10
+ *
11
+ * Cursor(默认):
10
12
  * {
11
13
  * "mcpServers": {
12
14
  * "bkui-knowledge": {
13
15
  * "command": "npx",
14
- * "args": ["-y", "@blueking/bkui-knowledge"]
16
+ * "args": ["-y", "@blueking/bkui-knowledge", "${workspaceFolder}"]
15
17
  * }
16
18
  * }
17
19
  * }
18
20
  *
21
+ * CodeBuddy:
22
+ * {
23
+ * "bkui-knowledge": {
24
+ * "command": "npx",
25
+ * "args": ["-y", "@blueking/bkui-knowledge", "--ide=codebuddy"]
26
+ * }
27
+ * }
28
+ *
29
+ * Claude Code(无需额外配置,自动从 MCP initialize 请求获取项目路径):
30
+ * {
31
+ * "bkui-knowledge": {
32
+ * "command": "npx",
33
+ * "args": ["-y", "@blueking/bkui-knowledge", "--ide=claude-code"]
34
+ * }
35
+ * }
36
+ *
37
+ * 参数说明:
38
+ * - 第一个非 -- 开头的参数: 项目路径
39
+ * - --ide=cursor|codebuddy|claude-code: 指定目标 IDE(默认 cursor)
40
+ *
41
+ * 项目路径传递方式(优先级从高到低):
42
+ * 1. 命令行参数: npx @blueking/bkui-knowledge /path/to/project
43
+ * 2. 环境变量: BKUI_PROJECT_ROOT=/path/to/project
44
+ * 3. MCP initialize 请求中的 rootUri(Claude Code 等支持此协议的客户端)
45
+ * 4. 当前工作目录 (cwd)
46
+ *
19
47
  * 更新机制:
20
48
  * - skills 内置在 npm 包中
21
49
  * - 更新 skills 时:修改代码 → npm publish
@@ -25,14 +53,33 @@
25
53
  const fs = require('fs');
26
54
  const path = require('path');
27
55
 
28
- // 配置
29
- const CONFIG = {
30
- skillsDir: '.cursor/skills',
31
- commandsDir: '.cursor/commands',
32
- rulesDir: '.cursor/rules',
33
- versionFile: '.cursor/.bkui-knowledge-version'
56
+ // IDE 配置映射
57
+ const IDE_CONFIGS = {
58
+ cursor: {
59
+ name: 'Cursor',
60
+ configDir: '.cursor',
61
+ skillsDir: '.cursor/skills',
62
+ versionFile: '.cursor/.bkui-knowledge-version'
63
+ },
64
+ codebuddy: {
65
+ name: 'CodeBuddy',
66
+ configDir: '.codebuddy',
67
+ skillsDir: '.codebuddy/skills',
68
+ versionFile: '.codebuddy/.bkui-knowledge-version'
69
+ },
70
+ 'claude-code': {
71
+ name: 'Claude Code',
72
+ configDir: '.claude',
73
+ skillsDir: '.claude/skills',
74
+ versionFile: '.claude/.bkui-knowledge-version'
75
+ }
34
76
  };
35
77
 
78
+ // 用于存储从 MCP initialize 请求获取的项目路径
79
+ let mcpRootUri = null;
80
+ // 标记是否已经同步过 skills
81
+ let skillsSynced = false;
82
+
36
83
  // npm 包根目录
37
84
  const PKG_ROOT = path.join(__dirname, '..');
38
85
 
@@ -42,12 +89,72 @@ function log(msg) {
42
89
  }
43
90
 
44
91
  /**
45
- * 获取用户项目根目录(cwd)
92
+ * 解析 --ide 参数,获取目标 IDE
93
+ * @returns {string} IDE 标识符 (cursor | codebuddy)
94
+ */
95
+ function getTargetIDE() {
96
+ const ideArg = process.argv.find(arg => arg.startsWith('--ide='));
97
+ if (ideArg) {
98
+ const ide = ideArg.split('=')[1].toLowerCase();
99
+ if (IDE_CONFIGS[ide]) {
100
+ return ide;
101
+ }
102
+ log(`警告: 未知 IDE "${ide}",使用默认值 cursor`);
103
+ }
104
+ return 'cursor'; // 默认使用 Cursor
105
+ }
106
+
107
+ /**
108
+ * 获取当前 IDE 配置
109
+ * @returns {object} IDE 配置对象
110
+ */
111
+ function getIDEConfig() {
112
+ const ide = getTargetIDE();
113
+ return IDE_CONFIGS[ide];
114
+ }
115
+
116
+ /**
117
+ * 获取用户项目根目录
118
+ * 优先级:命令行参数 > 环境变量 > MCP rootUri > cwd
46
119
  */
47
120
  function getProjectRoot() {
121
+ // 1. 命令行参数: node bkui-knowledge.js /path/to/project (过滤掉 -- 开头的参数)
122
+ const pathArg = process.argv.slice(2).find(arg => !arg.startsWith('-'));
123
+ if (pathArg) {
124
+ return pathArg;
125
+ }
126
+ // 2. 环境变量: BKUI_PROJECT_ROOT=/path/to/project
127
+ if (process.env.BKUI_PROJECT_ROOT) {
128
+ return process.env.BKUI_PROJECT_ROOT;
129
+ }
130
+ // 3. MCP initialize 请求中的 rootUri
131
+ if (mcpRootUri) {
132
+ return mcpRootUri;
133
+ }
134
+ // 4. 默认使用 cwd
48
135
  return process.cwd();
49
136
  }
50
137
 
138
+ /**
139
+ * 从 file:// URI 提取路径
140
+ * @param {string} uri - file:// URI
141
+ * @returns {string} 文件系统路径
142
+ */
143
+ function uriToPath(uri) {
144
+ if (!uri) return null;
145
+ if (uri.startsWith('file://')) {
146
+ // file:///path/to/dir -> /path/to/dir
147
+ let filePath = uri.slice(7);
148
+ // Windows: file:///C:/path -> C:/path
149
+ if (filePath.match(/^\/[A-Za-z]:\//)) {
150
+ filePath = filePath.slice(1);
151
+ }
152
+ return decodeURIComponent(filePath);
153
+ }
154
+ // 如果不是 file:// URI,直接返回(可能已经是路径)
155
+ return uri;
156
+ }
157
+
51
158
  /**
52
159
  * 获取当前包版本
53
160
  */
@@ -62,9 +169,12 @@ function getPackageVersion() {
62
169
 
63
170
  /**
64
171
  * 检查是否需要同步
172
+ * @param {string} projectRoot - 项目根目录
173
+ * @param {string} currentVersion - 当前版本
174
+ * @param {object} ideConfig - IDE 配置
65
175
  */
66
- function needsSync(projectRoot, currentVersion) {
67
- const versionFile = path.join(projectRoot, CONFIG.versionFile);
176
+ function needsSync(projectRoot, currentVersion, ideConfig) {
177
+ const versionFile = path.join(projectRoot, ideConfig.versionFile);
68
178
  if (!fs.existsSync(versionFile)) {
69
179
  return true;
70
180
  }
@@ -73,70 +183,63 @@ function needsSync(projectRoot, currentVersion) {
73
183
  }
74
184
 
75
185
  /**
76
- * 生成 Cursor Rules 文件(自动注入 AI 上下文)
186
+ * 递归扫描目录,返回相对路径列表
187
+ * @param {string} dirPath - 目录路径
188
+ * @param {string} relativePath - 相对路径前缀
189
+ * @returns {string[]} 文件相对路径列表
77
190
  */
78
- function generateRules(projectRoot, manifest) {
79
- const rulesDir = path.join(projectRoot, CONFIG.rulesDir);
80
- fs.mkdirSync(rulesDir, { recursive: true });
81
-
82
- const skillList = manifest.skills.items.map(s => `| ${s.id} | ${s.name} |`).join('\n');
83
- const apiPriority = manifest.componentApis.priority.map(n => `bk-${n}`).join(', ');
84
- const allApis = manifest.componentApis.items.map(a => a.id).join(', ');
85
- const recommendedSkills = manifest.recommendedSkills || [];
86
-
87
- const rulesContent = `---
88
- description: BKUI 蓝鲸前端知识库规则(自动注入)
89
- globs: ["**/*.vue", "**/*.ts", "**/*.tsx"]
90
- ---
91
-
92
- # BKUI 蓝鲸前端技术规范
93
-
94
- 你是蓝鲸前端技术专家,拥有团队知识库访问权限。采用**渐进式披露架构**。
95
-
96
- ## ✅ Skills 已自动同步
97
-
98
- 推荐的 skills 已自动同步到 \`.cursor/skills/\` 目录:
99
- ${recommendedSkills.map(id => `- ${id}`).join('\n')}
100
-
101
- ## 可用资源索引
102
-
103
- ### Skills (调用 get_skill 获取详情)
104
- | ID | 名称 |
105
- |----|------|
106
- ${skillList}
107
-
108
- > 💡 bkui-builder 包含布局模版和页面模版 (assets/)
109
-
110
- ### Component APIs (调用 get_component_api 获取文档)
111
- ⚠️ **高优先级 (必须先查询):** ${apiPriority}
112
-
113
- 全部组件: ${allApis}
114
-
115
- ## 工作流程
116
- 1. 分析需求 → 确定需要哪些资源
117
- 2. 使用布局组件? → get_component_api({ componentName: 'navigation' })
118
- 3. 需要模板代码? → get_skill({ skillId: 'bkui-builder' })
119
- 4. 批量获取? → batch_load({ skillIds: [...], componentNames: [...] })
120
-
121
- ## 强制规范
122
- - 组件库: bkui-vue (前缀 bk-)
123
- - 语法: Vue 3 <script setup lang="ts">
124
- - 布局: 必须使用 bk-navigation
191
+ function scanSkillDir(dirPath, relativePath) {
192
+ const results = [];
193
+ try {
194
+ const items = fs.readdirSync(dirPath);
195
+ for (const item of items) {
196
+ const fullPath = path.join(dirPath, item);
197
+ const relPath = relativePath ? `${relativePath}/${item}` : item;
198
+ const stat = fs.statSync(fullPath);
199
+ if (stat.isDirectory()) {
200
+ results.push(...scanSkillDir(fullPath, relPath));
201
+ } else {
202
+ results.push(relPath);
203
+ }
204
+ }
205
+ } catch (e) {
206
+ // 忽略错误
207
+ }
208
+ return results;
209
+ }
125
210
 
126
- ## 常见错误 (必须避免)
127
- <bk-navigation :default-open-keys> ✅ default-open
128
- <bk-menu :default-open-keys> :opened-keys
129
- <bk-dialog v-model> v-model:isShow
130
- `;
211
+ /**
212
+ * 生成 skill 的可用资源列表
213
+ * @param {string} skillDir - skill 目录路径
214
+ * @param {string} skillId - skill ID
215
+ * @returns {string} 资源列表 Markdown
216
+ */
217
+ function generateResourcesList(skillDir, skillId) {
218
+ const subDirs = ['scripts', 'references', 'assets', 'rules'];
219
+ const resources = [];
220
+
221
+ subDirs.forEach(dir => {
222
+ const dirPath = path.join(skillDir, dir);
223
+ if (fs.existsSync(dirPath)) {
224
+ const files = scanSkillDir(dirPath, '');
225
+ files.forEach(file => {
226
+ resources.push(`- \`skill://${skillId}/${dir}/${file}\``);
227
+ });
228
+ }
229
+ });
131
230
 
132
- fs.writeFileSync(path.join(rulesDir, 'bkui.mdc'), rulesContent, 'utf-8');
133
- log(' .cursor/rules/bkui.mdc (规则自动注入)');
231
+ if (resources.length > 0) {
232
+ return `\n\n---\n## 📦 可用资源\n\n${resources.join('\n')}\n\n> 根据 SKILL.md 中的 IF-THEN 规则判断是否需要加载\n`;
233
+ }
234
+ return '';
134
235
  }
135
236
 
136
237
  /**
137
238
  * 同步 skills 到用户项目(从 npm 包内置的 knowledge 目录)
239
+ * @param {string} projectRoot - 项目根目录
240
+ * @param {object} ideConfig - IDE 配置
138
241
  */
139
- function syncSkills(projectRoot) {
242
+ function syncSkills(projectRoot, ideConfig) {
140
243
  try {
141
244
  const manifestPath = path.join(PKG_ROOT, 'knowledge/manifest.json');
142
245
 
@@ -151,18 +254,16 @@ function syncSkills(projectRoot) {
151
254
  const version = `${pkgVersion}-${manifest.updated_at || 'unknown'}`;
152
255
 
153
256
  // 检查是否需要同步
154
- if (!needsSync(projectRoot, version)) {
155
- log(`skills 已是最新版本 (v${pkgVersion})`);
257
+ if (!needsSync(projectRoot, version, ideConfig)) {
258
+ log(`[${ideConfig.name}] skills 已是最新版本 (v${pkgVersion})`);
156
259
  return;
157
260
  }
158
261
 
159
- log(`同步 skills (v${pkgVersion})...`);
262
+ log(`[${ideConfig.name}] 同步 skills (v${pkgVersion})...`);
160
263
 
161
264
  // 创建目录
162
- const skillsDir = path.join(projectRoot, CONFIG.skillsDir);
163
- const commandsDir = path.join(projectRoot, CONFIG.commandsDir);
265
+ const skillsDir = path.join(projectRoot, ideConfig.skillsDir);
164
266
  fs.mkdirSync(skillsDir, { recursive: true });
165
- fs.mkdirSync(commandsDir, { recursive: true });
166
267
 
167
268
  // 同步推荐的 skills
168
269
  let count = 0;
@@ -173,25 +274,28 @@ function syncSkills(projectRoot) {
173
274
  const skillFilePath = path.join(PKG_ROOT, 'knowledge', manifest.skills.base_path, skill.path);
174
275
  if (!fs.existsSync(skillFilePath)) continue;
175
276
 
176
- const content = fs.readFileSync(skillFilePath, 'utf-8');
277
+ // 读取原始内容
278
+ let content = fs.readFileSync(skillFilePath, 'utf-8');
279
+
280
+ // 生成并附加资源列表(与 mcp-core.js 的 get_skill 逻辑一致)
281
+ const skillDir = path.dirname(skillFilePath);
282
+ const resourcesList = generateResourcesList(skillDir, skillId);
283
+ content += resourcesList;
284
+
177
285
  fs.writeFileSync(path.join(skillsDir, `${skillId}.md`), content, 'utf-8');
178
- fs.writeFileSync(path.join(commandsDir, `${skillId}.md`), `请加载使用 ${skillId} skill`, 'utf-8');
179
286
 
180
287
  log(` ✓ ${skillId}`);
181
288
  count++;
182
289
  }
183
290
 
184
- // 生成 Cursor Rules 文件
185
- generateRules(projectRoot, manifest);
186
-
187
291
  // 保存版本信息
188
- fs.mkdirSync(path.dirname(path.join(projectRoot, CONFIG.versionFile)), { recursive: true });
189
- fs.writeFileSync(path.join(projectRoot, CONFIG.versionFile), version, 'utf-8');
292
+ fs.mkdirSync(path.dirname(path.join(projectRoot, ideConfig.versionFile)), { recursive: true });
293
+ fs.writeFileSync(path.join(projectRoot, ideConfig.versionFile), version, 'utf-8');
190
294
 
191
- log(`同步完成!共 ${count} 个 skills + rules`);
295
+ log(`[${ideConfig.name}] 同步完成!共 ${count} 个 skills`);
192
296
 
193
297
  } catch (error) {
194
- log(`同步失败: ${error.message}(不影响 MCP 服务)`);
298
+ log(`[${ideConfig.name}] 同步失败: ${error.message}(不影响 MCP 服务)`);
195
299
  }
196
300
  }
197
301
 
@@ -208,6 +312,27 @@ async function startMcpServer() {
208
312
 
209
313
  async function handleMessage(message) {
210
314
  if (message.method === "initialize") {
315
+ // 从 initialize 请求中提取项目路径
316
+ const params = message.params || {};
317
+
318
+ // 尝试从 rootUri 或 workspaceFolders 获取项目路径
319
+ if (params.rootUri) {
320
+ mcpRootUri = uriToPath(params.rootUri);
321
+ log(`从 MCP initialize 获取项目路径: ${mcpRootUri}`);
322
+ } else if (params.workspaceFolders && params.workspaceFolders.length > 0) {
323
+ mcpRootUri = uriToPath(params.workspaceFolders[0].uri);
324
+ log(`从 MCP workspaceFolders 获取项目路径: ${mcpRootUri}`);
325
+ }
326
+
327
+ // 延迟同步 skills(在获取到项目路径后)
328
+ if (!skillsSynced && mcpRootUri) {
329
+ const projectRoot = getProjectRoot();
330
+ const ideConfig = getIDEConfig();
331
+ log(`[延迟同步] 工作目录: ${projectRoot}, IDE: ${ideConfig.name}`);
332
+ syncSkills(projectRoot, ideConfig);
333
+ skillsSynced = true;
334
+ }
335
+
211
336
  return {
212
337
  protocolVersion: "2024-11-05",
213
338
  serverInfo: { name: "bkui-knowledge-server", version: "1.0.0" },
@@ -302,16 +427,34 @@ async function startMcpServer() {
302
427
  log('MCP stdio 服务已启动');
303
428
  }
304
429
 
430
+ /**
431
+ * 检查是否有明确的项目路径(命令行参数或环境变量)
432
+ */
433
+ function hasExplicitProjectPath() {
434
+ const pathArg = process.argv.slice(2).find(arg => !arg.startsWith('-'));
435
+ return !!(pathArg || process.env.BKUI_PROJECT_ROOT);
436
+ }
437
+
305
438
  /**
306
439
  * 主入口
307
440
  */
308
441
  async function main() {
309
- const projectRoot = getProjectRoot();
310
-
311
- // 1. 同步 skills(同步执行,从 npm 包读取)
312
- syncSkills(projectRoot);
442
+ const ideConfig = getIDEConfig();
443
+
444
+ // 如果有明确的项目路径(命令行参数或环境变量),立即同步
445
+ // 否则等待 MCP initialize 请求获取项目路径
446
+ if (hasExplicitProjectPath()) {
447
+ const projectRoot = getProjectRoot();
448
+ log(`工作目录: ${projectRoot}`);
449
+ log(`目标 IDE: ${ideConfig.name}`);
450
+ syncSkills(projectRoot, ideConfig);
451
+ skillsSynced = true;
452
+ } else {
453
+ log(`等待 MCP initialize 请求获取项目路径...`);
454
+ log(`目标 IDE: ${ideConfig.name}`);
455
+ }
313
456
 
314
- // 2. 启动 MCP 服务
457
+ // 启动 MCP 服务
315
458
  await startMcpServer();
316
459
  }
317
460
 
@@ -107,6 +107,43 @@
107
107
  "category": "security",
108
108
  "path": "nodejs-security-check/SKILL.md",
109
109
  "tags": ["security", "nodejs", "backend", "ssrf", "sql-injection"]
110
+ },
111
+ {
112
+ "id": "bkui-quick-start",
113
+ "name": "BKUI 快速入门",
114
+ "category": "engineering",
115
+ "path": "bkui-quick-start/SKILL.md",
116
+ "tags": ["bkui", "规范", "索引", "入门"]
117
+ },
118
+ {
119
+ "id": "vue-best-practices",
120
+ "name": "Vue 3 开发最佳实践",
121
+ "category": "engineering",
122
+ "path": "external/vue-skills/skills/vue-best-practices/SKILL.md",
123
+ "tags": ["vue3", "typescript", "vue-tsc", "volar", "vite", "pinia"],
124
+ "external": true,
125
+ "source": "https://github.com/hyf0/vue-skills"
126
+ },
127
+ {
128
+ "id": "bk-skill-creator",
129
+ "name": "Skill 创建指南",
130
+ "category": "engineering",
131
+ "path": "bk-skill-creator/SKILL.md",
132
+ "tags": ["skill", "knowledge", "template", "guide"]
133
+ },
134
+ {
135
+ "id": "bk-security-redlines",
136
+ "name": "蓝鲸代码安全三大红线",
137
+ "category": "security",
138
+ "path": "bk-security-redlines/SKILL.md",
139
+ "tags": ["security", "input-validation", "auth", "encryption", "redlines"]
140
+ },
141
+ {
142
+ "id": "web-security-guide",
143
+ "name": "Web 安全漏洞学习指南",
144
+ "category": "security",
145
+ "path": "web-security-guide/SKILL.md",
146
+ "tags": ["security", "owasp", "vulnerability", "injection", "xss", "csrf", "ssrf"]
110
147
  }
111
148
  ]
112
149
  },
@@ -663,5 +700,5 @@
663
700
  ]
664
701
  },
665
702
 
666
- "recommendedSkills": ["bkui-builder", "bkui-cheatsheet", "code-review", "js-security-check"]
703
+ "recommendedSkills": ["bkui-quick-start", "bkui-builder", "bkui-cheatsheet", "vue-best-practices", "code-review", "js-security-check"]
667
704
  }
@@ -23,7 +23,7 @@ wc -c knowledge/skills/your-skill-id/SKILL.md
23
23
 
24
24
  ## 文件说明
25
25
 
26
- - **SKILL.md**: 核心文档,**必须 ≤ 3KB**
26
+ - **SKILL.md**: 核心文档,**必须 ≤ 2KB**
27
27
  - **references/**: 详细参考文档,按需加载
28
28
  - **assets/**: 代码模板、脚本等资产
29
29
  - **README.md**: 对内说明(不会被 AI 加载)
@@ -0,0 +1,47 @@
1
+ ---
2
+ id: security/bk-security-redlines
3
+ name: 蓝鲸代码安全三大红线
4
+ category: security
5
+ description: 基于 IEG 安全规范,覆盖输入校验、鉴权、数据加密三大高危领域
6
+ tags: [security, input-validation, auth, encryption, redlines]
7
+ updated_at: 2026-01-23
8
+ ---
9
+
10
+ # 蓝鲸代码安全三大红线
11
+
12
+ ## ⚠️ 核心规则
13
+
14
+ ### 红线 1:外部输入未校验
15
+
16
+ 外部输入进入**高危操作**前,必须完成**服务端强约束校验**(类型/长度/格式/白名单),不可绕过。
17
+
18
+ **高危操作**:命令执行、模板解释/eval、文件路径、请求目标、SQL/NoSQL 构造、渲染解析、协议输出
19
+
20
+ ### 红线 2:敏感接口未鉴权
21
+
22
+ 高危能力或敏感资源接口必须同时实施**身份认证 + 权限校验**,缺一即违规。
23
+
24
+ **禁止**:接口无认证、仅登录不校验权限、依赖前端字段/URL/IP 判权、服务间调用无鉴权
25
+
26
+ ### 红线 3:敏感数据未加密
27
+
28
+ 敏感数据(密码/Token/AKSK/私钥/PII)在存储、传输、日志、导出任一环节保护不当即违规。
29
+
30
+ **禁止**:硬编码凭证、明文存储、异常回显细节、日志记录敏感字段、URL 携带 token
31
+
32
+ ## 常见错误
33
+
34
+ | 错误做法 | 正确做法 |
35
+ |---------|---------|
36
+ | ❌ 仅前端/网关校验 | ✅ 服务端强约束校验 |
37
+ | ❌ 仅判空/黑名单 | ✅ 白名单 + 类型/长度/格式 |
38
+ | ❌ 内网可达即放通 | ✅ 服务间调用也需鉴权 |
39
+ | ❌ 日志记录完整请求 | ✅ 脱敏后记录 |
40
+
41
+ ## 📦 按需加载资源
42
+
43
+ | 资源 | URI | 说明 |
44
+ |-----|-----|------|
45
+ | 输入校验详解 | `skill://bk-security-redlines/references/input-validation.md` | 7 类高危操作场景 |
46
+ | 鉴权检查详解 | `skill://bk-security-redlines/references/auth-check.md` | 8 类鉴权缺失场景 |
47
+ | 数据加密详解 | `skill://bk-security-redlines/references/data-encryption.md` | 8 类加密缺失场景 |
@@ -0,0 +1,73 @@
1
+ # 红线 2:敏感接口未鉴权 - 详解
2
+
3
+ ## 定义
4
+
5
+ 凡提供高危能力或访问敏感资源的接口,必须在服务端实施完整鉴权:
6
+
7
+ - **身份认证**:确认"你是谁"
8
+ - **权限校验**:确认"你能做什么"
9
+
10
+ 任一缺失即违规。
11
+
12
+ ---
13
+
14
+ ## 8 类鉴权缺失场景
15
+
16
+ ### 2.1 接口缺失身份认证
17
+
18
+ **业务场景**:
19
+ - 新增 API
20
+ - 后台管理接口
21
+ - 内部运维接口
22
+ - RPC/SDK 入口
23
+ - 仅凭"内网可达"放通
24
+
25
+ ### 2.2 接口缺失权限校验
26
+
27
+ **业务场景**:
28
+ - 仅校验登录不校验角色/租户/项目/资源范围
29
+ - 后台管理操作未做 RBAC/ABAC
30
+
31
+ ### 2.3 鉴权依赖不可信要素
32
+
33
+ **业务场景**:
34
+ - `is_admin` 等前端字段判权
35
+ - URL 前缀隔离
36
+ - 仅网关策略
37
+ - 仅 IP 白名单
38
+
39
+ ### 2.4 服务间调用缺失鉴权
40
+
41
+ **业务场景**:
42
+ - 服务间调用
43
+ - 内部 SDK
44
+ - 代调用
45
+ - 组件联动
46
+
47
+ ### 2.5 资源访问缺失对象鉴权
48
+
49
+ **业务场景**:
50
+ - 仅凭 id/task_id/file_id/cluster_id/app_id 直接读写资源
51
+ - 未校验当前用户是否有权访问该资源
52
+
53
+ ### 2.6 回调消息缺失验源
54
+
55
+ **业务场景**:
56
+ - 回调接口
57
+ - Webhook
58
+ - 消息消费
59
+ - 事件触发入口
60
+
61
+ ### 2.7 会话操作缺失 CSRF 防护
62
+
63
+ **业务场景**:
64
+ - Cookie 会话的敏感操作
65
+ - 未使用 CSRF Token
66
+ - 未校验 Origin/Referer
67
+
68
+ ### 2.8 调试运维缺失鉴权
69
+
70
+ **业务场景**:
71
+ - debug/admin/metrics/health 端点
72
+ - 运维开关
73
+ - 临时接口
@@ -0,0 +1,78 @@
1
+ # 红线 3:敏感数据未加密 - 详解
2
+
3
+ ## 定义
4
+
5
+ 敏感数据在代码、存储、传输、日志、异常输出、导出/备份等任一环节保护不当即违规。
6
+
7
+ ## 敏感数据范围
8
+
9
+ - 密码/Token/AKSK/连接串/私钥/加密密钥
10
+ - 权限票据
11
+ - 个人敏感信息(PII)
12
+ - 内部系统地址与关键配置
13
+
14
+ ---
15
+
16
+ ## 8 类加密缺失场景
17
+
18
+ ### 3.1 敏感信息硬编码暴露
19
+
20
+ **业务场景**:
21
+ - 代码常量/默认配置/示例文件/CI 脚本中写入:
22
+ - 密码
23
+ - Token
24
+ - AK/SK
25
+ - 连接串
26
+ - 私钥
27
+ - 加密密钥
28
+
29
+ ### 3.2 敏感信息明文存储
30
+
31
+ **业务场景**:
32
+ - 数据库字段明文存 token/密码/私钥
33
+ - 配置文件明文凭证
34
+ - 缓存/搜索系统写入明文敏感字段
35
+
36
+ ### 3.3 异常回显泄露细节
37
+
38
+ **业务场景**:
39
+ - API 返回堆栈、SQL、文件路径
40
+ - API 返回内部域名、配置内容、密钥片段
41
+ - 将异常信息原样透传给调用方
42
+
43
+ ### 3.4 日志链路泄露敏感
44
+
45
+ **业务场景**:
46
+ - 全量记录 request/response
47
+ - 记录 Authorization/Cookie/Token
48
+ - trace/span/metrics 写入 PII/凭证
49
+
50
+ ### 3.5 票据出现在 URL/前端
51
+
52
+ **业务场景**:
53
+ - token 放 query 参数
54
+ - 跳转携带票据
55
+ - localStorage/sessionStorage 存长效 token/敏感字段
56
+
57
+ ### 3.6 敏感传输缺少加密
58
+
59
+ **业务场景**:
60
+ - HTTP 明文传 token/凭证/PII
61
+ - 跳过证书校验
62
+ - RPC/MQ 链路未加密传输敏感字段
63
+
64
+ ### 3.7 导出备份暴露敏感
65
+
66
+ **业务场景**:
67
+ - 导出 zip/csv 含凭证/配置/PII
68
+ - dump/日志包上传对象存储
69
+ - 权限过宽、无过期控制或可公开访问
70
+
71
+ ### 3.8 密码学使用不规范
72
+
73
+ **业务场景**:
74
+ - 自研加密算法
75
+ - 弱算法(MD5/SHA1 用于密码、DES/RC4 等)
76
+ - 固定 IV/盐
77
+ - 同密钥多用途
78
+ - 密钥落配置/日志或在接口返回中泄漏