autosnippet 3.3.5 → 3.3.6

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 (203) hide show
  1. package/dashboard/dist/assets/icons-D1aVZYFW.js +1 -0
  2. package/dashboard/dist/assets/index-CxHOu8Hd.css +1 -0
  3. package/dashboard/dist/assets/index-DDdAOpYT.js +128 -0
  4. package/dashboard/dist/index.html +3 -3
  5. package/dist/bin/api-server.js +1 -0
  6. package/dist/bin/cli.d.ts +1 -0
  7. package/dist/bin/cli.js +136 -9
  8. package/dist/lib/agent/AgentFactory.d.ts +0 -17
  9. package/dist/lib/agent/AgentFactory.js +1 -25
  10. package/dist/lib/agent/capabilities.d.ts +11 -0
  11. package/dist/lib/agent/capabilities.js +29 -5
  12. package/dist/lib/agent/context/ExplorationTracker.js +10 -1
  13. package/dist/lib/agent/context/exploration/ExplorationStrategies.d.ts +2 -0
  14. package/dist/lib/agent/context/exploration/ExplorationStrategies.js +2 -2
  15. package/dist/lib/agent/domain/insight-analyst.d.ts +47 -3
  16. package/dist/lib/agent/domain/insight-analyst.js +111 -11
  17. package/dist/lib/agent/domain/insight-evolver.d.ts +69 -0
  18. package/dist/lib/agent/domain/insight-evolver.js +230 -0
  19. package/dist/lib/agent/domain/insight-gate.d.ts +42 -0
  20. package/dist/lib/agent/domain/insight-gate.js +41 -0
  21. package/dist/lib/agent/domain/insight-producer.d.ts +27 -2
  22. package/dist/lib/agent/domain/insight-producer.js +60 -5
  23. package/dist/lib/agent/domain/scan-prompts.js +10 -7
  24. package/dist/lib/agent/memory/ActiveContext.d.ts +2 -28
  25. package/dist/lib/agent/memory/MemoryCoordinator.d.ts +2 -2
  26. package/dist/lib/agent/memory/SessionStore.d.ts +6 -12
  27. package/dist/lib/agent/memory/SessionStore.js +9 -15
  28. package/dist/lib/agent/memory/memory-flush-contract.d.ts +49 -0
  29. package/dist/lib/agent/memory/memory-flush-contract.js +16 -0
  30. package/dist/lib/agent/memory/session-store-schema.d.ts +20 -0
  31. package/dist/lib/agent/memory/session-store-schema.js +41 -0
  32. package/dist/lib/agent/presets.d.ts +89 -1
  33. package/dist/lib/agent/presets.js +53 -5
  34. package/dist/lib/agent/tools/_shared.d.ts +7 -15
  35. package/dist/lib/agent/tools/_shared.js +20 -21
  36. package/dist/lib/agent/tools/composite.d.ts +25 -22
  37. package/dist/lib/agent/tools/composite.js +108 -109
  38. package/dist/lib/agent/tools/evolution-tools.d.ts +145 -0
  39. package/dist/lib/agent/tools/evolution-tools.js +161 -0
  40. package/dist/lib/agent/tools/index.d.ts +163 -92
  41. package/dist/lib/agent/tools/index.js +9 -1
  42. package/dist/lib/agent/tools/lifecycle.d.ts +7 -1
  43. package/dist/lib/agent/tools/lifecycle.js +59 -75
  44. package/dist/lib/cli/AiScanService.js +1 -1
  45. package/dist/lib/cli/KnowledgeSyncService.js +1 -1
  46. package/dist/lib/core/AstAnalyzer.d.ts +1 -0
  47. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.d.ts → domain/dimension/DimensionCopy.d.ts} +2 -2
  48. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.js → domain/dimension/DimensionCopy.js} +22 -72
  49. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +54 -0
  50. package/dist/lib/domain/dimension/DimensionRegistry.js +620 -0
  51. package/dist/lib/domain/dimension/DimensionSop.d.ts +55 -0
  52. package/dist/lib/domain/dimension/DimensionSop.js +1604 -0
  53. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +61 -0
  54. package/dist/lib/domain/dimension/UnifiedDimension.js +53 -0
  55. package/dist/lib/domain/dimension/index.d.ts +10 -0
  56. package/dist/lib/domain/dimension/index.js +9 -0
  57. package/dist/lib/domain/knowledge/FieldSpec.d.ts +1 -1
  58. package/dist/lib/domain/knowledge/FieldSpec.js +29 -16
  59. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +33 -111
  60. package/dist/lib/domain/knowledge/KnowledgeEntry.js +27 -6
  61. package/dist/lib/domain/knowledge/KnowledgeRepository.d.ts +1 -0
  62. package/dist/lib/domain/knowledge/KnowledgeRepository.js +3 -0
  63. package/dist/lib/domain/knowledge/Lifecycle.js +1 -1
  64. package/dist/lib/domain/knowledge/StyleGuide.d.ts +1 -1
  65. package/dist/lib/domain/knowledge/StyleGuide.js +1 -1
  66. package/dist/lib/domain/knowledge/UnifiedValidator.js +15 -0
  67. package/dist/lib/external/mcp/McpServer.js +4 -0
  68. package/dist/lib/external/mcp/handlers/TargetClassifier.d.ts +1 -1
  69. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.d.ts +8 -16
  70. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +10 -10
  71. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.d.ts +7 -0
  72. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +20 -0
  73. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +52 -132
  74. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +204 -17
  75. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.d.ts +11 -75
  76. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.js +40 -191
  77. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.d.ts +13 -78
  78. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +30 -52
  79. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.d.ts +0 -1
  80. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts +99 -12
  81. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +172 -161
  82. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +7 -17
  83. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.d.ts +46 -0
  84. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.js +58 -0
  85. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.d.ts +25 -0
  86. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.js +47 -0
  87. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +50 -12
  88. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +30 -10
  89. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-text.js +1 -1
  90. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.d.ts +24 -0
  91. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.js +14 -0
  92. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.d.ts +14 -0
  93. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.js +48 -0
  94. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.d.ts +21 -0
  95. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.js +45 -0
  96. package/dist/lib/external/mcp/handlers/bootstrap/shared/skill-generator.d.ts +1 -1
  97. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.d.ts +27 -0
  98. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.js +44 -0
  99. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +14 -10
  100. package/dist/lib/external/mcp/handlers/bootstrap-external.js +39 -51
  101. package/dist/lib/external/mcp/handlers/bootstrap-internal.d.ts +2 -0
  102. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +115 -82
  103. package/dist/lib/external/mcp/handlers/consolidated.d.ts +4 -4
  104. package/dist/lib/external/mcp/handlers/consolidated.js +107 -332
  105. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +69 -1
  106. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +54 -0
  107. package/dist/lib/external/mcp/handlers/evolve-external.js +226 -0
  108. package/dist/lib/external/mcp/handlers/knowledge.js +26 -2
  109. package/dist/lib/external/mcp/handlers/rescan-external.d.ts +76 -0
  110. package/dist/lib/external/mcp/handlers/rescan-external.js +335 -0
  111. package/dist/lib/external/mcp/handlers/rescan-internal.d.ts +120 -0
  112. package/dist/lib/external/mcp/handlers/rescan-internal.js +359 -0
  113. package/dist/lib/external/mcp/handlers/search.d.ts +6 -5
  114. package/dist/lib/external/mcp/handlers/search.js +6 -5
  115. package/dist/lib/external/mcp/handlers/types.d.ts +2 -1
  116. package/dist/lib/external/mcp/handlers/wiki-external.js +2 -2
  117. package/dist/lib/external/mcp/tools.d.ts +8 -18
  118. package/dist/lib/external/mcp/tools.js +58 -2
  119. package/dist/lib/http/routes/knowledge.js +122 -1
  120. package/dist/lib/http/routes/modules.js +25 -3
  121. package/dist/lib/http/routes/panorama.js +16 -4
  122. package/dist/lib/infrastructure/cache/CacheCoordinator.d.ts +41 -0
  123. package/dist/lib/infrastructure/cache/CacheCoordinator.js +105 -0
  124. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.d.ts +7 -0
  125. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.js +28 -0
  126. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +1 -1
  127. package/dist/lib/injection/ServiceContainer.js +55 -0
  128. package/dist/lib/injection/ServiceMap.d.ts +8 -1
  129. package/dist/lib/injection/modules/KnowledgeModule.js +15 -1
  130. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +4 -0
  131. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +16 -1
  132. package/dist/lib/service/bootstrap/BootstrapEventEmitter.d.ts +3 -2
  133. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +1 -1
  134. package/dist/lib/service/bootstrap/DeliveryVerifier.d.ts +51 -0
  135. package/dist/lib/service/bootstrap/DeliveryVerifier.js +163 -0
  136. package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +5 -0
  137. package/dist/lib/service/bootstrap/UiStartupTasks.js +20 -0
  138. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +54 -0
  139. package/dist/lib/service/bootstrap/bootstrap-event-types.js +10 -0
  140. package/dist/lib/service/cleanup/CleanupService.d.ts +85 -0
  141. package/dist/lib/service/cleanup/CleanupService.js +324 -0
  142. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +39 -43
  143. package/dist/lib/service/delivery/FileProtection.d.ts +20 -0
  144. package/dist/lib/service/delivery/FileProtection.js +54 -0
  145. package/dist/lib/service/delivery/SkillsSyncer.js +16 -21
  146. package/dist/lib/service/evolution/ContentPatcher.d.ts +44 -0
  147. package/dist/lib/service/evolution/ContentPatcher.js +310 -0
  148. package/dist/lib/service/evolution/ProposalExecutor.d.ts +4 -0
  149. package/dist/lib/service/evolution/ProposalExecutor.js +77 -13
  150. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +64 -0
  151. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +458 -0
  152. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +89 -0
  153. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +492 -0
  154. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +44 -0
  155. package/dist/lib/service/evolution/createSupersedeProposal.js +81 -0
  156. package/dist/lib/service/guard/ComplianceReporter.d.ts +4 -0
  157. package/dist/lib/service/guard/ComplianceReporter.js +51 -0
  158. package/dist/lib/service/guard/GuardCheckEngine.js +5 -4
  159. package/dist/lib/service/knowledge/ConfidenceRouter.js +1 -1
  160. package/dist/lib/service/knowledge/KnowledgeService.d.ts +11 -1
  161. package/dist/lib/service/knowledge/KnowledgeService.js +44 -4
  162. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +225 -0
  163. package/dist/lib/service/knowledge/RecipeProductionGateway.js +384 -0
  164. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +3 -2
  165. package/dist/lib/service/panorama/DimensionAnalyzer.js +15 -140
  166. package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
  167. package/dist/lib/service/search/SearchEngine.d.ts +11 -10
  168. package/dist/lib/service/search/SearchEngine.js +38 -36
  169. package/dist/lib/service/search/SearchTypes.d.ts +14 -8
  170. package/dist/lib/service/search/SearchTypes.js +1 -1
  171. package/dist/lib/service/search/tokenizer.d.ts +1 -1
  172. package/dist/lib/service/search/tokenizer.js +2 -2
  173. package/dist/lib/shared/schemas/common.d.ts +4 -4
  174. package/dist/lib/shared/schemas/http-requests.d.ts +12 -1
  175. package/dist/lib/shared/schemas/http-requests.js +8 -0
  176. package/dist/lib/shared/schemas/mcp-tools.d.ts +32 -2
  177. package/dist/lib/shared/schemas/mcp-tools.js +38 -0
  178. package/dist/lib/types/evolution.d.ts +135 -0
  179. package/dist/lib/types/evolution.js +6 -0
  180. package/dist/lib/types/graph-shared.d.ts +25 -0
  181. package/dist/lib/types/graph-shared.js +7 -0
  182. package/dist/lib/types/knowledge-wire.d.ts +131 -0
  183. package/dist/lib/types/knowledge-wire.js +7 -0
  184. package/dist/lib/types/project-snapshot-builder.d.ts +19 -0
  185. package/dist/lib/types/project-snapshot-builder.js +189 -0
  186. package/dist/lib/types/project-snapshot.d.ts +399 -0
  187. package/dist/lib/types/project-snapshot.js +17 -0
  188. package/dist/lib/types/search-wire.d.ts +46 -0
  189. package/dist/lib/types/search-wire.js +7 -0
  190. package/dist/lib/types/snapshot-views.d.ts +58 -0
  191. package/dist/lib/types/snapshot-views.js +103 -0
  192. package/package.json +1 -1
  193. package/skills/autosnippet-recipes/SKILL.md +1 -1
  194. package/templates/instructions/agent-static.md +2 -0
  195. package/templates/instructions/conventions.md +3 -1
  196. package/templates/recipes-setup/README.md +2 -2
  197. package/dashboard/dist/assets/icons-BJ2mUBi8.js +0 -1
  198. package/dashboard/dist/assets/index-B659K9t5.js +0 -128
  199. package/dashboard/dist/assets/index-NCm40PMD.css +0 -1
  200. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.d.ts +0 -169
  201. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +0 -727
  202. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.d.ts +0 -370
  203. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +0 -821
