autosnippet 2.9.0 → 2.11.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 +12 -12
- package/bin/cli.js +53 -40
- package/config/constitution.yaml +9 -2
- package/dashboard/dist/assets/{icons-CH-H9x0E.js → icons-D4IWpDIk.js} +105 -100
- package/dashboard/dist/assets/index-CWBNcF9z.css +1 -0
- package/dashboard/dist/assets/index-DHtzhbuG.js +120 -0
- package/dashboard/dist/index.html +3 -3
- package/lib/cli/AiScanService.js +35 -36
- package/lib/cli/KnowledgeSyncService.js +345 -0
- package/lib/cli/SetupService.js +8 -26
- package/lib/cli/UpgradeService.js +28 -0
- package/lib/core/gateway/GatewayActionRegistry.js +48 -58
- package/lib/domain/index.js +16 -11
- package/lib/domain/knowledge/KnowledgeEntry.js +289 -0
- package/lib/domain/knowledge/KnowledgeRepository.js +123 -0
- package/lib/domain/knowledge/Lifecycle.js +99 -0
- package/lib/domain/knowledge/index.js +27 -0
- package/lib/domain/knowledge/values/Constraints.js +128 -0
- package/lib/domain/knowledge/values/Content.js +69 -0
- package/lib/domain/knowledge/values/Quality.js +81 -0
- package/lib/domain/knowledge/values/Reasoning.js +70 -0
- package/lib/domain/knowledge/values/Relations.js +142 -0
- package/lib/domain/knowledge/values/Stats.js +72 -0
- package/lib/domain/knowledge/values/index.js +9 -0
- package/lib/external/ai/AiProvider.js +85 -11
- package/lib/external/mcp/McpServer.js +7 -5
- package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +18 -2
- package/lib/external/mcp/handlers/bootstrap.js +116 -11
- package/lib/external/mcp/handlers/browse.js +76 -73
- package/lib/external/mcp/handlers/candidate.js +26 -275
- package/lib/external/mcp/handlers/guard.js +2 -0
- package/lib/external/mcp/handlers/knowledge.js +267 -0
- package/lib/external/mcp/handlers/structure.js +25 -23
- package/lib/external/mcp/handlers/system.js +10 -12
- package/lib/external/mcp/tools.js +134 -140
- package/lib/http/HttpServer.js +14 -8
- package/lib/http/routes/ai.js +4 -3
- package/lib/http/routes/extract.js +48 -4
- package/lib/http/routes/knowledge.js +246 -0
- package/lib/http/routes/search.js +12 -17
- package/lib/infrastructure/database/migrations/016_unified_knowledge_entries.js +395 -0
- package/lib/infrastructure/database/migrations/017_camelcase_knowledge_entries.js +107 -0
- package/lib/infrastructure/external/XcodeAutomation.js +187 -103
- package/lib/injection/ServiceContainer.js +69 -60
- package/lib/repository/knowledge/KnowledgeRepository.impl.js +338 -0
- package/lib/service/automation/DirectiveDetector.js +2 -3
- package/lib/service/automation/FileWatcher.js +59 -28
- package/lib/service/automation/XcodeIntegration.js +931 -156
- package/lib/service/automation/handlers/AlinkHandler.js +5 -4
- package/lib/service/automation/handlers/CreateHandler.js +53 -19
- package/lib/service/automation/handlers/DraftHandler.js +1 -1
- package/lib/service/automation/handlers/GuardHandler.js +183 -20
- package/lib/service/automation/handlers/SearchHandler.js +25 -22
- package/lib/service/candidate/SimilarityService.js +2 -2
- package/lib/service/chat/AnalystAgent.js +9 -0
- package/lib/service/chat/CandidateGuardrail.js +22 -11
- package/lib/service/chat/ChatAgent.js +132 -54
- package/lib/service/chat/ContextWindow.js +5 -5
- package/lib/service/chat/HandoffProtocol.js +1 -0
- package/lib/service/chat/ProducerAgent.js +40 -13
- package/lib/service/chat/ReasoningLayer.js +854 -0
- package/lib/service/chat/ReasoningTrace.js +329 -0
- package/lib/service/chat/tools.js +308 -205
- package/lib/service/cursor/CursorDeliveryPipeline.js +279 -0
- package/lib/service/cursor/KnowledgeCompressor.js +87 -0
- package/lib/service/cursor/RulesGenerator.js +168 -0
- package/lib/service/cursor/SkillsSyncer.js +268 -0
- package/lib/service/cursor/TokenBudget.js +58 -0
- package/lib/service/cursor/TopicClassifier.js +141 -0
- package/lib/service/guard/GuardCheckEngine.js +99 -10
- package/lib/service/guard/GuardService.js +57 -46
- package/lib/service/knowledge/ConfidenceRouter.js +159 -0
- package/lib/service/knowledge/KnowledgeFileWriter.js +595 -0
- package/lib/service/knowledge/KnowledgeService.js +802 -0
- package/lib/service/recipe/RecipeParser.js +3 -12
- package/lib/service/search/SearchEngine.js +67 -22
- package/lib/service/skills/SignalCollector.js +14 -9
- package/lib/service/skills/SkillAdvisor.js +13 -11
- package/lib/service/snippet/SnippetFactory.js +5 -5
- package/lib/service/spm/SpmService.js +15 -48
- package/lib/shared/RecipeReadinessChecker.js +6 -11
- package/package.json +1 -1
- package/scripts/install-cursor-skill.js +0 -6
- package/scripts/migrate-md-to-knowledge.mjs +364 -0
- package/skills/autosnippet-analysis/SKILL.md +15 -7
- package/skills/autosnippet-candidates/SKILL.md +8 -8
- package/skills/autosnippet-coldstart/SKILL.md +8 -4
- package/skills/autosnippet-concepts/SKILL.md +7 -6
- package/skills/autosnippet-create/SKILL.md +13 -13
- package/skills/autosnippet-intent/SKILL.md +3 -2
- package/skills/autosnippet-lifecycle/SKILL.md +5 -5
- package/skills/autosnippet-recipes/SKILL.md +18 -6
- package/templates/constitution.yaml +1 -1
- package/templates/copilot-instructions.md +6 -6
- package/templates/recipes-setup/README.md +3 -3
- package/dashboard/dist/assets/index-CqJRvYRL.js +0 -197
- package/dashboard/dist/assets/index-DICm9PNa.css +0 -1
- package/lib/cli/CandidateSyncService.js +0 -261
- package/lib/cli/SyncService.js +0 -356
- package/lib/domain/candidate/Candidate.js +0 -196
- package/lib/domain/candidate/CandidateRepository.js +0 -107
- package/lib/domain/candidate/Reasoning.js +0 -52
- package/lib/domain/recipe/Recipe.js +0 -421
- package/lib/domain/recipe/RecipeRepository.js +0 -54
- package/lib/domain/types/CandidateStatus.js +0 -52
- package/lib/http/routes/candidates.js +0 -559
- package/lib/http/routes/recipes.js +0 -397
- package/lib/repository/candidate/CandidateRepository.impl.js +0 -230
- package/lib/repository/recipe/RecipeRepository.impl.js +0 -498
- package/lib/service/candidate/CandidateAggregator.js +0 -52
- package/lib/service/candidate/CandidateFileWriter.js +0 -383
- package/lib/service/candidate/CandidateService.js +0 -1001
- package/lib/service/recipe/RecipeFileWriter.js +0 -514
- package/lib/service/recipe/RecipeService.js +0 -786
- package/lib/service/recipe/RecipeStatsTracker.js +0 -148
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ProducerAgent.js — v3.0 生产者 Agent
|
|
3
3
|
*
|
|
4
4
|
* 职责:
|
|
5
|
-
* - 将 Analyst 的分析文本转换为结构化的
|
|
5
|
+
* - 将 Analyst 的分析文本转换为结构化的 submit_knowledge 调用
|
|
6
6
|
* - 遵循 PROJECT_SNAPSHOT_STYLE_GUIDE 格式
|
|
7
7
|
* - 使用 read_project_file 获取代码片段
|
|
8
8
|
* - CandidateGuardrail 验证每次提交
|
|
@@ -21,19 +21,20 @@ import Logger from '../../infrastructure/logging/Logger.js';
|
|
|
21
21
|
|
|
22
22
|
const PRODUCER_SYSTEM_PROMPT = `你是知识管理专家。你会收到一段代码分析文本,需要将其中的知识点转化为结构化的知识候选。
|
|
23
23
|
|
|
24
|
-
核心原则: 分析文本已经包含了所有发现,你的唯一工作是将它们格式化为
|
|
24
|
+
核心原则: 分析文本已经包含了所有发现,你的唯一工作是将它们格式化为 submit_knowledge 调用。
|
|
25
25
|
|
|
26
26
|
每个候选必须:
|
|
27
27
|
1. 有清晰的标题 (描述知识点的核心,使用项目真实类名)
|
|
28
|
-
2. 有项目特写风格的正文 (
|
|
28
|
+
2. 有项目特写风格的正文 (content.markdown 字段,结合代码展示)
|
|
29
29
|
3. 标注相关文件路径
|
|
30
|
-
4. 选择正确的
|
|
30
|
+
4. 选择正确的 kind (rule/pattern/fact)
|
|
31
|
+
5. 提供完整的 Cursor 交付字段 (trigger, doClause, whenClause 等)
|
|
31
32
|
|
|
32
33
|
工作流程:
|
|
33
34
|
1. 阅读分析文本,识别每个独立的知识点/发现
|
|
34
35
|
2. 用 read_project_file 批量获取关键代码片段:
|
|
35
36
|
read_project_file({ filePaths: ["FileA.m", "FileB.m"], maxLines: 80 })
|
|
36
|
-
3. 立刻调用
|
|
37
|
+
3. 立刻调用 submit_knowledge 提交
|
|
37
38
|
4. 重复直到分析中的所有知识点都已提交
|
|
38
39
|
|
|
39
40
|
关键规则:
|
|
@@ -55,7 +56,7 @@ const PRODUCER_SYSTEM_PROMPT = `你是知识管理专家。你会收到一段代
|
|
|
55
56
|
// ──────────────────────────────────────────────────────────────────
|
|
56
57
|
|
|
57
58
|
const PRODUCER_TOOLS = [
|
|
58
|
-
'
|
|
59
|
+
'submit_knowledge',
|
|
59
60
|
'submit_with_check',
|
|
60
61
|
'read_project_file',
|
|
61
62
|
];
|
|
@@ -79,7 +80,7 @@ const PRODUCER_BUDGET = {
|
|
|
79
80
|
|
|
80
81
|
const STYLE_GUIDE = `# 「项目特写」写作要求
|
|
81
82
|
|
|
82
|
-
|
|
83
|
+
submit_knowledge 的 content.markdown 字段必须是「项目特写」。
|
|
83
84
|
|
|
84
85
|
## 什么是「项目特写」
|
|
85
86
|
将一种技术的**基本用法**与**本项目的具体特征**融合为一体。
|
|
@@ -93,7 +94,30 @@ submit_candidate 的 code 字段必须是「项目特写」。
|
|
|
93
94
|
## 格式要求
|
|
94
95
|
- 标题使用项目真实类名/前缀,不用占位名
|
|
95
96
|
- 代码来源标注: (来源: FileName.m:行号)
|
|
96
|
-
-
|
|
97
|
+
- 不要纯代码罗列,必须有项目上下文
|
|
98
|
+
|
|
99
|
+
## Cursor 交付字段(每个 submit_knowledge 必须附带)
|
|
100
|
+
|
|
101
|
+
每个候选必须提供以下交付字段,它们直接决定在 Cursor IDE 中作为 Rules 的展示质量。
|
|
102
|
+
注意:language / category / knowledgeType / source 由系统自动设置,无需填写。
|
|
103
|
+
|
|
104
|
+
### 必填
|
|
105
|
+
- trigger: "@" + 核心类名 kebab-case,如 @bd-base-request。每个候选 trigger 必须唯一
|
|
106
|
+
- kind: 此候选的知识类型 — rule(强制约束) / pattern(实现模式) / fact(项目事实)
|
|
107
|
+
- doClause: 英文祈使句 ≤60 tokens,概括此知识的正向规则(以动词开头)。如 "Use dispatch_once for thread-safe singleton initialization"
|
|
108
|
+
- description: 中文简述 ≤80 字,引用真实类名和数字
|
|
109
|
+
|
|
110
|
+
### 推荐
|
|
111
|
+
- dontClause: 反向约束英文描述(不以 "Don't" 开头,调用方会加前缀)。如 "use @synchronized for singleton"
|
|
112
|
+
- whenClause: 触发场景英文。如 "When implementing singleton pattern or global shared instance"
|
|
113
|
+
- topicHint: 主题分类,取值 networking / ui / data / architecture / conventions
|
|
114
|
+
- coreCode: 最典型纯代码片段 3-8 行(不含 Markdown 格式、无 # 标题、无围栏、无 > 引用)
|
|
115
|
+
|
|
116
|
+
### 规范
|
|
117
|
+
1. trigger 以 @ 开头,kebab-case,不得在同一批次重复
|
|
118
|
+
2. doClause 英文祈使句,不含中文
|
|
119
|
+
3. coreCode 是可直接复制到编辑器的纯代码
|
|
120
|
+
4. kind 根据内容本质判断:强制约束 → rule,实现模式 → pattern,项目事实 → fact`;
|
|
97
121
|
|
|
98
122
|
// ──────────────────────────────────────────────────────────────────
|
|
99
123
|
// Prompt 构建
|
|
@@ -135,10 +159,11 @@ function buildProducerPrompt(analysisReport, dimConfig, projectInfo) {
|
|
|
135
159
|
1. 每个独立的知识点单独提交为一个候选 — 目标: 至少 3 个候选
|
|
136
160
|
2. 先使用分析中已有的代码片段直接提交候选; 仅在需要更多代码上下文时才用 read_project_file
|
|
137
161
|
3. filePaths 填写分析中提到的相关文件路径
|
|
138
|
-
4.
|
|
162
|
+
4. description 中文简述 ≤80 字,引用真实类名
|
|
139
163
|
5. reasoning 中 sources 必须非空,填写来源文件名如 ["FileName.m"],confidence 填 0.7~0.9
|
|
140
164
|
6. 不要跳过任何分析中提到的知识点
|
|
141
|
-
7. 如果 read_project_file
|
|
165
|
+
7. 如果 read_project_file 失败(文件不存在),直接用分析文本内容提交,不要重试其他路径
|
|
166
|
+
8. 每个候选必须有 trigger (@kebab-case)、kind (rule/pattern/fact)、doClause (英文祈使句)`);
|
|
142
167
|
|
|
143
168
|
return parts.join('\n\n');
|
|
144
169
|
}
|
|
@@ -207,7 +232,7 @@ export class ProducerAgent {
|
|
|
207
232
|
|
|
208
233
|
// 统计提交 (区分成功/失败)
|
|
209
234
|
const submitCalls = (result.toolCalls || []).filter(
|
|
210
|
-
tc => (tc.tool || tc.name) === '
|
|
235
|
+
tc => (tc.tool || tc.name) === 'submit_knowledge' || (tc.tool || tc.name) === 'submit_with_check'
|
|
211
236
|
);
|
|
212
237
|
const successCount = submitCalls.filter(tc => {
|
|
213
238
|
const res = tc.result;
|
|
@@ -221,7 +246,7 @@ export class ProducerAgent {
|
|
|
221
246
|
if (rejectedCount > successCount && rejectedCount >= 2 && options.retryOnRejection !== false) {
|
|
222
247
|
this.#logger.info(`[ProducerAgent] 高拒绝率 (${rejectedCount}/${submitCalls.length}) — 尝试修正`);
|
|
223
248
|
try {
|
|
224
|
-
const retryPrompt = `你的 ${rejectedCount} 个提交被拒绝了。请根据拒绝原因改进后重新提交,确保:\n1.
|
|
249
|
+
const retryPrompt = `你的 ${rejectedCount} 个提交被拒绝了。请根据拒绝原因改进后重新提交,确保:\n1. content.markdown 字段 ≥ 200 字符\n2. 包含代码块 (\`\`\`)\n3. 包含来源标注 (来源: FileName.m:行号)\n4. 标题使用项目真实类名\n5. 必填: trigger (@kebab-case)、kind (rule/pattern/fact)、doClause (英文祈使句)`;
|
|
225
250
|
const retryResult = await this.#chatAgent.execute(retryPrompt, {
|
|
226
251
|
source: 'system',
|
|
227
252
|
conversationId: options.sessionId ? `producer-retry-${options.sessionId}-${dimId}` : undefined,
|
|
@@ -238,7 +263,7 @@ export class ProducerAgent {
|
|
|
238
263
|
});
|
|
239
264
|
|
|
240
265
|
const retrySubmits = (retryResult.toolCalls || []).filter(
|
|
241
|
-
tc => (tc.tool || tc.name) === '
|
|
266
|
+
tc => (tc.tool || tc.name) === 'submit_knowledge' || (tc.tool || tc.name) === 'submit_with_check'
|
|
242
267
|
);
|
|
243
268
|
const retrySuccess = retrySubmits.filter(tc => {
|
|
244
269
|
const res = tc.result;
|
|
@@ -263,6 +288,7 @@ export class ProducerAgent {
|
|
|
263
288
|
toolCalls: [...(result.toolCalls || []), ...(retryResult.toolCalls || [])],
|
|
264
289
|
reply: retryResult.reply || result.reply || '',
|
|
265
290
|
tokenUsage: mergedTokenUsage,
|
|
291
|
+
reasoningQuality: retryResult.reasoningQuality || result.reasoningQuality || null,
|
|
266
292
|
};
|
|
267
293
|
} catch (retryErr) {
|
|
268
294
|
this.#logger.warn(`[ProducerAgent] 修正轮失败 "${dimId}": ${retryErr.message}`);
|
|
@@ -277,6 +303,7 @@ export class ProducerAgent {
|
|
|
277
303
|
toolCalls: result.toolCalls || [],
|
|
278
304
|
reply: result.reply || '',
|
|
279
305
|
tokenUsage: result.tokenUsage || null,
|
|
306
|
+
reasoningQuality: result.reasoningQuality || null,
|
|
280
307
|
};
|
|
281
308
|
} catch (err) {
|
|
282
309
|
this.#logger.error(`[ProducerAgent] ❌ dimension "${dimId}" error: ${err.message}`);
|