autosnippet 2.5.0 → 2.7.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 (72) hide show
  1. package/bin/cli.js +35 -0
  2. package/dashboard/dist/assets/{icons-Dtm0E6DS.js → icons-Cq4-iQhP.js} +152 -87
  3. package/dashboard/dist/assets/index-DBxH7pVn.css +1 -0
  4. package/dashboard/dist/assets/index-Dw2F6qAS.js +197 -0
  5. package/dashboard/dist/assets/{react-markdown-CWxUbOf4.js → react-markdown-BA6FB2NP.js} +1 -1
  6. package/dashboard/dist/assets/{syntax-highlighter-CJ2drQQb.js → syntax-highlighter-CVLHn9O5.js} +1 -1
  7. package/dashboard/dist/assets/{vendor-f83ah6cm.js → vendor-BotF760a.js} +61 -61
  8. package/dashboard/dist/index.html +6 -6
  9. package/lib/bootstrap.js +1 -1
  10. package/lib/cli/SetupService.js +33 -8
  11. package/lib/cli/UpgradeService.js +139 -2
  12. package/lib/core/ast/ProjectGraph.js +599 -0
  13. package/lib/core/gateway/Gateway.js +19 -4
  14. package/lib/core/gateway/GatewayActionRegistry.js +2 -2
  15. package/lib/domain/recipe/Recipe.js +3 -0
  16. package/lib/external/ai/AiProvider.js +117 -10
  17. package/lib/external/ai/providers/ClaudeProvider.js +197 -0
  18. package/lib/external/ai/providers/GoogleGeminiProvider.js +235 -1
  19. package/lib/external/ai/providers/OpenAiProvider.js +131 -0
  20. package/lib/external/mcp/McpServer.js +2 -1
  21. package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +216 -0
  22. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +468 -0
  23. package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +162 -0
  24. package/lib/external/mcp/handlers/bootstrap/skills.js +225 -0
  25. package/lib/external/mcp/handlers/bootstrap.js +151 -1634
  26. package/lib/external/mcp/handlers/browse.js +1 -1
  27. package/lib/external/mcp/handlers/candidate.js +1 -33
  28. package/lib/external/mcp/handlers/skill.js +126 -31
  29. package/lib/external/mcp/tools.js +25 -3
  30. package/lib/http/middleware/requestLogger.js +23 -4
  31. package/lib/http/routes/ai.js +3 -1
  32. package/lib/http/routes/auth.js +3 -2
  33. package/lib/http/routes/candidates.js +49 -25
  34. package/lib/http/routes/commands.js +0 -8
  35. package/lib/http/routes/guardRules.js +1 -16
  36. package/lib/http/routes/recipes.js +4 -17
  37. package/lib/http/routes/search.js +16 -22
  38. package/lib/http/routes/skills.js +40 -3
  39. package/lib/http/routes/snippets.js +0 -33
  40. package/lib/http/routes/spm.js +37 -63
  41. package/lib/http/utils/routeHelpers.js +31 -0
  42. package/lib/infrastructure/audit/AuditStore.js +18 -0
  43. package/lib/infrastructure/config/Paths.js +9 -0
  44. package/lib/infrastructure/logging/Logger.js +86 -3
  45. package/lib/infrastructure/realtime/RealtimeService.js +2 -5
  46. package/lib/infrastructure/vector/JsonVectorAdapter.js +24 -1
  47. package/lib/injection/ServiceContainer.js +62 -3
  48. package/lib/service/bootstrap/BootstrapTaskManager.js +400 -0
  49. package/lib/service/candidate/CandidateFileWriter.js +68 -27
  50. package/lib/service/candidate/CandidateService.js +156 -10
  51. package/lib/service/chat/AnalystAgent.js +216 -0
  52. package/lib/service/chat/CandidateGuardrail.js +134 -0
  53. package/lib/service/chat/ChatAgent.js +1272 -155
  54. package/lib/service/chat/ContextWindow.js +730 -0
  55. package/lib/service/chat/ConversationStore.js +377 -0
  56. package/lib/service/chat/HandoffProtocol.js +180 -0
  57. package/lib/service/chat/Memory.js +40 -10
  58. package/lib/service/chat/ProducerAgent.js +240 -0
  59. package/lib/service/chat/ToolRegistry.js +149 -5
  60. package/lib/service/chat/tools.js +1493 -60
  61. package/lib/service/recipe/RecipeFileWriter.js +12 -1
  62. package/lib/service/skills/EventAggregator.js +187 -0
  63. package/lib/service/skills/SignalCollector.js +549 -0
  64. package/lib/service/skills/SkillAdvisor.js +324 -0
  65. package/lib/service/skills/SkillHooks.js +13 -5
  66. package/lib/service/spm/SpmService.js +2 -2
  67. package/package.json +1 -1
  68. package/templates/copilot-instructions.md +20 -3
  69. package/templates/cursor-rules/autosnippet-conventions.mdc +21 -4
  70. package/templates/cursor-rules/autosnippet-skills.mdc +45 -0
  71. package/dashboard/dist/assets/index-B7VpZOCz.css +0 -1
  72. package/dashboard/dist/assets/index-D87IZTmZ.js +0 -187