@@ -5,17 +5,7 @@ export declare const PROJECT_ROOT: string;
5
5
  export declare const SKILLS_DIR: string;
6
6
  /** 项目级 skills 目录 */
7
7
  export declare const PROJECT_SKILLS_DIR: string;
8
- export declare const DIMENSION_DISPLAY_GROUP: {
9
- architecture: string;
10
- 'code-pattern': string;
11
- 'project-profile': string;
12
- 'best-practice': string;
13
- 'code-standard': string;
14
- 'event-and-data-flow': string;
15
- 'objc-deep-scan': string;
16
- 'category-scan': string;
17
- 'agent-guidelines': string;
18
- };
8
+ export { DIMENSION_DISPLAY_GROUP } from '#domain/dimension/DimensionRegistry.js';
19
9
  /**
20
10
  * 基于维度元数据 (dimensionMeta) 检查提交是否合法
21
11
  * @param dimensionMeta
@@ -25,10 +15,7 @@ export declare const DIMENSION_DISPLAY_GROUP: {
25
15
  export declare function checkDimensionType(dimensionMeta: DimensionMeta, params: Record<string, unknown>, logger?: {
26
16
  info(msg: string, ...args: unknown[]): void;
27
17
  warn(msg: string, ...args: unknown[]): void;
28
- } | null): {
29
- status: string;
30
- reason: string;
31
- } | null;
18
+ } | null): null;
32
19
  /** DI container service lookup (returns dynamic service instances) */
33
20
  export interface ServiceContainer {
34
21
  get(name: string): any;
@@ -67,3 +54,8 @@ export interface ToolSchemaEntry {
67
54
  description: string;
68
55
  parameters: Record<string, unknown>;
69
56
  }
57
+ /**
58
+ * 剥离标题中冗余的项目名前缀(如 "BiliDili 分页控制器" → "分页控制器")
59
+ * 同一知识库内所有条目都属于同一项目,标题中重复项目名没有信息量。
60
+ */
61
+ export declare function stripProjectNamePrefix(title: string, projectRoot: string): string;
@@ -6,18 +6,8 @@ export const PROJECT_ROOT = PACKAGE_ROOT;
6
6
  export const SKILLS_DIR = _SKILLS_DIR;
7
7
  /** 项目级 skills 目录 */
8
8
  export const PROJECT_SKILLS_DIR = path.resolve(PACKAGE_ROOT, '.autosnippet', 'skills');
9
- // Bootstrap 维度展示分组 — 9 个细粒度维度合并为 4 个展示组
10
- export const DIMENSION_DISPLAY_GROUP = {
11
- architecture: 'architecture', // → 架构与设计
12
- 'code-pattern': 'architecture', // → 架构与设计
13
- 'project-profile': 'architecture', // → 架构与设计
14
- 'best-practice': 'best-practice', // → 规范与实践
15
- 'code-standard': 'best-practice', // → 规范与实践
16
- 'event-and-data-flow': 'event-and-data-flow', // → 事件与数据流
17
- 'objc-deep-scan': 'objc-deep-scan', // → 深度扫描
18
- 'category-scan': 'objc-deep-scan', // → 深度扫描
19
- 'agent-guidelines': 'agent-guidelines', // skill-only
20
- };
9
+ // Bootstrap 维度展示分组 — DimensionRegistry 自动生成
10
+ export { DIMENSION_DISPLAY_GROUP } from '#domain/dimension/DimensionRegistry.js';
21
11
  /**
22
12
  * 基于维度元数据 (dimensionMeta) 检查提交是否合法
23
13
  * @param dimensionMeta
@@ -25,15 +15,7 @@ export const DIMENSION_DISPLAY_GROUP = {
25
15
  * @returns | null} 不合法返回 rejected,合法返回 null
26
16
  */
27
17
  export function checkDimensionType(dimensionMeta, params, logger) {
28
- // 1. Skill-only 维度不允许提交 Candidate
29
- if (dimensionMeta.outputType === 'skill') {
30
- logger?.info(`[submit_knowledge] ✗ rejected — dimension "${dimensionMeta.id}" is skill-only, cannot submit candidates`);
31
- return {
32
- status: 'rejected',
33
- reason: `当前维度 "${dimensionMeta.id}" 的输出类型为 skill-only,不允许调用 submit_knowledge。请只在最终回复中提供 dimensionDigest JSON。`,
34
- };
35
- }
36
- // 2. knowledgeType 校验 — 不在允许列表时自动修正为第一个允许类型
18
+ // 1. knowledgeType 校验 — 不在允许列表时自动修正为第一个允许类型
37
19
  const allowed = dimensionMeta.allowedKnowledgeTypes || [];
38
20
  if (allowed.length > 0 && params.knowledgeType) {
39
21
  if (!allowed.includes(params.knowledgeType)) {
@@ -44,3 +26,20 @@ export function checkDimensionType(dimensionMeta, params, logger) {
44
26
  }
45
27
  return null;
46
28
  }
29
+ /**
30
+ * 剥离标题中冗余的项目名前缀(如 "BiliDili 分页控制器" → "分页控制器")
31
+ * 同一知识库内所有条目都属于同一项目,标题中重复项目名没有信息量。
32
+ */
33
+ export function stripProjectNamePrefix(title, projectRoot) {
34
+ if (!title || !projectRoot) {
35
+ return title;
36
+ }
37
+ const projectName = path.basename(projectRoot);
38
+ if (!projectName || projectName.length < 2) {
39
+ return title;
40
+ }
41
+ // 匹配: "ProjectName 标题" / "ProjectName的标题" / "ProjectName — 标题"
42
+ const prefix = new RegExp(`^${projectName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*[的—–-]?\\s*`, 'i');
43
+ const stripped = title.replace(prefix, '');
44
+ return stripped.length > 0 ? stripped : title;
45
+ }
@@ -47,6 +47,8 @@ export interface SubmitWithCheckParams {
47
47
  sourceFile?: string;
48
48
  threshold?: number;
49
49
  knowledgeType?: string;
50
+ /** 被替代的旧 Recipe ID(进化架构入口) */
51
+ supersedes?: string;
50
52
  [key: string]: unknown;
51
53
  }
52
54
  export interface PlanTaskParams {
@@ -188,13 +190,14 @@ export declare const submitWithCheck: {
188
190
  type: string;
189
191
  description: string;
190
192
  };
193
+ supersedes: {
194
+ type: string;
195
+ description: string;
196
+ };
191
197
  };
192
198
  required: string[];
193
199
  };
194
200
  handler: (params: SubmitWithCheckParams, ctx: ToolHandlerContext) => Promise<{
195
- status: string;
196
- reason: string;
197
- } | {
198
201
  submitted: boolean;
199
202
  status: string;
200
203
  reason: string;
@@ -204,10 +207,19 @@ export declare const submitWithCheck: {
204
207
  confidence: string;
205
208
  hint: string;
206
209
  };
210
+ error?: undefined;
211
+ similar?: undefined;
212
+ highestSimilarity?: undefined;
213
+ } | {
214
+ submitted: boolean;
215
+ reason: string;
216
+ error: string;
217
+ status?: undefined;
218
+ errors?: undefined;
219
+ warnings?: undefined;
220
+ _meta?: undefined;
207
221
  similar?: undefined;
208
222
  highestSimilarity?: undefined;
209
- entry?: undefined;
210
- error?: undefined;
211
223
  } | {
212
224
  submitted: boolean;
213
225
  reason: string;
@@ -224,37 +236,28 @@ export declare const submitWithCheck: {
224
236
  status?: undefined;
225
237
  errors?: undefined;
226
238
  warnings?: undefined;
227
- entry?: undefined;
228
239
  error?: undefined;
229
240
  } | {
241
+ _meta: {
242
+ confidence: string;
243
+ hint: string;
244
+ };
245
+ _supersedeProposal?: {
246
+ proposalId: string;
247
+ } | undefined;
230
248
  submitted: boolean;
231
- entry: any;
249
+ entry: unknown;
232
250
  similar: {
233
251
  file: string;
234
252
  title: string;
235
253
  similarity: number;
236
254
  }[];
237
- _meta: {
238
- confidence: string;
239
- hint: string;
240
- };
241
255
  status?: undefined;
242
256
  reason?: undefined;
243
257
  errors?: undefined;
244
258
  warnings?: undefined;
245
- highestSimilarity?: undefined;
246
259
  error?: undefined;
247
- } | {
248
- submitted: boolean;
249
- reason: string;
250
- error: string;
251
- status?: undefined;
252
- errors?: undefined;
253
- warnings?: undefined;
254
- _meta?: undefined;
255
- similar?: undefined;
256
260
  highestSimilarity?: undefined;
257
- entry?: undefined;
258
261
  }>;
259
262
  };
260
263
  /**
@@ -9,9 +9,8 @@
9
9
  * ── review_my_output 元工具: 自我质量审查
10
10
  */
11
11
  import { getInternalAgentRequiredFields, getSystemInjectedFields, } from '#domain/knowledge/FieldSpec.js';
12
- import { UnifiedValidator } from '#domain/knowledge/UnifiedValidator.js';
13
12
  import { findSimilarRecipes } from '#service/candidate/SimilarityService.js';
14
- import { checkDimensionType, DIMENSION_DISPLAY_GROUP, } from './_shared.js';
13
+ import { checkDimensionType, DIMENSION_DISPLAY_GROUP, stripProjectNamePrefix, } from './_shared.js';
15
14
  // ────────────────────────────────────────────────────────────
16
15
  // 34. analyze_code — 组合工具 (Guard + Recipe 搜索)
17
16
  // ────────────────────────────────────────────────────────────
@@ -182,13 +181,24 @@ export const submitWithCheck = {
182
181
  enum: ['basic', 'intermediate', 'advanced'],
183
182
  description: '复杂度',
184
183
  },
185
- sourceFile: { type: 'string', description: '来源文件相对路径' },
184
+ sourceFile: {
185
+ type: 'string',
186
+ description: 'Recipe md 文件相对路径(由系统自动设置,无需手动填写)',
187
+ },
186
188
  threshold: { type: 'number', description: '相似度阈值,默认 0.7' },
189
+ supersedes: {
190
+ type: 'string',
191
+ description: '被替代的旧 Recipe ID。传入后将创建 supersede 提案,72h 观察窗口后自动替代。',
192
+ },
187
193
  },
188
194
  required: getInternalAgentRequiredFields(),
189
195
  },