@@ -0,0 +1,324 @@
1
+ /**
2
+ * SkillAdvisor — 基于使用模式的 Skill 推荐引擎
3
+ *
4
+ * 分析项目使用行为并推荐创建 Skill:
5
+ * 1. Guard 违规模式 — 同类违规反复出现 → 编码规范 Skill
6
+ * 2. Memory 偏好积累 — 用户偏好超过阈值 → 约定总结 Skill
7
+ * 3. Recipe 分布缺口 — 某类 Recipe 高频使用但无对应 Skill
8
+ * 4. 搜索 miss — 高频搜索但低命中 → 知识盲区 Skill
9
+ *
10
+ * 设计原则:
11
+ * - 只做分析和推荐,不自动创建(由 Agent 决策执行 create_skill)
12
+ * - 静默降级:任何数据源读取失败不影响其他维度
13
+ * - 零 AI 调用 — 纯规则分析,确保即时返回
14
+ * - 推荐结果包含 draft 草稿(name + description + rationale),
15
+ * Agent 可直接调用 create_skill 创建
16
+ */
17
+
18
+ import fs from 'node:fs';
19
+ import path from 'node:path';
20
+ import { getProjectSkillsPath } from '../../infrastructure/config/Paths.js';
21
+
22
+ export class SkillAdvisor {
23
+ #projectRoot;
24
+ #db;
25
+
26
+ /**
27
+ * @param {string} projectRoot — 用户项目根目录
28
+ * @param {object} [opts]
29
+ * @param {object} [opts.database] — better-sqlite3 实例(可选)
30
+ */
31
+ constructor(projectRoot, { database } = {}) {
32
+ this.#projectRoot = projectRoot;
33
+ this.#db = database || null;
34
+ }
35
+
36
+ /**
37
+ * 生成 Skill 推荐列表
38
+ *
39
+ * @returns {{
40
+ * suggestions: Array<{
41
+ * name: string,
42
+ * description: string,
43
+ * rationale: string,
44
+ * source: string,
45
+ * priority: 'high' | 'medium' | 'low',
46
+ * signals: object
47
+ * }>,
48
+ * analysisContext: object
49
+ * }}
50
+ */
51
+ suggest() {
52
+ const existingSkills = this.#listExistingProjectSkills();
53
+ const suggestions = [];
54
+ const analysisContext = {};
55
+
56
+ // ── 维度 1: Guard 违规模式 ──
57
+ try {
58
+ const guardInsights = this.#analyzeGuardPatterns();
59
+ analysisContext.guard = guardInsights.summary;
60
+ suggestions.push(...guardInsights.suggestions.filter(
61
+ s => !existingSkills.has(s.name),
62
+ ));
63
+ } catch { /* silent */ }
64
+
65
+ // ── 维度 2: Memory 偏好积累 ──
66
+ try {
67
+ const memoryInsights = this.#analyzeMemoryPatterns();
68
+ analysisContext.memory = memoryInsights.summary;
69
+ suggestions.push(...memoryInsights.suggestions.filter(
70
+ s => !existingSkills.has(s.name),
71
+ ));
72
+ } catch { /* silent */ }
73
+
74
+ // ── 维度 3: Recipe 分布与使用 ──
75
+ try {
76
+ const recipeInsights = this.#analyzeRecipePatterns();
77
+ analysisContext.recipes = recipeInsights.summary;
78
+ suggestions.push(...recipeInsights.suggestions.filter(
79
+ s => !existingSkills.has(s.name),
80
+ ));
81
+ } catch { /* silent */ }
82
+
83
+ // ── 维度 4: 候选积压 ──
84
+ try {
85
+ const candidateInsights = this.#analyzeCandidatePatterns();
86
+ analysisContext.candidates = candidateInsights.summary;
87
+ suggestions.push(...candidateInsights.suggestions.filter(
88
+ s => !existingSkills.has(s.name),
89
+ ));
90
+ } catch { /* silent */ }
91
+
92
+ // 按优先级排序:high > medium > low
93
+ const priorityOrder = { high: 0, medium: 1, low: 2 };
94
+ suggestions.sort((a, b) => (priorityOrder[a.priority] || 2) - (priorityOrder[b.priority] || 2));
95
+
96
+ return {
97
+ suggestions,
98
+ existingProjectSkills: [...existingSkills],
99
+ analysisContext,
100
+ hint: suggestions.length > 0
101
+ ? `发现 ${suggestions.length} 个 Skill 创建建议。你可以使用 autosnippet_create_skill 工具直接创建,也可以根据 rationale 自行判断是否需要。`
102
+ : '当前项目使用模式暂无明确的 Skill 创建建议。继续使用后会积累更多信号。',
103
+ };
104
+ }
105
+
106
+ // ═══════════════════════════════════════════════════════
107
+ // 维度 1: Guard 违规模式分析
108
+ // ═══════════════════════════════════════════════════════
109
+
110
+ #analyzeGuardPatterns() {
111
+ const suggestions = [];
112
+ if (!this.#db) return { summary: 'DB 不可用', suggestions };
113
+
114
+ try {
115
+ // 查询 Guard 违规记录(audit_logs 中 action LIKE 'guard%' + result='violation')
116
+ const rows = this.#db.prepare(`
117
+ SELECT json_extract(operation_data, '$.ruleName') as ruleName,
118
+ COUNT(*) as cnt
119
+ FROM audit_logs
120
+ WHERE action LIKE 'guard%'
121
+ AND result = 'violation'
122
+ GROUP BY ruleName
123
+ HAVING cnt >= 3
124
+ ORDER BY cnt DESC
125
+ LIMIT 5
126
+ `).all();
127
+
128
+ if (rows.length > 0) {
129
+ const topRule = rows[0];
130
+ suggestions.push({
131
+ name: `project-guard-${_kebab(topRule.ruleName || 'common')}`,
132
+ description: `项目编码规范 — 基于高频 Guard 违规「${topRule.ruleName}」(${topRule.cnt} 次)自动推荐`,
133
+ rationale: `Guard 规则「${topRule.ruleName}」被违反 ${topRule.cnt} 次,说明团队可能不了解此规范。创建 Skill 可以让 AI 在编码时主动提醒,并提供正确写法参考。`,
134
+ source: 'guard_violations',
135
+ priority: topRule.cnt >= 10 ? 'high' : 'medium',
136
+ signals: { ruleName: topRule.ruleName, violationCount: topRule.cnt, allRules: rows },
137
+ });
138
+ }
139
+
140
+ return {
141
+ summary: { violationRules: rows.length, topViolations: rows.slice(0, 3) },
142
+ suggestions,
143
+ };
144
+ } catch {
145
+ return { summary: 'Guard audit_log 查询失败', suggestions };
146
+ }
147
+ }
148
+
149
+ // ═══════════════════════════════════════════════════════
150
+ // 维度 2: Memory 偏好分析
151
+ // ═══════════════════════════════════════════════════════
152
+
153
+ #analyzeMemoryPatterns() {
154
+ const suggestions = [];
155
+ const memoryPath = path.join(this.#projectRoot, '.autosnippet', 'memory.jsonl');
156
+
157
+ if (!fs.existsSync(memoryPath)) {
158
+ return { summary: '无 Memory 记录', suggestions };
159
+ }
160
+
161
+ try {
162
+ const raw = fs.readFileSync(memoryPath, 'utf-8').trim();
163
+ if (!raw) return { summary: '无 Memory 记录', suggestions };
164
+
165
+ const entries = raw.split('\n')
166
+ .map(l => { try { return JSON.parse(l); } catch { return null; } })
167
+ .filter(Boolean);
168
+
169
+ const preferences = entries.filter(e => e.type === 'preference');
170
+
171
+ if (preferences.length >= 5) {
172
+ // 有足够多的偏好积累 → 建议归纳为 Skill
173
+ const sample = preferences.slice(-5).map(p => p.content).join('\n- ');
174
+ suggestions.push({
175
+ name: 'project-conventions',
176
+ description: `项目约定总结 — 基于 ${preferences.length} 条团队偏好自动推荐`,
177
+ rationale: `Memory 中已积累 ${preferences.length} 条用户偏好(如"我们不用…"、"以后都…"),建议归纳为一个 Skill 文档,让 AI 在每次对话中都能参考:\n- ${sample}`,
178
+ source: 'memory_preferences',
179
+ priority: preferences.length >= 10 ? 'high' : 'medium',
180
+ signals: { totalPreferences: preferences.length, recentSamples: preferences.slice(-5) },
181
+ });
182
+ }
183
+
184
+ return {
185
+ summary: { totalEntries: entries.length, preferences: preferences.length },
186
+ suggestions,
187
+ };
188
+ } catch {
189
+ return { summary: 'Memory 读取失败', suggestions };
190
+ }
191
+ }
192
+
193
+ // ═══════════════════════════════════════════════════════
194
+ // 维度 3: Recipe 分布与使用热度
195
+ // ═══════════════════════════════════════════════════════
196
+
197
+ #analyzeRecipePatterns() {
198
+ const suggestions = [];
199
+ if (!this.#db) return { summary: 'DB 不可用', suggestions };
200
+
201
+ try {
202
+ // 按 category 分布
203
+ const categories = this.#db.prepare(`
204
+ SELECT category, COUNT(*) as cnt
205
+ FROM recipes
206
+ WHERE category IS NOT NULL AND category != ''
207
+ GROUP BY category
208
+ ORDER BY cnt DESC
209
+ `).all();
210
+
211
+ // 按 language 分布
212
+ const languages = this.#db.prepare(`
213
+ SELECT language, COUNT(*) as cnt
214
+ FROM recipes
215
+ WHERE language IS NOT NULL AND language != ''
216
+ GROUP BY language
217
+ ORDER BY cnt DESC
218
+ `).all();
219
+
220
+ // 高频使用但无自定义 Skill 的 category
221
+ const topCategory = categories[0];
222
+ if (topCategory && topCategory.cnt >= 10) {
223
+ const catName = topCategory.category.toLowerCase();
224
+ suggestions.push({
225
+ name: `project-${_kebab(catName)}-patterns`,
226
+ description: `${topCategory.category} 模式汇总 — 该类 Recipe 数量最多(${topCategory.cnt} 条),建议创建专属开发指南`,
227
+ rationale: `项目中 ${topCategory.category} 类 Recipe 高达 ${topCategory.cnt} 条,占比最大。创建一个 Skill 汇总此类别的核心设计模式、常见用法和注意事项,让 AI 在处理相关代码时有更精准的参考。`,
228
+ source: 'recipe_distribution',
229
+ priority: 'low',
230
+ signals: { category: topCategory.category, recipeCount: topCategory.cnt, allCategories: categories },
231
+ });
232
+ }
233
+
234
+ // 高使用量 Recipe 统计(adoption_count + application_count >= 5)
235
+ let hotRecipes = [];
236
+ try {
237
+ hotRecipes = this.#db.prepare(`
238
+ SELECT title, category,
239
+ (adoption_count + application_count) as total_usage
240
+ FROM recipes
241
+ WHERE (adoption_count + application_count) >= 5
242
+ ORDER BY total_usage DESC
243
+ LIMIT 10
244
+ `).all();
245
+ } catch { /* 查询失败时降级为空 */ }
246
+
247
+ return {
248
+ summary: { categories: categories.length, languages, hotRecipeCount: hotRecipes.length },
249
+ suggestions,
250
+ };
251
+ } catch {
252
+ return { summary: 'Recipe 查询失败', suggestions };
253
+ }
254
+ }
255
+
256
+ // ═══════════════════════════════════════════════════════
257
+ // 维度 4: 候选积压分析
258
+ // ═══════════════════════════════════════════════════════
259
+
260
+ #analyzeCandidatePatterns() {
261
+ const suggestions = [];
262
+ if (!this.#db) return { summary: 'DB 不可用', suggestions };
263
+
264
+ try {
265
+ const stats = this.#db.prepare(`
266
+ SELECT
267
+ COUNT(*) as total,
268
+ SUM(CASE WHEN status='pending' THEN 1 ELSE 0 END) as pending,
269
+ SUM(CASE WHEN status='rejected' THEN 1 ELSE 0 END) as rejected
270
+ FROM candidates
271
+ `).get();
272
+
273
+ // 大量被拒绝 → 提示候选质量 Skill
274
+ if (stats && stats.rejected >= 10) {
275
+ suggestions.push({
276
+ name: 'project-candidate-quality',
277
+ description: `候选提交质量指南 — ${stats.rejected} 条候选被拒,建议创建提交标准 Skill`,
278
+ rationale: `已有 ${stats.rejected} 条候选被驳回(总计 ${stats.total} 条)。创建一个 Skill 明确项目的候选提交标准(哪些代码值得提取、必填字段要求、质量标杆),可以减少返工。`,
279
+ source: 'candidate_rejection',
280
+ priority: stats.rejected >= 20 ? 'high' : 'medium',
281
+ signals: { total: stats.total, pending: stats.pending, rejected: stats.rejected },
282
+ });
283
+ }
284
+
285
+ return {
286
+ summary: stats || {},
287
+ suggestions,
288
+ };
289
+ } catch {
290
+ return { summary: '候选查询失败', suggestions };
291
+ }
292
+ }
293
+
294
+ // ═══════════════════════════════════════════════════════
295
+ // 辅助方法
296
+ // ═══════════════════════════════════════════════════════
297
+
298
+ /**
299
+ * 列出已有的项目级 Skill 名称集合(避免重复推荐)
300
+ */
301
+ #listExistingProjectSkills() {
302
+ const names = new Set();
303
+ const dir = getProjectSkillsPath(this.#projectRoot);
304
+ try {
305
+ fs.readdirSync(dir, { withFileTypes: true })
306
+ .filter(d => d.isDirectory())
307
+ .forEach(d => names.add(d.name));
308
+ } catch { /* no project skills */ }
309
+ return names;
310
+ }
311
+ }
312
+
313
+ /**
314
+ * 字符串转 kebab-case(简化版)
315
+ */
316
+ function _kebab(str) {
317
+ return (str || 'unknown')
318
+ .replace(/[^a-zA-Z0-9\s-]/g, '')
319
+ .replace(/\s+/g, '-')
320
+ .toLowerCase()
321
+ .substring(0, 30);
322
+ }
323
+
324
+ export default SkillAdvisor;
@@ -10,18 +10,26 @@
10
10
  * - onGuardCheck(violation, ctx) → violation (可修改)
11
11
  * - onBootstrapComplete(stats, ctx) → void
12
12
  *
13
- * 加载顺序: 内置 skills/ → 项目级 .autosnippet/skills/(同名覆盖)
13
+ * 加载顺序: 内置 skills/ → 项目级 AutoSnippet/skills/(同名覆盖)
14
14
  */
15
15
 
16
16
  import fs from 'node:fs';
17
17
  import path from 'node:path';
18
18
  import { fileURLToPath } from 'node:url';
19
19
  import Logger from '../../infrastructure/logging/Logger.js';
20
+ import { getProjectSkillsPath } from '../../infrastructure/config/Paths.js';
20
21
 
21
22
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
- const PROJECT_ROOT = path.resolve(__dirname, '../../..');
23
- const SKILLS_DIR = path.resolve(PROJECT_ROOT, 'skills');
24
- const PROJECT_SKILLS_DIR = path.resolve(PROJECT_ROOT, '.autosnippet', 'skills');
23
+ const SKILLS_DIR = path.resolve(__dirname, '../../../skills');
24
+
25
+ /**
26
+ * 获取项目级 Skills 目录(运行时动态解析)
27
+ * 路径: {projectRoot}/AutoSnippet/skills/
28
+ */
29
+ function _getProjectSkillsDir() {
30
+ const projectRoot = process.env.ASD_PROJECT_DIR || process.cwd();
31
+ return getProjectSkillsPath(projectRoot);
32
+ }
25
33
 
26
34
  const HOOK_NAMES = [
27
35
  'onCandidateSubmit',
@@ -48,7 +56,7 @@ export class SkillHooks {
48
56
  await this.#loadFromDir(SKILLS_DIR, loaded);
49
57
 
50
58
  // 2. 项目级 skills(覆盖同名)
51
- await this.#loadFromDir(PROJECT_SKILLS_DIR, loaded);
59
+ await this.#loadFromDir(_getProjectSkillsDir(), loaded);
52
60
 
53
61
  // 3. 注册所有钩子
54
62
  for (const [skillName, mod] of loaded) {
@@ -650,7 +650,7 @@ export class SpmService {
650
650
  const CODE_EXTS = isDirectoryTarget
651
651
  ? new Set(['.swift', '.m', '.mm', '.h', '.c', '.cpp', '.js', '.ts', '.tsx', '.jsx', '.py', '.java', '.kt', '.go', '.rs', '.rb', '.vue', '.mjs', '.cjs'])
652
652
  : new Set(['.swift', '.m', '.h', '.c', '.cpp', '.mm']);
653
- const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'Pods', '.build', 'DerivedData', 'vendor', '__pycache__', '.venv', 'target']);
653
+ const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'Pods', 'Carthage', '.build', 'DerivedData', 'vendor', '__pycache__', '.venv', 'target']);
654
654
  const MAX_FILES = 300;
655
655
 
656
656
  const files = [];
@@ -889,7 +889,7 @@ export class SpmService {
889
889
  // 非 SPM 项目:直接扫描常见源码目录(fallback)
890
890
  this.#logger.info('[SpmService] scanProject: No SPM targets, falling back to directory scan');
891
891
  const CODE_EXTS = new Set(['.swift', '.m', '.mm', '.h', '.js', '.ts', '.tsx', '.jsx', '.py', '.java', '.kt', '.go', '.rs', '.rb', '.vue', '.mjs', '.cjs']);
892
- const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'Pods', '.build', 'DerivedData', 'vendor', '__pycache__', '.venv', 'target']);
892
+ const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'Pods', 'Carthage', '.build', 'DerivedData', 'vendor', '__pycache__', '.venv', 'target']);
893
893
  const srcDirs = ['Sources', 'src', 'lib', 'app', 'pages', 'components', 'modules', 'packages'];
894
894
 
895
895
  const walkDir = (dir, targetName) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autosnippet",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "AutoSnippet - 连接开发者、AI 与项目知识库的工具",
5
5
  "type": "module",
6
6
  "main": "lib/bootstrap.js",
@@ -9,6 +9,7 @@
9
9
  ## 知识库与结构
10
10
  - 知识库根目录:`AutoSnippet/`(用户项目可通过 boxspec `knowledgeBase.dir` 自定义)
11
11
  - Recipe:`AutoSnippet/recipes/*.md`(Markdown + Frontmatter + Snippet + Usage Guide)
12
+ - **Project Skills**:`AutoSnippet/skills/<name>/SKILL.md`(项目级 AI 知识增强文档,跟随 Git)
12
13
  - constitution.yaml:`AutoSnippet/constitution.yaml`(权限宪法:角色 + 能力 + 治理规则)
13
14
  - 运行时 DB:`.autosnippet/autosnippet.db`(SQLite,recipes/candidates/snippets 索引缓存)
14
15
  - 向量索引:`.autosnippet/context/`(`asd embed` 生成)
@@ -51,14 +52,21 @@
51
52
  - `autosnippet_submit_draft_recipes` — 解析草稿 Markdown 文件
52
53
  - `autosnippet_enrich_candidates` — AI 补全缺失语义字段
53
54
 
54
- ### 项目扫描
55
+ ### 项目扫描 & 冷启动
55
56
  - `autosnippet_get_targets` / `autosnippet_get_target_files` / `autosnippet_get_target_metadata`
56
57
  - `autosnippet_scan_project` — 轻量探查(文件清单 + Guard 审计)
57
- - `autosnippet_bootstrap_knowledge` — 冷启动知识库初始化(9 大知识维度)
58
+ - `autosnippet_bootstrap_knowledge` — 冷启动知识库初始化(9 维度 + 自动生成 Project Skills)
59
+ - `autosnippet_bootstrap_refine` — Bootstrap 候选 AI 润色(summary/insight/relations)
58
60
 
59
61
  ### Guard & 治理
60
62
  - `autosnippet_guard_check` / `autosnippet_guard_audit_files` / `autosnippet_compliance_report`
61
63
 
64
+ ### Skills
65
+ - `autosnippet_list_skills` — 列出所有可用 Skills(内置 + 项目级)
66
+ - `autosnippet_load_skill` — 加载 Skill 完整文档
67
+ - `autosnippet_create_skill` — 创建项目级 Skill(写入 `AutoSnippet/skills/`)
68
+ - `autosnippet_suggest_skills` — 基于使用模式推荐创建 Skill
69
+
62
70
  ### 其它
63
71
  - `autosnippet_health` / `autosnippet_capabilities` / `autosnippet_confirm_usage`
64
72
 
@@ -67,10 +75,19 @@
67
75
  - Frontmatter 必填字段(7):`title`、`trigger`(@开头)、`category`(8 选 1)、`language`、`summary_cn`、`summary_en`、`headers`。
68
76
  - Usage Guide 必须用 `###` 三级标题分段,列表式书写,禁止一行文字墙。
69
77
 
78
+ ## Project Skills
79
+ - **发现**:`autosnippet_list_skills` — 列出所有可用 Skills(内置 + 项目级)
80
+ - **加载**:`autosnippet_load_skill(skillName)` — 获取 Skill 完整操作指南
81
+ - **创建**:`autosnippet_create_skill(name, description, content)` — 创建项目级 Skill
82
+ - **推荐**:`autosnippet_suggest_skills` — 基于使用模式推荐创建 Skill
83
+ - **Bootstrap 自动生成**:冷启动 Phase 5.5 自动生成 4 个 Project Skills(code-standard, architecture, project-profile, agent-guidelines)
84
+ - **优先级**:项目级 Skill 同名覆盖内置;宏观知识查 Skill,微观代码模式查 Recipe
85
+
70
86
  ## 推荐工作流
71
87
  - **查找**:`autosnippet_search`(推荐)或 `autosnippet_context_search`(上下文感知)。
72
88
  - **产出候选**:`autosnippet_validate_candidate` 预校验 → `autosnippet_submit_candidate` 提交。
73
- - **批量扫描**:`autosnippet_bootstrap_knowledge`(冷启动)→ analysisFramework 逐维度分析 → `autosnippet_submit_candidates`。
89
+ - **冷启动**:`autosnippet_bootstrap_knowledge` `autosnippet_enrich_candidates` `autosnippet_bootstrap_refine` 逐 Target 深入 → `autosnippet_submit_candidates`。
90
+ - **Skills 创建**:`autosnippet_suggest_skills` 分析 → `autosnippet_create_skill` 固化知识。
74
91
  - **采纳反馈**:`autosnippet_confirm_usage`(记录使用量影响排序权重)。
75
92
 
76
93
  ## 与 Cursor 规则联动
@@ -41,9 +41,19 @@ Recipes are classified into three kinds:
41
41
  - **Retry policy**: If an MCP call fails, do not retry within the same agent turn; fall back to static docs or already-read context.
42
42
  - **Adoption tracking**: Tool `autosnippet_confirm_usage` records that a Recipe was adopted or applied (affects usage stats and authority ranking). Show it when the user explicitly adopts a recipe, not immediately after presenting one.
43
43
  - **Batch scan**: Ask Cursor in natural language (e.g. "scan all targets in this project", "batch extract candidates") to trigger the batch-scan workflow. The workflow calls `autosnippet_get_targets` → `autosnippet_get_target_files` → extract per file → `autosnippet_submit_candidates` automatically.
44
- - **Cold start**: Use `autosnippet_bootstrap_knowledge` for full project knowledge initialization covering 9 dimensions (project norms, usage patterns, architecture, code patterns, best practices, bug fixes, knowledge graph, library characteristics, agent dev notes).
44
+ - **Cold start**: Use `autosnippet_bootstrap_knowledge` for full project knowledge initialization covering 9 dimensions. Phase 5.5 auto-generates 4 Project Skills (code-standard, architecture, project-profile, agent-guidelines) to `AutoSnippet/skills/`.
45
45
 
46
- ## MCP tools (31 total)
46
+ ## Project Skills
47
+
48
+ - **Skills 目录**: `AutoSnippet/skills/<name>/SKILL.md` — 跟随项目 Git 管理
49
+ - **发现**: `autosnippet_list_skills` — 列出所有可用 Skills(内置 + 项目级)
50
+ - **加载**: `autosnippet_load_skill(skillName)` — 获取 Skill 完整文档
51
+ - **创建**: `autosnippet_create_skill(name, description, content)` — 创建项目级 Skill
52
+ - **推荐**: `autosnippet_suggest_skills` — 基于使用模式推荐创建 Skill
53
+ - **优先级**: 项目级 Skill 同名覆盖内置 Skill;Skill > Recipe(宏观知识优先查 Skill)
54
+ - **Bootstrap 自动生成**: 冷启动会自动生成 `project-code-standard`、`project-architecture`、`project-profile`、`project-agent-guidelines` 四个 Project Skills
55
+
56
+ ## MCP tools (36 total)
47
57
 
48
58
  ### Search (prefer search / context_search)
49
59
  - `autosnippet_search` — Unified search (auto: BM25 + semantic fusion)
@@ -66,14 +76,21 @@ Recipes are classified into three kinds:
66
76
  - `autosnippet_submit_draft_recipes` — Parse draft Markdown files
67
77
  - `autosnippet_enrich_candidates` — AI-fill missing semantic fields
68
78
 
69
- ### Project scanning
79
+ ### Project scanning & bootstrap
70
80
  - `autosnippet_get_targets` / `autosnippet_get_target_files` / `autosnippet_get_target_metadata`
71
81
  - `autosnippet_scan_project` — Lightweight probe (file list + Guard audit)
72
- - `autosnippet_bootstrap_knowledge` — Cold-start knowledge initialization
82
+ - `autosnippet_bootstrap_knowledge` — Cold-start knowledge initialization (9 dimensions + auto Project Skills)
83
+ - `autosnippet_bootstrap_refine` — AI refinement for bootstrap candidates (summary/insight/relations)
73
84
 
74
85
  ### Guard & governance
75
86
  - `autosnippet_guard_check` / `autosnippet_guard_audit_files` / `autosnippet_compliance_report`
76
87
 
88
+ ### Skills
89
+ - `autosnippet_list_skills` — List all available Skills (builtin + project)
90
+ - `autosnippet_load_skill` — Load a Skill's full document
91
+ - `autosnippet_create_skill` — Create a project-level Skill in `AutoSnippet/skills/`
92
+ - `autosnippet_suggest_skills` — Recommend Skills based on usage patterns
93
+
77
94
  ### Other
78
95
  - `autosnippet_health` / `autosnippet_capabilities` / `autosnippet_confirm_usage`
79
96
 
@@ -0,0 +1,45 @@
1
+ ---
2
+ description: AutoSnippet Project Skills — 项目级知识增强文档索引与使用指引
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # AutoSnippet Project Skills
7
+
8
+ Project Skills 是针对当前项目自动生成或手动创建的 AI Agent 知识增强文档。
9
+ 它们存放在 `AutoSnippet/skills/` 目录下,跟随项目 Git 管理。
10
+
11
+ ## 如何发现与加载
12
+
13
+ 1. **列出所有 Skills**:调用 `autosnippet_list_skills` 查看当前可用的 Skills(含内置 + 项目级)
14
+ 2. **加载完整内容**:调用 `autosnippet_load_skill(skillName)` 获取具体 Skill 的完整文档
15
+ 3. **按需加载**:不确定该用哪个 Skill 时,先加载 `autosnippet-intent` 做意图路由
16
+ 4. **创建 Skill**:调用 `autosnippet_create_skill(name, description, content)` 创建项目级 Skill
17
+ 5. **Skill 推荐**:调用 `autosnippet_suggest_skills` 获取基于使用模式的 Skill 创建建议
18
+
19
+ ## Bootstrap 自动生成的 Project Skills
20
+
21
+ 冷启动(`autosnippet_bootstrap_knowledge`)Phase 5.5 会自动为 4 个宏观维度生成 Project Skills:
22
+
23
+ | Skill | 维度 | 说明 |
24
+ |-------|------|------|
25
+ | `project-code-standard` | 代码规范 | 命名约定、文件组织规范 |
26
+ | `project-architecture` | 架构模式 | 分层架构、模块边界、依赖图 |
27
+ | `project-profile` | 项目特征 | 技术栈、模块结构、代码指标 |
28
+ | `project-agent-guidelines` | Agent 约束 | 强制规则、TODO/FIXME、WARNING |
29
+
30
+ 生成后的 Skill 文件位于 `AutoSnippet/skills/<name>/SKILL.md`,自动跟随 Git。
31
+ 调用 `autosnippet_load_skill` 可加载完整内容。
32
+
33
+ ## 推荐工作流
34
+
35
+ 冷启动完整流程:
36
+ 1. `autosnippet_bootstrap_knowledge` — 9 维度分析 + 自动生成 Project Skills
37
+ 2. `autosnippet_enrich_candidates` — 补全缺失语义字段
38
+ 3. `autosnippet_bootstrap_refine` — AI 润色 summary/insight/relations
39
+ 4. 逐 Target 深入分析 → `autosnippet_submit_candidates`
40
+
41
+ ## 使用优先级
42
+
43
+ - **Project Skills > 内置 Skills**:同名时项目级覆盖内置
44
+ - **Skill > Recipe**:宏观架构/规范知识优先查 Skill,微观代码模式查 Recipe
45
+ - **Skills 是只读参考**:不要直接修改 SKILL.md,应通过 `autosnippet_create_skill` 工具创建或更新