190
196
  handler: async (params, ctx) => {
191
197
  const projectRoot = ctx.projectRoot;
198
+ // ── 标题正规化:剥离冗余的项目名前缀 ──
199
+ if (params.title) {
200
+ params.title = stripProjectNamePrefix(params.title, projectRoot);
201
+ }
192
202
  // ── Bootstrap 维度类型校验 ──
193
203
  const dimMeta = ctx._dimensionMeta;
194
204
  if (dimMeta && ctx.source === 'system') {
@@ -206,122 +216,111 @@ export const submitWithCheck = {
206
216
  params.tags.push('bootstrap');
207
217
  }
208
218
  }
209
- // Step 0.5: UnifiedValidator 质量验证(与 submit_knowledge 对齐)
219
+ // ── 系统自动设置 ──
220
+ const item = {
221
+ ...params,
222
+ language: ctx._projectLanguage || '',
223
+ category: dimMeta ? dimMeta.id : 'general',
224
+ knowledgeType: dimMeta?.allowedKnowledgeTypes?.[0] || params.knowledgeType || 'code-pattern',
225
+ source: ctx.source === 'system' ? 'bootstrap' : 'agent',
226
+ agentNotes: dimMeta
227
+ ? { dimensionId: dimMeta.id, outputType: dimMeta.outputType || 'candidate' }
228
+ : null,
229
+ };
210
230
  if (dimMeta && ctx.source === 'system') {
211
- const validator = ctx._validator ||
212
- new UnifiedValidator({
213
- existingTitles: ctx._submittedTitles || new Set(),
214
- existingFingerprints: ctx._submittedPatterns || new Set(),
215
- });
216
- const validResult = validator.validate(params, {
217
- systemInjectedFields: getSystemInjectedFields(),
231
+ const displayGroup = DIMENSION_DISPLAY_GROUP[dimMeta.id] || dimMeta.id;
232
+ item.tags = [...new Set([...(item.tags || []), displayGroup])];
233
+ }
234
+ // ── 委托 RecipeProductionGateway 统一管道(含查重) ──
235
+ try {
236
+ const { RecipeProductionGateway } = await import('#service/knowledge/RecipeProductionGateway.js');
237
+ const gateway = new RecipeProductionGateway({
238
+ knowledgeService: ctx.container.get('knowledgeService'),
239
+ projectRoot,
240
+ logger: ctx.logger,
241
+ proposalRepository: ctx.container.get('proposalRepository') ?? null,
242
+ findSimilarRecipes,
218
243
  });
219
- if (!validResult.pass) {
220
- ctx.logger?.info(`[submit_with_check] ✗ validator rejected: ${validResult.errors.join('; ')}`);
244
+ const gatewayResult = await gateway.create({
245
+ source: 'agent-tool',
246
+ items: [item],
247
+ options: {
248
+ skipSimilarityCheck: false,
249
+ skipConsolidation: true,
250
+ similarityThreshold: params.threshold || 0.7,
251
+ supersedes: params.supersedes,
252
+ existingTitles: ctx._submittedTitles,
253
+ existingFingerprints: ctx._submittedPatterns,
254
+ systemInjectedFields: getSystemInjectedFields(),
255
+ userId: 'agent',
256
+ },
257
+ });
258
+ // ── 映射 Gateway 结果 → 原有返回格式 ──
259
+ // 验证拒绝
260
+ if (gatewayResult.rejected.length > 0 && gatewayResult.created.length === 0) {
261
+ const rej = gatewayResult.rejected[0];
262
+ if (rej.reason === 'validation_failed') {
263
+ return {
264
+ submitted: false,
265
+ status: 'rejected',
266
+ reason: 'validation_failed',
267
+ errors: rej.errors,
268
+ warnings: rej.warnings,
269
+ _meta: {
270
+ confidence: 'high',
271
+ hint: '请根据错误信息调整内容后重新提交。',
272
+ },
273
+ };
274
+ }
275
+ return { submitted: false, reason: 'submit_error', error: rej.errors.join('\n') };
276
+ }
277
+ // 重复阻止
278
+ if (gatewayResult.duplicates.length > 0) {
279
+ const dup = gatewayResult.duplicates[0];
221
280
  return {
222
281
  submitted: false,
223
- status: 'rejected',
224
- reason: 'validation_failed',
225
- errors: validResult.errors,
226
- warnings: validResult.warnings,
282
+ reason: 'duplicate_blocked',
283
+ similar: dup.similarTo,
284
+ highestSimilarity: dup.similarTo[0]?.similarity || 0,
227
285
  _meta: {
228
286
  confidence: 'high',
229
- hint: '请根据错误信息调整内容后重新提交。',
287
+ hint: `发现高度相似 Recipe(相似度 ${((dup.similarTo[0]?.similarity || 0) * 100).toFixed(0)}%),已阻止提交。`,
230
288
  },
231
289
  };
232
290
  }
233
- }
234
- // Step 1: 查重
235
- const threshold = params.threshold || 0.7;
236
- const contentObj2 = params.content && typeof params.content === 'object'
237
- ? params.content
238
- : { markdown: '', pattern: '' };
239
- const cand = {
240
- title: params.title || '',
241
- summary: params.description || '',
242
- code: contentObj2.markdown || contentObj2.pattern || '',
243
- };
244
- const similar = findSimilarRecipes(projectRoot, cand, { threshold: 0.5, topK: 5 });
245
- const hasDuplicate = similar.some((s) => s.similarity >= threshold);
246
- if (hasDuplicate) {
247
- return {
248
- submitted: false,
249
- reason: 'duplicate_blocked',
250
- similar,
251
- highestSimilarity: similar[0]?.similarity || 0,
252
- _meta: {
253
- confidence: 'high',
254
- hint: `发现高度相似 Recipe(相似度 ${(similar[0]?.similarity * 100).toFixed(0)}%),已阻止提交。`,
255
- },
256
- };
257
- }
258
- // Step 2: 提交 — 委托给 submit_knowledge handler
259
- try {
260
- const knowledgeService = ctx.container.get('knowledgeService');
261
- const reasoning = params.reasoning || {
262
- whyStandard: '',
263
- sources: ['agent'],
264
- confidence: 0.7,
265
- };
266
- const systemFields = {
267
- language: ctx._projectLanguage || '',
268
- category: dimMeta
269
- ? DIMENSION_DISPLAY_GROUP[dimMeta.id] || dimMeta.id
270
- : 'general',
271
- knowledgeType: dimMeta?.allowedKnowledgeTypes?.[0] || 'code-pattern',
272
- source: ctx.source === 'system' ? 'bootstrap' : 'agent',
273
- };
274
- const data = {
275
- ...systemFields,
276
- title: params.title || '',
277
- description: params.description || '',
278
- tags: params.tags || [],
279
- trigger: params.trigger || '',
280
- kind: params.kind || 'pattern',
281
- topicHint: params.topicHint || '',
282
- whenClause: params.whenClause || '',
283
- doClause: params.doClause || '',
284
- dontClause: params.dontClause || '',
285
- coreCode: contentObj2.pattern || '',
286
- content: contentObj2,
287
- reasoning,
288
- // V3 扩展字段直透(与 submit_knowledge 对齐)
289
- headers: params.headers || [],
290
- usageGuide: params.usageGuide || '',
291
- scope: params.scope || '',
292
- complexity: params.complexity || '',
293
- // 注意: sourceFile 由 KnowledgeFileWriter.persist() 自动设置,
294
- // 不应从 AI params/reasoning.sources 取值(那是项目源文件路径,不是知识文件路径)
295
- sourceFile: '',
296
- // agentNotes / aiInsight(与 submit_knowledge 对齐)
297
- agentNotes: dimMeta
298
- ? { dimensionId: dimMeta.id, outputType: dimMeta.outputType || 'candidate' }
299
- : null,
300
- aiInsight: reasoning.whyStandard || params.description || null,
301
- };
302
- if (dimMeta && ctx.source === 'system') {
303
- const displayGroup = DIMENSION_DISPLAY_GROUP[dimMeta.id] || dimMeta.id;
304
- data.tags = [...new Set([...(data.tags || []), displayGroup])];
305
- }
306
- const created = await knowledgeService.create(data, { userId: 'agent' });
307
- // QualityScorer 自动评分(与 submit_knowledge 对齐)
308
- try {
309
- await knowledgeService.updateQuality(created.id, { userId: 'agent' });
310
- }
311
- catch {
312
- /* best effort */
291
+ // 成功创建
292
+ if (gatewayResult.created.length > 0) {
293
+ const created = gatewayResult.created[0];
294
+ const raw = created.raw;
295
+ const entry = typeof raw.toJSON === 'function'
296
+ ? raw.toJSON()
297
+ : raw;
298
+ // 获取低相似度匹配(如有)
299
+ const contentObj2 = params.content && typeof params.content === 'object'
300
+ ? params.content
301
+ : { markdown: '', pattern: '' };
302
+ const cand = {
303
+ title: params.title || '',
304
+ summary: params.description || '',
305
+ code: contentObj2.markdown || contentObj2.pattern || '',
306
+ };
307
+ const similar = findSimilarRecipes(projectRoot, cand, { threshold: 0.5, topK: 5 });
308
+ return {
309
+ submitted: true,
310
+ entry,
311
+ similar: similar.length > 0 ? similar : [],
312
+ ...(gatewayResult.supersedeProposal
313
+ ? { _supersedeProposal: gatewayResult.supersedeProposal }
314
+ : {}),
315
+ _meta: {
316
+ confidence: 'high',
317
+ hint: similar.length > 0
318
+ ? `已提交,但有 ${similar.length} 个低相似度匹配。`
319
+ : '已提交,无重复风险。',
320
+ },
321
+ };
313
322
  }
314
- return {
315
- submitted: true,
316
- entry: typeof created.toJSON === 'function' ? created.toJSON() : created,
317
- similar: similar.length > 0 ? similar : [],
318
- _meta: {
319
- confidence: 'high',
320
- hint: similar.length > 0
321
- ? `已提交,但有 ${similar.length} 个低相似度匹配。`
322
- : '已提交,无重复风险。',
323
- },
324
- };
323
+ return { submitted: false, reason: 'submit_error', error: 'No items created' };
325
324
  }
326
325
  catch (err) {
327
326
  return { submitted: false, reason: 'submit_error', error: err.message };
@@ -0,0 +1,145 @@
1
+ /**
2
+ * evolution-tools.ts — Evolution Agent 专用工具
3
+ *
4
+ * 三个提案驱动的决策工具,供 Evolution Agent 在 rescan 时对现有 Recipe 做出明确决策:
5
+ * - propose_evolution: 附加进化提案(代码已变但知识仍有价值)
6
+ * - confirm_deprecation: 确认 Recipe 应被废弃(加速 deprecate 流程)
7
+ * - skip_evolution: 显式跳过进化决策(仍然有效或信息不足)
8
+ *
9
+ * @module agent/tools/evolution-tools
10
+ */
11
+ import type { ToolHandlerContext } from './_shared.js';
12
+ export interface ProposeEvolutionParams {
13
+ recipeId: string;
14
+ type: 'enhance' | 'correction';
15
+ description: string;
16
+ evidence: {
17
+ sourceStatus: 'exists' | 'moved' | 'modified' | 'deleted';
18
+ currentCode?: string;
19
+ newLocation?: string;
20
+ suggestedChanges: string;
21
+ };
22
+ confidence: number;
23
+ }
24
+ interface ConfirmDeprecationParams {
25
+ recipeId: string;
26
+ reason: string;
27
+ }
28
+ interface SkipEvolutionParams {
29
+ recipeId: string;
30
+ reason: string;
31
+ }
32
+ export declare const proposeEvolution: {
33
+ name: string;
34
+ description: string;
35
+ parameters: {
36
+ type: string;
37
+ properties: {
38
+ recipeId: {
39
+ type: string;
40
+ description: string;
41
+ };
42
+ type: {
43
+ type: string;
44
+ enum: string[];
45
+ description: string;
46
+ };
47
+ description: {
48
+ type: string;
49
+ description: string;
50
+ };
51
+ evidence: {
52
+ type: string;
53
+ description: string;
54
+ properties: {
55
+ sourceStatus: {
56
+ type: string;
57
+ enum: string[];
58
+ description: string;
59
+ };
60
+ currentCode: {
61
+ type: string;
62
+ description: string;
63
+ };
64
+ newLocation: {
65
+ type: string;
66
+ description: string;
67
+ };
68
+ suggestedChanges: {
69
+ type: string;
70
+ description: string;
71
+ };
72
+ };
73
+ required: string[];
74
+ };
75
+ confidence: {
76
+ type: string;
77
+ description: string;
78
+ };
79
+ };
80
+ required: string[];
81
+ };
82
+ handler: (params: ProposeEvolutionParams, ctx: ToolHandlerContext) => Promise<{
83
+ status: "error";
84
+ message: string;
85
+ recipeId: string;
86
+ proposalId?: undefined;
87
+ type?: undefined;
88
+ expiresAt?: undefined;
89
+ } | {
90
+ status: "proposed";
91
+ proposalId: string;
92
+ recipeId: string;
93
+ type: "enhance" | "correction";
94
+ expiresAt: number;
95
+ message?: undefined;
96
+ }>;
97
+ };
98
+ export declare const confirmDeprecation: {
99
+ name: string;
100
+ description: string;
101
+ parameters: {
102
+ type: string;
103
+ properties: {
104
+ recipeId: {
105
+ type: string;
106
+ description: string;
107
+ };
108
+ reason: {
109
+ type: string;
110
+ description: string;
111
+ };
112
+ };
113
+ required: string[];
114
+ };
115
+ handler: (params: ConfirmDeprecationParams, ctx: ToolHandlerContext) => Promise<{
116
+ status: string;
117
+ recipeId: string;
118
+ reason: string;
119
+ result: unknown;
120
+ }>;
121
+ };
122
+ export declare const skipEvolution: {
123
+ name: string;
124
+ description: string;
125
+ parameters: {
126
+ type: string;
127
+ properties: {
128
+ recipeId: {
129
+ type: string;
130
+ description: string;
131
+ };
132
+ reason: {
133
+ type: string;
134
+ description: string;
135
+ };
136
+ };
137
+ required: string[];
138
+ };
139
+ handler: (params: SkipEvolutionParams, _ctx: ToolHandlerContext) => Promise<{
140
+ status: string;
141
+ recipeId: string;
142
+ reason: string;
143
+ }>;
144
+ };
145
+ export {};